/** * Test exceptional case. * * @expectedException \InvalidArgumentException * @expectedExceptionMessage Cannot save Profiles, it is not associated to Users */ public function testErrorOnUnknownAlias() { $table = $this->getMockBuilder('Cake\\ORM\\Table')->setMethods(['save'])->setConstructorArgs([['alias' => 'Users']])->getMock(); $entity = new Entity(); $entity->set('profile', ['key' => 'value']); $this->associations->saveChildren($table, $entity, ['Profiles'], ['atomic' => true]); }
/** * Performs the actual saving of an entity based on the passed options. * * @param \Cake\Datasource\EntityInterface $entity the entity to be saved * @param \ArrayObject $options the options to use for the save operation * @return \Cake\Datasource\EntityInterface|bool * @throws \RuntimeException When an entity is missing some of the primary keys. */ protected function _processSave($entity, $options) { $primaryColumns = (array) $this->primaryKey(); if ($options['checkExisting'] && $primaryColumns && $entity->isNew() && $entity->has($primaryColumns)) { $alias = $this->alias(); $conditions = []; foreach ($entity->extract($primaryColumns) as $k => $v) { $conditions["{$alias}.{$k}"] = $v; } $entity->isNew(!$this->exists($conditions)); } $mode = $entity->isNew() ? RulesChecker::CREATE : RulesChecker::UPDATE; if ($options['checkRules'] && !$this->checkRules($entity, $mode, $options)) { return false; } $options['associated'] = $this->_associations->normalizeKeys($options['associated']); $event = $this->dispatchEvent('Model.beforeSave', compact('entity', 'options')); if ($event->isStopped()) { return $event->result; } $saved = $this->_associations->saveParents($this, $entity, $options['associated'], ['_primary' => false] + $options->getArrayCopy()); if (!$saved && $options['atomic']) { return false; } $data = $entity->extract($this->schema()->columns(), true); $isNew = $entity->isNew(); if ($isNew) { $success = $this->_insert($entity, $data); } else { $success = $this->_update($entity, $data); } if ($success) { $success = $this->_associations->saveChildren($this, $entity, $options['associated'], ['_primary' => false] + $options->getArrayCopy()); if ($success || !$options['atomic']) { $this->dispatchEvent('Model.afterSave', compact('entity', 'options')); $entity->clean(); if (!$options['atomic'] && !$options['_primary']) { $entity->isNew(false); $entity->source($this->registryAlias()); } $success = true; } } if (!$success && $isNew) { $entity->unsetProperty($this->primaryKey()); $entity->isNew(true); } if ($success) { return $entity; } return false; }
/** * Handles the saving of children associations and executing the afterSave logic * once the entity for this table has been saved successfully. * * @param \Cake\Datasource\EntityInterface $entity the entity to be saved * @param \ArrayObject $options the options to use for the save operation * @return bool True on success * @throws \Cake\ORM\Exception\RolledbackTransactionException If the transaction * is aborted in the afterSave event. */ protected function _onSaveSuccess($entity, $options) { $success = $this->_associations->saveChildren($this, $entity, $options['associated'], ['_primary' => false] + $options->getArrayCopy()); if (!$success && $options['atomic']) { return false; } $this->dispatchEvent('Model.afterSave', compact('entity', 'options')); if ($options['atomic'] && !$this->connection()->inTransaction()) { throw new RolledbackTransactionException(['table' => get_class($this)]); } if (!$options['atomic'] && !$options['_primary']) { $entity->clean(); $entity->isNew(false); $entity->source($this->registryAlias()); } return true; }