public function testDiff() { $a = array(array('name' => 'main'), array('name' => 'about')); $b = array(array('name' => 'main'), array('name' => 'about'), array('name' => 'contact')); $result = Set::diff($a, $b); $expected = array(2 => array('name' => 'contact')); $this->assertIdentical($expected, $result); $result = Set::diff($a, array()); $expected = $a; $this->assertIdentical($expected, $result); $result = Set::diff(array(), $b); $expected = $b; $this->assertIdentical($expected, $result); $b = array(array('name' => 'me'), array('name' => 'about')); $result = Set::diff($a, $b); $expected = array(array('name' => 'main')); $this->assertIdentical($expected, $result); }
/** * This method generates a new version. * * It creates a duplication of the object, to allow restoring. It marks all prior * versions as `outdated` and the new one as `active`. * * You probably want to create a new version of an entity, whenever save is called. To achieve * this, you have to take care, all data is set into the entity and Versions::add with updated * entity is called. * * In the following example you can see, how a meta-field, `versions` is used, to decide if * a version needs to be created, or not. * * {{{ * public function save($entity, $data = array(), array $options = array()) { * if (!empty($data)) { * $entity->set($data); * } * if (!isset($options['callbacks']) || $options['callbacks'] !== false) { * $versions = static::meta('versions'); * if (($versions === true) || (is_callable($versions) && $versions($entity, $options))) { * $version_id = Versions::add($entity, $options); * if ($version_id) { * $entity->set(compact('version_id')); * } * } * } * return parent::save($entity, null, $options); * } * }}} * * You have to set `versions` to true, in meta like this: * * {{{ * $model::meta('versions', true); * // OR * static::meta('versions', function($entity, $options){ * return (bool) Environment::is('production'); * }); * }}} * * @param object $entity the instance, that needs to created a new version for * @param array $options additional options * @filter */ public static function add($entity, array $options = array()) { $defaults = array('force' => false); $options += $defaults; $params = compact('entity', 'options'); return static::_filter(__METHOD__, $params, function ($self, $params) { extract($params); $model = $entity->model(); if ($model == $self || !$entity->exists()) { return false; } $key = $model::meta('key'); $foreign_id = (string) $entity->{$key}; $export = $entity->export(); $updated = Set::diff($self::cleanData($export['update']), $self::cleanData($export['data'])); if (empty($updated)) { if (!$options['force']) { return false; } $updated = $entity->data(); } $self::update(array('status' => 'outdated'), compact('model', 'foreign_id')); $data = array('model' => $model, 'foreign_id' => $foreign_id, 'status' => 'active', 'name' => (string) $entity->title(), 'fields' => $updated, 'data' => json_encode($entity->data()), 'created' => time()); $version = $self::create($data); if (!$version->save()) { return false; } return $version->id(); }); }