views:

66

answers:

0

I'm trying to write a Meta behavior for a project I am working on that will allow me to assign custom variables/attributes to a model, similar to how you can create custom fields in a wordpress post.

I have created a Meta behavior that binds the meta model to the model it is acting on and also has a beforeSave callback that loops through the models data variable and puts the model name into the meta array.

Everything is saving but when I check the database the model field is coming back empty.

The database structure for the Meta is

id - A unique if for the meta
model - The name of the model that this meta entry is associated with
foreign_id - The id of the above model that this meta entry is associated with
key - Name of the meta variable
value - Value of the meta variable

The data that comes to the saveAll function from the form is

Array
(
    [Page] => Array
        (
            [id] => 12
            [name] => Test
            [slug] => a/b/c/d
            [layout] => 0
            [body] => Test multilevel
        )

    [Meta] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [key] => page_title
                    [value] => About Us
                )

            [1] => Array
                (
                    [id] => 6
                    [key] => test4
                    [value] => test
                )

            [2] => Array
                (
                    [key] => test3
                    [value] => lala
                )

        )

)

and after it has run through the behavior beforeSave it is

Array
(
    [Page] => Array
        (
            [id] => 12
            [name] => Test
            [slug] => a/b/c/d
            [layout] => 0
            [body] => Test multilevel
            [modified] => 2010-05-04 15:56:54
        )

    [Meta] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [key] => page_title
                    [value] => About Us
                    [model] => Page
                )

            [1] => Array
                (
                    [id] => 6
                    [key] => test4
                    [value] => test
                    [model] => Page
                )

            [2] => Array
                (
                    [key] => test3
                    [value] => lala
                    [model] => Page
                )

        )

)

The code from the behavior is

<?php
/**
 * Meta Model Behavior
 * 
 * Adds custom variables to models
 *
 **/
class MetaBehavior extends ModelBehavior {

/**
 * Contains configuration settings for use with individual model objects.
 * Individual model settings should be stored as an associative array, 
 * keyed off of the model name.
 *
 * @var array
 * @access public
 * @see Model::$alias
 */
    var $__settings = array();

    var $__defaults = array(
        'class' => 'Meta',
        'foreign_key' => 'foreign_id',
        'dependent' => true,
        'auto_bind' => true
    );

/**
 * Initiate Meta Behavior
 *
 * @param object $model
 * @param array $config
 * @return void
 * @access public
 */
    function setup(&$model, $settings = array()) {
        $default = $this->__defaults;
        $default['conditions'] = array('Meta.model' => $model->alias);

         if (!isset($this->__settings[$model->alias])) {
            $this->__settings[$model->alias] = $default;
        }

        $this->__settings[$model->alias] = array_merge($this->__settings[$model->alias], ife(is_array($settings), $settings, array()));

        if ($this->__settings[$model->alias]['auto_bind']) {
            $hasManyMeta = array(
                'Meta' => array(
                    'className' => $this->__settings[$model->alias]['class'],
                    'foreignKey' => $this->__settings[$model->alias]['foreign_key'],
                    'dependent' => $this->__settings[$model->alias]['dependent'],
                    'conditions' => $this->__settings[$model->alias]['conditions']
                )
            );
            $metaBelongsTo = array(
                $model->alias => array(
                    'className' => $model->alias,
                    'foreignKey' => $this->__settings[$model->alias]['foreign_key']
                )
            );
            $model->bindModel(array('hasMany' => $hasManyMeta), false);
            $model->Meta->bindModel(array('belongsTo' => $metaBelongsTo), false);
        }
    }

    function beforeSave(&$model) {
        foreach($model->data[$this->__settings['class']] as $key => $value) {
            $model->data[$this->__settings['class']][$key]['model'] = $model->alias;
        }
        return true;
    }

} // End of MetaBehavior

?>

I have a feeling it may be because of the relationships and the saveall is using the passed data (original) when saving the associations.

The only other way I thought of doing it would be to remove the relationships and put some code into the afterSave function of the behavior to handle the saving and then put some other code into the afterFind to retrieve them.

Any ideas?

Cheers, Dean