We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Central Preprocessor for incoming requests

hi guys

I have a landing page in angular where I have 3 forms : Login, Signup and forgot password. Now all the three forms POST via $http service on a single controller but 3 different actions.

Each action does a certain common tasks like regenrating the CSRF tokens, cleansing the form data. I want to follow DRY approach and abstract away these certain task at a single place. I am pretty new to phalcon so don't know how to achieve it and where to achieve it in phalcon.

public function signUpAction() {

    if ($this->request->isPost()) {
        try{
            $rawPost    = $this->request->getJsonRawBody();
            $csrfKey    = $this->session->get('$PHALCON/CSRF/KEY$');
            @$csrfToken = $rawPost->{$csrfKey};

            if ($this->security->checkToken($csrfKey, $csrfToken)) {

                /* Common Tasks START  */
                $result['newCsrfKey'] = $this->security->getTokenKey();
                $result['newCsrfVal'] = $this->security->getToken();
                $cleanPost = Security::clean_external_data($rawPost);
                /* Common Tasks END */

                $cleanPost['password'] = Security::get_salted_hash($cleanPost['password']);
                $newUserEntity = new MoneyManagerUsers();
                $saved = $newUserEntity->save($cleanPost, ['name', 'email', 'password']);
            }
            else
                throw new Exception("CSRF ATTACK");

        }
        catch(Exception $e) {
            echo $e->getMessage(); die;
        }
    }

}
edited Oct '15

Create service SessionService or something like that, put your code there, register class, add this service to DI and get this service in action from di. I am adding properties to controller and using intialize method for getting all services which im using in my controlle actions(i have a lot of them cuz i like tiny controllers and dont like writeing everwhere where i sue service $this->di->get(serviceName), $this->sessionService for example is much cleaner.

You can find more about services and DI in documatnation.

Hey man thanks for the suggestion. However I found a simple workaroud for the situation. The beforeExecuteRoute && afterExecuteRoute provide a configuration space for my action execution.

What I did was declared a protected array in the controller which will be acting like a glue :

class MoneymanagerController extends ControllerBase{
      protected $retObj = [];
      protected $postBag = [];
      public function beforeExecuteRoute($dispatcher){
          if ($this->request->isPost()) {
                $this->retObj['newCsrfKey'] = $this->security->getTokenKey();
                $this->retObj['newCsrfVal'] = $this->security->getToken();
                $rawPost = $this->request->getJsonRawBody();
                $this->postBag = Security::clean_external_data($rawPost);
          }
      }
      // Other actions in the controller can access the clean form vals and CSRF tokens via $postBag && $retObj respectively
}

Let me know if this approach is good?

Probably

            $this->retObj['newCsrfKey'] = $this->security->getTokenKey();
            $this->retObj['newCsrfVal'] = $this->security->getToken();

these two statements will go in afterExecuteRoute method

edited Oct '15

Yea this approach is even better ;) But still you can put this code:

if ($this->request->isPost()) {
                $this->retObj['newCsrfKey'] = $this->security->getTokenKey();
                $this->retObj['newCsrfVal'] = $this->security->getToken();
                $rawPost = $this->request->getJsonRawBody();
                $this->postBag = Security::clean_external_data($rawPost);
          }

in service