예제 #1
0
 /**
  * {@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);
 }
예제 #3
0
 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);
 }
예제 #4
0
 /**
  * @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;
 }
예제 #5
0
 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();
 }
예제 #10
0
 /**
  * {@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();
 }
예제 #12
0
 /**
  * {@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;
 }
예제 #13
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;
 }
예제 #14
0
 /**
  * {@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();
     }
 }
예제 #15
0
    /**
     * {@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);
    }
예제 #16
0
 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;
 }
예제 #17
0
 /**
  * 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();
 }
예제 #18
0
 /**
  * Return parent directory path
  *
  * @param  string $path file path
  * @return string
  * @author Dmitry (dio) Levashov
  **/
 protected function _dirname($path)
 {
     return PathHelper::getParentPath($path);
 }
예제 #19
0
 /**
  * {@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;
 }
예제 #20
0
 /**
  * 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);
 }
예제 #21
0
 /**
  * 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;
 }
예제 #22
0
 /**
  * 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);
         }
     }
 }
예제 #23
0
 /**
  * {@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);
 }
예제 #24
0
 /**
  * @see StaticPathHelper::getParentPath
  */
 public function getParentPath($path)
 {
     return StaticPathHelper::getParentPath($path);
 }
예제 #25
0
 /**
  * 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);
 }
예제 #26
0
 /**
  * @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;
 }
예제 #27
0
 /**
  * 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['/']);
 }
예제 #28
0
 /**
  * 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();
         }
     }
 }
예제 #29
0
 /**
  * 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;
 }
예제 #30
0
 /**
  * {@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);
 }