Search code examples
phpfilteraoplithium

Lithium Generic Model Filter


I am currently developing a Lithium application which requires various things to be added to an object before save() is called.

Ideally I would be able to write a filter to apply to the Model class (the base model that other models extends) such as the following:

Model::applyFilter('save', function($self, $params, $chain) {
    // Logic here
});

Is this possible? If so should it be a bootstrapped file?


Solution

  • If I'm not misunderstanding what you're saying, you want to, for example, automatically add a value for 'created' or 'modified' to an object before save.

    Here's how I do that.

    From my extensions/data/Model.php

    <?php
    namespace app\extensions\data;
    use lithium\security\Password;
    
    class Model extends \lithium\data\Model {
    
        public static function __init() {
            parent::__init();
    
            // {{{ Filters
            static::applyFilter('save', function($self, $params, $chain) {
                $date   = date('Y-m-d H:i:s', time());
                $schema = $self::schema();
    
                //do these things only if they don't exist (i.e.  on creation of object)
                if (!$params['entity']->exists()) {
    
                    //hash password
                    if (isset($params['data']['password'])) {
                        $params['data']['password'] = Password::hash($params['data']['password']);
                    }
    
                    //if 'created' doesn't already exist and is defined in the schema...
                    if (empty($params['date']['created']) && array_key_exists('created', $schema)) {
                        $params['data']['created'] = $date;
                    }
                }
    
                if (array_key_exists('modified', $schema)) {
                    $params['data']['modified'] = $date;
                }
                return $chain->next($self, $params, $chain);
            });
            // }}}
        }
    }
    
    ?>
    

    I have some password hashing there as well. You can remove that without affecting any functionality.