Search code examples
phpinheritancelithium

Does $_schema get inherited in Lithium parent & child Model?


We all know that functions are inherited, but how about the protected $_schema of Lithium Model?

For example, I have:

class ParentModel extends Model {
   protected $_schema = array(
     'name' => array('type' => 'string'),
     'address' => array('type' => 'string'),
    );
}

class ChildModel extends ParentModel {
    protected $_schema = array(
        'mobile' => array('type' => 'string'),
        'email' => array('type' => 'string'),
    );
}

I wonder when saving a ChildModel record, would the $_schema of ChildModel combined with the $_schema of ParentModel? That's:

array(
    'name' => array('type' => 'string'),
    'address' => array('type' => 'string'),
    'mobile' => array('type' => 'string'),
    'email' => array('type' => 'string'),
);

How can I check if this is the case?

Big Thanks


Solution

  • Typically in PHP, variables defined this way will override the parent class' default value for the same class. However, Lithium models have code that iterates through parents and merges in their defaults for $_schema and all other variables listed in $_inherits and the defaults returned by Model::_inherited().

    Here is the code for this in the 1.0-beta release

    /**
     * Merge parent class attributes to the current instance.
     */
    protected function _inherit() {
        $inherited = array_fill_keys($this->_inherited(), array());
        foreach (static::_parents() as $parent) {
            $parentConfig = get_class_vars($parent);
            foreach ($inherited as $key => $value) {
                if (isset($parentConfig["{$key}"])) {
                    $val = $parentConfig["{$key}"];
                    if (is_array($val)) {
                        $inherited[$key] += $val;
                    }
                }
            }
            if ($parent === __CLASS__) {
                break;
            }
        }
        foreach ($inherited as $key => $value) {
            if (is_array($this->{$key})) {
                $this->{$key} += $value;
            }
        }
    }
    /**
     * Return inherited attributes.
     *
     * @param array
     */
    protected function _inherited() {
        return array_merge($this->_inherits, array(
            'validates',
            'belongsTo',
            'hasMany',
            'hasOne',
            '_meta',
            '_finders',
            '_query',
            '_schema',
            '_classes',
            '_initializers'
        ));
    }
    

    Here are some of the unit tests that cover this functionality: https://github.com/UnionOfRAD/lithium/blob/1.0-beta/tests/cases/data/ModelTest.php#L211-L271