/** * Add the current node and all parent identifiers to be used for cache entry tagging * * @Flow\Before("method(Neos\Flow\Mvc\Routing\RouterCachingService->extractUuids())") * @param JoinPointInterface $joinPoint The current join point * @return void */ public function addCurrentNodeIdentifier(JoinPointInterface $joinPoint) { $values = $joinPoint->getMethodArgument('values'); if (!isset($values['node']) || strpos($values['node'], '@') === false) { return; } // Build context explicitly without authorization checks because the security context isn't available yet // anyway and any Entity Privilege targeted on Workspace would fail at this point: $this->securityContext->withoutAuthorizationChecks(function () use($joinPoint, $values) { $contextPathPieces = NodePaths::explodeContextPath($values['node']); $context = $this->contextFactory->create(['workspaceName' => $contextPathPieces['workspaceName'], 'dimensions' => $contextPathPieces['dimensions'], 'invisibleContentShown' => true]); $node = $context->getNode($contextPathPieces['nodePath']); if (!$node instanceof NodeInterface) { return; } $values['node-identifier'] = $node->getIdentifier(); $node = $node->getParent(); $values['node-parent-identifier'] = array(); while ($node !== null) { $values['node-parent-identifier'][] = $node->getIdentifier(); $node = $node->getParent(); } $joinPoint->setMethodArgument('values', $values); }); }
public function setUp() { parent::setUp(); $this->markSkippedIfNodeTypesPackageIsNotInstalled(); $this->contextFactory = $this->objectManager->get(ContextFactoryInterface::class); $contentContext = $this->contextFactory->create(array('workspaceName' => 'live')); $this->siteImportService = $this->objectManager->get(SiteImportService::class); $this->siteExportService = $this->objectManager->get(SiteExportService::class); $this->importedSite = $this->siteImportService->importFromFile(__DIR__ . '/' . $this->fixtureFileName, $contentContext); $this->persistenceManager->persistAll(); }
/** * @return void */ public function setUp() { parent::setUp(); $this->nodeTypeManager = $this->objectManager->get(NodeTypeManager::class); $this->liveWorkspace = new Workspace('live'); $this->workspaceRepository = $this->objectManager->get(WorkspaceRepository::class); $this->workspaceRepository->add($this->liveWorkspace); $this->persistenceManager->persistAll(); $this->contextFactory = $this->objectManager->get(ContextFactoryInterface::class); $this->context = $this->contextFactory->create(['workspaceName' => 'live']); $this->nodeDataRepository = $this->objectManager->get(NodeDataRepository::class); }
/** * @return void */ public function setUp() { parent::setUp(); $this->nodeDataRepository = new NodeDataRepository(); $this->contextFactory = $this->objectManager->get(ContextFactoryInterface::class); $this->nodeTypeManager = $this->objectManager->get(NodeTypeManager::class); $workspace = new Workspace('live'); $this->objectManager->get(WorkspaceRepository::class)->add($workspace); $this->persistenceManager->persistAll(); $context = $this->contextFactory->create(array('workspaceName' => 'live')); $this->rootNode = $context->getRootNode(); }
public function setUp() { parent::setUp(); $this->router->setRoutesConfiguration(null); $this->nodeDataRepository = $this->objectManager->get(NodeDataRepository::class); $domainRepository = $this->objectManager->get(DomainRepository::class); $siteRepository = $this->objectManager->get(SiteRepository::class); $this->contextFactory = $this->objectManager->get(ContextFactoryInterface::class); $contextProperties = array('workspaceName' => 'live'); $contentContext = $this->contextFactory->create($contextProperties); $siteImportService = $this->objectManager->get(SiteImportService::class); $siteImportService->importFromFile(__DIR__ . '/../../Fixtures/NodeStructure.xml', $contentContext); $this->persistenceManager->persistAll(); /** @var Domain $currentDomain */ $currentDomain = $domainRepository->findOneByActiveRequest(); if ($currentDomain !== null) { $contextProperties['currentSite'] = $currentDomain->getSite(); $contextProperties['currentDomain'] = $currentDomain; } else { $contextProperties['currentSite'] = $siteRepository->findFirst(); } $contentContext = $this->contextFactory->create($contextProperties); $this->contentContext = $contentContext; $this->propertyMapper = $this->objectManager->get(PropertyMapper::class); $this->viewHelper = new NodeViewHelper(); /** @var $requestHandler FunctionalTestRequestHandler */ $requestHandler = self::$bootstrap->getActiveRequestHandler(); $httpRequest = $requestHandler->getHttpRequest(); $httpRequest->setBaseUri(new Uri('http://neos.test/')); $controllerContext = new ControllerContext(new ActionRequest($httpRequest), $requestHandler->getHttpResponse(), new Arguments(array()), new UriBuilder()); $this->inject($this->viewHelper, 'controllerContext', $controllerContext); $typoScriptObject = $this->getAccessibleMock(TemplateImplementation::class, array('dummy'), array(), '', false); $this->tsRuntime = new Runtime(array(), $controllerContext); $this->tsRuntime->pushContextArray(array('documentNode' => $this->contentContext->getCurrentSiteNode()->getNode('home'), 'alternativeDocumentNode' => $this->contentContext->getCurrentSiteNode()->getNode('home/about-us/mission'))); $this->inject($typoScriptObject, 'tsRuntime', $this->tsRuntime); /** @var AbstractTemplateView|\PHPUnit_Framework_MockObject_MockObject $mockView */ $mockView = $this->getAccessibleMock(FluidView::class, array(), array(), '', false); $mockView->expects($this->any())->method('getTypoScriptObject')->will($this->returnValue($typoScriptObject)); $viewHelperVariableContainer = new ViewHelperVariableContainer(); $viewHelperVariableContainer->setView($mockView); $this->inject($this->viewHelper, 'viewHelperVariableContainer', $viewHelperVariableContainer); $templateVariableContainer = new TemplateVariableContainer(array()); $this->inject($this->viewHelper, 'templateVariableContainer', $templateVariableContainer); $this->viewHelper->setRenderChildrenClosure(function () use($templateVariableContainer) { $linkedNode = $templateVariableContainer->get('linkedNode'); return $linkedNode !== null ? $linkedNode->getLabel() : ''; }); $this->viewHelper->initialize(); }
/** * Create a new empty site. * * @param string $packageKey Package Name to create * @param string $siteName Site Name to create * @param string $nodeType NodeType name for the root node to create * @Flow\Validate(argumentName="$packageKey", type="\Neos\Neos\Validation\Validator\PackageKeyValidator") * @return void */ public function createSiteNodeAction($packageKey, $siteName, $nodeType) { $nodeName = $this->nodeService->generateUniqueNodeName(SiteService::SITES_ROOT_PATH, $siteName); if ($this->siteRepository->findOneByNodeName($nodeName)) { $this->addFlashMessage('Error:A site with siteNodeName "%s" already exists', Message::SEVERITY_ERROR, [$nodeName], 1412372375); $this->redirect('createSiteNode'); } $siteNodeType = $this->nodeTypeManager->getNodeType($nodeType); if ($siteNodeType === null || $siteNodeType->getName() === 'Neos.Neos:FallbackNode') { $this->addFlashMessage('Error: The given node type "%s" was not found', 'Import error', Message::SEVERITY_ERROR, [$nodeType], 1412372375); $this->redirect('createSiteNode'); } if ($siteNodeType->isOfType('Neos.Neos:Document') === false) { $this->addFlashMessage('Error: The given node type "%s" is not based on the superType "%s"', Message::SEVERITY_ERROR, [$nodeType, 'Neos.Neos:Document'], 1412372375); $this->redirect('createSiteNode'); } $rootNode = $this->nodeContextFactory->create()->getRootNode(); // We fetch the workspace to be sure it's known to the persistence manager and persist all // so the workspace and site node are persisted before we import any nodes to it. $rootNode->getContext()->getWorkspace(); $this->persistenceManager->persistAll(); $sitesNode = $rootNode->getNode(SiteService::SITES_ROOT_PATH); if ($sitesNode === null) { $sitesNode = $rootNode->createNode(NodePaths::getNodeNameFromPath(SiteService::SITES_ROOT_PATH)); } $siteNode = $sitesNode->createNode($nodeName, $siteNodeType); $siteNode->setProperty('title', $siteName); $site = new Site($nodeName); $site->setSiteResourcesPackageKey($packageKey); $site->setState(Site::STATE_ONLINE); $site->setName($siteName); $this->siteRepository->add($site); $this->addFlashMessage('Successfully created site "%s" with siteNode "%s", type "%s" and packageKey "%s"', '', null, [$siteName, $nodeName, $nodeType, $packageKey], 1412372266); $this->unsetLastVisitedNodeAndRedirect('index'); }
/** * {@inheritdoc} * * @param FlowQuery $flowQuery The FlowQuery object * @param array $arguments The arguments for this operation * @return void */ public function evaluate(FlowQuery $flowQuery, array $arguments) { if (!isset($arguments[0]) || !is_array($arguments[0])) { throw new FlowQueryException('context() requires an array argument of context properties', 1398030427); } $output = array(); foreach ($flowQuery->getContext() as $contextNode) { $contextProperties = $contextNode->getContext()->getProperties(); $modifiedContext = $this->contextFactory->create(array_merge($contextProperties, $arguments[0])); $nodeInModifiedContext = $modifiedContext->getNodeByIdentifier($contextNode->getIdentifier()); if ($nodeInModifiedContext !== null) { $output[$nodeInModifiedContext->getPath()] = $nodeInModifiedContext; } } $flowQuery->setContext(array_values($output)); }
/** * @test */ public function setDimensionsToEMptyArrayRemovesDimensions() { $siteImportService = $this->objectManager->get(SiteImportService::class); $siteImportService->importFromFile(__DIR__ . '/../Fixtures/NodeStructure.xml', $this->context); $this->persistenceManager->persistAll(); $this->inject($this->contextFactory, 'contextInstances', []); $nodeDataRepository = $this->objectManager->get(NodeDataRepository::class); // The context is not important here, just a quick way to get a (live) workspace $context = $this->contextFactory->create(); // The identifier comes from the Fixture. /** @var NodeData $resultingNodeData */ $resultingNodeData = $nodeDataRepository->findOneByIdentifier('9fa376af-a1b8-83ac-bedc-9ad83c8598bc', $context->getWorkspace(true), []); $this->assertNotEmpty($resultingNodeData->getDimensions()); $resultingNodeData->setDimensions([]); $nodeDataRepository->update($resultingNodeData); $this->persistenceManager->persistAll(); $this->persistenceManager->clearState(); $this->inject($this->contextFactory, 'contextInstances', []); // The context is not important here, just a quick way to get a (live) workspace $context = $this->contextFactory->create(); // The identifier comes from the Fixture. /** @var NodeData $resultingNodeData */ $resultingNodeData = $nodeDataRepository->findOneByIdentifier('9fa376af-a1b8-83ac-bedc-9ad83c8598bc', $context->getWorkspace(true), []); $this->assertEmpty($resultingNodeData->getDimensions()); }
/** * 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); }
/** * Flush the node changes and reset the persistence manager and node data registry * * @return void */ public function flushNodeChanges() { $nodeDataRepository = $this->objectManager->get(NodeDataRepository::class); $nodeDataRepository->flushNodeRegistry(); $this->persistenceManager->persistAll(); $this->persistenceManager->clearState(); $this->contextFactory->reset(); }
/** * @return void */ public function setUp() { parent::setUp(); $workspaceRepository = $this->objectManager->get(\Neos\ContentRepository\Domain\Repository\WorkspaceRepository::class); $workspaceRepository->add(new Workspace('live')); $this->persistenceManager->persistAll(); $this->contextFactory = $this->objectManager->get(\Neos\ContentRepository\Domain\Service\ContextFactoryInterface::class); $this->context = $this->contextFactory->create(array('workspaceName' => 'live')); $siteImportService = $this->objectManager->get(\Neos\Neos\Domain\Service\SiteImportService::class); $siteImportService->importFromFile(__DIR__ . '/Fixtures/SortableNodes.xml', $this->context); $this->persistenceManager->persistAll(); $this->persistenceManager->clearState(); $this->inject($this->contextFactory, 'contextInstances', array()); // The context is not important here, just a quick way to get a (live) workspace // $context = $this->contextFactory->create(); $this->nodeDataRepository = $this->objectManager->get(\Neos\ContentRepository\Domain\Repository\NodeDataRepository::class); }
/** * Creates a new content context based on the given workspace and the NodeData object. * * @param Workspace $workspace Workspace for the new context * @param array $dimensionValues The dimension values for the new context * @param array $contextProperties Additional pre-defined context properties * @return Context */ protected function createContext(Workspace $workspace, array $dimensionValues, array $contextProperties = array()) { $presetsMatchingDimensionValues = $this->contentDimensionPresetSource->findPresetsByTargetValues($dimensionValues); $dimensions = array_map(function ($preset) { return $preset['values']; }, $presetsMatchingDimensionValues); $contextProperties += array('workspaceName' => $workspace->getName(), 'inaccessibleContentShown' => true, 'invisibleContentShown' => true, 'removedContentShown' => true, 'dimensions' => $dimensions); return $this->contextFactory->create($contextProperties); }
/** * Returns the node this even refers to, if it can be resolved. * * It might happen that, if this event refers to a node contained in a site which is not available anymore, * Doctrine's proxy class of the Site domain model will fail with an EntityNotFoundException. We catch this * case and return NULL. * * @return NodeInterface */ public function getNode() { try { $context = $this->contextFactory->create(array('workspaceName' => $this->userService->getUserWorkspace()->getName(), 'dimensions' => $this->dimension, 'currentSite' => $this->getCurrentSite(), 'invisibleContentShown' => true)); return $context->getNodeByIdentifier($this->nodeIdentifier); } catch (EntityNotFoundException $e) { return null; } }
/** * Create a Context for a workspace given by name to be used in this controller. * * @param string $workspaceName Name of the current workspace * @return \Neos\ContentRepository\Domain\Service\Context */ protected function createContext($workspaceName) { $contextProperties = array('workspaceName' => $workspaceName); $currentDomain = $this->domainRepository->findOneByActiveRequest(); if ($currentDomain !== null) { $contextProperties['currentSite'] = $currentDomain->getSite(); $contextProperties['currentDomain'] = $currentDomain; } return $this->contextFactory->create($contextProperties); }
/** * @test */ public function createNodeFromTemplateUsesWorkspacesOfContext() { $nodeTemplate = $this->generateBasicNodeTemplate(); $userWorkspace = new Workspace('user1', $this->liveWorkspace); $this->workspaceRepository->add($userWorkspace); $this->context = $this->contextFactory->create(array('workspaceName' => 'user1')); $rootNode = $this->context->getNode('/'); $node = $rootNode->createNodeFromTemplate($nodeTemplate, 'just-a-node'); $workspace = $node->getWorkspace(); $this->assertEquals('user1', $workspace->getName(), 'Node should be created in workspace of context'); }
/** * @test */ public function removedNodeWithoutExistingTargetNodeDataWillBeRemovedWhenPublished() { $homepageNode = $this->rootNode->createNode('homepage'); $homepageNode->remove(); $this->rootNode->getWorkspace()->publish($this->liveWorkspace); $this->saveNodesAndTearDownRootNodeAndRepository(); $this->setUpRootNodeAndRepository(); $liveContext = $this->contextFactory->create(array('workspaceName' => 'live', 'removedContentShown' => true)); $liveRootNode = $liveContext->getRootNode(); $liveHomepageNode = $liveRootNode->getNode('homepage'); $this->assertTrue($liveHomepageNode === null, 'A removed node should be removed after publishing, but it was still found'); }
/** * Export the given $site to the XMLWriter * * @param Site $site * @param string $nodeTypeFilter * @return void */ protected function exportSite(Site $site, $nodeTypeFilter) { /** @var ContentContext $contentContext */ $contentContext = $this->contextFactory->create(array('currentSite' => $site, 'invisibleContentShown' => true, 'inaccessibleContentShown' => true)); $siteNode = $contentContext->getCurrentSiteNode(); $this->xmlWriter->startElement('site'); $this->xmlWriter->writeAttribute('name', $site->getName()); $this->xmlWriter->writeAttribute('state', $site->getState()); $this->xmlWriter->writeAttribute('siteResourcesPackageKey', $site->getSiteResourcesPackageKey()); $this->xmlWriter->writeAttribute('siteNodeName', $siteNode->getName()); $this->nodeExportService->export($siteNode->getPath(), $contentContext->getWorkspaceName(), $this->xmlWriter, false, false, $this->resourcesPath, $nodeTypeFilter); $this->xmlWriter->endElement(); }
/** * @return void */ protected function saveNodesAndTearDownRootNodeAndRepository() { if ($this->nodeDataRepository !== null) { $this->nodeDataRepository->flushNodeRegistry(); } /** @var NodeFactory $nodeFactory */ $nodeFactory = $this->objectManager->get(NodeFactory::class); $nodeFactory->reset(); $this->contextFactory->reset(); $this->persistenceManager->persistAll(); $this->persistenceManager->clearState(); $this->nodeDataRepository = null; $this->rootNode = null; }
/** * @test */ public function evaluateSkipsNodesNotAvailableInModifiedContext() { $suppliedContextProperties = array('infiniteImprobabilityDrive' => true); $nodeContextProperties = array('infiniteImprobabilityDrive' => false, 'autoRemoveUnsuitableContent' => true); $nodeIdentifier = 'c575c430-c971-11e3-a6e7-14109fd7a2dd'; $mockNode = $this->createMock(NodeInterface::class); $mockNode->expects($this->any())->method('getIdentifier')->will($this->returnValue($nodeIdentifier)); $mockFlowQuery = $this->buildFlowQueryWithNodeInContext($mockNode, $nodeContextProperties); $modifiedNodeContext = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock(); $this->mockContextFactory->expects($this->any())->method('create')->will($this->returnValue($modifiedNodeContext)); $modifiedNodeContext->expects($this->once())->method('getNodeByIdentifier')->with($nodeIdentifier)->will($this->returnValue(null)); $mockFlowQuery->expects($this->atLeastOnce())->method('setContext')->with(array()); $this->operation->evaluate($mockFlowQuery, array($suppliedContextProperties)); }
/** * Get all node variants for the given identifier * * A variant of a node can have different dimension values and path (for non-aggregate nodes). * The resulting node instances might belong to a different context. * * @param string $identifier The identifier of a node * @return array<\Neos\ContentRepository\Domain\Model\NodeInterface> */ public function getNodeVariantsByIdentifier($identifier) { $nodeVariants = array(); $nodeDataElements = $this->nodeDataRepository->findByIdentifierWithoutReduce($identifier, $this->getWorkspace()); /** @var NodeData $nodeData */ foreach ($nodeDataElements as $nodeData) { $contextProperties = $this->getProperties(); $contextProperties['dimensions'] = $nodeData->getDimensionValues(); unset($contextProperties['targetDimensions']); $adjustedContext = $this->contextFactory->create($contextProperties); $nodeVariant = $this->nodeFactory->createFromNodeData($nodeData, $adjustedContext); $nodeVariants[] = $nodeVariant; } return $nodeVariants; }
/** * @test */ public function nodeFromLiveWorkspaceMovedInUserWorkspaceRetainsShadowNodeInGroupWorkspace() { $liveContext = $this->contextFactory->create([]); $liveContext->getRootNode()->createNode('foo')->createNode('bar')->createNode('baz'); $this->persistenceManager->persistAll(); $this->rootNode->getNode('foo/bar/baz')->moveInto($this->rootNode->getNode('foo')); $this->persistenceManager->persistAll(); $this->rootNode->getContext()->getWorkspace()->publish($this->groupWorkspace); $this->persistenceManager->persistAll(); $groupContext = $this->contextFactory->create(['workspaceName' => $this->currentGroupWorkspace]); $movedBazNode = $groupContext->getRootNode()->getNode('foo')->getNode('baz'); $this->assertInstanceOf(NodeInterface::class, $movedBazNode); $shadowNode = $this->nodeDataRepository->findShadowNodeByPath('/foo/bar/baz', $this->groupWorkspace, $groupContext->getDimensions()); $this->assertInstanceOf(NodeData::class, $shadowNode); $this->assertNotNull($shadowNode->getMovedTo()); $this->assertTrue($shadowNode->isRemoved()); }
/** * @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)); }
/** * @param string $nodePath * @param array $nodeTypeProperties * @return NodeInterface */ protected function setUpNodeWithNodeType($nodePath, $nodeTypeProperties = array()) { $mockLiveWorkspace = $this->getMockBuilder(Workspace::class)->disableOriginalConstructor()->getMock(); $mockNode = $this->createMock(NodeInterface::class); $mockNodeType = $this->getMockBuilder(NodeType::class)->disableOriginalConstructor()->getMock(); $mockNodeType->expects($this->any())->method('getProperties')->will($this->returnValue($nodeTypeProperties)); $mockNode->expects($this->any())->method('getNodeType')->will($this->returnValue($mockNodeType)); $mockContext = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock(); $mockContext->expects($this->any())->method('getWorkspace')->will($this->returnValue($mockLiveWorkspace)); $mockContext->expects($this->any())->method('getNode')->with($nodePath)->will($this->returnValue($mockNode)); $mockNode->expects($this->any())->method('getContext')->will($this->returnValue($mockContext)); // Simulate context properties by returning the same properties that were given to the ContextFactory $this->mockContextFactory->expects($this->any())->method('create')->will($this->returnCallback(function ($contextProperties) use($mockContext) { $mockContext->expects($this->any())->method('getProperties')->will($this->returnValue($contextProperties)); return $mockContext; })); return $mockNode; }
/** * Imports one or multiple sites from the XML file at $pathAndFilename * * @param string $pathAndFilename * @return Site The imported site * @throws UnknownPackageException|InvalidPackageStateException|NeosException */ public function importFromFile($pathAndFilename) { /** @var Site $importedSite */ $site = null; $xmlReader = new \XMLReader(); $xmlReader->open($pathAndFilename, null, LIBXML_PARSEHUGE); if ($this->workspaceRepository->findOneByName('live') === null) { $this->workspaceRepository->add(new Workspace('live')); $this->persistenceManager->persistAll(); } while ($xmlReader->read()) { if ($xmlReader->nodeType != \XMLReader::ELEMENT || $xmlReader->name !== 'site') { continue; } $site = $this->getSiteByNodeName($xmlReader->getAttribute('siteNodeName')); $site->setName($xmlReader->getAttribute('name')); $site->setState((int) $xmlReader->getAttribute('state')); $siteResourcesPackageKey = $xmlReader->getAttribute('siteResourcesPackageKey'); if (!$this->packageManager->isPackageAvailable($siteResourcesPackageKey)) { throw new UnknownPackageException(sprintf('Package "%s" specified in the XML as site resources package does not exist.', $siteResourcesPackageKey), 1303891443); } if (!$this->packageManager->isPackageActive($siteResourcesPackageKey)) { throw new InvalidPackageStateException(sprintf('Package "%s" specified in the XML as site resources package is not active.', $siteResourcesPackageKey), 1303898135); } $site->setSiteResourcesPackageKey($siteResourcesPackageKey); $rootNode = $this->contextFactory->create()->getRootNode(); // We fetch the workspace to be sure it's known to the persistence manager and persist all // so the workspace and site node are persisted before we import any nodes to it. $rootNode->getContext()->getWorkspace(); $this->persistenceManager->persistAll(); $sitesNode = $rootNode->getNode(SiteService::SITES_ROOT_PATH); if ($sitesNode === null) { $sitesNode = $rootNode->createNode(NodePaths::getNodeNameFromPath(SiteService::SITES_ROOT_PATH)); } $this->nodeImportService->import($xmlReader, $sitesNode->getPath(), dirname($pathAndFilename) . '/Resources'); } if ($site === null) { throw new NeosException(sprintf('The XML file did not contain a valid site node.'), 1418999522); } $this->emitSiteImported($site); return $site; }
public function setUp() { parent::setUp(); $this->markSkippedIfNodeTypesPackageIsNotInstalled(); if ($this->liveWorkspace === null) { $this->liveWorkspace = new Workspace('live'); $this->workspaceRepository = $this->objectManager->get(WorkspaceRepository::class); $this->workspaceRepository->add($this->liveWorkspace); $this->workspaceRepository->add(new Workspace('test', $this->liveWorkspace)); $this->persistenceManager->persistAll(); } $this->contextFactory = $this->objectManager->get(ContextFactoryInterface::class); $contentContext = $this->contextFactory->create(array('workspaceName' => 'live')); $siteImportService = $this->objectManager->get(SiteImportService::class); $siteImportService->importFromFile($this->fixtureFileName, $contentContext); $this->persistenceManager->persistAll(); if ($this->nodeContextPath !== null) { $this->node = $this->getNodeWithContextPath($this->nodeContextPath); } }
/** * @test */ public function nodesInPathAreHiddenIfBetterVariantInOtherPathExists() { $this->contentDimensionRepository->setDimensionsConfiguration(['test' => ['default' => 'a']]); $variantContextA = $this->contextFactory->create(['dimensions' => ['test' => ['a']], 'targetDimensions' => ['test' => 'a']]); $container1 = $variantContextA->getRootNode()->createNode('container1'); $variantContextA->getRootNode()->createNode('container2'); $container1->createNode('node-with-variant'); $variantContextB = $this->contextFactory->create(['dimensions' => ['test' => ['b', 'a']], 'targetDimensions' => ['test' => 'b']]); $nodeWithVariantOriginal = $variantContextB->getNode('/container1/node-with-variant'); $variantContextB->getNode('/container2')->createNode('node-with-variant', null, $nodeWithVariantOriginal->getIdentifier()); $this->persistenceManager->persistAll(); $this->contextFactory->reset(); $variantContextB = $this->contextFactory->create(['dimensions' => ['test' => ['b', 'a']], 'targetDimensions' => ['test' => 'b']]); // Both containers should be available due to fallbacks $this->assertCount(2, $variantContextB->getRootNode()->getChildNodes()); // This should NOT find the node created in variantContextA as // a better matching (with "b" dimension value) variant (same identifier) exists in container two $this->assertCount(0, $variantContextB->getNode('/container1')->getChildNodes()); // This is the better matching variant and should be found. $this->assertCount(1, $variantContextB->getNode('/container2')->getChildNodes()); }
/** * Converts the specified $source into a Node. * * If $source is a UUID it is expected to refer to the identifier of a NodeData record of the "live" workspace * * Otherwise $source has to be a valid node path: * * The node path must be an absolute context node path and can be specified as a string or as an array item with the * key "__contextNodePath". The latter case is for updating existing nodes. * * This conversion method does not support / allow creation of new nodes because new nodes should be created through * the createNode() method of an existing reference node. * * Also note that the context's "current node" is not affected by this object converter, you will need to set it to * whatever node your "current" node is, if any. * * All elements in the source array which start with two underscores (like __contextNodePath) are specially treated * by this converter. * * All elements in the source array which start with a *single underscore (like _hidden) are *directly* set on the Node * object. * * All other elements, not being prefixed with underscore, are properties of the node. * * @param string|array $source Either a string or array containing the absolute context node path which identifies the node. For example "/sites/mysitecom/homepage/about@user-admin" * @param string $targetType not used * @param array $subProperties not used * @param PropertyMappingConfigurationInterface $configuration * @return mixed An object or \Neos\Error\Messages\Error if the input format is not supported or could not be converted for other reasons * @throws NodeException */ public function convertFrom($source, $targetType = null, array $subProperties = array(), PropertyMappingConfigurationInterface $configuration = null) { if (is_string($source)) { $source = array('__contextNodePath' => $source); } if (!is_array($source) || !isset($source['__contextNodePath'])) { return new Error('Could not convert ' . gettype($source) . ' to Node object, a valid absolute context node path as a string or array is expected.', 1302879936); } try { $nodePathAndContext = NodePaths::explodeContextPath($source['__contextNodePath']); $nodePath = $nodePathAndContext['nodePath']; $workspaceName = $nodePathAndContext['workspaceName']; $dimensions = $nodePathAndContext['dimensions']; } catch (\InvalidArgumentException $exception) { return new Error('Could not convert array to Node object because the node path was invalid.', 1285162903); } $context = $this->contextFactory->create($this->prepareContextProperties($workspaceName, $configuration, $dimensions)); $workspace = $context->getWorkspace(false); if (!$workspace) { return new Error(sprintf('Could not convert the given source to Node object because the workspace "%s" as specified in the context node path does not exist.', $workspaceName), 1383577859); } $node = $context->getNode($nodePath); if (!$node) { return new Error(sprintf('Could not convert array to Node object because the node "%s" does not exist.', $nodePath), 1370502328); } if (isset($source['_nodeType']) && $source['_nodeType'] !== $node->getNodeType()->getName()) { if ($context->getWorkspace()->getName() === 'live') { throw new NodeException('Could not convert the node type in live workspace', 1429989736); } $oldNodeType = $node->getNodeType(); $targetNodeType = $this->nodeTypeManager->getNodeType($source['_nodeType']); $node->setNodeType($targetNodeType); $this->nodeService->setDefaultValues($node); $this->nodeService->cleanUpAutoCreatedChildNodes($node, $oldNodeType); $this->nodeService->createChildNodes($node); } unset($source['_nodeType']); $this->setNodeProperties($node, $node->getNodeType(), $source, $context, $configuration); return $node; }
/** * {@inheritdoc} */ public function createRedirectsForPublishedNode(NodeInterface $node, Workspace $targetWorkspace) { $nodeType = $node->getNodeType(); if ($targetWorkspace->getName() !== 'live' || !$nodeType->isOfType('Neos.Neos:Document')) { return; } $context = $this->contextFactory->create(['workspaceName' => 'live', 'invisibleContentShown' => true, 'dimensions' => $node->getContext()->getDimensions()]); $targetNode = $context->getNodeByIdentifier($node->getIdentifier()); if ($targetNode === null) { // The page has been added return; } $targetNodeUriPath = $this->buildUriPathForNodeContextPath($targetNode->getContextPath()); if ($targetNodeUriPath === null) { throw new Exception('The target URI path of the node could not be resolved', 1451945358); } $hosts = $this->getHostnames($node->getContext()); // The page has been removed if ($node->isRemoved()) { $this->flushRoutingCacheForNode($targetNode); $statusCode = (int) $this->defaultStatusCode['gone']; $this->redirectStorage->addRedirect($targetNodeUriPath, '', $statusCode, $hosts); return; } // compare the "old" node URI to the new one $nodeUriPath = $this->buildUriPathForNodeContextPath($node->getContextPath()); // use the same regexp than the ContentContextBar Ember View $nodeUriPath = preg_replace('/@[A-Za-z0-9;&,\\-_=]+/', '', $nodeUriPath); if ($nodeUriPath === null || $nodeUriPath === $targetNodeUriPath) { // The page node path has not been changed return; } $this->flushRoutingCacheForNode($targetNode); $statusCode = (int) $this->defaultStatusCode['redirect']; $this->redirectStorage->addRedirect($targetNodeUriPath, $nodeUriPath, $statusCode, $hosts); $q = new FlowQuery([$node]); foreach ($q->children('[instanceof Neos.Neos:Document]') as $childrenNode) { $this->createRedirectsForPublishedNode($childrenNode, $targetWorkspace); } }
/** * Create a new site * * This command allows to create a blank site with just a single empty document in the default dimension. * The name of the site, the packageKey must be specified. * * If no ``nodeType`` option is specified the command will use `Neos.Neos.NodeTypes:Page` as fallback. The node type * must already exists and have the superType ``Neos.Neos:Document``. * * If no ``nodeName` option is specified the command will create a unique node-name from the name of the site. * If a node name is given it has to be unique for the setup. * * If the flag ``activate` is set to false new site will not be activated. * * @param string $name The name of the site * @param string $packageKey The site package * @param string $nodeType The node type to use for the site node. (Default = Neos.Neos.NodeTypes:Page) * @param string $nodeName The name of the site node. If no nodeName is given it will be determined from the siteName. * @param boolean $inactive The new site is not activated immediately (default = false). * @return void */ public function createCommand($name, $packageKey, $nodeType = 'Neos.Neos.NodeTypes:Page', $nodeName = null, $inactive = false) { if ($nodeName === null) { $nodeName = $this->nodeService->generateUniqueNodeName(SiteService::SITES_ROOT_PATH, $name); } if ($this->siteRepository->findOneByNodeName($nodeName)) { $this->outputLine('<error>A site with siteNodeName "%s" already exists</error>', [$nodeName]); $this->quit(1); } if ($this->packageManager->isPackageAvailable($packageKey) === false) { $this->outputLine('<error>Could not find package "%s"</error>', [$packageKey]); $this->quit(1); } $siteNodeType = $this->nodeTypeManager->getNodeType($nodeType); if ($siteNodeType === null || $siteNodeType->getName() === 'Neos.Neos:FallbackNode') { $this->outputLine('<error>The given node type "%s" was not found</error>', [$nodeType]); $this->quit(1); } if ($siteNodeType->isOfType('Neos.Neos:Document') === false) { $this->outputLine('<error>The given node type "%s" is not based on the superType "%s"</error>', [$nodeType, 'Neos.Neos:Document']); $this->quit(1); } $rootNode = $this->nodeContextFactory->create()->getRootNode(); // We fetch the workspace to be sure it's known to the persistence manager and persist all // so the workspace and site node are persisted before we import any nodes to it. $rootNode->getContext()->getWorkspace(); $this->persistenceManager->persistAll(); $sitesNode = $rootNode->getNode(SiteService::SITES_ROOT_PATH); if ($sitesNode === null) { $sitesNode = $rootNode->createNode(NodePaths::getNodeNameFromPath(SiteService::SITES_ROOT_PATH)); } $siteNode = $sitesNode->createNode($nodeName, $siteNodeType); $siteNode->setProperty('title', $name); $site = new Site($nodeName); $site->setSiteResourcesPackageKey($packageKey); $site->setState($inactive ? Site::STATE_OFFLINE : Site::STATE_ONLINE); $site->setName($name); $this->siteRepository->add($site); $this->outputLine('Successfully created site "%s" with siteNode "%s", type "%s", packageKey "%s" and state "%s"', [$name, $nodeName, $nodeType, $packageKey, $inactive ? 'offline' : 'online']); }
/** * Generates a Context that exactly fits the given NodeData Workspace and Dimensions. * * TODO: We could get more specific about removed and invisible content by adding some more logic here that generates fitting values. * * @param NodeData $nodeData * @return Context */ public function createContextMatchingNodeData(NodeData $nodeData) { return $this->contextFactory->create(array('workspaceName' => $nodeData->getWorkspace()->getName(), 'invisibleContentShown' => true, 'inaccessibleContentShown' => true, 'removedContentShown' => true, 'dimensions' => $nodeData->getDimensionValues())); }