/** * Helper method for importing to add a node with the proper uuid behavior * * @param \PHPCR\NodeInterface $parentNode the node to add this node to * @param string $nodename the node name to use * @param string $type the primary type name to use * @param int $uuidBehavior one of the constants of ImportUUIDBehaviorInterface * * @return NodeInterface the created node * * @throws \PHPCR\ItemExistsException if IMPORT_UUID_COLLISION_THROW and * duplicate id * @throws \PHPCR\NodeType\ConstraintViolationException if behavior is remove or * replace and the node with the uuid is in the parent path. */ private static function addNode(NodeInterface $parentNode, $nodename, $type, $properties, $uuidBehavior) { $forceReferenceable = false; if (isset($properties['jcr:uuid'])) { try { $existing = $parentNode->getSession()->getNodeByIdentifier($properties['jcr:uuid']['values']); switch ($uuidBehavior) { case self::IMPORT_UUID_CREATE_NEW: unset($properties['jcr:uuid']); $forceReferenceable = true; break; case self::IMPORT_UUID_COLLISION_THROW: throw new ItemExistsException('There already is a node with uuid ' . $properties['jcr:uuid']['values'] . ' in this workspace.'); case self::IMPORT_UUID_COLLISION_REMOVE_EXISTING: case self::IMPORT_UUID_COLLISION_REPLACE_EXISTING: if (self::IMPORT_UUID_COLLISION_REPLACE_EXISTING == $uuidBehavior && 'jcr:root' == $nodename && $existing->getDepth() == 0) { break; } if (!strncmp($existing->getPath() . '/', $parentNode->getPath() . "/{$nodename}", strlen($existing->getPath() . '/'))) { throw new ConstraintViolationException('Trying to remove/replace parent of the path we are adding to. ' . $existing->getIdentifier() . ' at ' . $existing->getPath()); } if (self::IMPORT_UUID_COLLISION_REPLACE_EXISTING == $uuidBehavior) { // replace the found node. spec is not precise: do we keep the name or use the one of existing? $parentNode = $existing->getParent(); } $existing->remove(); break; default: // @codeCoverageIgnoreStart throw new RepositoryException("Unexpected type {$uuidBehavior}"); // @codeCoverageIgnoreEnd } } catch (\PHPCR\ItemNotFoundException $e) { // nothing to do, we can add the node without conflict } } /* we add a jcr:root somewhere in the tree (either create new ids or * the root was not referenceable. do not make jackrabbit think it * would be the real root node. */ if ('jcr:root' === $nodename && 'rep:root' === $type) { $type = 'nt:unstructured'; } if ('jcr:root' == $nodename && isset($existing) && $existing->getDepth() === 0 && self::IMPORT_UUID_COLLISION_REPLACE_EXISTING == $uuidBehavior) { // update the root node properties // http://www.day.com/specs/jcr/2.0/11_Import.html#11.9%20Importing%20%3CI%3Ejcr:root%3C/I%3E NodeHelper::purgeWorkspace($parentNode->getSession()); $node = $existing; } else { $node = $parentNode->addNode($nodename, $type); } foreach ($properties as $name => $info) { if ('jcr:primaryType' == $name) { // handled in node constructor } elseif ('jcr:mixinTypes' == $name) { if (is_array($info['values'])) { foreach ($info['values'] as $type) { $node->addMixin($type); } } else { $node->addMixin($info['values']); } } elseif ('jcr:created' == $name || 'jcr:createdBy' == $name) { // skip PROTECTED properties. TODO: get the names from node type instead of hardcode } elseif ('jcr:uuid' == $name) { //avoid to throw an exception when trying to set a UUID when importing from XML $node->setProperty($name, $info['values'], $info['type'], false); } else { $node->setProperty($name, $info['values'], $info['type']); } } if ($forceReferenceable && !$node->isNodeType('mix:referenceable')) { $node->addMixin('mix:referenceable'); } return $node; }
/** * {@inheritdoc} */ public function write(NodeInterface $node, PropertyInterface $property, $userId, $webspaceKey, $languageCode, $segmentKey) { $value = $property->getValue(); if ($value instanceof ArrayableInterface) { $value = $value->toArray(); } if (isset($value)) { // remove not existing ids $session = $node->getSession(); $selectedNodes = $session->getNodesByIdentifier($value); $ids = []; foreach ($selectedNodes as $selectedNode) { if ($selectedNode->getIdentifier() === $node->getIdentifier()) { throw new \InvalidArgumentException('You are not allowed to link a page to itself!'); } $ids[] = $selectedNode->getIdentifier(); } $value = $ids; } // set value to node $node->setProperty($property->getName(), $value, PropertyType::REFERENCE); }
/** * Creates every node on the path to the given node. Also uses the same UUIDs for these nodes. * * @param NodeInterface $node */ private function createNodesWithUuid(NodeInterface $node) { $path = $node->getPath(); if ($this->liveSession->itemExists($path)) { return; } $currentDefaultNode = $node->getSession()->getRootNode(); $currentLiveNode = $this->liveSession->getRootNode(); $pathSegments = explode('/', ltrim($path, '/')); foreach ($pathSegments as $pathSegment) { $currentDefaultNode = $currentDefaultNode->getNode($pathSegment); if ($currentLiveNode->hasNode($pathSegment)) { $currentLiveNode = $currentLiveNode->getNode($pathSegment); continue; } $currentLiveNode = $currentLiveNode->addNode($pathSegment); $currentLiveNode->setMixins(['mix:referenceable']); $currentLiveNode->setProperty('jcr:uuid', $currentDefaultNode->getIdentifier()); } }
/** * {@inheritdoc} */ public function getSession() { return $this->node->getSession(); }
/** * adopts resource locator of children by iteration. * * @param NodeInterface $contentNode * @param int $userId * @param string $webspaceKey * @param string $languageCode * @param bool $iterate * @param string $segmentKey */ private function adaptResourceLocators(NodeInterface $contentNode, $userId, $webspaceKey, $languageCode, $segmentKey = null, $iterate = true) { foreach ($contentNode->getNodes() as $node) { // determine structure $templatePropertyName = $this->nodeHelper->getTranslatedPropertyName('template', $languageCode); if (!$node->hasProperty($templatePropertyName)) { continue; } $template = $node->getPropertyValue($templatePropertyName); $structure = $this->structureManager->getStructure($template); // only if rlp exists if ($structure->hasTag('sulu.rlp')) { // get rlp try { $rlp = $this->loadByContent($node, $webspaceKey, $languageCode); } catch (ResourceLocatorNotFoundException $ex) { $contentNode->getSession()->save(); $rlpPart = $node->getPropertyValue($this->nodeHelper->getTranslatedPropertyName('title', $languageCode)); $prentRlp = $this->mapper->getParentPath($node->getIdentifier(), $webspaceKey, $languageCode, $segmentKey); // generate new resourcelocator $rlp = $this->generate($rlpPart, $prentRlp, $webspaceKey, $languageCode); } // determine rlp property $property = $structure->getPropertyByTagName('sulu.rlp'); $contentType = $this->contentTypeManager->get($property->getContentTypeName()); $property->setValue($rlp); // write value to node $translatedProperty = $this->nodeHelper->getTranslatedProperty($property, $languageCode); $contentType->write($node, $translatedProperty, $userId, $webspaceKey, $languageCode, $segmentKey); } // for node move the tree will be copied to then there is the iteration over this function // for node copy the iteration is done by the content-type which calls over the move function // recursively this function if ($iterate) { $this->adaptResourceLocators($node, $userId, $webspaceKey, $languageCode, $segmentKey); } } }
public function testGetSession() { $sess = $this->node->getSession(); $this->assertInstanceOf('PHPCR\\SessionInterface', $sess); //how to further check if we got the right session? }