/** * 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); }
/** * 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']); } }
/** * Injects configured field values into entity if those fields are not dirty. * * @param \Cake\Event\Event $event Event. * @param \Cake\ORM\Entity $entity Entity. * @param \ArrayObject $options Options. * @return void */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { $eventName = $event->name(); $events = $this->config('events'); $new = $entity->isNew() !== false; foreach ($events[$eventName] as $field => $when) { if (!in_array($when, ['always', 'new', 'existing'])) { throw new UnexpectedValueException(sprintf('When should be one of "always", "new" or "existing". The passed value "%s" is invalid', $when)); } if ($entity->dirty($field)) { continue; } if ($when === 'always' || $when === 'new' && $new || $when === 'existing' && !$new) { $entity->set($field, current(Hash::extract((array) $options, $this->config('propertiesMap.' . $field)))); } } }
/** * This event is fired before each entity is saved * * @param \Cake\Event\Event $event The event data * @param \Cake\Datasource\EntityInterface $entity The entity being saved * @return void */ public function beforeSave(Event $event, Entity $entity) { $config = $this->config(); foreach (array_keys($config) as $field) { if (!$entity->dirty($field)) { continue; } $newPos = $entity->{$field}; $oldEntity = $this->getOldEntity($entity, $field); if (is_null($oldEntity)) { // Adding new entity $oldPos = null; } else { $oldPos = $oldEntity->{$field}; } list($conditions, $expression) = $this->getQueryData($oldPos, $newPos, $field); $this->reorder($conditions, $expression); } }
/** * 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); }
/** * beforeSave callback * * @param \Cake\Event\Event $event Event. * @param \Cake\ORM\Entity $entity The Entity. * @param array $options Options. * @return void */ public function beforeSave($event, $entity, $options) { $uploads = []; $fields = $this->getFieldList(); foreach ($fields as $field => $data) { if (!is_string($entity->get($field))) { $uploads[$field] = $entity->get($field); $entity->set($field, null); } if (!$entity->isNew()) { $dirtyField = $entity->dirty($field); $originalField = $entity->getOriginal($field); if ($dirtyField && !is_null($originalField) && !is_array($originalField)) { $fieldConfig = $this->config($field); if ($fieldConfig['removeFileOnUpdate']) { $this->_removeFile($entity->getOriginal($field)); } } } } $this->_uploads = $uploads; }
/** * Callback for Model.beforeSave event. * * @param \Cake\Event\Event $event The afterSave event that was fired. * @param \Cake\ORM\Entity $entity The entity that was saved. * @param \ArrayObject $options Options. * @return void */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { $config = $this->_config; if (!$entity->isNew() && !$config['onUpdate']) { return; } if ($entity->dirty($config['field']) && (!$entity->isNew() || !empty($entity->{$config['field']}))) { return; } $fields = (array) $config['displayField']; $parts = []; foreach ($fields as $field) { $value = Hash::get($entity, $field); if ($value === null && !$entity->isNew()) { return; } if (!empty($value) || is_numeric($value)) { $parts[] = $value; } } $slug = $this->slug($entity, implode($config['separator'], $parts), $config['separator']); $entity->set($config['field'], $slug); }
/** * Ensures that the provided entity contains non-empty values for the left and * right fields * * @param \Cake\ORM\Entity $entity The entity to ensure fields for * @return void */ protected function _ensureFields($entity) { $config = $this->config(); $fields = [$config['left'], $config['right']]; $values = array_filter($entity->extract($fields)); if (count($values) === count($fields)) { return; } $fresh = $this->_table->get($entity->get($this->_getPrimaryKey()), $fields); $entity->set($fresh->extract($fields), ['guard' => false]); foreach ($fields as $field) { $entity->dirty($field, false); } }
/** * Implementation of the beforesave event, handles uploading / saving and overwriting of image records * @param \Cake\Event\Event $event [description] * @param \Cake\ORM\Entity $entity [description] * @param ArrayObject $options [description] * @return void */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { $fields = $this->config('fields'); $alias = $this->_table->registryAlias(); $newOptions = [$this->_imagesTable->alias() => ['validate' => false]]; $options['associated'] = $newOptions + $options['associated']; $entities = []; foreach ($fields as $_fieldName => $fieldType) { $uploadedImages = []; $field = $entity->{$_fieldName}; $field = $fieldType == 'one' ? [$field] : $field; if (!$field) { continue; } foreach ($field as $index => $image) { $uploadeImage = null; if (!empty($image['tmp_name'])) { // server based file uploads $uploadeImage = $this->_upload($image['name'], $image['tmp_name'], false); } elseif (is_string($image)) { // any other 'path' based uploads $uploadeImage = $this->_upload($image, $image, true); } if (!empty($uploadeImage)) { $uploadedImages[$index] = $uploadeImage + ['field_index' => $index, 'model' => $alias, 'field' => $_fieldName]; } } if (!empty($uploadedImages)) { if (!$entity->isNew()) { $imagesTableAlias = $this->_imagesTable->alias(); $preexisting = $this->_imagesTable->find()->where(['model' => $alias, 'field' => $_fieldName, 'foreign_key' => $entity->{$this->_table->primaryKey()}])->order(['field_index' => 'ASC']); foreach ($preexisting as $image) { if (isset($uploadedImages[$image->field_index])) { $entities[$image->field_index] = $this->_imagesTable->patchEntity($image, $uploadedImages[$image->field_index]); } elseif ($fieldType == 'one') { $this->_imagesTable->delete($image); } } } $new = array_diff_key($uploadedImages, $entities); foreach ($new as $image) { $entities[] = $this->_imagesTable->newEntity($image); } } $entity->dirty($_fieldName, false); } $entity->set('_images', $entities); }
/** * Get old order and scope values. * * @param \Cake\ORM\Entity $entity Entity. * * @return array */ protected function _getOldValues(Entity $entity) { $config = $this->config(); $fields = array_merge($config['scope'], [$config['order']]); $values = []; foreach ($fields as $field) { if ($entity->dirty($field)) { $values[$field] = $entity->getOriginal($field); } elseif ($entity->has($field)) { $values[$field] = $entity->get($field); } } if (count($fields) != count($values)) { $primaryKey = $entity->get($this->_table->primaryKey()); $values = $this->_table->get($primaryKey, ['fields' => $fields, 'limit' => 1])->toArray(); } $order = $values[$config['order']]; unset($values[$config['order']]); return [$order, $values]; }
/** * Helper method for saving an association's data. * * @param Association $association The association object to save with. * @param Entity $entity The entity to save * @param array $nested Options for deeper associations * @param array $options Original options * @return bool Success */ protected function _save($association, $entity, $nested, $options) { if (!$entity->dirty($association->property())) { return true; } if (!empty($nested)) { $options = (array) $nested + $options; } return (bool) $association->save($entity, $options); }
/** * Vlastní implementace beforeSave z pluginu * * @param Event $event * @param Entity $entity * @param ArrayObject $options * * @return bool */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { $fields = $this->config('fields'); $alias = $this->_table->registryAlias(); $newOptions = [$this->_imagesTable->alias() => ['validate' => false]]; $options['associated'] = $newOptions + $options['associated']; $entities = []; foreach ($fields as $_fieldName => $fieldType) { $uploadedImages = []; $field = $entity->{$_fieldName}; $field = $fieldType == 'one' ? [$field] : $field; if (isset($field['id'])) { //Úprava existujícího obrázku $field = array_filter($field, 'strlen'); $image = $this->_imagesTable->get($field['id']); $image->modified = Time::now(); $entities[] = $this->_imagesTable->patchEntity($image, $field); } else { if ($field !== null) { //Nativní chování, podle toho jestli existuje field index foreach ($field as $index => $image) { $uploadedImage = null; if (!empty($image['tmp_name'])) { // server based file uploads $uploadedImage = $this->_upload($image['name'], $image['tmp_name'], false); } elseif (is_string($image)) { // any other 'path' based uploads $uploadedImage = $this->_upload($image, $image, true); } if (!empty($uploadedImage)) { $uploadedImages[$index] = $uploadedImage + ['field_index' => $index, 'model' => $alias, 'field' => $_fieldName, 'modified' => Time::now()]; if (isset($field['extra_data']) && is_array($field['extra_data'])) { $uploadedImages[$index] = array_merge($field['extra_data'], $uploadedImages[$index]); } } } if (!empty($uploadedImages)) { if ($this->config('pile')) { //Pokud se mají obrázky nakládat místo přepisování TODO saveStrategy v modelu? $query = $this->_imagesTable->find(); $maxFieldIndex = $query->select(['field_index' => $query->func()->max('field_index')])->first()->field_index; foreach ($uploadedImages as $image) { $image['field_index'] = ++$maxFieldIndex; $image['created'] = Time::now(); $entities[] = $this->_imagesTable->newEntity($image); } } else { if (!$entity->isNew()) { $preexisting = $this->_imagesTable->find()->where(['model' => $alias, 'field' => $_fieldName, 'foreign_key' => $entity->{$this->_table->primaryKey()}])->order(['field_index' => 'ASC']); foreach ($preexisting as $image) { if (isset($uploadedImages[$image->field_index])) { $entities[$image->field_index] = $this->_imagesTable->patchEntity($image, $uploadedImages[$image->field_index]); } elseif ($fieldType == 'one') { $this->_imagesTable->delete($image); } } } $new = array_diff_key($uploadedImages, $entities); foreach ($new as $image) { $image['created'] = Time::now(); $entities[] = $this->_imagesTable->newEntity($image); } } } $entity->dirty($_fieldName, false); } } } if (count($entities)) { $entity->set('_images', $entities); return true; } else { if (count($_FILES)) { //nejsou entity ale jsou data return false; } else { return true; } } }
/** * Method to find out if the current slug needs updating. * * The deep option is useful if you cannot rely on dirty() because * of maybe some not in sync slugs anymore (saving the same title again, * but the slug is completely different, for example). * * @param \Cake\ORM\Entity $entity * @param bool $deep If true it will generate a new slug and compare it to the currently stored one. * @return bool */ public function needsSlugUpdate($entity, $deep = false) { foreach ((array) $this->_config['label'] as $label) { if ($entity->dirty($label)) { return true; } } if ($deep) { $copy = clone $entity; $this->slug($copy, ['overwrite' => true]); return $copy->get($this->_config['field']) !== $entity->get($this->_config['field']); } return false; }
/** * Update a field, if it hasn't been updated already * * @param \Cake\ORM\Entity $entity Entity instance. * @param string $field Field name * @return void */ protected function updateField(Entity $entity, $field) { if ($entity->dirty($field)) { return; } $entity->set($field, $this->getUserId()); }
/** * Update a field, if it hasn't been updated already * * @param \Cake\ORM\Entity $entity Entity instance. * @param string $field Field name * @param bool $refreshTimestamp Whether to refresh timestamp. * @return void */ protected function _updateField(Entity $entity, $field, $refreshTimestamp) { if ($entity->dirty($field)) { return; } if (substr($field, -3) == '_by') { $user_id = $this->Auth->User('id'); $entity->set($field, $user_id); } else { $entity->set($field, $this->timestamp(null, $refreshTimestamp)); } }
/** * Tests that only the properties marked as dirty are actually saved * to the database * * @group save * @return void */ public function testSaveOnlyDirtyProperties() { $entity = new \Cake\ORM\Entity(['username' => 'superuser', 'password' => 'root', 'created' => new Time('2013-10-10 00:00'), 'updated' => new Time('2013-10-10 00:00')]); $entity->clean(); $entity->dirty('username', true); $entity->dirty('created', true); $entity->dirty('updated', true); $table = TableRegistry::get('users'); $this->assertSame($entity, $table->save($entity)); $this->assertEquals($entity->id, self::$nextUserId); $row = $table->find('all')->where(['id' => self::$nextUserId])->first(); $entity->set('password', null); $this->assertEquals($entity->toArray(), $row->toArray()); }
/** * Update a field, if it hasn't been updated already * * @param \Cake\ORM\Entity $entity Entity instance. * @param string $field Field name * @param bool $authUser Whether to use currently authed user. * @return void */ protected function _updateField(Entity $entity, $field) { if ($entity->dirty($field)) { return; } if ($this->_user !== null) { $entity->set($field, $this->_user); } }
/** * Run before a model is saved, used to set up slug for model. * * @param \Cake\ORM\Entity $entity The entity that is going to be saved * @return bool True if save should proceed, false otherwise */ public function geocode(Entity $entity) { $addressfields = (array) $this->_config['address']; $addressData = []; $dirty = false; foreach ($addressfields as $field) { $fieldData = $entity->get($field); if ($fieldData) { $addressData[] = $fieldData; } if ($entity->dirty($field)) { $dirty = true; } } if (!$dirty) { if ($this->_config['allowEmpty'] || $entity->lat && $entity->lng) { return true; } if ($entity instanceof Entity) { $this->invalidate($entity); } return false; } return $this->_geocode($entity, $addressData); }
/** * Callback for Model.beforeSave event. * * @param \Cake\Event\Event $event The afterSave event that was fired. * @param \Cake\ORM\Entity $entity The entity that was saved. * @param \ArrayObject $options Options. * @return void */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { $config = $this->_config; $return = $entity->dirty($config['field']) || !$entity->isNew() && !$config['onUpdate']; if ($return) { return; } $fields = (array) $config['displayField']; $parts = []; foreach ($fields as $field) { if (!isset($entity->{$field}) && !$entity->isNew()) { return; } $parts[] = $entity->{$field}; } $slug = $this->slug($entity, implode($config['separator'], $parts), $config['separator']); $entity->set($config['field'], $slug); }
/** * Update a field, if it hasn't been updated already * * @param \Cake\ORM\Entity $entity Entity instance. * @param string $field Field name * @param bool $refreshTimestamp Whether to refresh timestamp. * @return void */ protected function _updateField(Entity $entity, $field, $refreshTimestamp) { if ($entity->dirty($field)) { return; } $entity->set($field, $this->timestamp(null, $refreshTimestamp)); }
/** * Tests __debugInfo * * @return void */ public function testDebugInfo() { $entity = new Entity(['foo' => 'bar'], ['markClean' => true]); $entity->accessible('name', true); $entity->virtualProperties(['baz']); $entity->dirty('foo', true); $entity->errors('foo', ['An error']); $entity->source('foos'); $result = $entity->__debugInfo(); $expected = ['new' => true, 'accessible' => ['*' => true, 'name' => true], 'properties' => ['foo' => 'bar'], 'dirty' => ['foo' => true], 'original' => [], 'virtual' => ['baz'], 'errors' => ['foo' => ['An error']], 'repository' => 'foos']; $this->assertSame($expected, $result); }
/** * Helper method used to generated multiple translated field entities * out of the data found in the `_translations` property in the passed * entity. The result will be put into its `_i18n` property * * @param \Cake\ORM\Entity $entity Entity * @return void */ protected function _bundleTranslatedFields($entity) { $translations = (array) $entity->get('_translations'); if (empty($translations) && !$entity->dirty('_translations')) { return; } $primaryKey = (array) $this->_table->primaryKey(); $key = $entity->get(current($primaryKey)); foreach ($translations as $lang => $translation) { if (!$translation->id) { $update = ['id' => $key, 'locale' => $lang]; $translation->set($update, ['setter' => false]); } } $entity->set('_i18n', $translations); }
/** * Implementation of the beforeSave event, handles uploading / saving and overwriting of image records. * * @param Event $event Event object. * @param Entity $entity Entity object. * @param \ArrayObject $options Options array. * @return void */ public function beforeSave(Event $event, Entity $entity, \ArrayObject $options) { $fields = $this->config('fields'); $alias = $this->_table->alias(); $options['associated'] = [$this->_imagesTable->alias() => ['validate' => false]] + $options['associated']; $entities = []; foreach ($fields as $fieldName => $fieldType) { $uploadedImages = []; $field = $entity->get($fieldName); $field = $fieldType == 'one' ? [$field] : $field; foreach ($field as $image) { $result = array(); if (!empty($image['tmp_name'])) { $result = $this->_upload($image['name'], $image['tmp_name'], false); } elseif (is_string($image)) { $result = $this->_upload($image, $image, true); } if (!empty($result)) { $uploadedImages[] = $result + ['model' => $alias, 'field' => $fieldName]; } } if (!empty($uploadedImages)) { if (!$entity->isNew() && $fieldType == 'one') { $preexisting = $this->_imagesTable->find()->where(['model' => $alias, 'field' => $fieldName, 'foreign_key' => $entity->id])->bufferResults(false); foreach ($preexisting as $index => $image) { $this->_imagesTable->delete($image); } } foreach ($uploadedImages as $image) { $entities[] = $this->_imagesTable->newEntity($image); } } $entity->dirty($fieldName, true); } $entity->set('_images', $entities); }
/** * Provides empty values * * @return void */ public function testIsDirtyFromClone() { $entity = new Entity(['a' => 1, 'b' => 2], ['markNew' => false, 'markClean' => true]); $this->assertFalse($entity->isNew()); $this->assertFalse($entity->dirty()); $cloned = clone $entity; $cloned->isNew(true); $this->assertTrue($cloned->dirty()); $this->assertTrue($cloned->dirty('a')); $this->assertTrue($cloned->dirty('b')); }
/** * beforeSave callback * * @param \Cake\Event\Event $event Event. * @param \Cake\ORM\Entity $entity The Entity. * @param array $options Options. * @return void */ public function beforeSave($event, $entity, $options) { $uploads = []; $fields = $this->getFieldList(); $this->_customerSite = $options['loggedInCustomer']; foreach ($fields as $field => $data) { if (!is_string($entity->get($field))) { $uploads[$field] = $entity->get($field); $entity->set($field, null); } if (!$entity->isNew()) { $dirtyField = $entity->dirty($field); $originalField = $entity->getOriginal($field); if ($dirtyField && !is_null($originalField) && !is_array($originalField)) { $fieldConfig = $this->config($field); } } } $this->_uploads = $uploads; /* * if (empty($options['loggedInUser'])) { return; } if ($entity->isNew()) { $entity->set('created_by', $options['loggedInUser']); } $entity->set('modified_by', $options['loggedInUser']); */ }
/** * Helper method used to generated multiple translated field entities * out of the data found in the `_translations` property in the passed * entity. The result will be put into its `_i18n` property * * @param \Cake\ORM\Entity $entity Entity * @return void */ protected function _bundleTranslatedFields($entity) { $translations = (array) $entity->get('_translations'); if (empty($translations) && !$entity->dirty('_translations')) { return; } $fields = $this->_config['fields']; $primaryKey = (array) $this->_table->primaryKey(); $key = $entity->get(current($primaryKey)); $find = []; foreach ($translations as $lang => $translation) { foreach ($fields as $field) { if (!$translation->dirty($field)) { continue; } $find[] = ['locale' => $lang, 'field' => $field, 'foreign_key' => $key]; $contents[] = new Entity(['content' => $translation->get($field)], ['useSetters' => false]); } } if (empty($find)) { return; } $results = $this->_findExistingTranslations($find); $model = $this->config('conditions.model'); foreach ($find as $i => $translation) { if (!empty($results[$i])) { $contents[$i]->set('id', $results[$i], ['setter' => false]); $contents[$i]->isNew(false); } else { $translation['model'] = $model; $contents[$i]->set($translation, ['setter' => false, 'guard' => false]); $contents[$i]->isNew(true); } } $entity->set('_i18n', $contents); }
/** * Callback for Model.beforeSave event. * * @param \Cake\Event\Event $event The afterSave event that was fired. * @param \Cake\ORM\Entity $entity The entity that was saved. * @param \ArrayObject $options Options. * @return void */ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) { $slugField = $this->config('field'); $fields = (array) $this->config('displayField'); $separator = $this->config('separator'); if (!$entity->isNew() || $entity->dirty($slugField)) { return; } $parts = []; foreach ($fields as $field) { if ($entity->errors($field)) { return; } $parts[] = $entity->{$field}; } $entity->set($slugField, $this->slug($entity, implode($separator, $parts), $separator)); }