/** * save */ public function beforeSave(Event $event, Entity $entity) { $config = $this->config(); $fields = $config['fields']; foreach ($fields as $key => $value) { $historic[$value] = $entity->get($value); } if (!$entity->isNew() && ($historicOld = $this->_table->Historics->find()->where([$this->foreignKey => $entity->id])->toArray())) { $this->_table->Historics->patchEntity($historicOld[0], ['is_active' => 0]); $entity->set('historics', [$this->_table->Historics->newEntity($historic), $historicOld[0]]); } else { $entity->set('historics', [$this->_table->Historics->newEntity($historic)]); } $entity->dirty('historics', true); }
public function __construct(Table $table, Entity $entity, $field, array $settings) { $this->setRoot(TMP . 'ProfferTests'); $this->setTable($table->alias()); $this->setField($field); $this->setSeed('proffer_test'); if (isset($settings['thumbnailSizes'])) { $this->setPrefixes($settings['thumbnailSizes']); } $this->setFilename($entity->get($field)); }
/** * Generate unique slug by field. * * @param Entity $entity * @return mixed|string */ protected function _generateUniqueSlug(Entity $entity) { $conditions = []; $slug = $entity->get($this->_config['slug'], ''); if ($this->_config['unique']) { $conditions[$this->_config['slug'] . ' LIKE'] = $slug . '%'; } if ($id = $entity->get('id', false)) { $conditions[$this->_table->primaryKey() . ' !='] = $id; } if (empty($slug)) { $slug = $entity->get($this->_config['field'], 'Title'); } if ($this->_config['translate']) { $Slug = new Slug(); $slug = $Slug->create($slug); } $duplicates = $this->_table->find()->where($conditions)->toArray(); if (!empty($duplicates)) { $duplicates = $this->_extractSlug($duplicates); if (!in_array($slug, $duplicates)) { return $slug; } $index = 1; $startSlug = $slug; while ($index > 0) { if (!in_array($startSlug . $this->_config['separator'] . $index, $duplicates)) { $slug = $startSlug . $this->_config['separator'] . $index; $index = -1; } $index++; } } return $slug; }
/** * get appropriate fields with files * move uploaded file and set path to entity field, but only if a file was selected * * @param Entity $entity */ public function uploadFile(Entity $entity) { $config = $this->config(); if (!is_array($config['field'])) { $field = $entity->get($config['field']); if (empty($field['tmp_name'])) { $entity->unsetProperty($config['field']); } else { if ($entity->get($config['field']) != $entity->getOriginal($config['field'])) { $originalFilePath = $entity->getOriginal($config['field']); $this->_delete($originalFilePath); } $filePath = $this->_moveFile($field); $entity->set($config['field'], $filePath); } } else { foreach ($config['field'] as $value) { $field = $entity->get($value); if (empty($field['tmp_name'])) { $entity->unsetProperty($config['field']); } else { if ($entity->get($config['field']) != $entity->getOriginal($config['field'])) { $originalFilePath = $entity->getOriginal($config['field']); $this->_delete($originalFilePath); } $filePath = $this->_moveFile($field); $entity->set($config['field'], $filePath); } } } }
/** * Modifies the entity before it is saved so that uploaded file data is persisted * in the database too. * * @param \Cake\Event\Event $event The beforeSave event that was fired * @param \Cake\ORM\Entity $entity The entity that is going to be saved * @param \ArrayObject $options the options passed to the save method * @return void|false */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { foreach ($this->config() as $field => $settings) { if (Hash::get((array) $entity->get($field), 'error') !== UPLOAD_ERR_OK) { if (Hash::get($settings, 'restoreValueOnFailure', true)) { $entity->set($field, $entity->getOriginal($field)); $entity->dirty($field, false); } continue; } $data = $entity->get($field); $path = $this->getPathProcessor($entity, $data, $field, $settings); $basepath = $path->basepath(); $filename = $path->filename(); $data['name'] = $filename; $files = $this->constructFiles($entity, $data, $field, $settings, $basepath); $writer = $this->getWriter($entity, $data, $field, $settings); $success = $writer->write($files); if ((new Collection($success))->contains(false)) { return false; } $entity->set($field, $filename); $entity->set(Hash::get($settings, 'fields.dir', 'dir'), $basepath); $entity->set(Hash::get($settings, 'fields.size', 'size'), $data['size']); $entity->set(Hash::get($settings, 'fields.type', 'type'), $data['type']); } }
public function slug(Entity $entity) { $config = $this->config(); if (!($value = $entity->get($config['slug']))) { $value = $entity->get($config['field']); } $entity->set($config['slug'], Inflector::slug($value, $config['replacement'])); }
/** * Render ajax toggle element. * * @param array|string $url * @param array $data * @param Entity|\Cake\ORM\Entity $entity * @return string */ public function toggle($entity, $url = [], array $data = []) { if (empty($url)) { $url = ['action' => 'toggle', 'prefix' => $this->request->param('prefix'), 'plugin' => $this->request->param('plugin'), 'controller' => $this->request->param('controller'), (int) $entity->get('id'), (int) $entity->get('status')]; } $data = Hash::merge(['url' => $url, 'entity' => $entity], $data); return $this->_View->element(__FUNCTION__, $data); }
/** * Returns the basepath for the current field/data combination. * If a `path` is specified in settings, then that will be used as * the replacement pattern * * @return string * @throws LogicException if a replacement is not valid for the current dataset */ public function basepath() { $defaultPath = 'webroot{DS}files{DS}{model}{DS}{field}{DS}'; $path = Hash::get($this->settings, 'path', $defaultPath); if (strpos($path, '{primaryKey}') !== false) { if ($this->entity->isNew()) { throw new LogicException('{primaryKey} substitution not allowed for new entities'); } if (is_array($this->table->primaryKey())) { throw new LogicException('{primaryKey} substitution not valid for composite primary keys'); } } $replacements = ['{primaryKey}' => $this->entity->get($this->table->primaryKey()), '{model}' => $this->table->alias(), '{relatedModel}' => $this->entity->model, '{table}' => $this->table->table(), '{field}' => $this->field, '{time}' => time(), '{microtime}' => microtime(), '{DS}' => DIRECTORY_SEPARATOR]; return str_replace(array_keys($replacements), array_values($replacements), $path); }
/** * Construct the class and setup the defaults * * @param Table $table Instance of the table * @param Entity $entity Instance of the entity data * @param string $field The name of the upload field * @param array $settings Array of settings for the upload field */ public function __construct(Table $table, Entity $entity, $field, array $settings) { if (isset($settings['root'])) { $this->setRoot($settings['root']); } else { $this->setRoot(WWW_ROOT . 'files'); } $this->setTable($table->alias()); $this->setField($field); $this->setSeed($this->generateSeed($entity->get($settings['dir']))); if (isset($settings['thumbnailSizes'])) { $this->setPrefixes($settings['thumbnailSizes']); } $this->setFilename($entity->get($field)); }
/** * Check if there is some files to upload and modify the entity before * it is saved. * * At the end, for each files to upload, unset their "virtual" property. * * @param Event $event The beforeSave event that was fired. * @param Entity $entity The entity that is going to be saved. * * @throws \LogicException When the path configuration is not set. * @throws \ErrorException When the function to get the upload path failed. * * @return void */ public function beforeSave(Event $event, Entity $entity) { $config = $this->_config; foreach ($config['fields'] as $field => $fieldOption) { $data = $entity->toArray(); $virtualField = $field . $config['suffix']; if (!isset($data[$virtualField]) || !is_array($data[$virtualField])) { continue; } $file = $entity->get($virtualField); if ((int) $file['error'] === UPLOAD_ERR_NO_FILE) { continue; } if (!isset($fieldOption['path'])) { throw new \LogicException(__('The path for the {0} field is required.', $field)); } if (isset($fieldOption['prefix']) && (is_bool($fieldOption['prefix']) || is_string($fieldOption['prefix']))) { $this->_prefix = $fieldOption['prefix']; } $extension = (new File($file['name'], false))->ext(); $uploadPath = $this->_getUploadPath($entity, $fieldOption['path'], $extension); if (!$uploadPath) { throw new \ErrorException(__('Error to get the uploadPath.')); } $folder = new Folder($this->_config['root']); $folder->create($this->_config['root'] . dirname($uploadPath)); if ($this->_moveFile($entity, $file['tmp_name'], $uploadPath, $field, $fieldOption)) { if (!$this->_prefix) { $this->_prefix = ''; } $entity->set($field, $this->_prefix . $uploadPath); } $entity->unsetProperty($virtualField); } }
/** * Run before a model is saved, used to set up slug for model. * * @param \Cake\Event\Event $event The event that was triggered * @param \Cake\ORM\Entity $entity The entity being saved * @param array $options Array of options for the save operation * @return bool True if save should proceed, false otherwise * @throws \Cake\Error\FatalErrorException When some of the specified columns * in config's "label" is not present in the entity being saved */ public function beforeSave(Event $event, $entity, $options = []) { if (!$this->_enabled) { return true; } $config = $this->config(); $isNew = $entity->isNew(); if ($isNew && in_array($config['on'], ['create', 'both']) || !$isNew && in_array($config['on'], ['update', 'both'])) { if (!is_array($config['label'])) { $config['label'] = [$config['label']]; } foreach ($config['label'] as $field) { if (!$entity->has($field)) { throw new FatalErrorException(__d('cms', 'SluggableBehavior was not able to generate a slug reason: entity\'s property "{0}" not found', $field)); } } $label = ''; foreach ($config['label'] as $field) { $val = $entity->get($field); $label .= !empty($val) ? " {$val}" : ''; } if (!empty($label)) { $slug = $this->_slug($label, $entity); $entity->set($config['slug'], $slug); } } return true; }
/** * Takes an entity from the source table and looks if there is a field * matching the property name for this association. The found entity will be * saved on the target table for this association by passing supplied * `$options` * * @param \Cake\ORM\Entity $entity an entity from the source table * @param array|\ArrayObject $options options to be passed to the save method in * the target table * @return bool|Entity false if $entity could not be saved, otherwise it returns * the saved entity * @see Table::save() * @throws \InvalidArgumentException when the association data cannot be traversed. */ public function save(Entity $entity, array $options = []) { $targetEntities = $entity->get($this->property()); if (empty($targetEntities)) { return $entity; } if (!is_array($targetEntities) && !$targetEntities instanceof \Traversable) { $name = $this->property(); $message = sprintf('Could not save %s, it cannot be traversed', $name); throw new \InvalidArgumentException($message); } $properties = array_combine((array) $this->foreignKey(), $entity->extract((array) $this->source()->primaryKey())); $target = $this->target(); $original = $targetEntities; foreach ($targetEntities as $k => $targetEntity) { if (!$targetEntity instanceof Entity) { break; } if (!empty($options['atomic'])) { $targetEntity = clone $targetEntity; } $targetEntity->set($properties, ['guard' => false]); if ($target->save($targetEntity, $options)) { $targetEntities[$k] = $targetEntity; continue; } if (!empty($options['atomic'])) { $original[$k]->errors($targetEntity->errors()); $entity->set($this->property(), $original); return false; } } $entity->set($this->property(), $targetEntities); return $entity; }
/** * Validates a single entity by getting the correct validator object from * the table and traverses associations passed in $options to validate them * as well. * * @param \Cake\ORM\Entity $entity The entity to be validated * @param array|\ArrayObject $options options for validation, including an optional key of * associations to also be validated. * @return bool true if all validations passed, false otherwise */ public function one(Entity $entity, $options = []) { $valid = true; $types = [Association::ONE_TO_ONE, Association::MANY_TO_ONE]; $propertyMap = $this->_buildPropertyMap($options); $options = new ArrayObject($options); foreach ($propertyMap as $key => $assoc) { $value = $entity->get($key); $association = $assoc['association']; if (!$value) { continue; } $isOne = in_array($association->type(), $types); if ($isOne && !$value instanceof Entity) { $valid = false; continue; } $validator = $association->target()->entityValidator(); if ($isOne) { $valid = $validator->one($value, $assoc['options']) && $valid; } else { $valid = $validator->many($value, $assoc['options']) && $valid; } } if (!isset($options['validate'])) { $options['validate'] = true; } return $this->_processValidation($entity, $options) && $valid; }
public function getFilePath(Entity $entity, $path, $extension) { $id = $entity->get('id'); $path = trim($path, '/'); $replace = ['%id1000' => ceil($id / 1000), '%id100' => ceil($id / 100), '%id' => $id, '%y' => date('y'), '%m' => date('m')]; $path = strtr($path, $replace) . '.' . $extension; return $path; }
public function beforeSave(Event $event, Entity $entity) { $config = $this->config(); $value = $entity->get($config['field']); $id = isset($entity->id) ? $entity->id : 0; $slug = $this->createSLug(strtolower(Inflector::slug($value, $config['replacement'])), 0, $id); $entity->set($config['slug'], $slug); }
public function afterSave(Event $event, Entity $entity, ArrayObject $options) { $ulPathSuffix = DS . date('Y') . DS . date('m') . DS . $this->_table->alias() . DS; $folder = new Folder(Configure::read('Upload.path') . $ulPathSuffix, true, 755); $table = TableRegistry::get('WoodyAttachments.Attachments'); foreach ($this->_config['fields'] as $field => $options) { if (isset($entity->get($field)[0]['tmp_name'])) { foreach ($entity->get($field) as $file) { $newFileName = substr(Text::uuid(), 0, 13) . '-' . $file['name']; $attachment = array(); if (move_uploaded_file($file['tmp_name'], $folder->path . $newFileName)) { $attachment['file_name'] = $newFileName; $attachment['file_path'] = $ulPathSuffix; $attachment['file_size'] = $file['size']; $attachment['mime_type'] = $file['type']; $attachment['real_name'] = $file['name']; $attachment['entity'] = $this->_table->alias(); $attachment['entity_id'] = $entity->get('id'); $attachmentEntity = $table->newEntity($attachment); if ($table->save($attachmentEntity)) { $this->runFileOperations($attachmentEntity, $options); } unset($attachment); } } } else { $file = $entity->get($field); $newFileName = substr(Text::uuid(), 0, 13) . '-' . $file['name']; if (move_uploaded_file($file['tmp_name'], $folder->path . $newFileName)) { $attachment['file_name'] = $newFileName; $attachment['file_path'] = $ulPathSuffix; $attachment['file_size'] = $file['size']; $attachment['mime_type'] = $file['type']; $attachment['real_name'] = $file['name']; $attachment['entity'] = $this->_table->alias(); $attachment['entity_id'] = $entity->get('id'); $attachmentEntity = $table->newEntity($attachment); if ($table->save($attachmentEntity)) { $this->runFileOperations($attachmentEntity, $options); } } } } return true; }
public function slug(Entity $entity) { $config = $this->config(); $value = $entity->get($config['field']); $data['plugin'] = $config['plugin']; $data['controller'] = $config['controller']; $data['action'] = $config['action']; $data['pass'] = $entity->get($config['pass']); $redirect = $this->Slugs->find()->where($data)->first(); $data['created'] = date('Y-m-d H:i:s'); $data['slug'] = strtolower(Text::slug($value, $config['replacement'])); // debug($redirect); if (!is_object($redirect)) { $redirect = $this->Slugs->newEntity(); } $redirect = $this->Slugs->patchEntity($redirect, $data); $this->Slugs->save($redirect); }
/** * afterSave Event * * @param Event $event Event * @param Entity $entity Record * @return void */ public function afterSave(Event $event, Entity $entity) { $fields = array_merge([$this->_table->primaryKey(), $this->config('sortField')], $this->config('columnScope')); $savedEntity = $this->_table->get($entity->get($this->_table->primaryKey()), ['fields' => $fields]); $scope = $this->config('scope'); foreach ($this->config('columnScope') as $column) { $scope[$column] = $savedEntity->get($column); } $entitySort = $savedEntity->{$this->config('sortField')}; $entityId = $entity->get($this->_table->primaryKey()); if (empty($entitySort)) { $nextSortValue = $this->getNextSortValue($scope); $this->_table->updateAll([$this->config('sortField') => $nextSortValue], [$this->_table->primaryKey() => $entityId]); } else { if ($entitySort < $this->__originalSortValue) { $currentScope = $scope; $currentScope[] = "{$this->config('sortField')} <" . $this->__originalSortValue; $currentScope[] = "{$this->config('sortField')} >=" . $entitySort; $currentScope[] = [$this->_table->primaryKey() . ' !=' => $entity->id]; $query = $this->_table->query()->update(); $query->where($currentScope); $query->set([$this->config('sortField') => $query->newExpr($this->config('sortField') . ' + 1')]); $query->execute(); } elseif ($entitySort > $this->__originalSortValue) { $currentScope = $scope; $currentScope[] = "{$this->config('sortField')} >" . $this->__originalSortValue; $currentScope[] = "{$this->config('sortField')} <=" . $entitySort; $currentScope[] = [$this->_table->primaryKey() . ' !=' => $entity->id]; $query = $this->_table->query()->update(); $query->where($currentScope); $query->set([$this->config('sortField') => $query->newExpr($this->config('sortField') . ' - 1')]); $query->execute(); } elseif ($entitySort == $this->__originalSortValue) { $currentScope = $scope; $currentScope[] = "{$this->config('sortField')} >=" . $entitySort; $currentScope[] = [$this->_table->primaryKey() . ' !=' => $entity->id]; $query = $this->_table->query()->update(); $query->where($currentScope); $query->set([$this->config('sortField') => $query->newExpr($this->config('sortField') . ' + 1')]); $query->execute(); } } $this->__originalSortValue = null; }
public function deleteOldUpload(Entity $entity, $field) { $file = $entity->get($field); if (empty($file)) { return true; } if (file_exists(WWW_ROOT . $file)) { unlink(WWW_ROOT . $file); } }
public function slug(Entity $entity) { $config = $this->config(); $value = $entity->get($config['field']); if (empty($value) && !empty($config['secondaryField'])) { $value = $entity->get($config['secondaryField']); } $baseSlug = Inflector::slug(strtolower($value), $config['replacement']); //Append "-1", "-2", etc. if slug already exists $counter = 0; do { $slug = $baseSlug; if ($counter > 0) { $slug .= $config['replacement'] . $counter; } $counter++; $existing = $this->_table->find('slug', ['slug' => $slug])->first(); } while (!empty($existing)); $entity->set($config['slug'], $slug); }
/** * Save also related model data * * @param \Cake\Event\Event * @param \Cake\ORM\Entity; * @return void */ public function beforeSave(Event $event, Entity $entity) { foreach ($this->config('fields') as $field => $mapped) { list($mappedTable, $mappedField) = explode('.', $mapped); if (!isset($this->_table->{$mappedTable}) || $this->_table->{$mappedTable}->isOwningSide($this->_table)) { throw new Exception(sprintf('Incorrect definition of related data to persist for %s', $mapped)); } // get related entity $related = $this->_table->{$mappedTable}->get($entity->get($this->_table->{$mappedTable}->foreignKey())); // set field value $entity->set($field, $related->get($mappedField)); } }
public function afterSave(Event $event, Entity $entity, $options) { $config = $this->_config; foreach ($config['fields'] as $fieldKey => $fieldValue) { $filePath = $entity->get($fieldKey); if (!empty($filePath)) { foreach ($fieldValue as $fieldTypeKey => $fieldTypeValue) { $type = $fieldTypeValue['type']; $this->{$type}($fieldTypeValue, $filePath); } } } }
/** * Before Saving the entity, slug it. * @param Event $event * @param Entity $entity * @return void */ public function afterSave(Event $event, Entity $entity, $options) { $config = $this->config(); # load the config built by the instantiated behavior $original = $entity->get($config['field']); # manually store $original - wasn't working for some reason otherwise $entity->set($config['field'], $this->_generateSlug($entity)); # set the slug # if the slug is actually different than before - save it if ($entity->dirty() && $original != $entity->get($config['field'])) { $this->_table->save($entity); } }
/** * Before save * Transforma o valor de BRL para o formato SQL antes de salvar a entidade * no banco de dados * * @param Event $event Instância do evento * @param Entity $entity Instância da entidade a ser salva pelo ORM * @return bool * @access public */ public function beforeSave(Event $event, Entity $entity) { foreach ($this->_table->schema()->columns() as $campo) { $valor = $entity->get($campo); if (!empty($valor) && $this->_table->schema()->columnType($campo) === "float") { if (!is_string($valor) || preg_match('/^[0-9]+(\\.[0-9]+)?$/', $valor)) { continue; } $entity->set($campo, str_replace(['.', ','], ['', '.'], $valor)); } } return true; }
public function afterDelete(Event $event, Entity $entity, $options) { $config = $this->_config; foreach ($config['fields'] as $field) { $entityField = $entity->get($field); if (!empty($entityField)) { $filePath = $config['root'] . $entityField; $file = new File($filePath, false, 755); if ($file->exists() === true) { $file->delete(); } } } }
/** * Encrypt values before saving to DB * @param Event $event Event object * @param Entity $entity Entity object * @return void */ public function beforeSave(Event $event, Entity $entity) { $entity->_cyphered = []; foreach ($this->config('fields') as $field => $type) { if ($entity->has($field)) { $value = $entity->get($field); // Convert values to db representation before encrypting them $dbValue = Type::build($type)->toDatabase($value, $this->_table->connection()->driver()); $cryptedValue = $this->encrypt($dbValue); $entity->set($field, $cryptedValue); $entity->_cyphered[$field] = $value; } } }
/** * Write hidden tag for confirm page. * * @param \Cake\ORM\Entity $entity The entity that is patched * @param string $field The image field name * @return string */ public function hidden(Entity $entity, $field) { $value = $entity->get($field); if (empty($value['tmp_name']) || $value === null) { return ''; } if (!is_array($value)) { return $this->Form->hidden($field); } $tag = ''; foreach ($value as $key => $subValue) { $tag .= $this->Form->hidden("{$field}.{$key}"); } return $tag; }
/** * Generate a mock of the ProfferPath class with various set returns to ensure that the path is always consistent * * @param Table $table Instance of the table * @param Entity $entity Instance of the entity * @return \PHPUnit_Framework_MockObject_MockObject */ private function getProfferPathMock(Table $table, Entity $entity) { $path = $this->getMockBuilder('Proffer\\Lib\\ProfferPath')->setConstructorArgs([$table, $entity, 'photo', $this->config['photo']])->setMethods(['fullPath', 'getFolder'])->getMock(); $path->expects($this->any())->method('fullPath')->with($this->logicalOr($this->equalTo(null), $this->equalTo('square'), $this->equalTo('portrait')))->will($this->returnCallback(function ($param) use($table, $entity) { $filename = ''; if ($param !== null) { $filename = $param . '_'; } $entityFieldData = $entity->get('photo'); if (is_array($entityFieldData)) { $filename .= $entityFieldData['name']; } else { $filename .= $entityFieldData; } return TMP . 'ProfferTests' . DS . $table->alias() . DS . 'photo' . DS . 'proffer_test' . DS . $filename; })); $path->expects($this->any())->method('getFolder')->willReturn(TMP . 'ProfferTests' . DS . $table->alias() . DS . 'photo' . DS . 'proffer_test' . DS); return $path; }
/** * Decodes the fields of an array/entity (if the value itself was encoded) * * @param \Cake\ORM\Entity $entity * @param string $type Type (input/output) * @return void */ public function processItems(Entity $entity, $type = 'input') { $fields = $this->_config['fields']; foreach ($fields as $field => $map) { if (is_numeric($field)) { $field = $map; $map = []; } else { $map = (array) $map; } $val = $entity->get($field); if (!$val && !is_numeric($val)) { continue; } if (!$map) { $map = $this->_config[$type]; } if (!$map) { continue; } $entity->set($field, $this->_process($val, $map)); } }
/** * Save the before and after state of the modified entity to the Revisions table. * * @param Event $event [description] * @param Entity $entity [description] * @return void */ public function afterSave(Event $event, Entity $entity) { # get the current configuration $config = $this->config(); # pessimistic - expect not to have to update anything $trigger = false; # if watch is set, use it switch (true) { # if `watch` is set AND one of the fields we're watching has been changed, trigger a save case !empty($config['watch']): $trigger = !empty($entity->extractOriginalChanged($config['watch'])); break; # if `ignore` is set AND at least one other non-ignored field was changed, trigger a save # if `ignore` is set AND at least one other non-ignored field was changed, trigger a save case !empty($config['ignore']): $trigger = !empty(array_diff($entity->extractOriginalChanged($this->_table->schema()->columns()), $entity->extractOriginalChanged($config['ignore']))); break; # if SOMETHING changed, and we're not explicity watching or ignoring anything, trigger anyway # if SOMETHING changed, and we're not explicity watching or ignoring anything, trigger anyway default: $trigger = $entity->dirty(); break; } # if we don't need to trigger a save, stop if (!$trigger) { return; } # rebuild the original entity $before = $this->_table->patchEntity($before = clone $entity, $before->extractOriginal($this->_table->schema()->columns())); # load the Revisions Model $this->Revisions = TableRegistry::get('Revisions.Revisions'); # build the Revision record $r = $this->Revisions->newEntity(['model' => $this->_table->table(), 'modelPrimaryKey' => $entity->get($this->_table->primaryKey()), 'before_edit' => json_encode($before), 'after_edit' => json_encode($entity)]); # and save it $this->Revisions->save($r); }