sdlins
sdlins

Reputation: 2295

Is there a way to make table fields protected in Yii models to enforce getter/setters in the model?

Example...

Person - fields of the table:

Now, let's suppose I have the model $person in my code. I would like that everytime was called $person->name='TheName' Yii called the my customized function $person->setName('TheName'), enforcing the setter.

Is there a way to accomplish that?

I tryed to make the model's attributes protected/private but it does not work. Yii seems only to call the setter/getter AFTER to check if the attribute exists at the table. When the attribute exists, yii set it and no setter is called.

Thanks in advance.

UPDATE: The reason is that I have already so many use of $model->attribX in a system but now I need to implement someway to trigge some 'chained' update depending on $model->attribX is changed and I dont want to change all of '$model->attribX' by something like '$model->changeAttribX(...)';

Upvotes: 1

Views: 1037

Answers (2)

Jon
Jon

Reputation: 437434

Yii's implementation of __get and __set in CActiveRecord is different than the "standard" one in CComponent; the latter checks for (and prefers to use) a getter and a setter for the property, while the former does not do this at all.

To directly answer your question: you would need to build this functionality into your own class having the two implementations mentioned above as a guide, e.g. somewhat like this for the setter:

public function setAttribute($name,$value)
{
    $setter='set'.$name;
    if(method_exists($this,$setter))
        $this->$setter($value);
    else if(property_exists($this,$name))
        $this->$name=$value;
    else if(isset($this->getMetaData()->columns[$name]))
        $this->_attributes[$name]=$value;
    else
        return false;

    return true;
}

This implementation gives precedence to getters and setters over bare properties, which may or may not be what you want. After subclassing CActiveRecord like this, you would derive your own models from the subclass.

Important consideration: All the same, you do not say what you want to achieve using this functionality and this raises questions. For example, usually features like this are used to validate values, but Yii has its own validation system in place. It is possible that there is a better (more Yii-like) way to do what you want.

Upvotes: 2

Mukesh Soni
Mukesh Soni

Reputation: 6668

What i get from your question is - "I want to do some stuff before the field is saved in the database". If that is the question, you can override the beforeSave() method.

public function beforeSave() {
    if (count($this->name) > 100)
       echo "how come your name is so big?";

    return parent::beforeSave();
}

Upvotes: 0

Related Questions