Hidden model fields
Probably there are some fields in your models, usually holding sensitive data, that you do not want to display to the end users. In my case these are passwords, activation codes, etc. I want to ensure that values stored in these fields will be never exposed, neither intentionally nor by accident. So I came up with this little solution.
This is implementation of afterFind() callback function that should be placed inside of app_model.php file.
// app_model.php class AppModel extends Model { var $hiddenFields = array(); function afterFind($result, $primary = false) { foreach ($result as &$row) foreach ($this->hiddenFields as $field) if (isset($row[$this->name][$field])) unset($row[$this->name][$field]); return $result; } }
The last thing to do is to define $hiddenFields variable in your model.
var $hiddenFields = array('password', 'activation_code');
As you may have noticed, values of these fields are retrieved from the database and later unset. If you don’t want them to be retrieved at all (this would be more secure), you should take care of filtering this fields out in beforeFind() callback method, however this could be quite cumbersome. For me it was OK enough to just unset them after retrieval, so I even didn’t try to do it through beforeFind().
There are also drawbacks. For example you can’t retrieve someone’s password and send it by e-mail when someone forgets it (in fact you can still get it with model’s query() method, but it’s not a ‘clean’ way). In such situations you should generate new random password instead of reminding the forgotten one.
If you have any views on this, please leave a comment.
Related posts
4 Responses to 'Hidden model fields'
Sorry, comments are closed for this post.

Hi,
I tried your method but get this error…
Parse error: parse error, unexpected ‘&’, expecting T_VARIABLE or ‘$’ in /…../app/app_model.php on line 7
is it because I’m running on PHP 4?
JC
20 Nov 07 at 10:37
Hi,
I didn’t test it on PHP4. That may be the case, but I’m not sure.
Alternatively you can write:
function afterFind($result, $primary = false) { foreach ($result as $k => $row) foreach ($this->hiddenFields as $field) if (isset($result[$k][$this->name][$field])) unset($result[$k][$this->name][$field]); return $result; }admin
20 Nov 07 at 12:36
Hey,
Thanks for the code - just what I was looking for.
Small problem though, I’m using the containable feature of CakePHP 1.2, and there are some HABTM/HasMany models such as PostsUsers … in that it returns all the Users info who made posts. The ‘password’ field is not being hidden in there. Basically the array is one level deeper and your code doesnt loop through that. I’m not sure how to modify your code to achieve that, maybe you can help out?
Thanks
Fahd
22 Mar 09 at 03:27
Hi,
this code is a bit old now. In fact I didn’t use this for some time myself :)
If I was to write this again, I’d probably encapsulate this in a Behavior, so that would be easier to hide fields from associated finds.
Michał Szajbe
27 Mar 09 at 16:56