private function doSerializeResource(Resource $resource, $depth = 0)
 {
     $data = array();
     $repositoryAlias = $this->registry->getRepositoryAlias($resource->getRepository());
     $data['repository_alias'] = $repositoryAlias;
     $data['repository_type'] = $this->registry->getRepositoryType($resource->getRepository());
     $data['payload_alias'] = $this->payloadAliasRegistry->getPayloadAlias($resource);
     $data['payload_type'] = null;
     if ($resource instanceof CmfResource) {
         $data['payload_type'] = $resource->getPayloadType();
     }
     $data['path'] = $resource->getPath();
     $data['label'] = $data['node_name'] = PathHelper::getNodeName($data['path']);
     $data['repository_path'] = $resource->getRepositoryPath();
     $enhancers = $this->enhancerRegistry->getEnhancers($repositoryAlias);
     $children = array();
     foreach ($resource->listChildren() as $name => $childResource) {
         $children[$name] = array();
         if ($depth < 2) {
             $children[$name] = $this->doSerializeResource($childResource, $depth + 1);
         }
     }
     $data['children'] = $children;
     if ($resource instanceof BodyResource) {
         $data['body'] = $resource->getBody();
     }
     foreach ($enhancers as $enhancer) {
         $data = $enhancer->enhance($data, $resource);
     }
     return $data;
 }
Пример #2
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);
 }
 public function preFlush(ManagerEventArgs $args)
 {
     if (empty($this->stack)) {
         return;
     }
     $metadataFactory = $args->getObjectManager()->getMetadataFactory();
     foreach ($this->stack as $data) {
         $children = $data['children'];
         $ctMetadata = $data['ct_metadata'];
         $childrenField = $data['field'];
         $index = 0;
         foreach ($children as $child) {
             $childMetadata = $metadataFactory->getMetadataFor(ClassUtils::getRealClass(get_class($child)));
             $expectedId = $this->encoder->encode($childrenField, $index++);
             $identifier = $childMetadata->getIdentifierValue($child);
             $idGenerator = $childMetadata->idGenerator;
             if ($idGenerator !== ClassMetadata::GENERATOR_TYPE_ASSIGNED) {
                 throw new \InvalidArgumentException(sprintf('Currently, all documents which belong to a mapped collection must use the ' . 'assigned ID generator strategy, "%s" is using "%s".', $childMetadata->getName(), $idGenerator));
             }
             if (!$identifier || PathHelper::getNodeName($identifier) !== $expectedId) {
                 throw new \InvalidArgumentException(sprintf('Child mapped to content type "%s" on field "%s" has an unexpected ID "%s". ' . 'It is currently necessary to envoke the CollectionIdentifierUpdater on all ' . 'documents (at least those which have collections) before they are persisted.', $ctMetadata->getType(), $childrenField, $identifier));
             }
         }
     }
 }
Пример #5
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;
 }
Пример #6
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);
 }
 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();
 }
Пример #8
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;
 }
Пример #9
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();
         }
     }
 }
 /**
  * @dataProvider provideOrder
  */
 public function testOrder($nodes, $orderBy, $expectedOrder)
 {
     $rootNode = $this->session->getNode('/');
     foreach ($nodes as $nodeName => $nodeProperties) {
         $node = $rootNode->addNode($nodeName);
         foreach ($nodeProperties as $name => $value) {
             $node->setProperty($name, $value);
         }
     }
     $this->session->save();
     $qm = $this->session->getWorkspace()->getQueryManager();
     $query = $qm->createQuery('SELECT * FROM [nt:unstructured] WHERE value IS NOT NULL ORDER BY ' . $orderBy, \PHPCR\Query\QueryInterface::JCR_SQL2);
     $result = $query->execute();
     $rows = $result->getRows();
     $this->assertGreaterThan(0, count($rows));
     foreach ($rows as $index => $row) {
         $path = $row->getNode()->getPath();
         $name = PathHelper::getNodeName($path);
         $expectedName = $expectedOrder[$index];
         $this->assertEquals($expectedName, $name);
     }
 }
Пример #11
0
 /**
  * Return file name
  *
  * @param  string $path file path
  * @return string
  * @author Dmitry (dio) Levashov
  **/
 protected function _basename($path)
 {
     return PathHelper::getNodeName($path);
 }
Пример #12
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);
 }
Пример #13
0
 /**
  * Reorder $moved (child of $parent) before or after $target
  *
  * @param string $parent the id of the parent
  * @param string $moved the id of the child being moved
  * @param string $target the id of the target node
  * @param bool $before insert before or after the target
  * 
  * @return void
  */
 public function reorder($parent, $moved, $target, $before)
 {
     $parentNode = $this->session->getNode($parent);
     $targetName = PathHelper::getNodeName($target);
     if (!$before) {
         $nodesIterator = $parentNode->getNodes();
         $nodesIterator->rewind();
         while ($nodesIterator->valid()) {
             if ($nodesIterator->key() == $targetName) {
                 break;
             }
             $nodesIterator->next();
         }
         $targetName = null;
         if ($nodesIterator->valid()) {
             $nodesIterator->next();
             if ($nodesIterator->valid()) {
                 $targetName = $nodesIterator->key();
             }
         }
     }
     $parentNode->orderBefore(PathHelper::getNodeName($moved), $targetName);
     $this->session->save();
 }
Пример #14
0
 /**
  * Copy or move a node by UUID to a detination parent.
  *
  * Note that the bulk of this method is about the resource locator and can
  * be removed if we integrate the RoutingAuto component.
  *
  * @param string $webspaceKey
  * @param string $locale
  * @param bool $move
  *
  * @return StructureInterface
  */
 private function copyOrMove($uuid, $destParentUuid, $userId, $webspaceKey, $locale, $move = true)
 {
     // find localizations
     $webspace = $this->webspaceManager->findWebspaceByKey($webspaceKey);
     $localizations = $webspace->getAllLocalizations();
     // load from phpcr
     $document = $this->documentManager->find($uuid, $locale);
     $parentDocument = $this->documentManager->find($destParentUuid, $locale);
     if ($move) {
         // move node
         $this->documentManager->move($document, $destParentUuid);
     } else {
         // copy node
         $copiedPath = $this->documentManager->copy($document, $destParentUuid);
         $document = $this->documentManager->find($copiedPath, $locale);
         $this->documentManager->refresh($parentDocument);
     }
     $originalLocale = $locale;
     // modifiy the resource locators -- note this can be removed once the routing auto
     // system is implemented.
     foreach ($localizations as $locale) {
         $locale = $locale->getLocalization();
         if (!$document instanceof ResourceSegmentBehavior) {
             break;
         }
         // prepare parent content node
         // finding the document will update the locale without reloading from PHPCR
         $this->documentManager->find($document->getUuid(), $locale);
         $this->documentManager->find($parentDocument->getUuid(), $locale);
         $parentResourceLocator = '/';
         if ($parentDocument instanceof ResourceSegmentBehavior) {
             $parentResourceLocator = $parentDocument->getResourceSegment();
         }
         // TODO: This could be optimized
         $localizationState = $this->inspector->getLocalizationState($document);
         if ($localizationState !== LocalizationState::LOCALIZED) {
             continue;
         }
         if ($document->getRedirectType() !== RedirectType::NONE) {
             continue;
         }
         $strategy = $this->getResourceLocator()->getStrategy();
         $nodeName = PathHelper::getNodeName($document->getResourceSegment());
         $newResourceLocator = $strategy->generate($nodeName, $parentDocument->getResourceSegment(), $webspaceKey, $locale);
         $document->setResourceSegment($newResourceLocator);
         $this->documentManager->persist($document, $locale, array('user' => $userId));
     }
     $this->documentManager->flush();
     //
     $this->documentManager->find($document->getUuid(), $originalLocale);
     return $this->documentToStructure($document);
 }
 /**
  * @param Request $request
  *
  * @return Response
  *
  * @throws AccessDeniedException
  */
 public function autoCompleteAction(Request $request)
 {
     /** @var Admin $admin */
     $admin = $this->pool->getInstance($request->get('code'));
     $admin->setRequest($request);
     // check user permission
     if (false === $admin->isGranted('LIST')) {
         throw new AccessDeniedException();
     }
     // subject will be empty to avoid unnecessary database requests and keep auto-complete function fast
     $admin->setSubject($admin->getNewInstance());
     $fieldDescription = $this->retrieveFieldDescription($admin, $request->get('field'));
     $formAutocomplete = $admin->getForm()->get($fieldDescription->getName());
     if ($formAutocomplete->getConfig()->getAttribute('disabled')) {
         throw new AccessDeniedException('Autocomplete list can`t be retrieved because the form element is disabled or read_only.');
     }
     $class = $formAutocomplete->getConfig()->getOption('class');
     $property = $formAutocomplete->getConfig()->getAttribute('property');
     $minimumInputLength = $formAutocomplete->getConfig()->getAttribute('minimum_input_length');
     $itemsPerPage = $formAutocomplete->getConfig()->getAttribute('items_per_page');
     $reqParamPageNumber = $formAutocomplete->getConfig()->getAttribute('req_param_name_page_number');
     $toStringCallback = $formAutocomplete->getConfig()->getAttribute('to_string_callback');
     $searchText = $request->get('q');
     if (mb_strlen($searchText, 'UTF-8') < $minimumInputLength) {
         return new JsonResponse(array('status' => 'KO', 'message' => 'Too short search string.'), 403);
     }
     $page = $request->get($reqParamPageNumber);
     $offset = ($page - 1) * $itemsPerPage;
     /** @var ModelManager $modelManager */
     $modelManager = $formAutocomplete->getConfig()->getOption('model_manager');
     $dm = $modelManager->getDocumentManager();
     if ($class) {
         /** @var $qb \Doctrine\ODM\PHPCR\Query\Builder\QueryBuilder */
         $qb = $dm->getRepository($class)->createQueryBuilder('a');
         $qb->where()->fullTextSearch("a.{$property}", '*' . $searchText . '*');
         $qb->setFirstResult($offset);
         //fetch one more to determine if there are more pages
         $qb->setMaxResults($itemsPerPage + 1);
         $query = $qb->getQuery();
         $results = $query->execute();
     } else {
         /** @var $qb \PHPCR\Util\QOM\QueryBuilder */
         $qb = $dm->createPhpcrQueryBuilder();
         // TODO: node type should probably be configurable
         $qb->from($qb->getQOMFactory()->selector('a', 'nt:unstructured'));
         $qb->where($qb->getQOMFactory()->fullTextSearch('a', $property, '*' . $searchText . '*'));
         // handle attribute translation
         $qb->orWhere($qb->getQOMFactory()->fullTextSearch('a', $dm->getTranslationStrategy('attribute')->getTranslatedPropertyName($request->getLocale(), $property), '*' . $searchText . '*'));
         $qb->setFirstResult($offset);
         //fetch one more to determine if there are more pages
         $qb->setMaxResults($itemsPerPage + 1);
         $results = $dm->getDocumentsByPhpcrQuery($qb->getQuery());
     }
     //did we max out x+1
     $more = count($results) == $itemsPerPage + 1;
     $method = $request->get('_method_name');
     $items = array();
     foreach ($results as $path => $document) {
         // handle child translation
         if (strpos(PathHelper::getNodeName($path), Translation::LOCALE_NAMESPACE . ':') === 0) {
             $document = $dm->find(null, PathHelper::getParentPath($path));
         }
         if (!method_exists($document, $method)) {
             continue;
         }
         $label = $document->{$method}();
         if ($toStringCallback !== null) {
             if (!is_callable($toStringCallback)) {
                 throw new \RuntimeException('Option "to_string_callback" does not contain callable function.');
             }
             $label = call_user_func($toStringCallback, $document, $property);
         }
         $items[] = array('id' => $admin->id($document), 'label' => $label);
     }
     return new JsonResponse(array('status' => 'OK', 'more' => $more, 'items' => $items));
 }
Пример #16
0
 /**
  * Search for a next document.
  *
  * @param string|object $path       document instance or path from which to search
  * @param string|object $anchor     document instance or path which serves as an anchor from which to flatten the hierarchy
  * @param null|int      $depth      depth up to which to traverse down the tree when an anchor is provided
  * @param bool          $ignoreRole if to ignore the role
  * @param null|string   $class      the class to filter by
  *
  * @return null|object
  */
 private function searchDepthNext($path, $anchor, $depth = null, $ignoreRole = false, $class = null)
 {
     if (is_object($path)) {
         $path = $this->getDm()->getUnitOfWork()->getDocumentId($path);
     }
     if (null === $path || '/' === $path) {
         return;
     }
     $node = $this->getDm()->getPhpcrSession()->getNode($path);
     if (is_object($anchor)) {
         $anchor = $this->getDm()->getUnitOfWork()->getDocumentId($anchor);
     }
     if (0 !== strpos($path, $anchor)) {
         throw new \RuntimeException("The anchor path '{$anchor}' is not a parent of the current path '{$path}'.");
     }
     // take the first eligible child if there are any
     if (null === $depth || PathHelper::getPathDepth($path) - PathHelper::getPathDepth($anchor) < $depth) {
         $childNames = $node->getNodeNames()->getArrayCopy();
         $result = $this->checkChildren($childNames, $path, $ignoreRole, $class);
         if ($result) {
             return $result;
         }
     }
     $parent = $node->getParent();
     $parentPath = PathHelper::getParentPath($path);
     // take the first eligible sibling
     if (0 === strpos($parentPath, $anchor)) {
         $childNames = $parent->getNodeNames()->getArrayCopy();
         $key = array_search($node->getName(), $childNames);
         $childNames = array_slice($childNames, $key + 1);
         $result = $this->checkChildren($childNames, $parentPath, $ignoreRole, $class);
         if ($result) {
             return $result;
         }
     }
     // take the first eligible parent, traverse up
     while ('/' !== $parentPath) {
         $parent = $parent->getParent();
         if (false === strpos($parent->getPath(), $anchor)) {
             return;
         }
         $childNames = $parent->getNodeNames()->getArrayCopy();
         $key = array_search(PathHelper::getNodeName($parentPath), $childNames);
         $childNames = array_slice($childNames, $key + 1);
         $parentPath = $parent->getPath();
         $result = $this->checkChildren($childNames, $parentPath, $ignoreRole, $class);
         if ($result) {
             return $result;
         }
     }
     return;
 }
Пример #17
0
 /**
  * {@inheritdoc}
  */
 public function toString($object)
 {
     if (!is_object($object)) {
         return parent::toString($object);
     }
     if (method_exists($object, '__toString') && null !== $object->__toString()) {
         $string = (string) $object;
         return '' !== $string ? $string : $this->trans('link_add', array(), 'SonataAdminBundle');
     }
     $dm = $this->getModelManager()->getDocumentManager();
     if ($dm->contains($object)) {
         return PathHelper::getNodeName($dm->getUnitOfWork()->getDocumentId($object));
     }
     return parent::toString($object);
 }
Пример #18
0
 /**
  * @expectedException \PHPCR\RepositoryException
  * @expectedExceptionMessage must be an absolute path
  */
 public function testGetNodeNameMustBeAbsolute()
 {
     PathHelper::getNodeName('foobar');
 }
Пример #19
0
 /**
  * @param string $path           the path for which we need the references
  * @param string $name           the name of the referencing properties or null for all
  * @param bool   $weak_reference whether to get weak or strong references
  *
  * @return array list of paths to nodes that reference $path
  */
 protected function getNodeReferences($path, $name = null, $weak_reference = false)
 {
     $path = $this->encodeAndValidatePathForDavex($path);
     $identifier = $weak_reference ? 'weakreferences' : 'references';
     $request = $this->getRequest(Request::PROPFIND, $path);
     $request->setBody($this->buildPropfindRequest(array('dcr:' . $identifier)));
     $request->setDepth(0);
     $dom = $request->executeDom();
     $references = array();
     foreach ($dom->getElementsByTagNameNS(self::NS_DCR, $identifier) as $node) {
         foreach ($node->getElementsByTagNameNS(self::NS_DAV, 'href') as $ref) {
             $refpath = str_replace($this->workspaceUriRoot, '', urldecode($ref->textContent));
             $refpath = $this->removeTrailingSlash($refpath);
             if (null === $name || PathHelper::getNodeName($refpath) === $name) {
                 $references[] = $refpath;
             }
         }
     }
     return $references;
 }
Пример #20
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);
 }
Пример #21
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
     if ($dm->find($class, $path)) {
         // path already exists
         $ext = pathinfo($media->getName(), PATHINFO_EXTENSION);
         $media->setName($media->getName() . '_' . time() . '_' . rand() . ($ext ? '.' . $ext : ''));
     }
     if (!$media->getParent()) {
         $parent = $dm->find(null, PathHelper::getParentPath($path));
         $media->setParent($parent);
     }
 }
Пример #22
0
 /**
  * {@inheritDoc}
  */
 public function index($workspace, $path, Node $node)
 {
     $index = $this->getIndex($workspace);
     $document = new Document();
     $nodeName = PathHelper::getNodeName($path);
     $localNodeName = $nodeName;
     // PathHelper::getLocalNodeName($path);
     $parentPath = PathHelper::getParentPath($path);
     $document->addField(Field::Keyword(self::IDX_PATH, $path));
     $document->addField(Field::Keyword(self::IDX_NODENAME, $nodeName));
     $document->addField(Field::Keyword(self::IDX_NODELOCALNAME, $localNodeName));
     $document->addField(Field::Keyword(self::IDX_PARENTPATH, $parentPath));
     foreach ($node->getProperties() as $propertyName => $property) {
         $propertyValue = $property['value'];
         $propertyType = $property['type'];
         if ($propertyName === Storage::INTERNAL_UUID) {
             $document->addField(Field::Keyword(Storage::INTERNAL_UUID, $propertyValue));
             continue;
         }
         switch ($propertyType) {
             case PropertyType::TYPENAME_STRING:
             case PropertyType::TYPENAME_NAME:
             case PropertyType::TYPENAME_PATH:
             case PropertyType::TYPENAME_URI:
                 $value = (array) $propertyValue;
                 $value = join(self::MULTIVALUE_SEPARATOR, $value);
                 $document->addField(Field::Text($propertyName, $value));
                 break;
             case PropertyType::TYPENAME_DATE:
                 $values = (array) $propertyValue;
                 foreach ($values as $i => $value) {
                     if ($value instanceof \DateTime) {
                         $values[$i] = $value->format('c');
                     }
                 }
                 $value = join(self::MULTIVALUE_SEPARATOR, $values);
                 $document->addField(Field::Text($propertyName, $value));
                 break;
             case PropertyType::TYPENAME_DECIMAL:
             case PropertyType::TYPENAME_LONG:
             case PropertyType::TYPENAME_DOUBLE:
                 $values = (array) $propertyValue;
                 foreach ($values as &$value) {
                     $value = sprintf('%0' . strlen(PHP_INT_MAX) . 's', $value);
                 }
                 $value = join(self::MULTIVALUE_SEPARATOR, $values);
                 $document->addField(Field::Text($propertyName, $value));
                 break;
             case PropertyType::TYPENAME_BOOLEAN:
                 $values = (array) $propertyValue;
                 foreach ($values as &$value) {
                     if ($propertyValue === 'false') {
                         $value = self::VALUE_BOOLEAN_FALSE;
                     } else {
                         $value = 1;
                     }
                 }
                 $value = join(self::MULTIVALUE_SEPARATOR, $values);
                 $document->addField(Field::Text($propertyName, $value));
                 break;
         }
     }
     $index->addDocument($document);
 }
Пример #23
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);
    }
Пример #24
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);
 }
Пример #25
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;
 }
Пример #26
0
 /**
  * Returns an array representation of the document
  *
  * @param ModelManager $manager the manager to use with this document
  * @param object       $document
  *
  * @return array
  */
 protected function documentToArray(ModelManager $manager, $document)
 {
     $className = ClassUtils::getClass($document);
     $rel = in_array($className, array_keys($this->validClasses)) ? $className : 'undefined';
     $rel = $this->normalizeClassname($rel);
     $admin = $this->getAdmin($document);
     if (null !== $admin) {
         $label = $admin->toString($document);
         $id = $admin->getNormalizedIdentifier($document);
         $urlSafeId = $admin->getUrlsafeIdentifier($document);
     } else {
         $label = method_exists($document, '__toString') ? (string) $document : ClassUtils::getClass($document);
         $id = $manager->getNormalizedIdentifier($document);
         $urlSafeId = $manager->getUrlsafeIdentifier($document);
     }
     if (substr($label, 0, 1) === '/') {
         $label = PathHelper::getNodeName($label);
     }
     // TODO: ideally the tree should simply not make the node clickable
     $label .= $admin ? '' : ' ' . $this->translator->trans('not_editable', array(), 'SonataDoctrinePHPCRAdmin');
     $hasChildren = false;
     if (isset($this->validClasses[$className]['valid_children']) && count($this->validClasses[$className]['valid_children'])) {
         if ($this->preciseChildren) {
             // determine if a node has children the accurate way. we need to
             // loop over all documents, as a PHPCR node might have children but
             // only invalid ones. this is quite costly.
             $hasChildren = (bool) count($this->getDocumentChildren($manager, $document));
         } else {
             // just check if there is any child node
             $hasChildren = $manager->getDocumentManager()->getNodeForDocument($document)->hasNodes();
         }
     }
     return array('data' => $label, 'attr' => array('id' => $id, 'url_safe_id' => $urlSafeId, 'rel' => $rel), 'state' => $hasChildren ? 'closed' : null);
 }
Пример #27
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);
 }
Пример #28
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;
 }
Пример #29
0
 /**
  * @see StaticPathHelper::getNodeName
  */
 public function getNodeName($path)
 {
     return StaticPathHelper::getNodeName($path);
 }
Пример #30
0
 /** {@inheritDoc} */
 public function contains($element)
 {
     if (!$this->isInitialized()) {
         $uow = $this->dm->getUnitOfWork();
         // Shortcut for new documents
         $documentState = $uow->getDocumentState($element);
         if ($documentState === UnitOfWork::STATE_NEW) {
             return false;
         }
         // Document is scheduled for inclusion
         if ($documentState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
             return false;
         }
         $documentId = $uow->getDocumentId($element);
         if (PathHelper::getParentPath($documentId) !== PathHelper::getParentPath($uow->getDocumentId($this->document))) {
             return false;
         }
         $nodeName = PathHelper::getNodeName($documentId);
         return in_array($nodeName, $this->getOriginalNodeNames());
     }
     return parent::contains($element);
 }