/** * Change the property on the given node. * * @param NodeData $node * @return NodeData */ public function execute(NodeData $node) { $node = $this->nodeFactory->createFromNodeData($node, $this->nodeFactory->createContextMatchingNodeData($node)); $column0 = $node->getPrimaryChildNode(); $column0->setName('contents'); return $node; }
/** * Returns the contact form list * * @return void */ public function indexAction() { $forms = $this->nodeDataRepository->findByNodeType('Lelesys.Plugin.ContactForm:ContactForm'); $formNodes = array(); $context = $this->contextFactory->create(array('workspaceName' => 'live')); foreach ($forms as $form) { $node = $this->nodeFactory->createFromNodeData($form, $context); $formNodes[] = $node; } $this->view->assign('forms', $formNodes); }
/** * Change the property on the given node. * * @param NodeData $node * @return NodeData */ public function execute(NodeData $node) { $node = $this->nodeFactory->createFromNodeData($node, $this->contextFactory->create(array('workspaceName' => $node->getWorkspace()->getName(), 'invisibleContentShown' => true, 'inaccessibleContentShown' => true))); if (!$node) { return; } $column0 = $node->getPrimaryChildNode(); if (!$column0) { return; } foreach ($column0->getChildNodes() as $childNode) { $node = $childNode->copyAfter($node, NodePaths::generateRandomNodeName()); } return $node; }
/** * @test */ public function createContextMatchingNodeDataCreatesMatchingContext() { $dimensionValues = array('language' => array('is')); $workspaceName = 'some-workspace'; $mockContext = $this->getMock('TYPO3\\TYPO3CR\\Domain\\Service\\Context', null, array(), '', false); $mockWorkspace = $this->getMock('TYPO3\\TYPO3CR\\Domain\\Model\\Workspace', array(), array(), 'MockWorkspace', false); $mockWorkspace->expects(self::any())->method('getName')->will(self::returnValue($workspaceName)); $mockContextFactory = $this->getMock('TYPO3\\TYPO3CR\\Domain\\Service\\ContextFactoryInterface', array(), array(), '', false); $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->getMock('TYPO3\\TYPO3CR\\Domain\\Model\\NodeData', array(), array(), '', false); $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); }
/** * Search all properties for given $term * * TODO: Implement a better search when Flow offer the possibility * * @param string $term * @param array $searchNodeTypes * @param Context $context * @param NodeInterface $startingPoint * @return array <\TYPO3\TYPO3CR\Domain\Model\NodeInterface> */ public function findByProperties($term, array $searchNodeTypes, Context $context, NodeInterface $startingPoint = null) { if (strlen($term) === 0) { 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; }
/** * 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 \TYPO3\TYPO3CR\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); }
/** * 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; }
/** * Returns an array of usage reference objects. * * @param AssetInterface $asset * @return array<\TYPO3\Neos\Domain\Model\Dto\AssetUsageInNodeProperties> * @throws \TYPO3\TYPO3CR\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 \TYPO3\TYPO3CR\Domain\Model\NodeInterface $documentNode */ $documentNode = $flowQuery->closest('[instanceof TYPO3.Neos:Document]')->get(0); $relatedNodes[] = new AssetUsageInNodeProperties($asset, $site, $documentNode, $node, $accessible); } $this->firstlevelCache[$assetIdentifier] = $relatedNodes; return $this->firstlevelCache[$assetIdentifier]; }
/** * 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. "TYPO3.Neos:Page", "!TYPO3.Neos:Page,TYPO3.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; }
/** * Create a node for the given NodeData, given that it is a variant of the current node * * @param NodeData $nodeData * @return Node */ protected function createNodeForVariant($nodeData) { $contextProperties = $this->context->getProperties(); $contextProperties['dimensions'] = $nodeData->getDimensionValues(); unset($contextProperties['targetDimensions']); $adjustedContext = $this->contextFactory->create($contextProperties); return $this->nodeFactory->createFromNodeData($nodeData, $adjustedContext); }
/** * Find all nodes of a specific node type * * @param string $nodeType * @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($nodeType, ContentContext $context) { $nodes = array(); $siteNode = $context->getCurrentSiteNode(); foreach ($this->nodeDataRepository->findByParentAndNodeTypeRecursively($siteNode->getPath(), $nodeType, $context->getWorkspace()) as $nodeData) { $nodes[] = $this->nodeFactory->createFromNodeData($nodeData, $context); } return $nodes; }
/** * Given a context a new node is returned that is like this node, but * lives in the new context. * * @param \TYPO3\TYPO3CR\Domain\Service\Context $context * @return NodeInterface */ public function createVariantForContext($context) { $nodeData = clone $this->nodeData; $nodeData->adjustToContext($context); $this->nodeDataRepository->add($nodeData); $node = $this->nodeFactory->createFromNodeData($nodeData, $context); $this->context->getFirstLevelNodeCache()->flush(); $this->emitNodeAdded($node); return $node; }
/** * @param Context $context * @return NodeInterface * @throws NodeTypeNotFoundException * @throws NodeConfigurationException */ public function findOrCreateMetaDataRootNode(Context $context) { if ($this->metaDataRootNode instanceof NodeInterface) { return $this->metaDataRootNode; } $metaDataRootNodeData = $this->metaDataRepository->findOneByPath('/' . MetaDataRepository::METADATA_ROOT_NODE_NAME, $context->getWorkspace()); if ($metaDataRootNodeData !== null) { $metaDataRootNode = $this->nodeFactory->createFromNodeData($metaDataRootNodeData, $context); return $metaDataRootNode; } $nodeTemplate = new NodeTemplate(); $nodeTemplate->setNodeType($this->nodeTypeManager->getNodeType('unstructured')); $nodeTemplate->setName(MetaDataRepository::METADATA_ROOT_NODE_NAME); $context = $this->contextFactory->create(['workspaceName' => 'live']); $rootNode = $context->getRootNode(); $this->metaDataRootNode = $rootNode->createNodeFromTemplate($nodeTemplate); $this->persistenceManager->persistAll(); return $this->metaDataRootNode; }
/** * Returns a list of nodes contained in the given workspace which are not yet published * * @param Workspace $workspace * @return array<\TYPO3\TYPO3CR\Domain\Model\NodeInterface> * @api */ public function getUnpublishedNodes(Workspace $workspace) { if ($workspace->getBaseWorkspace() === NULL) { return array(); } $nodeData = $this->nodeDataRepository->findByWorkspace($workspace); $unpublishedNodes = array(); foreach ($nodeData as $singleNodeData) { /** @var NodeData $singleNodeData */ // Skip the root entry from the workspace as it can't be published if ($singleNodeData->getPath() === '/') { continue; } $node = $this->nodeFactory->createFromNodeData($singleNodeData, $this->createContext($workspace, $singleNodeData->getDimensionValues())); if ($node !== NULL) { $unpublishedNodes[] = $node; } } $unpublishedNodes = $this->sortNodesForPublishing($unpublishedNodes); return $unpublishedNodes; }
/** * 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/mysite.com/ * @param mixed $endPoint Either an absolute path or an actual node specifying the end point, for example /sites/mysite.com/homepage/subpage * @return array<\TYPO3\TYPO3CR\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 \TYPO3\TYPO3CR\Domain\Model\NodeInterface ? $startingPoint->getPath() : $startingPoint; $endPointPath = $endPoint instanceof \TYPO3\TYPO3CR\Domain\Model\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; } } return $nodes; }
/** * 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<\TYPO3\TYPO3CR\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 NodeType $nodeType * @param string $workspaceName * @param boolean $dryRun * @return void */ protected function reorderChildNodesByNodeType(NodeType $nodeType, $workspaceName, $dryRun) { $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; } } } }
/** * {@inheritdoc} * * @param FlowQuery $flowQuery the FlowQuery object * @param array $arguments the arguments for this operation * @return mixed|null if the operation is final, the return value */ public function evaluate(FlowQuery $flowQuery, array $arguments) { $imagePropertyName = $arguments[0]; if ($this->contextNode->hasProperty($imagePropertyName)) { $image = $this->contextNode->getProperty($imagePropertyName); if ($image instanceof ImageVariant) { $image = $image->getOriginalAsset(); } if ($image instanceof Image) { $identifier = $image->getIdentifier(); $nodeData = $this->metaDataRepository->findOneByAssetIdentifier($identifier, $this->contextNode->getContext()->getWorkspace()); if ($nodeData instanceof NodeData) { return $this->nodeFactory->createFromNodeData($nodeData, $this->contextNode->getContext()); } } } return null; }
/** * 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('TYPO3.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('TYPO3\\TYPO3CR\\Domain\\Service\\Context')->disableOriginalConstructor()->getMock(); $expectedContextProperties = array('workspaceName' => $this->mockWorkspace->getName(), 'inaccessibleContentShown' => true, 'invisibleContentShown' => true, 'removedContentShown' => true, 'currentSite' => $this->mockSite, 'dimensions' => array()); $this->mockContextFactory->expects($this->any())->method('create')->with($expectedContextProperties)->will($this->returnValue($mockContext)); $mockNodeData1 = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Model\\NodeData')->disableOriginalConstructor()->getMock(); $mockNodeData2 = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Model\\NodeData')->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('TYPO3\\TYPO3CR\\Domain\\Model\\NodeInterface')->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)); }
/** * Get Related Nodes for an asset * * @param Asset $asset * @return void */ public function relatedNodesAction(Asset $asset) { $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 Node $documentNode */ $documentNode = $flowQuery->closest('[instanceof TYPO3.Neos:Document]')->get(0); $documentNodeIdentifier = $documentNode instanceof NodeInterface ? $documentNode->getIdentifier() : null; $relatedNodes[$site->getNodeName()]['site'] = $site; $relatedNodes[$site->getNodeName()]['documentNodes'][$documentNodeIdentifier]['node'] = $documentNode; $relatedNodes[$site->getNodeName()]['documentNodes'][$documentNodeIdentifier]['nodes'][] = ['node' => $node, 'nodeData' => $relatedNodeData, 'contextDocumentNode' => $documentNode, 'accessible' => $accessible]; } $this->view->assignMultiple(['asset' => $asset, 'relatedNodes' => $relatedNodes, 'contentDimensions' => $this->contentDimensionPresetSource->getAllPresets(), 'userWorkspace' => $userWorkspace]); }