public function test_constructor() { $select = Jam_Query_Builder_Select::factory('test_author'); $this->assertInstanceOf('Jam_Query_Builder_Select', $select); $this->assertEquals(Jam::meta('test_author'), $select->meta()); $this->assertEquals('SELECT `test_authors`.* FROM `test_authors`', (string) $select); }
/** * Getter of the meta object for this iterator (based on $_model) * @return Jam_Model * @throws Kohana_Exception If $_model not present */ public function meta() { if (!$this->model()) { throw new Kohana_Exception('Model not set'); } return Jam::meta($this->model()); }
public function compile($db = NULL) { if ($this->context_model() and $meta = Jam::meta(Jam_Query_Builder::aliased_model($this->context_model()))) { $db = Database::instance($meta->db()); } $original_on = $this->_on; $original_using = $this->_using; $original_table = $this->_table; if (!empty($this->_on)) { foreach ($this->_on as &$condition) { $condition[0] = Jam_Query_Builder::resolve_attribute_name($condition[0], $this->model() ? $this->model() : $this->_table); $condition[2] = Jam_Query_Builder::resolve_attribute_name($condition[2], $this->context_model()); } } $this->_table = Jam_Query_Builder::resolve_table_alias($this->_table); if (!empty($this->_using)) { foreach ($this->_using as &$column) { $column = Jam_Query_Builder::resolve_attribute_name($column, $this->meta()); } } $additional_joins = ''; foreach ($this->_joins as $join) { $additional_joins .= ' ' . $join->compile($db); } $compiled = parent::compile($db) . $additional_joins; $this->_on = $original_on; $this->_using = $original_using; $this->_table = $original_table; return $compiled; }
/** * @covers Model_Purchase_Item_Promotion::initialize */ public function test_initialize() { $meta = Jam::meta('purchase_item_promotion'); $this->assertSame('purchase_items', $meta->table()); $this->assertTrue($meta->field('is_payable')->default); $this->assertTrue($meta->field('is_discount')->default); }
public function test_constructor() { $select = Jam_Query_Builder_Update::factory('test_author'); $select->value('name', 'Test'); $this->assertInstanceOf('Jam_Query_Builder_Update', $select); $this->assertEquals(Jam::meta('test_author'), $select->meta()); $this->assertEquals('UPDATE `test_authors` SET `name` = \'Test\'', (string) $select); }
public function test_initialize() { $association = Jam::meta('purchase_item_product')->association('shipping_item'); $this->assertInstanceOf('Jam_Association_Hasone', $association); $this->assertAttributeSame('purchase_item_id', 'foreign_key', $association); $this->assertAttributeSame('purchase_item', 'inverse_of', $association); $this->assertAttributeSame(Jam_Association::DELETE, 'dependent', $association); }
/** * Constructs a new Jam_Builder instance. * * $model is not actually allowed to be NULL. It has * a default because PHP throws strict errors otherwise. * * @throws Kohana_Exception * @param string|null $model * @param mixed|null $key */ public function __construct($model) { parent::__construct(); $this->_meta = Jam::meta($model); if (!$this->_meta) { throw new Kohana_Exception('There is no model :model for select', array(':model' => $model)); } $this->meta()->events()->trigger('builder.after_construct', $this); }
/** * Constructs a new Jam_Builder instance. * * $model is not actually allowed to be NULL. It has * a default because PHP throws strict errors otherwise. * * @throws Kohana_Exception * @param string|null $model * @param mixed|null $key */ public function __construct($model, $key = NULL) { parent::__construct(); $this->_meta = Jam::meta($model); if ($key !== NULL) { Jam_Query_Builder::find_primary_key($this, $key); } $this->meta()->events()->trigger('builder.after_construct', $this); }
/** * @covers ::initialize */ public function test_initialize() { $category = Jam::meta('category2'); $this->assertArrayHasKey('parent', $category->associations()); $this->assertInstanceOf('Jam_Association_Materializedpath_Belongsto', $category->association('parent')); $this->assertArrayHasKey('children', $category->associations()); $this->assertInstanceOf('Jam_Association_Materializedpath_Hasmany', $category->association('children')); $this->assertArrayHasKey('path', $category->fields()); }
public function setUp() { parent::setUp(); $this->collection = new Jam_Query_Builder_Collection('test_element'); $this->collection->load_fields($this->data); $this->parent = Jam::build('test_author')->load_fields(array('id' => 1, 'name' => 'author')); $this->association = $this->getMock('Jam_Association_Hasmany', array('item_get', 'item_set', 'item_unset', 'clear', 'save', 'collection')); $this->association->initialize(Jam::meta('test_author'), 'test_elements'); $this->array = new Jam_Array_Association(); $this->array->model('test_element')->association($this->association)->parent($this->parent); }
public function action_index() { $q = $this->request->query('query'); $models = explode(',', $this->request->query('model')); $response = array(); foreach ($models as $model) { $name_key = $this->request->query('name') ?: Jam::meta($model)->name_key(); $model_response = Jam::all($model)->limit(5)->where_open()->where($name_key, 'LIKE', "%{$q}%")->or_where(':primary_key', '=', $q)->where_close(); $model_response = array_map(function ($item) use($models, $model) { return array('name' => (count($models) > 1 ? ucfirst(Inflector::humanize($model)) . ' - ' : '') . '<span class="typeahead-display-val">' . $item->name() . '</span> <small class="muted">(' . $item->id() . ')</small>', 'id' => $item->id(), 'model' => $model); }, $model_response->as_array()); $response = array_merge($response, $model_response); } $this->response->headers('Content-Type', 'application/json'); $this->response->body(json_encode($response)); }
public function test_initialize_skippable() { $meta = Jam::meta('test_purchase_item'); $this->assertInstanceOf('Jam_Field_Boolean', $meta->field(Jam_Behavior_Freezable::DEFAULT_SKIPPABLE_FIELD)); $behaviors = $meta->behaviors(); $freezable = $behaviors['freezable']; $this->assertSame(Jam_Behavior_Freezable::DEFAULT_SKIPPABLE_FIELD, $freezable->_skippable); $this->assertSame(array(), $freezable->_skippable_field_options); $meta = Jam::meta('test_skippable'); $this->assertInstanceOf('Jam_Field_Boolean', $meta->field('is_meldable')); $this->assertTrue($meta->field('is_meldable')->default); $behaviors = $meta->behaviors(); $freezable = $behaviors['freezable']; $this->assertSame('is_meldable', $freezable->_skippable); $this->assertSame(array('default' => TRUE), $freezable->_skippable_field_options); }
/** * Get the primary key from whatever value you have * * @param string $model_name The name of the model * @param string|integer|Jam_Validated|array $value the value or a container of the value * @return string|integer|NULL NULL when no value is provided or could be extracted. */ public static function primary_key($model_name, $value) { if (!$value) { return NULL; } if ($value instanceof Jam_Validated) { return $value->id(); } if (is_integer($value) or is_numeric($value)) { return (int) $value; } if (is_string($value)) { return $value; } if (is_array($value)) { return Arr::get($value, Jam::meta($model_name)->primary_key()); } }
protected static function _get_current_children_of_parent($current, $parent, array $children = array()) { if ($current === $parent) { return $children; } foreach ($children as $association_name => $association_children) { $name = is_numeric($association_name) ? $association_children : $association_name; $association = Jam::meta($parent)->association($name); if ($association and !$association->is_polymorphic()) { $child_model = $association->foreign_model; $child_children = is_numeric($association_name) ? array() : $association_children; $result = Jam_Behavior_Cascade::_get_current_children_of_parent($current, $child_model, $child_children); if ($result !== NULL) { return $result; } } } return NULL; }
public function model_after_delete(Jam_Model $model) { if ($model->loaded() and $this->join_table_dependent) { $this->erase_query($model)->execute(Jam::meta($this->model)->db()); } }
/** * @covers Jam::insert */ public function test_insert() { $insert = Jam::insert('test_author'); $this->assertInstanceOf('Jam_Query_Builder_Insert', $insert); $this->assertSame(Jam::meta('test_author'), $insert->meta()); $this->assertEquals('INSERT INTO `test_authors` () VALUES ', $insert->compile()); $insert = Jam::insert('test_author', array('name', 'email')); $this->assertEquals('INSERT INTO `test_authors` (`name`, `email`) VALUES ', $insert->compile()); }
public function unserialize($data) { $data = unserialize($data); $this->_meta = Jam::meta($data['meta']); $this->load_fields($data['fields']); }
/** * @covers Jam_Behavior_Taxonomable::initialize */ public function test_initialize() { $meta = Jam::meta('taxonomy_event'); $this->assertInstanceOf('Jam_Association_Taxonomy_Terms', $meta->association('terms')); $this->assertInstanceOf('Jam_Association_Hasmany', $meta->association('terms_items')); }
protected function _execute(array $options) { $module_name = $options['module']; $dir = Arr::get(Kohana::modules(), $module_name); $meta = Jam::meta($options['model']); $controller = $options['controller'] ?: Inflector::plural($meta->model()); $item_name = $meta->model(); $item_title = ucwords(Inflector::humanize($meta->model())); $plural_name = str_replace('_', ' ', $controller); $author = $options['author']; $controller_option = $options['controller'] ? '->controller(\'' . $controller . '\')' : NULL; $controller_title = Jam::capitalize_class_name($plural_name); $controller_path = str_replace('_', DIRECTORY_SEPARATOR, $controller_title); $controller_dir = $dir . 'classes' . DIRECTORY_SEPARATOR . 'Controller' . DIRECTORY_SEPARATOR . 'Tart'; $controller_file = $controller_dir . DIRECTORY_SEPARATOR . $controller_path . EXT; $controller_class = 'Controller_Tart_' . str_replace(' ', '_', $controller_title); $views_path = 'tart' . DIRECTORY_SEPARATOR . strtolower($controller_path); $views_dir = $dir . 'views' . DIRECTORY_SEPARATOR . $views_path . DIRECTORY_SEPARATOR; $extra_controller = $options['controller'] ? ", array('controller' => '{$controller}')" : ''; $extra_controller_delete = $options['controller'] ? "array('controller' => '{$controller}', 'action' => 'delete')" : "'delete'"; $batch_index = NULL; $batch_delete = NULL; $batch_modify = NULL; if (!is_dir($views_dir)) { mkdir($views_dir, 0777, TRUE); } if (!is_dir(dirname($controller_file))) { mkdir(dirname($controller_file), 0777, TRUE); } if ($options['batch_delete'] !== FALSE or $options['batch_modify'] !== FALSE) { $actions = ''; if ($options['batch_delete'] !== FALSE) { $actions .= "\n\t\t\t\t'delete' => 'Delete',"; $batch_delete = <<<BATCH_DELETE \tpublic function batch_delete(\$ids) \t{ \t\tif (\$this->request->method() == Request::POST) \t\t{ \t\t\t\$result = array(); \t\t\tforeach (Jam::all('{$meta->model()}')->where_key(\$ids) as \${$item_name}) \t\t\t{ \t\t\t\t\$result[] = \${$item_name}->delete(); \t\t\t} \t\t\t\$this->notify('success', count(\$result).' {$plural_name} deleted'); \t\t\t\$this->redirect(Tart::uri('{$controller}')); \t\t} \t\telse \t\t{ \t\t\t\$table = Tart::table(Jam::all('{$meta->model()}')->where_key(\$ids)) \t\t\t\t->selected(\$ids) \t\t\t\t->columns('{$meta->name_key()}', Tart::column()); \t\t\t\$this->template->content = View::factory('{$views_path}/batch_delete', array('table' => \$table)); \t\t} \t} BATCH_DELETE; } if ($options['batch_modify'] !== FALSE) { $actions .= "\n\t\t\t\t'modify' => 'Modify',"; $batch_modify = <<<BATCH_MODIFY \tpublic function batch_modify(\$ids) \t{ \t\t\$params = array('{$meta->name_key()}'); \t\tif (\$this->request->method() == Request::POST) \t\t{ \t\t\t\$modified = Tart_Request::modified_params(\$this->request->post(), \$params); \t\t\tforeach (Jam::all('{$meta->model()}')->where_key(\$ids) as \$item) \t\t\t{ \t\t\t\t\$item->set(\$modified)->save(); \t\t\t} \t\t\t\$this->notify('success', count(\$ids).' {$plural_name} modified: '.Tart_Request::to_modifications(\$modified)); \t\t\t\$this->redirect(Tart::uri('{$controller}')); \t\t} \t\telse \t\t{ \t\t\t\$table = Tart::table(Jam::all('{$meta->model()}')->where_key(\$ids)) \t\t\t\t->selected(\$ids) \t\t\t\t->columns('{$meta->name_key()}', Tart::column()); \t\t\t\$item = Jam::build('{$meta->model()}', Jam_Form::common_params(\$table->collection(), \$params)); \t\t\t\$this->template->content = View::factory('{$views_path}/batch_modify', array('table' => \$table, 'form' => Jam::form(\$item, 'tart_general')->validation(FALSE))); \t\t} \t} BATCH_MODIFY; } $batch_index = <<<BATCH_INDEX \t\t\t->batch_actions(array({$actions} \t\t\t)) BATCH_INDEX; } $controller_content = <<<CONTROLLER <?php defined('SYSPATH') OR die('No direct script access.'); /** * Tart Controller: {$controller_title} * * @package {$module_name} * @author {$author} * @copyright (c) 2011-2013 Despark Ltd. */ class {$controller_class} extends Controller_Tart_Layout { \tpublic function action_index() \t{ \t\t\$collection = Jam::all('{$meta->model()}'); \t\t\$filter = Tart::filter(\$this->request->query()) \t\t\t{$controller_option} \t\t\t->entries(array( \t\t\t\t'q' => Tart::entry('search'), \t\t\t)) \t\t\t->apply(\$collection); \t\t\$index = Tart::index(\$collection, \$this->request->query('offset')) \t\t\t{$controller_option} {$batch_index} \t\t\t->columns(array( \t\t\t\t'{$meta->name_key()}' => Tart::column(), \t\t\t\t'actions' => Tart::column('actions'), \t\t\t)); \t\t\$this->template->set(array( \t\t\t'content' => View::factory('{$views_path}/index', array('index' => \$index, 'filter' => \$filter)), \t\t\t'sidebar' => View::factory('{$views_path}/sidebar', array('filter' => \$filter)), \t\t)); \t} \tpublic function action_edit() \t{ \t\t\$item = Jam::find_insist('{$meta->model()}', \$this->request->param('id')); \t\tif (\$this->request->method() === Request::POST AND \$item->set(\$this->post())->check()) \t\t{ \t\t\t\$this->notify('success', '{$item_title} Updated'); \t\t\t\$item->save(); \t\t} \t\t\$this->template->content = View::factory('{$views_path}/edit', array('item' => \$item)); \t} \tpublic function action_new() \t{ \t\t\$item = Jam::build('{$meta->model()}'); \t\tif (\$this->request->method() === Request::POST AND \$item->set(\$this->post())->check()) \t\t{ \t\t\t\$item->save(); \t\t\t\$this->notify('success', '{$item_title} Created'); \t\t\t\$this->redirect(Tart::uri(\$item{$extra_controller})); \t\t} \t\t\$this->template->content = View::factory('{$views_path}/new', array('item' => \$item)); \t} \tpublic function action_delete() \t{ \t\t\$item = Jam::find_insist('{$meta->model()}', \$this->request->param('id')); \t\t\$item->delete(); \t\t\$this->notify('success', "{$item_title} \\{\$item->name()\\} deleted"); \t\t\$this->redirect(Tart::uri('{$controller}')); \t} {$batch_delete} {$batch_modify} } CONTROLLER; Minion_Jam_Generate::modify_file($controller_file, $controller_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); $index_file = $views_dir . 'index' . EXT; $index_content = <<<VIEW_INDEX <ul class="breadcrumb"> \t<li class="active"> \t\t{$controller_title} <?php echo \$filter->render_active(); ?> \t</li> \t<li class="pull-right"> \t\t<?php echo \$index->pagination()->pager(); ?> \t</li> </ul> <?php echo \$index->render(); ?> VIEW_INDEX; Minion_Jam_Generate::modify_file($index_file, $index_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); $sidebar_file = $views_dir . 'sidebar' . EXT; $sidebar_content = <<<VIEW_SIDEBAR <ul class="nav nav-tabs nav-stacked"> \t<li> \t\t<?php echo Tart_Html::anchor(Tart::uri(Jam::build('{$meta->model()}'){$extra_controller}), '<i class="icon-plus"></i> Add {$item_title}'); ?> \t</li> </ul> <?php echo \$filter->render() ?> VIEW_SIDEBAR; Minion_Jam_Generate::modify_file($sidebar_file, $sidebar_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); $new_file = $views_dir . 'new' . EXT; $new_content = <<<VIEW_NEW <ul class="breadcrumb"> \t<li> \t\t<?php echo Tart_Html::anchor(Tart::uri('{$controller}'), '{$controller_title}'); ?> \t\t<span class="divider">/</span> \t</li> \t<li class="active"> \t\tCreate New {$item_title} \t</li> </ul> <?php echo Form::open(Tart::uri(\$item{$extra_controller}), array('class' => 'form-horizontal', 'enctype' => 'multipart/form-data')) ?> \t<?php echo View::factory('{$views_path}/form', array('item' => \$item)) ?> \t<div class="form-actions"> \t\t<?php echo Tart_Html::anchor(Tart::uri('{$controller}'), 'Cancel', array('class' => 'btn btn-link')); ?> \t\t<button type="submit" class="btn btn-primary">Create {$item_title}</button> \t</div> <?php echo Form::close() ?> VIEW_NEW; Minion_Jam_Generate::modify_file($new_file, $new_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); $edit_file = $views_dir . 'edit' . EXT; $edit_content = <<<VIEW_EDIT <ul class="breadcrumb"> \t<li> \t\t<a href="<?php echo Tart::uri('{$controller}') ?>">{$controller_title}</a> \t\t<span class="divider">/</span> \t</li> \t<li class="active"> \t\tEdit {$item_name} <strong><?php echo \$item->name() ?></strong> \t</li> </ul> <?php echo Form::open(Tart::uri(\$item{$extra_controller}), array('class' => 'form-horizontal', 'enctype' => 'multipart/form-data')) ?> \t<?php echo View::factory('{$views_path}/form', array('item' => \$item)) ?> \t<div class="form-actions"> \t\t<?php echo Tart_Html::anchor(Tart::uri('{$controller}'), 'Cancel', array('class' => 'btn btn-link')); ?> \t\t<button type="submit" class="btn btn-primary">Save changes</button> \t\t<?php echo Tart_Html::anchor(Tart::uri(\$item, {$extra_controller_delete}), 'Delete {$item_title}', array('class' => 'btn btn-danger pull-right', 'data-confirm' => 'Are you sure you want to delete this {$item_title}?')); ?> \t</div> <?php echo Form::close() ?> VIEW_EDIT; Minion_Jam_Generate::modify_file($edit_file, $edit_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); $form_file = $views_dir . 'form' . EXT; $form_content = <<<VIEW_FORM <?php \$form = Jam::form(\$item, 'tart_general') ?> <fieldset> \t<legend>Information</legend> \t<?php echo \$form->row('input', '{$meta->name_key()}') ?> </fieldset> VIEW_FORM; Minion_Jam_Generate::modify_file($form_file, $form_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); if ($options['batch_delete'] !== FALSE) { $batch_delete_file = $views_dir . 'batch_delete' . EXT; $batch_delete_content = <<<VIEW_BATCH_DELETE <ul class="breadcrumb"> \t<li> \t\t<?php echo Tart_Html::anchor(Tart::uri('{$controller}'), '{$controller_title}'); ?> \t\t<span class="divider">/</span> \t</li> \t<li class="active"> \t\tBatch Delete \t</li> </ul> <?php echo Form::open(Tart::uri('{$controller}', 'batch'), array('class' => 'form-horizontal', 'enctype' => 'multipart/form-data')) ?> \t<?php echo \$table->render() ?> \t<div class="form-actions"> \t\t<?php echo Tart_Html::anchor(Tart::uri('{$controller}'), 'Cancel', array('class' => 'btn btn-link')); ?> \t\t<button type="submit" class="btn btn-primary" name="action" value="delete">Delete Selected</button> \t</div> <?php echo Form::close() ?> VIEW_BATCH_DELETE; Minion_Jam_Generate::modify_file($batch_delete_file, $batch_delete_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); } if ($options['batch_modify'] !== FALSE) { $batch_modify_file = $views_dir . 'batch_modify' . EXT; $batch_modify_content = <<<VIEW_BATCH_MODIFY <ul class="breadcrumb"> \t<li> \t\t<?php echo Tart_Html::anchor(Tart::uri('{$controller}'), '{$controller_title}'); ?> \t\t<span class="divider">/</span> \t</li> \t<li class="active"> \t\tBatch Modify \t</li> </ul> <?php echo Form::open(Tart::uri('{$controller}', 'batch'), array('class' => 'form-horizontal', 'enctype' => 'multipart/form-data')) ?> \t<?php echo \$table->render() ?> \t<fieldset> \t\t<legend>Modify Selected Items</legend> \t\t<?php echo \$form->row('input', '{$meta->name_key()}', array('clear' => TRUE)); ?> \t</fieldset> \t<div class="form-actions"> \t\t<?php echo Tart_Html::anchor(Tart::uri('{$controller}'), 'Cancel', array('class' => 'btn btn-link')); ?> \t\t<button type="submit" class="btn btn-primary" name="action" value="modify">Modify Selected Items</button> \t</div> <?php echo Form::close() ?> VIEW_BATCH_MODIFY; Minion_Jam_Generate::modify_file($batch_modify_file, $batch_modify_content, $options['force'] !== FALSE, $options['unlink'] !== FALSE); } }
/** * Use the remove query to remove all items from the collection * @param Jam_Validated $model * @param Jam_Array_Association $collection */ public function clear(Jam_Validated $model, Jam_Array_Association $collection) { if ($ids = array_filter($collection->ids())) { $query = $this->remove_items_query($model, $ids); if ($query) { $query->execute(Jam::meta($this->model)->db()); } } }
/** * @covers Model_Purchase::initialize */ public function test_initialize() { $meta = Jam::meta('purchase'); $this->assertSame('number', $meta->name_key()); }
public function setUp() { parent::setUp(); $this->children = Jam::meta('test_closurelist')->association('children'); $this->model = Jam::build('test_closurelist')->load_fields(array('id' => 4, 'name' => 'one')); }
/** * Constructs a new Jam_Builder instance. * * $model is not actually allowed to be NULL. It has * a default because PHP throws strict errors otherwise. * * @throws Kohana_Exception * @param string $model * @param array $columns */ public function __construct($model, array $columns = array()) { $this->_meta = Jam::meta($model); parent::__construct($this->meta()->table(), $columns); $this->meta()->events()->trigger('builder.after_construct', $this); }
function __construct(Jam_Validated $model) { $this->_object = $model; $this->_meta = Jam::meta($model); }
public function build(Jam_Validated $model, array $attributes = NULL) { $foreign = Jam::meta($this->foreign_model($model)); if (!$foreign) { return NULL; } $item = Jam::build($foreign->model(), $attributes); if ($this->inverse_of and $foreign->association($this->inverse_of) instanceof Jam_Association_Hasone) { $item->retrieved($this->inverse_of, $model); } return $item; }
public function unserialize($data) { $data = unserialize($data); $this->_meta = Jam::meta($this); $this->_original = Arr::merge($this->meta()->defaults(), $data['original']); $this->_changed = $data['changed']; $this->_unmapped = $data['unmapped']; $this->_saved = $data['saved']; $this->_loaded = $data['loaded']; $this->_deleted = $data['deleted']; foreach ($this->_changed as $name => $attribute) { $association = $this->meta()->association($name); if ($association and $association instanceof Jam_Association_Collection) { $association->assign_internals($this, $attribute); } } }
/** * @covers Jam_Query_Builder_Insert::meta */ public function test_meta() { $insert = new Jam_Query_Builder_Insert('test_author'); $this->assertSame(Jam::meta('test_author'), $insert->meta()); }
public function unserialize($data) { $data = unserialize($data); $this->_meta = Jam::meta($this); $this->_original = $data['original']; $this->_changed = $data['changed']; $this->_unmapped = $data['unmapped']; }
/** * * @dataProvider provider_unique_key */ public function test_unique_key($value, $expected_attribute) { $this->assertEquals($expected_attribute, Jam::meta('test_user')->unique_key($value)); }
/** * Implement Serializable * More lightweight than default serialization. */ public function unserialize($data) { $data = json_decode($data, TRUE); $this->_meta = Jam::meta($this); $this->_loaded = isset($data['id']); if ($this->_loaded) { $this->_original = (array) $data; } else { $this->_original = $this->meta()->defaults(); $this->_changed = (array) $data; } }