/** * Tests on a tree: * * a * a1 * a2 * b (TestingNodeType) * b1 (TestingNodeType) * b1a * b2 * b3 (TestingNodeTypeWithSubnodes) * b3a (TestingNodeType) * b3b * * @test * @dataProvider closestOperationDataProvider */ public function closestOperationTests($currentNodePath, $nodeTypeFilter, $expectedNodePath) { $nodeTypeManager = $this->objectManager->get(NodeTypeManager::class); $testNodeType1 = $nodeTypeManager->getNodeType('Neos.ContentRepository.Testing:NodeType'); $testNodeType2 = $nodeTypeManager->getNodeType('Neos.ContentRepository.Testing:NodeTypeWithSubnodes'); $rootNode = $this->node->getNode('/'); $nodeA = $rootNode->createNode('a'); $nodeA->createNode('a1'); $nodeA->createNode('a2'); $nodeB = $rootNode->createNode('b', $testNodeType1); $nodeB1 = $nodeB->createNode('b1', $testNodeType1); $nodeB1->createNode('b1a'); $nodeB->createNode('b2'); $nodeB3 = $nodeB->createNode('b3', $testNodeType2); $nodeB3->createNode('b3a', $testNodeType1); $nodeB3->createNode('b3b'); $currentNode = $rootNode->getNode($currentNodePath); $q = new FlowQuery(array($currentNode)); $actualNode = $q->closest($nodeTypeFilter)->get(0); if ($expectedNodePath === null) { if ($actualNode !== null) { $this->fail('Expected resulting node to be NULL'); } $this->assertNull($actualNode); } else { $this->assertSame($expectedNodePath, $actualNode->getPath()); } }
/** * @param array $nodes */ public function assignNodes(array $nodes) { $data = array(); foreach ($nodes as $node) { if ($node->getPath() !== '/') { $q = new FlowQuery(array($node)); $closestDocumentNode = $q->closest('[instanceof Neos.Neos:Document]')->get(0); if ($closestDocumentNode !== null) { $data[] = array('nodeContextPath' => $node->getContextPath(), 'documentNodeContextPath' => $closestDocumentNode->getContextPath()); } else { $this->systemLogger->log('You have a node that is no longer connected to a parent. Path: ' . $node->getPath() . ' (Identifier: ' . $node->getIdentifier() . ')'); } } } $this->assign('value', array('data' => $data, 'success' => true)); }
/** * @Flow\Around("method(Neos\Flow\Mvc\Routing\UriBuilder->uriFor())") * @param \Neos\Flow\Aop\JoinPointInterface $joinPoint The current join point * @return string The result of the target method if it has not been intercepted */ public function rewritePluginViewUris(JoinPointInterface $joinPoint) { /** @var ActionRequest $request */ $request = $joinPoint->getProxy()->getRequest(); $arguments = $joinPoint->getMethodArguments(); $currentNode = $request->getInternalArgument('__node'); if (!$request->getMainRequest()->hasArgument('node') || !$currentNode instanceof Node) { return $joinPoint->getAdviceChain()->proceed($joinPoint); } $currentNode = $request->getInternalArgument('__node'); $controllerObjectName = $this->getControllerObjectName($request, $arguments); $actionName = $arguments['actionName'] !== null ? $arguments['actionName'] : $request->getControllerActionName(); $targetNode = $this->pluginService->getPluginNodeByAction($currentNode, $controllerObjectName, $actionName); // TODO override namespace $q = new FlowQuery(array($targetNode)); $pageNode = $q->closest('[instanceof Neos.Neos:Document]')->get(0); $result = $this->generateUriForNode($request, $joinPoint, $pageNode); return $result; }
/** * Takes care of creating a redirect to properly render the collection the given node is in. * * @param NodeInterface $node * @param string $typoScriptPath * @return string */ protected function redirectToRenderNode(NodeInterface $node, $typoScriptPath) { $q = new FlowQuery(array($node)); $closestContentCollection = $q->closest('[instanceof Neos.Neos:ContentCollection]')->get(0); $closestDocumentNode = $q->closest('[instanceof Neos.Neos:Document]')->get(0); $this->redirect('show', 'Frontend\\Node', 'Neos.Neos', ['node' => $closestDocumentNode, '__nodeContextPath' => $closestContentCollection->getContextPath(), '__affectedNodeContextPath' => $node->getContextPath(), '__typoScriptPath' => $typoScriptPath], 0, 303, 'html'); }
/** * 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]; }
/** * Fetch all master plugins that are available in the current * workspace. * * @param string $workspaceName Name of the workspace to use for querying the node * @param array $dimensions Optional list of dimensions and their values which should be used for querying the specified node * @return string JSON encoded array of node path => label */ public function masterPluginsAction($workspaceName = 'live', array $dimensions = array()) { $this->response->setHeader('Content-Type', 'application/json'); $contentContext = $this->createContentContext($workspaceName, $dimensions); $pluginNodes = $this->pluginService->getPluginNodesWithViewDefinitions($contentContext); $masterPlugins = array(); if (is_array($pluginNodes)) { /** @var $pluginNode NodeInterface */ foreach ($pluginNodes as $pluginNode) { if ($pluginNode->isRemoved()) { continue; } $q = new FlowQuery(array($pluginNode)); $page = $q->closest('[instanceof Neos.Neos:Document]')->get(0); if ($page === null) { continue; } $translationHelper = new TranslationHelper(); $masterPlugins[$pluginNode->getIdentifier()] = $translationHelper->translate('masterPlugins.nodeTypeOnPageLabel', null, ['nodeTypeName' => $translationHelper->translate($pluginNode->getNodeType()->getLabel()), 'pageLabel' => $page->getLabel()], 'Main', 'Neos.Neos'); } } return json_encode((object) $masterPlugins); }
/** * @param NodeInterface $node * @return NodeInterface */ public function render(NodeInterface $node) { $flowQuery = new FlowQuery(array($node)); return $flowQuery->closest('[instanceof Neos.Neos:Document]')->get(0); }
/** * Builds an array of changes for sites in the given workspace * * @param Workspace $selectedWorkspace * @return array */ protected function computeSiteChanges(Workspace $selectedWorkspace) { $siteChanges = []; foreach ($this->publishingService->getUnpublishedNodes($selectedWorkspace) as $node) { /** @var NodeInterface $node */ if (!$node->getNodeType()->isOfType('Neos.Neos:ContentCollection')) { $pathParts = explode('/', $node->getPath()); if (count($pathParts) > 2) { $siteNodeName = $pathParts[2]; $q = new FlowQuery([$node]); $document = $q->closest('[instanceof Neos.Neos:Document]')->get(0); // $document will be null if we have a broken root line for this node. This actually should never happen, but currently can in some scenarios. if ($document !== null) { $documentPath = implode('/', array_slice(explode('/', $document->getPath()), 3)); $relativePath = str_replace(sprintf(SiteService::SITES_ROOT_PATH . '/%s/%s', $siteNodeName, $documentPath), '', $node->getPath()); if (!isset($siteChanges[$siteNodeName]['siteNode'])) { $siteChanges[$siteNodeName]['siteNode'] = $this->siteRepository->findOneByNodeName($siteNodeName); } $siteChanges[$siteNodeName]['documents'][$documentPath]['documentNode'] = $document; $change = ['node' => $node, 'contentChanges' => $this->renderContentChanges($node)]; if ($node->getNodeType()->isOfType('Neos.Neos:Node')) { $change['configuration'] = $node->getNodeType()->getFullConfiguration(); } $siteChanges[$siteNodeName]['documents'][$documentPath]['changes'][$relativePath] = $change; } } } } $liveContext = $this->contextFactory->create(['workspaceName' => 'live']); ksort($siteChanges); foreach ($siteChanges as $siteKey => $site) { foreach ($site['documents'] as $documentKey => $document) { $liveDocumentNode = $liveContext->getNodeByIdentifier($document['documentNode']->getIdentifier()); $siteChanges[$siteKey]['documents'][$documentKey]['isMoved'] = $liveDocumentNode && $document['documentNode']->getPath() !== $liveDocumentNode->getPath(); $siteChanges[$siteKey]['documents'][$documentKey]['isNew'] = $liveDocumentNode === null; foreach ($document['changes'] as $changeKey => $change) { $liveNode = $liveContext->getNodeByIdentifier($change['node']->getIdentifier()); $siteChanges[$siteKey]['documents'][$documentKey]['changes'][$changeKey]['isNew'] = is_null($liveNode); $siteChanges[$siteKey]['documents'][$documentKey]['changes'][$changeKey]['isMoved'] = $liveNode && $change['node']->getPath() !== $liveNode->getPath(); } } ksort($siteChanges[$siteKey]['documents']); } return $siteChanges; }