TheStoryCoder TheStoryCoder - 1 month ago 26
PHP Question

Yii2: custom setter method/data transformation doesn't work on ActiveRecord?

I'm trying to do data transformation on an attribute by using the setter method

setUsr_firstname
for an attribute that is named
usr_firstname
.

class User extends ActiveRecord implements IdentityInterface {

public function rules() {
return [
[['usr_firstname', 'usr_lastname', ... ], 'required'],
...
];
}

...

public function setUsr_firstname($value) {
$this->usr_firstname = fix_wrong_title_case($value);
}
}


Then I do the following:

$model = new User(['scenario' => User::SCENARIO_REGISTER]);
$model->usr_firstname = 'John';


But the setter method is never called! I have tried naming the method all kinds of things - eg.
setUsrFirstname
- but nothing works. How do I get this to work?

UPDATE

Figured out it doesn't work for any ActiveRecord attribute, with or without an underscore in the attribute name.

Answer

Setter method is not called in case of properties declared directly or Active Record attributes (no matter if it's with the underscore or not).

Active Record's magic __set method assigns value directly to the mapped attribute.

You can achieve something similar with new virtual attribute:

public function setUsrFirstname($value)
{
    $this->usr_firstname = doSomethingWith($value);
}

public function getUsrFirstname()
{
    return $this->usr_firstname;
}

So now you can use it like:

$this->usrFirstname = 'John';
echo $this->usrFirstname;

If you want to modify the attribute in the life cycle of AR you can:

  • use FilterValidator to change it during validation,
  • override model's afterFind() method to change it after DB fetch,
  • override model's beforeSave() method to change it before saving to DB,
  • prepare behavior that can do all the things above,
  • prepare method to be called directly that will change it (you can use the first setter method for this; no need to call validate() and clearErrors()).
Comments