/**
  * Method which does the actual work of discarding, includes a protection against endless recursions and
  * multiple discarding of the same node.
  *
  * @param NodeInterface $node The node to discard
  * @param array &$alreadyDiscardedNodeIdentifiers List of node identifiers which already have been discarded during one discardNode() run
  * @return void
  * @throws \Neos\ContentRepository\Exception\WorkspaceException
  */
 protected function doDiscardNode(NodeInterface $node, array &$alreadyDiscardedNodeIdentifiers = [])
 {
     if ($node->getWorkspace()->getBaseWorkspace() === null) {
         throw new WorkspaceException('Nodes in a in a workspace without a base workspace cannot be discarded.', 1395841899);
     }
     if ($node->getPath() === '/') {
         return;
     }
     if (array_search($node->getIdentifier(), $alreadyDiscardedNodeIdentifiers) !== false) {
         return;
     }
     $alreadyDiscardedNodeIdentifiers[] = $node->getIdentifier();
     $possibleShadowNodeData = $this->nodeDataRepository->findOneByMovedTo($node->getNodeData());
     if ($possibleShadowNodeData instanceof NodeData) {
         if ($possibleShadowNodeData->getMovedTo() !== null) {
             $parentBasePath = $node->getPath();
             $affectedChildNodeDataInSameWorkspace = $this->nodeDataRepository->findByParentAndNodeType($parentBasePath, null, $node->getWorkspace(), null, false, true);
             foreach ($affectedChildNodeDataInSameWorkspace as $affectedChildNodeData) {
                 /** @var NodeData $affectedChildNodeData */
                 $affectedChildNode = $this->nodeFactory->createFromNodeData($affectedChildNodeData, $node->getContext());
                 $this->doDiscardNode($affectedChildNode, $alreadyDiscardedNodeIdentifiers);
             }
         }
         $this->nodeDataRepository->remove($possibleShadowNodeData);
     }
     $this->nodeDataRepository->remove($node);
     $this->emitNodeDiscarded($node);
 }
 /**
  * Returns an array of usage reference objects.
  *
  * @param AssetInterface $asset
  * @return array<\Neos\Neos\Domain\Model\Dto\AssetUsageInNodeProperties>
  * @throws \Neos\ContentRepository\Exception\NodeConfigurationException
  */
 public function getUsageReferences(AssetInterface $asset)
 {
     $assetIdentifier = $this->persistenceManager->getIdentifierByObject($asset);
     if (isset($this->firstlevelCache[$assetIdentifier])) {
         return $this->firstlevelCache[$assetIdentifier];
     }
     $userWorkspace = $this->userService->getPersonalWorkspace();
     $relatedNodes = [];
     foreach ($this->getRelatedNodes($asset) as $relatedNodeData) {
         $accessible = $this->domainUserService->currentUserCanReadWorkspace($relatedNodeData->getWorkspace());
         if ($accessible) {
             $context = $this->createContextMatchingNodeData($relatedNodeData);
         } else {
             $context = $this->createContentContext($userWorkspace->getName());
         }
         $site = $context->getCurrentSite();
         $node = $this->nodeFactory->createFromNodeData($relatedNodeData, $context);
         $flowQuery = new FlowQuery([$node]);
         /** @var \Neos\ContentRepository\Domain\Model\NodeInterface $documentNode */
         $documentNode = $flowQuery->closest('[instanceof Neos.Neos:Document]')->get(0);
         $relatedNodes[] = new AssetUsageInNodeProperties($asset, $site, $documentNode, $node, $accessible);
     }
     $this->firstlevelCache[$assetIdentifier] = $relatedNodes;
     return $this->firstlevelCache[$assetIdentifier];
 }
 /**
  * Search all properties for given $term
  *
  * TODO: Implement a better search when Flow offer the possibility
  *
  * @param string|array $term search term
  * @param array $searchNodeTypes
  * @param Context $context
  * @param NodeInterface $startingPoint
  * @return array <\Neos\ContentRepository\Domain\Model\NodeInterface>
  */
 public function findByProperties($term, array $searchNodeTypes, Context $context, NodeInterface $startingPoint = null)
 {
     if (empty($term)) {
         throw new \InvalidArgumentException('"term" cannot be empty: provide a term to search for.', 1421329285);
     }
     $searchResult = array();
     $nodeTypeFilter = implode(',', $searchNodeTypes);
     $nodeDataRecords = $this->nodeDataRepository->findByProperties($term, $nodeTypeFilter, $context->getWorkspace(), $context->getDimensions(), $startingPoint ? $startingPoint->getPath() : null);
     foreach ($nodeDataRecords as $nodeData) {
         $node = $this->nodeFactory->createFromNodeData($nodeData, $context);
         if ($node !== null) {
             $searchResult[$node->getPath()] = $node;
         }
     }
     return $searchResult;
 }
Пример #4
0
 /**
  * Given a context a new node is returned that is like this node, but
  * lives in the new context.
  *
  * @param Context $context
  * @return NodeInterface
  */
 public function createVariantForContext($context)
 {
     $autoCreatedChildNodes = [];
     $nodeType = $this->getNodeType();
     foreach ($nodeType->getAutoCreatedChildNodes() as $childNodeName => $childNodeConfiguration) {
         $childNode = $this->getNode($childNodeName);
         if ($childNode !== null) {
             $autoCreatedChildNodes[$childNodeName] = $childNode;
         }
     }
     $nodeData = new NodeData($this->nodeData->getPath(), $context->getWorkspace(), $this->nodeData->getIdentifier(), $context->getTargetDimensionValues());
     $nodeData->similarize($this->nodeData);
     if ($this->context !== $context) {
         $node = $this->nodeFactory->createFromNodeData($nodeData, $context);
     } else {
         $this->setNodeData($nodeData);
         $node = $this;
     }
     $this->context->getFirstLevelNodeCache()->flush();
     $this->emitNodeAdded($node);
     /**
      * @var $autoCreatedChildNode NodeInterface
      */
     foreach ($autoCreatedChildNodes as $autoCreatedChildNode) {
         $autoCreatedChildNode->createVariantForContext($context);
     }
     return $node;
 }
 /**
  * Finds a single node by its parent and (optionally) by its node type
  *
  * @param string $parentPath Absolute path of the parent node
  * @param string $nodeTypeFilter Filter the node type of the nodes, allows complex expressions (e.g. "Neos.Neos:Page", "!Neos.Neos:Page,Neos.Neos:Text" or NULL)
  * @param Context $context The containing context
  * @return NodeData The node found or NULL
  */
 public function findFirstByParentAndNodeTypeInContext($parentPath, $nodeTypeFilter, Context $context)
 {
     $firstNode = $this->findFirstByParentAndNodeType($parentPath, $nodeTypeFilter, $context->getWorkspace(), $context->getDimensions(), $context->isRemovedContentShown() ? null : false);
     if ($firstNode !== null) {
         $firstNode = $this->nodeFactory->createFromNodeData($firstNode, $context);
     }
     return $firstNode;
 }
 /**
  * Find all nodes of a specific node type
  *
  * @param array $nodeTypes
  * @param ContentContext $context current content context, see class doc comment for details
  * @return array<NodeInterface> all nodes of type $nodeType in the current $context
  */
 protected function getNodes(array $nodeTypes, ContentContext $context)
 {
     $nodes = [];
     $siteNode = $context->getCurrentSiteNode();
     foreach ($this->nodeDataRepository->findByParentAndNodeTypeRecursively($siteNode->getPath(), implode(',', $nodeTypes), $context->getWorkspace()) as $nodeData) {
         $nodes[] = $this->nodeFactory->createFromNodeData($nodeData, $context);
     }
     return $nodes;
 }
Пример #7
0
 /**
  * Finds all nodes lying on the path specified by (and including) the given
  * starting point and end point.
  *
  * @param mixed $startingPoint Either an absolute path or an actual node specifying the starting point, for example /sites/mysitecom
  * @param mixed $endPoint Either an absolute path or an actual node specifying the end point, for example /sites/mysitecom/homepage/subpage
  * @return array<\Neos\ContentRepository\Domain\Model\NodeInterface> The nodes found between and including the given paths or an empty array of none were found
  * @api
  */
 public function getNodesOnPath($startingPoint, $endPoint)
 {
     $startingPointPath = $startingPoint instanceof NodeInterface ? $startingPoint->getPath() : $startingPoint;
     $endPointPath = $endPoint instanceof NodeInterface ? $endPoint->getPath() : $endPoint;
     $nodeDataElements = $this->nodeDataRepository->findOnPath($startingPointPath, $endPointPath, $this->getWorkspace(), $this->getDimensions(), $this->isRemovedContentShown());
     $nodes = array();
     foreach ($nodeDataElements as $nodeData) {
         $node = $this->nodeFactory->createFromNodeData($nodeData, $this);
         if ($node !== null) {
             $nodes[] = $node;
             $this->firstLevelNodeCache->setByPath($node->getPath(), $node);
         }
     }
     return $nodes;
 }
 /**
  * @test
  */
 public function createContextMatchingNodeDataCreatesMatchingContext()
 {
     $dimensionValues = array('language' => array('is'));
     $workspaceName = 'some-workspace';
     $mockContext = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock();
     $mockWorkspace = $this->getMockBuilder(Workspace::class)->setMockClassName('MockWorkspace')->disableOriginalConstructor()->getMock();
     $mockWorkspace->expects(self::any())->method('getName')->will(self::returnValue($workspaceName));
     $mockContextFactory = $this->createMock(ContextFactoryInterface::class);
     $mockContextFactory->expects(self::once())->method('create')->with(array('workspaceName' => $workspaceName, 'invisibleContentShown' => true, 'inaccessibleContentShown' => true, 'removedContentShown' => true, 'dimensions' => $dimensionValues))->willReturn($mockContext);
     $this->inject($this->nodeFactory, 'contextFactory', $mockContextFactory);
     $mockNodeData = $this->getMockBuilder(NodeData::class)->disableOriginalConstructor()->getMock();
     $mockNodeData->expects(self::any())->method('getWorkspace')->will($this->returnValue($mockWorkspace));
     $mockNodeData->expects(self::any())->method('getDimensionValues')->willReturn($dimensionValues);
     $context = $this->nodeFactory->createContextMatchingNodeData($mockNodeData);
     self::assertEquals($mockContext, $context);
 }
 /**
  * Reorder child nodes for the given node type
  *
  * @param string $workspaceName
  * @param boolean $dryRun
  * @param NodeType $nodeType
  * @return void
  */
 protected function reorderChildNodesByNodeType($workspaceName, $dryRun, NodeType $nodeType)
 {
     $nodeTypes = $this->nodeTypeManager->getSubNodeTypes($nodeType->getName(), false);
     $nodeTypes[$nodeType->getName()] = $nodeType;
     if ($this->nodeTypeManager->hasNodeType((string) $nodeType)) {
         $nodeType = $this->nodeTypeManager->getNodeType((string) $nodeType);
         $nodeTypeNames[$nodeType->getName()] = $nodeType;
     } else {
         $this->output->outputLine('Node type "%s" does not exist', array((string) $nodeType));
         exit(1);
     }
     /** @var $nodeType NodeType */
     foreach ($nodeTypes as $nodeTypeName => $nodeType) {
         $childNodes = $nodeType->getAutoCreatedChildNodes();
         if ($childNodes === array()) {
             continue;
         }
         foreach ($this->getNodeDataByNodeTypeAndWorkspace($nodeTypeName, $workspaceName) as $nodeData) {
             /** @var NodeInterface $childNodeBefore */
             $childNodeBefore = null;
             $context = $this->nodeFactory->createContextMatchingNodeData($nodeData);
             $node = $this->nodeFactory->createFromNodeData($nodeData, $context);
             if (!$node instanceof NodeInterface) {
                 continue;
             }
             foreach ($childNodes as $childNodeName => $childNodeType) {
                 $childNode = $node->getNode($childNodeName);
                 if ($childNode) {
                     if ($childNodeBefore) {
                         if ($dryRun === false) {
                             if ($childNodeBefore->getIndex() >= $childNode->getIndex()) {
                                 $childNode->moveAfter($childNodeBefore);
                                 $this->output->outputLine('Moved node named "%s" after node named "%s" in "%s"', array($childNodeName, $childNodeBefore->getName(), $node->getPath()));
                             }
                         } else {
                             $this->output->outputLine('Should move node named "%s" after node named "%s" in "%s"', array($childNodeName, $childNodeBefore->getName(), $node->getPath()));
                         }
                     }
                 } else {
                     $this->output->outputLine('Missing child node named "%s" in "%s".', array($childNodeName, $node->getPath()));
                 }
                 $childNodeBefore = $childNode;
             }
         }
     }
 }
Пример #10
0
 /**
  * Return child nodes of specified node for usage in a TreeLoader based on filter
  *
  * @param Node $node The node to find child nodes for
  * @param string $term
  * @param string $nodeType
  * @return void
  */
 public function filterChildNodesForTreeAction(Node $node, $term, $nodeType)
 {
     $nodeTypes = strlen($nodeType) > 0 ? array($nodeType) : array_keys($this->nodeTypeManager->getSubNodeTypes('Neos.Neos:Document', false));
     $context = $node->getContext();
     if ($term !== '') {
         $nodes = $this->nodeSearchService->findByProperties($term, $nodeTypes, $context, $node);
     } else {
         $nodes = array();
         $nodeDataRecords = $this->nodeDataRepository->findByParentAndNodeTypeRecursively($node->getPath(), implode(',', $nodeTypes), $context->getWorkspace(), $context->getDimensions());
         foreach ($nodeDataRecords as $nodeData) {
             $matchedNode = $this->nodeFactory->createFromNodeData($nodeData, $context);
             if ($matchedNode !== null) {
                 $nodes[$matchedNode->getPath()] = $matchedNode;
             }
         }
     }
     $this->view->assignFilteredChildNodes($node, $nodes);
 }
 /**
  * @test
  */
 public function getUnpublishedNodesDoesNotReturnInvalidNodes()
 {
     $mockContext = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock();
     $expectedContextProperties = array('workspaceName' => $this->mockWorkspace->getName(), 'inaccessibleContentShown' => true, 'invisibleContentShown' => true, 'removedContentShown' => true, 'dimensions' => array());
     $this->mockContextFactory->expects($this->any())->method('create')->with($expectedContextProperties)->will($this->returnValue($mockContext));
     $mockNodeData1 = $this->getMockBuilder(NodeData::class)->disableOriginalConstructor()->getMock();
     $mockNodeData2 = $this->getMockBuilder(NodeData::class)->disableOriginalConstructor()->getMock();
     $mockNodeData1->expects($this->any())->method('getDimensionValues')->will($this->returnValue(array()));
     $mockNodeData2->expects($this->any())->method('getDimensionValues')->will($this->returnValue(array()));
     $mockNode1 = $this->getMockBuilder(NodeInterface::class)->getMock();
     $mockNode1->expects($this->any())->method('getNodeData')->will($this->returnValue($mockNodeData1));
     $mockNode1->expects($this->any())->method('getPath')->will($this->returnValue('/node1'));
     $this->mockNodeFactory->expects($this->at(0))->method('createFromNodeData')->with($mockNodeData1, $mockContext)->will($this->returnValue($mockNode1));
     $this->mockNodeFactory->expects($this->at(1))->method('createFromNodeData')->with($mockNodeData2, $mockContext)->will($this->returnValue(null));
     $this->mockNodeDataRepository->expects($this->atLeastOnce())->method('findByWorkspace')->with($this->mockWorkspace)->will($this->returnValue(array($mockNodeData1, $mockNodeData2)));
     $actualResult = $this->publishingService->getUnpublishedNodes($this->mockWorkspace);
     $this->assertSame($actualResult, array($mockNode1));
 }