/** * {@inheritdoc} */ public function setDefaults(MediaInterface $media, $parentPath = null) { $class = ClassUtils::getClass($media); // check and add name if possible if (!$media->getName()) { if ($media->getId()) { $media->setName(PathHelper::getNodeName($media->getId())); } else { throw new \RuntimeException(sprintf('Unable to set defaults, Media of type "%s" does not have a name or id.', $class)); } } $rootPath = is_null($parentPath) ? $this->rootPath : $parentPath; $path = ($rootPath === '/' ? $rootPath : $rootPath . '/') . $media->getName(); /** @var DocumentManager $dm */ $dm = $this->getObjectManager(); // TODO use PHPCR autoname once this is done: http://www.doctrine-project.org/jira/browse/PHPCR-103 if ($dm->find($class, $path)) { // path already exists $media->setName($media->getName() . '_' . time() . '_' . rand()); } if (!$media->getParent()) { $parent = $dm->find(null, PathHelper::getParentPath($path)); $media->setParent($parent); } }
/** * @param PersistEvent $event * * @throws DocumentManagerException */ public function handlePersist(PersistEvent $event) { $options = $event->getOptions(); $this->validateOptions($options); $document = $event->getDocument(); $parentPath = null; $nodeName = null; if ($options['path']) { $parentPath = PathHelper::getParentPath($options['path']); $nodeName = PathHelper::getNodeName($options['path']); } if ($options['parent_path']) { $parentPath = $options['parent_path']; } if ($parentPath) { $event->setParentNode($this->resolveParent($parentPath, $options)); } if ($options['node_name']) { if (!$event->hasParentNode()) { throw new DocumentManagerException(sprintf('The "node_name" option can only be used either with the "parent_path" option ' . 'or when a parent node has been established by a previous subscriber. ' . 'When persisting document: %s', DocumentHelper::getDebugTitle($document))); } $nodeName = $options['node_name']; } if (!$nodeName) { return; } if ($event->hasNode()) { $this->renameNode($event->getNode(), $nodeName); return; } $node = $this->strategy->createNodeForDocument($document, $event->getParentNode(), $nodeName); $event->setNode($node); }
public function setRouteRoot($routeRoot) { // make limitation on base path work parent::setRootPath($routeRoot); // TODO: fix widget to show root node when root is selectable // https://github.com/sonata-project/SonataDoctrinePhpcrAdminBundle/issues/148 $this->routeRoot = PathHelper::getParentPath($routeRoot); }
/** * @param string $path * * @return Route */ protected function createRoute($path) { $parentPath = PathHelper::getParentPath($path); $parent = $this->getDm()->find(null, $parentPath); $name = PathHelper::getNodeName($path); $route = new Route(); $route->setPosition($parent, $name); $this->getDm()->persist($route); $this->getDm()->flush(); return $route; }
public function removeProperty($workspace, $path) { $propertyName = PathHelper::getNodeName($path); $nodePath = PathHelper::getParentPath($path); $node = $this->nodeReader->readNode($workspace, $nodePath); $property = $node->getProperty($propertyName); if (in_array($property['type'], array('Reference', 'WeakReference'))) { $this->index->deindexReferrer($node->getPropertyValue(Storage::INTERNAL_UUID), $propertyName, $property['type'] === 'Reference' ? false : true); } $node->removeProperty($propertyName); $this->nodeWriter->writeNode($workspace, $nodePath, $node); }
/** * Finds the parent route document by concatenating the basepaths with the * requested path. * * @return null|object */ protected function findParentRoute($requestedPath) { $manager = $this->getManagerForClass('Symfony\\Cmf\\Bundle\\RoutingBundle\\Doctrine\\Phpcr\\Route'); $parentPaths = array(); foreach ($this->routeBasePaths as $basepath) { $parentPaths[] = PathHelper::getParentPath($basepath . $requestedPath); } $parentRoutes = $manager->findMany(null, $parentPaths); if (0 === count($parentRoutes)) { return; } return $parentRoutes->first(); }
/** * {@inheritdoc} */ public function create(Request $request) { $routes = array(); $manager = $this->getManagerForClass('Symfony\\Cmf\\Bundle\\RoutingBundle\\Doctrine\\Phpcr\\Route'); $parentPath = PathHelper::getParentPath($this->routeBasePath . $request->getPathInfo()); $parentRoute = $manager->find(null, $parentPath); if (!$parentRoute) { return $routes; } if ($parentRoute instanceof Route) { $routes[$parentRoute->getName()] = $parentRoute; } return $routes; }
protected function loadPhpcr($config, XmlFileLoader $loader, ContainerBuilder $container) { $loader->load('services-phpcr.xml'); $loader->load('migrator-phpcr.xml'); $prefix = $this->getAlias() . '.persistence.phpcr'; $container->setParameter($prefix . '.basepath', $config['basepath']); $container->setParameter($prefix . '.menu_basepath', PathHelper::getParentPath($config['basepath'])); if ($config['use_sonata_admin']) { $this->loadSonataAdmin($config, $loader, $container); } elseif (isset($config['sonata_admin'])) { throw new InvalidConfigurationException('Do not define sonata_admin options when use_sonata_admin is set to false'); } $container->setParameter($prefix . '.manager_name', $config['manager_name']); $container->setParameter($prefix . '.document.class', $config['document_class']); }
private function resolveSiblingName($siblingId, NodeInterface $parentNode, NodeInterface $node) { if (null === $siblingId) { return; } $siblingPath = $siblingId; if (UUIDHelper::isUUID($siblingId)) { $siblingPath = $this->nodeManager->find($siblingId)->getPath(); } if ($siblingPath !== null && PathHelper::getParentPath($siblingPath) !== $parentNode->getPath()) { throw new DocumentManagerException(sprintf('Cannot reorder documents which are not siblings. Trying to reorder "%s" to "%s"', $node->getPath(), $siblingPath)); } if (null !== $siblingPath) { return PathHelper::getNodeName($siblingPath); } return $node->getName(); }
/** * {@inheritDoc} */ public function init(ManagerRegistry $registry) { /** @var $dm DocumentManager */ $dm = $registry->getManagerForClass('Symfony\\Cmf\\Bundle\\SimpleCmsBundle\\Doctrine\\Phpcr\\Page'); if ($dm->find(null, $this->basePath)) { return; } $session = $dm->getPhpcrSession(); NodeHelper::createPath($session, PathHelper::getParentPath($this->basePath)); $page = new $this->documentClass(); $page->setId($this->basePath); $page->setLabel('Home'); $page->setTitle('Homepage'); $page->setBody('Autocreated Homepage'); $dm->persist($page); $dm->flush(); }
/** * {@inheritdoc} */ public function init(ManagerRegistry $registry) { /** @var $dm DocumentManager */ $dm = $registry->getManagerForClass('AppBundle\\Document\\SeoPage'); if ($dm->find(null, $this->basePath)) { return; } $session = $dm->getPhpcrSession(); NodeHelper::createPath($session, PathHelper::getParentPath($this->basePath)); /** @var \AppBundle\Document\SeoPage $page */ $page = new $this->documentClass(); $page->setId($this->basePath); $page->setLabel('Home'); $page->setTitle('Homepage'); $page->setBody('Autocreated Homepage'); $page->setIsVisibleForSitemap(true); $dm->persist($page); $dm->flush(); }
/** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $helper = $this->getPhpcrHelper(); $session = $this->getPhpcrSession(); $path = $input->getArgument('path'); $type = $input->getOption('type'); $dump = $input->getOption('dump'); $setProp = $input->getOption('set-prop'); $removeProp = $input->getOption('remove-prop'); $addMixins = $input->getOption('add-mixin'); $removeMixins = $input->getOption('remove-mixin'); try { $node = $session->getNode($path); } catch (PathNotFoundException $e) { $node = null; } if ($node) { $nodeType = $node->getPrimaryNodeType()->getName(); $output->writeln(sprintf('<info>Node at path </info>%s <info>already exists and has primary type</info> %s.', $path, $nodeType)); if ($nodeType != $type) { $output->writeln(sprintf('<error>You have specified node type "%s" but the existing node is of type "%s"</error>', $type, $nodeType)); return 1; } } else { $nodeName = PathHelper::getNodeName($path); $parentPath = PathHelper::getParentPath($path); try { $parentNode = $session->getNode($parentPath); } catch (PathNotFoundException $e) { $output->writeln(sprintf('<error>Parent path "%s" does not exist</error>', $parentPath)); return 2; } $output->writeln(sprintf('<info>Creating node: </info> %s [%s]', $path, $type)); $node = $parentNode->addNode($nodeName, $type); } $helper->processNode($output, $node, array('setProp' => $setProp, 'removeProp' => $removeProp, 'addMixins' => $addMixins, 'removeMixins' => $removeMixins, 'dump' => $dump)); $session->save(); return 0; }
/** * {@inheritDoc} * @throws RepositoryException when no binary data found */ public function getBinaryStream($path) { $this->assertLoggedIn(); $nodePath = PathHelper::getParentPath($path); $nodeId = $this->getSystemIdForNode($nodePath); $propertyName = PathHelper::getNodeName($path); $data = $this->getConnection()->fetchAll('SELECT data, idx FROM phpcr_binarydata WHERE node_id = ? AND property_name = ? AND workspace_name = ?', array($nodeId, $propertyName, $this->workspaceName)); if (count($data) === 0) { throw new RepositoryException('No binary data found in stream'); } $streams = array(); foreach ($data as $row) { if (is_resource($row['data'])) { $stream = $row['data']; } else { $stream = fopen('php://memory', 'rwb+'); fwrite($stream, $row['data']); rewind($stream); } $streams[] = $stream; } if (count($data) === 1) { // we don't know if this is a multivalue property or not. // TODO we should have something more efficient to know this. a flag in the database? // TODO use self::getProperty()->isMultiple() once implemented $node = $this->getNode($nodePath); if (!is_array($node->{':' . $propertyName})) { return reset($streams); } } return $streams; }
/** * {@inheritDoc} * * @api */ public function restore($removeExisting, $version, $absPath = null) { if ($this->objectManager->hasPendingChanges()) { throw new InvalidItemStateException('You may not call restore when there pending unsaved changes'); } if (is_string($version)) { if (!is_string($absPath)) { throw new InvalidArgumentException('To restore version by version name you need to specify the path to the node you want to restore to this name'); } $vh = $this->getVersionHistory($absPath); $version = $vh->getVersion($version); $versionPath = $version->getPath(); $nodePath = $absPath; } elseif (is_array($version)) { // @codeCoverageIgnoreStart throw new NotImplementedException('TODO: implement restoring a list of versions'); // @codeCoverageIgnoreEnd } elseif ($version instanceof VersionInterface && is_string($absPath)) { // @codeCoverageIgnoreStart throw new NotImplementedException('TODO: implement restoring a version to a specified path'); // @codeCoverageIgnoreEnd } elseif ($version instanceof VersionInterface) { $versionPath = $version->getPath(); $nodePath = $this->objectManager->getNodeByIdentifier($version->getContainingHistory()->getVersionableIdentifier())->getPath(); } else { throw new InvalidArgumentException(); } $this->objectManager->restore($removeExisting, $versionPath, $nodePath); $version->setCachedPredecessorsDirty(); if ($history = $this->objectManager->getCachedNode(PathHelper::getParentPath($version->getPath()), 'Version\\VersionHistory')) { $history->notifyHistoryChanged(); } }
/** * {@inheritDoc} */ public function getBinaryStream($path) { $this->assertLoggedIn(); $nodePath = PathHelper::getParentPath($path); $nodeId = $this->pathExists($nodePath); $propertyName = PathHelper::getNodeName($path); $data = $this->conn->fetchAll( 'SELECT data, idx FROM phpcr_binarydata WHERE node_id = ? AND property_name = ? AND workspace_name = ?', array($nodeId, $propertyName, $this->workspaceName) ); $streams = array(); foreach ($data as $row) { if (is_resource($row['data'])) { $stream = $row['data']; } else { $stream = fopen('php://memory', 'rwb+'); fwrite($stream, $row['data']); rewind($stream); } $streams[] = $stream; } // TODO even a multi value field could have only one value stored // we need to also fetch if the property is multi valued instead of this count() check if (count($data) > 1) { return $streams; } return reset($streams); }
public function testRemoveVersion() { $doc = $this->dm->find($this->typeVersion, '/functional/versionTestObj'); $this->dm->checkpoint($doc); $linearVersionHistory = $this->dm->getAllLinearVersions($doc); $lastVersion = end($linearVersionHistory); $lastVersionName = $lastVersion['name']; // Create a new version so that we are not trying to remove the last version $this->dm->checkpoint($doc); // Remove the version $version = $this->dm->findVersionByName($this->typeVersion, '/functional/versionTestObj', $lastVersionName); $removedVersionPath = $version->id; $this->dm->removeVersion($version); // Check it's not in the history anymore $this->assertFalse($this->dm->getPhpcrSession()->nodeExists(PathHelper::getParentPath($removedVersionPath))); return $lastVersionName; }
/** * Imports workspace. * * @param SessionInterface $session * @param string $path * @param string $fileName */ private function import(SessionInterface $session, $path, $fileName) { if ($session->nodeExists($path)) { $session->getNode($path)->remove(); $session->save(); } $session->importXML(PathHelper::getParentPath($path), $fileName, ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_THROW); $session->save(); }
/** * Return parent directory path * * @param string $path file path * @return string * @author Dmitry (dio) Levashov **/ protected function _dirname($path) { return PathHelper::getParentPath($path); }
/** * {@inheritDoc} */ public function getBinaryStream($path) { $this->assertLoggedIn(); $parentPath = PathHelper::getParentPath($path); $grid = $this->db->getGridFS(); $binary = $grid->getMongoCollection()->find(array('path' => $path, 'parent' => $parentPath, 'w_id' => $this->workspaceId)); if (empty($binary)) { throw new ItemNotFoundException('Binary ' . $path . ' not found.'); } // TODO: OPTIMIZE stream handling! $stream = fopen('php://memory', 'rwb+'); fwrite($stream, $binary->current()); rewind($stream); return $stream; }
/** * Set or update the path, depth, name and parent reference * * @param string $path the new path this item lives at * @param boolean $move whether this item is being moved in session context * and should store the current path until the next save operation. * * @private */ public function setPath($path, $move = false) { if ($move && is_null($this->oldPath)) { try { $this->checkState(); } catch (InvalidItemStateException $e) { // do not break if object manager tells the move to a child that was removed in backend return; } $this->oldPath = $this->path; } $this->path = $path; $this->depth = '/' === $path ? 0 : substr_count($path, '/'); $this->name = PathHelper::getNodeName($path); $this->parentPath = 0 === $this->depth ? null : PathHelper::getParentPath($path); }
/** * Creates a new node at the specified $relPath * * {@inheritDoc} * * In Jackalope, the child node type definition is immediately applied if no * primaryNodeTypeName is specified. * * The PathNotFoundException and ConstraintViolationException are thrown * immediately. * Version and Lock related exceptions are delayed until save. * * @api */ public function addNode($relPath, $primaryNodeTypeName = null) { $relPath = (string) $relPath; $this->checkState(); $ntm = $this->session->getWorkspace()->getNodeTypeManager(); // are we not the immediate parent? if (strpos($relPath, '/') !== false) { // forward to real parent $relPath = PathHelper::absolutizePath($relPath, $this->getPath(), true); $parentPath = PathHelper::getParentPath($relPath); $newName = PathHelper::getNodeName($relPath); try { $parentNode = $this->objectManager->getNodeByPath($parentPath); } catch (ItemNotFoundException $e) { //we have to throw a different exception if there is a property // with that name than if there is nothing at the path at all. // lets see if the property exists if ($this->session->propertyExists($parentPath)) { throw new ConstraintViolationException("Node '{$this->path}': Not allowed to add a node below property at {$parentPath}"); } throw new PathNotFoundException($e->getMessage(), $e->getCode(), $e); } return $parentNode->addNode($newName, $primaryNodeTypeName); } if (is_null($primaryNodeTypeName)) { if ($this->primaryType === 'rep:root') { $primaryNodeTypeName = 'nt:unstructured'; } else { $type = $ntm->getNodeType($this->primaryType); $nodeDefinitions = $type->getChildNodeDefinitions(); foreach ($nodeDefinitions as $def) { if (!is_null($def->getDefaultPrimaryType())) { $primaryNodeTypeName = $def->getDefaultPrimaryTypeName(); break; } } } if (is_null($primaryNodeTypeName)) { throw new ConstraintViolationException("No matching child node definition found for `{$relPath}' in type `{$this->primaryType}' for node '{$this->path}'. Please specify the type explicitly."); } } // create child node //sanity check: no index allowed. TODO: we should verify this is a valid node name if (false !== strpos($relPath, ']')) { throw new RepositoryException("The node '{$this->path}' does not allow an index in name of newly created node: {$relPath}"); } if (in_array($relPath, $this->nodes, true)) { throw new ItemExistsException("The node '{$this->path}' already has a child named '{$relPath}''."); //TODO: same-name siblings if nodetype allows for them } $data = array('jcr:primaryType' => $primaryNodeTypeName); $path = $this->getChildPath($relPath); $node = $this->factory->get('Node', array($data, $path, $this->session, $this->objectManager, true)); $this->addChildNode($node, false); // no need to check the state, we just checked when entering this method $this->objectManager->addNode($path, $node); if (is_array($this->originalNodesOrder)) { // new nodes are added at the end $this->originalNodesOrder[] = $relPath; } //by definition, adding a node sets the parent to modified $this->setModified(); return $node; }
/** * Executes all document moves * * @param array $documents array of all to be moved documents */ private function executeMoves($documents) { foreach ($documents as $oid => $value) { if (!$this->contains($oid)) { continue; } list($document, $targetPath) = $value; $sourcePath = $this->getDocumentId($document); if ($sourcePath === $targetPath) { continue; } $class = $this->dm->getClassMetadata(get_class($document)); if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::preMove)) { $this->eventListenersInvoker->invoke($class, Event::preMove, $document, new MoveEventArgs($document, $this->dm, $sourcePath, $targetPath), $invoke); } $parentNode = $this->session->getNode(PathHelper::getParentPath($targetPath)); $this->validateChildClass($parentNode, $class); $this->session->move($sourcePath, $targetPath); // update fields nodename, parentMapping and depth if they exist in this type $node = $this->session->getNode($targetPath); // get node from session, document class might not map it if ($class->nodename) { $class->setFieldValue($document, $class->nodename, $node->getName()); } if ($class->parentMapping) { $class->setFieldValue($document, $class->parentMapping, $this->getOrCreateProxyFromNode($node->getParent(), $this->getCurrentLocale($document, $class))); } if ($class->depthMapping) { $class->setFieldValue($document, $class->depthMapping, $node->getDepth()); } // update all cached children of the document to reflect the move (path id changes) foreach ($this->documentIds as $childOid => $id) { if (0 !== strpos($id, $sourcePath)) { continue; } $newId = $targetPath . substr($id, strlen($sourcePath)); $this->documentIds[$childOid] = $newId; $child = $this->getDocumentById($id); if (!$child) { continue; } unset($this->identityMap[$id]); $this->identityMap[$newId] = $child; $childClass = $this->dm->getClassMetadata(get_class($child)); if ($childClass->identifier) { $childClass->setIdentifierValue($child, $newId); if (!$child instanceof Proxy || $child->__isInitialized()) { $this->originalData[$oid][$childClass->identifier] = $newId; } } } if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::postMove)) { $this->eventListenersInvoker->invoke($class, Event::postMove, $document, new MoveEventArgs($document, $this->dm, $sourcePath, $targetPath), $invoke); } } }
/** * {@inheritDoc} */ public function getBinaryStream($path) { $this->assertLoggedIn(); $nodePath = PathHelper::getParentPath($path); $propertyName = PathHelper::getNodeName($path); $streams = array(); // TODO implement $data = array(); foreach ($data as $row) { if (is_resource($row['data'])) { $stream = $row['data']; } else { $stream = fopen('php://memory', 'rwb+'); fwrite($stream, $row['data']); rewind($stream); } $streams[] = $stream; } // TODO even a multi value field could have only one value stored // we need to also fetch if the property is multi valued instead of this count() check if (count($data) > 1) { return $streams; } return reset($streams); }
/** * @see StaticPathHelper::getParentPath */ public function getParentPath($path) { return StaticPathHelper::getParentPath($path); }
/** * Executes all document insertions * * @param array $documents array of all to be inserted documents */ private function executeInserts($documents) { // sort the documents to insert parents first but maintain child order $oids = array(); foreach ($documents as $oid => $document) { if (!$this->contains($oid)) { continue; } $oids[$oid] = $this->getDocumentId($document); } $order = array_flip(array_values($oids)); uasort($oids, function ($a, $b) use($order) { // compute the node depths $aCount = substr_count($a, '/'); $bCount = substr_count($b, '/'); // ensure that the original order is maintained for nodes with the same depth if ($aCount === $bCount) { return $order[$a] < $order[$b] ? -1 : 1; } return $aCount < $bCount ? -1 : 1; }); $associationChangesets = $associationUpdates = array(); foreach ($oids as $oid => $id) { $document = $documents[$oid]; $class = $this->dm->getClassMetadata(get_class($document)); // PHPCR does not validate nullable unless we would start to // generate custom node types, which we at the moment don't. // the ORM can delegate this validation to the relational database // that is using a strict schema foreach ($class->fieldMappings as $fieldName) { if (!isset($this->documentChangesets[$oid]['fields'][$fieldName]) && !$class->isNullable($fieldName) && !$this->isAutocreatedProperty($class, $fieldName)) { throw new PHPCRException(sprintf('Field "%s" of class "%s" is not nullable', $fieldName, $class->name)); } } $parentNode = $this->session->getNode(PathHelper::getParentPath($id)); $nodename = PathHelper::getNodeName($id); $node = $parentNode->addNode($nodename, $class->nodeType); if ($class->node) { $this->originalData[$oid][$class->node] = $node; } if ($class->nodename) { $this->originalData[$oid][$class->nodename] = $nodename; } try { $node->addMixin('phpcr:managed'); } catch (NoSuchNodeTypeException $e) { throw new PHPCRException('Register phpcr:managed node type first. See https://github.com/doctrine/phpcr-odm/wiki/Custom-node-type-phpcr:managed'); } foreach ($class->mixins as $mixin) { $node->addMixin($mixin); } if ($class->identifier) { $class->setIdentifierValue($document, $id); } if ($class->node) { $class->reflFields[$class->node]->setValue($document, $node); } if ($class->nodename) { // make sure this reflects the id generator strategy generated id $class->reflFields[$class->nodename]->setValue($document, $node->getName()); } // make sure this reflects the id generator strategy generated id if ($class->parentMapping && !$class->reflFields[$class->parentMapping]->getValue($document)) { $class->reflFields[$class->parentMapping]->setValue($document, $this->getOrCreateProxyFromNode($parentNode, $this->getCurrentLocale($document, $class))); } if ($this->writeMetadata) { $this->documentClassMapper->writeMetadata($this->dm, $node, $class->name); } $this->setMixins($class, $node, $document); $fields = isset($this->documentChangesets[$oid]['fields']) ? $this->documentChangesets[$oid]['fields'] : array(); foreach ($fields as $fieldName => $fieldValue) { // Ignore translatable fields (they will be persisted by the translation strategy) if (in_array($fieldName, $class->translatableFields)) { continue; } if (in_array($fieldName, $class->fieldMappings)) { $mapping = $class->mappings[$fieldName]; $type = PropertyType::valueFromName($mapping['type']); if (null === $fieldValue) { continue; } if ($mapping['multivalue'] && $fieldValue) { $fieldValue = (array) $fieldValue; if (isset($mapping['assoc'])) { $fieldValue = $this->processAssoc($node, $mapping, $fieldValue); } } $node->setProperty($mapping['property'], $fieldValue, $type); } elseif (in_array($fieldName, $class->referenceMappings) || in_array($fieldName, $class->referrersMappings)) { $associationUpdates[$oid] = $document; //populate $associationChangesets to force executeUpdates($associationUpdates) //to only update association fields $data = isset($associationChangesets[$oid]['fields']) ? $associationChangesets[$oid]['fields'] : array(); $data[$fieldName] = array(null, $fieldValue); $associationChangesets[$oid] = array('fields' => $data); } } $this->doSaveTranslation($document, $node, $class); if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::postPersist)) { $this->eventListenersInvoker->invoke($class, Event::postPersist, $document, new LifecycleEventArgs($document, $this->dm), $invoke); } } $this->documentChangesets = array_merge($this->documentChangesets, $associationChangesets); $this->executeUpdates($associationUpdates, false); }
/** * @param SessionInterface $session * @param QueryResultInterface $rows * * @return array */ protected function buildSearchResults(SessionInterface $session, QueryResultInterface $rows) { $searchResults = array(); /** @var $row RowInterface */ foreach ($rows as $row) { if (!$row->getValue('class')) { $parent = $session->getNode(PathHelper::getParentPath($row->getPath())); $contentId = $parent->getIdentifier(); $node = $parent; } else { $contentId = $row->getValue('uuid') ?: $row->getPath(); $node = $row->getNode(); } $url = $this->mapUrl($session, $node); if (false === $url) { continue; } $searchResults[$contentId] = array('url' => $url, 'title' => $row->getValue($this->searchFields['title']), 'summary' => $this->buildSummary($row)); } return $searchResults; }
/** * Generates a content-tree with paths of given content array. * * @param Content[] $contents * * @return Content[] */ private function generateTreeByPath(array $contents) { $childrenByPath = []; foreach ($contents as $content) { $path = PathHelper::getParentPath($content->getPath()); if (!isset($childrenByPath[$path])) { $childrenByPath[$path] = []; } $order = $content['order']; while (isset($childrenByPath[$path][$order])) { ++$order; } $childrenByPath[$path][$order] = $content; } foreach ($contents as $content) { if (!isset($childrenByPath[$content->getPath()])) { continue; } ksort($childrenByPath[$content->getPath()]); $content->setChildren(array_values($childrenByPath[$content->getPath()])); } ksort($childrenByPath['/']); return array_values($childrenByPath['/']); }
/** * Rewrites the path of a node for the movement operation, also updating * all cached children. * * This applies both to the cache and to the items themselves so * they return the correct value on getPath calls. * * @param string $curPath Absolute path of the node to rewrite * @param string $newPath The new absolute path */ protected function rewriteItemPaths($curPath, $newPath) { // update internal references in parent $parentCurPath = PathHelper::getParentPath($curPath); $parentNewPath = PathHelper::getParentPath($newPath); if (isset($this->objectsByPath['Node'][$parentCurPath])) { /** @var $node Node */ $node = $this->objectsByPath['Node'][$parentCurPath]; if (!$node->hasNode(PathHelper::getNodeName($curPath))) { throw new PathNotFoundException("Source path can not be found: {$curPath}"); } $node->unsetChildNode(PathHelper::getNodeName($curPath), true); } if (isset($this->objectsByPath['Node'][$parentNewPath])) { /** @var $node Node */ $node = $this->objectsByPath['Node'][$parentNewPath]; $node->addChildNode($this->getNodeByPath($curPath), true, PathHelper::getNodeName($newPath)); } // propagate to current and children items of $curPath, updating internal path /** @var $node Node */ foreach ($this->objectsByPath['Node'] as $path => $node) { // is it current or child? if (strpos($path, $curPath . '/') === 0 || $path == $curPath) { // curPath = /foo // newPath = /mo // path = /foo/bar // newItemPath= /mo/bar $newItemPath = substr_replace($path, $newPath, 0, strlen($curPath)); if (isset($this->objectsByPath['Node'][$path])) { $node = $this->objectsByPath['Node'][$path]; $this->objectsByPath['Node'][$newItemPath] = $node; unset($this->objectsByPath['Node'][$path]); $node->setPath($newItemPath, true); } // update uuid cache $this->objectsByUuid[$node->getIdentifier()] = $node->getPath(); } } }
/** * Extract the snippet path from the given path. * * @param string $path * * @return string * * @throws \InvalidArgumentException */ public function extractSnippetTypeFromPath($path) { if (substr($path, 0, 1) !== '/') { throw new \InvalidArgumentException(sprintf('Path must be absolute, got "%s"', $path)); } $snippetsPath = '/' . $this->getPath('base') . '/' . $this->getPath('snippet') . '/'; $newPath = PathHelper::getParentPath($path); $newPath = substr($newPath, strlen($snippetsPath)); if (false === $newPath) { throw new \InvalidArgumentException(sprintf('Cannot extract snippet template type from path "%s"', $path)); } return $newPath; }
/** * {@inheritDoc} * * @api */ public function move($srcAbsPath, $destAbsPath) { try { $parent = $this->objectManager->getNodeByPath(PathHelper::getParentPath($destAbsPath)); } catch (ItemNotFoundException $e) { throw new PathNotFoundException("Target path can not be found: {$destAbsPath}", $e->getCode(), $e); } if ($parent->hasNode(PathHelper::getNodeName($destAbsPath))) { // TODO same-name siblings throw new ItemExistsException('Target node already exists at ' . $destAbsPath); } if ($parent->hasProperty(PathHelper::getNodeName($destAbsPath))) { throw new ItemExistsException('Target property already exists at ' . $destAbsPath); } $this->objectManager->moveNode($srcAbsPath, $destAbsPath); }