marc casas
marc casas

Reputation: 143

How to create a whitelist of updatable fields in a CakePHP's model?

I want to create a whitelist of fields that I want to be updatable in CakePHP. I know that I can pass a fieldList array in the call to Model::save(), but this isn't what I'm looking for. What I want is that every model "publish" a list of the valid fields, so if I call the Model::save() method without a fieldList and with data that mustn't be updatable (like the ownerId) this won't be updated.

What can I do to get this behavior? Maybe override the Model::save method in every Model to call at the "original" Model::save with the whitelist? I think this is a good idea, because I don't pollute all the controllers with lots of duplicated whitelists...

Thanks for your help!

Upvotes: 1

Views: 918

Answers (2)

marc casas
marc casas

Reputation: 143

Well, thanks you all for your answers, but I was wrong: I don't need to add this functionality.

The problem I was trying to solve was a security problem, I was trying to avoid form tampering (I've discovered the name just now), and as I am a novice CakePHP user, I didn't know that CakePHP already manages this problem.

The answer to my question is very easy: I must use CakePHP's Security Plugin and use the Form Tampering prevention (http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#form-tampering-prevention).

Upvotes: 2

Martin Bean
Martin Bean

Reputation: 39399

Can‘t say I’ve ever needed to do this in CakePHP, but CakePHP only saves the fields you pass it.

If you really need to create a white-list and you’re certain you only ever want these fields saving and never any others in your database (although I don’t understand why you have columns for them if you never touch them) then you could emulate this behavior in a model callback method:

<?php
class User extends AppModel {

    public function beforeSave($options = array()) {
        $whitelist = array('first_name', 'last_name', 'email');

        foreach ($this->data[$this->alias] as $field => $value) {
            if (!in_array($field, $whitelist)) {
                unset($this->data[$this->alias][$field]);
            }
        }

        return true;
    }
}

This will just unset any data not in the $whitelist array, but if you really don’t want a column being updated then don’t pass a value for it.

Upvotes: 0

Related Questions