Search code examples
cakephpcallbackcakephp-2.1datamodel

Receive model data inside a CakePHP model callback function


I try to use existing model data inside a models callback function in CakePHP 2.1 but can't get it working. What I do is I try to get a users role in the beforeValidate() callback and check if it's empty. If yes, I'll set it. Normally I do it like this, and for the first creation of the record it works pretty well.

if (empty($this->data[$this->alias]['role']))
    $this->data[$this->alias]['role'] = 'user';

The problem is, every time an existing record (user) gets updated, the role will be set again.

Question: So, how do I check if the field role is already set in the record data, not the post data (seems like $this->data[$this->alias] only contains POST data)?


Solution

  • There are three solutions to this problem as I can see it.

    1. Set a default value in the database column (easiest, best?)
    2. Add role to your inputs everytime.
    3. Lookup the user and add a role if it's missing

    The first two options seem obvious, so I'll just illustrate the last.

    public function beforeValidate() {
      if (!empty($this->id) {
        $this->data[$this->alias][$this->primaryKey] = $this->id;
      }
      if (!empty($this->data[$this->alias][$this->primaryKey])) {
        // user exists, check their data
        $id = $this->data[$this->alias][$this->primaryKey];
        $user = $this->find('first', array(
          'conditions' => array($this->primaryKey => $id)
        ));
        $this->data[$this->alias]['role'] = $user[$this->alias]['role'];
      }
      if (empty($this->data[$this->alias]['role'])) {
        // new user but missing a role
        $this->data[$this->alias]['role'] = 'user';
      }
      return true;
    }
    

    This callback will check if an ID was passed, and if so it will look up the user and populate the role field. Then, it checks for an empty role and fills it with the default if necessary. Obviously he more code you have, the more possibilities for bugs, so I suggest the first option for default column values.