Class: ExtendedModel extends Model

ExtendedModel extends Model to include the ability to add arbitrary values to a single field that will be JSON encoded in storage and transparently decoded in use. This allows you to extend your Model data with any number of additional values without needing to change your schema.

Note that these values are not indexable directly, but for additional data that you don't need to search on, this can be useful. You can also build simple additional tables for indexing associated data that does need to be searched on, but that is outside of the scope of this class.

Usage:

1. By specifying allowed extended fields in $verify

<?php

class Foo extends ExtendedModel {
    // store extended data in a field named extradata
    public $_extended_field = 'extradata';

    public $verify = array (
        // regular field validations, followed by extended fields:
        'favorite_food' => array (
            'extended' => 1 // mark as extended
        ),
        'favorite_color' => array (
            'extended' => 1, // can also have validation rules:
            'regex' => '/^(red|green|blue|yellow|orange|purple|pink|brown)$/i'
        )
    );
}

// fetch an item
$foo = new Foo (1);

// since we've defined the extended fields, we can access them directly
$foo->favorite_food = 'pizza';

// this will fail to save because the validation fails
$foo->favorite_color = 'black';
if (! $foo->put ()) {
    echo $foo->error;
}

?>

2. By accessing the extradata field directly (will automatically serialize and unserialize for you), or through the ext() method:

<?php

class Foo extends ExtendedModel {
    // store extended data in a field named extradata
    public $_extended_field = 'extradata';
}

// fetch an item
$foo = new Foo (1);

// get its extradata field
$extra = $foo->extradata;

// or
$extra = $foo->ext ();

// add some fields to it
$extra['favorite_food'] = 'pizza';
$extra['favorite_color'] = 'green';

// or
$foo->ext ('favorite_food', 'pizza');
$foo->ext ('favorite_color', 'green');

// set it and save it
$foo->extradata = $extra;
$foo->put ();

// next time we retrieve the item
// our data will be there
$foo = new Foo (1);
$extra = $foo->extra;
echo $extra['favorite_food'];

// or
$foo = new Foo (1);
echo $foo->ext ('favorite_food');

?>

Properties

public $_extended_field

Override this in your child class to tell the ExtendedModel which field contains your extended properties.

public $_extended = false

This is the unserialized array of extended data from the extended field.

private $_extended_verify = array ()

Verification rules for extended attributes.

Methods

public __construct ($vals = false, $is_new = true)

Need to separate verify list for regular and extended attributes, so we override the constructor to do so.

public put ()

Need to verify extended fields, so we override the put() method. Note: On update forms, call update_extended() if the fields were set by the admin/util/extended handler.

public update_extended ()

Look for _extended field and auto-populate extended attributes. Will unset $_POST['_extended'] as a side-effect. Call this before calling put() on update forms that use the admin/util/extended handler.

public orig ()

Return the original data as an object, including extended fields.

public __get ($key)

Dynamic getter for user properties. If you get the field specified in the child class's $_extended_field property, it will automatically unserialize it into an array for you.

If an extended property has been defined in the $verify list, you can also get it directly using the usual $model->property syntax.

public __set ($key, $val)

Dynamic setter for extended properties field. If you set the field specified in the child class's $_extended_field property, it will automatically serialize it into JSON for storage.

If an extended property has been defined in the $verify list, you can also set it directly using the usual $model->property = '...' syntax.

public ext ($key, $val)

This method provides an easy getter/setter for the extended field values. It works around the fact that accessing the array elements directly from the extended field won't trigger the __get() and __set() magic methods.