/** * Adds a new item. * * Data is passed as POST. * * @param Request|array $requestOrData * @param array|null $pk * @param string|null $position If nested set. `first` (child), `last` (child), `prev` (sibling), `next` (sibling) * @param string|null $targetObjectKey * * @return mixed false if some went wrong or a array with the new primary keys. * * @throws \InvalidArgumentException */ public function add($requestOrData, $pk = null, $position = null, $targetObjectKey = null) { //collect values $targetObjectKey = Objects::normalizeObjectKey($targetObjectKey); $values = $this->collectData($requestOrData); $storageController = $this->objects->getStorageController($this->getObject()); if ($this->getPermissionCheck()) { foreach ($values as $fieldName => $value) { //todo, what if $targetObjectKey differs from $objectKey $aclRequest = ACLRequest::create($this->getObject(), $pk)->setField($fieldName)->onlyAddMode(); if (!$this->acl->check($aclRequest)) { unset($values[$fieldName]); } } } $args = ['pk' => $pk, 'values' => &$values, 'controller' => $this, 'position' => &$position, 'targetObjectKey' => &$targetObjectKey, 'mode' => 'add']; $eventPre = new GenericEvent($this->getObject(), $args); $this->eventDispatcher->dispatch('core/object/modify-pre', $eventPre); $this->eventDispatcher->dispatch('core/object/add-pre', $eventPre); $data = $this->mapData($values); if ($targetObjectKey && $targetObjectKey != $this->getObject()) { if ($position == 'prev' || $position == 'next') { throw new \InvalidArgumentException(sprintf('Its not possible to use `prev` or `next` to add a new entry with a different object key. [target: %s, self: %s]', $targetObjectKey, $this->getObject())); } $targetPk = $this->objects->normalizePk($targetObjectKey, $pk); //since propel's nested set behaviour only allows a single value as scope, we need to use the first pk $scope = current($targetPk); $result = $storageController->add($data, null, $position, $scope); } else { $result = $storageController->add($data, $pk, $position); } if ($this->getWithNewsFeed()) { $values = array_merge($values, $result); $this->utils->newNewsFeed($this->objects, $this->getObject(), $values, 'added'); } $args['result'] = $result; $event = new GenericEvent($this->getObject(), $args); $this->eventDispatcher->dispatch('core/object/modify', $event); $this->eventDispatcher->dispatch('core/object/add', $event); return $result; }