/** * Execute the migration * * @return void */ public function execute() { foreach ($this->nodeDataRepository->findAll() as $node) { foreach ($this->configuration as $migrationDescription) { if ($this->nodeFilterService->matchFilters($node, $migrationDescription['filters'])) { $this->nodeTransformationService->execute($node, $migrationDescription['transformations']); if (!$this->nodeDataRepository->isInRemovedNodes($node)) { $this->nodeDataRepository->update($node); } } } } }
/** * 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); }
/** * Remove dimensions on nodes "/" and "/sites" * * This empties the content dimensions on those nodes, so when traversing via the Node API from the root node, * the nodes below "/sites" are always reachable. * * @param string $workspaceName * @param boolean $dryRun * @return void */ public function removeContentDimensionsFromRootAndSitesNode($workspaceName, $dryRun) { $workspace = $this->workspaceRepository->findByIdentifier($workspaceName); $rootNodes = $this->nodeDataRepository->findByPath('/', $workspace); $sitesNodes = $this->nodeDataRepository->findByPath('/sites', $workspace); $this->output->outputLine('Checking for root and site nodes with content dimensions set ...'); /** @var \Neos\ContentRepository\Domain\Model\NodeData $rootNode */ foreach ($rootNodes as $rootNode) { if ($rootNode->getDimensionValues() !== []) { if ($dryRun === false) { $rootNode->setDimensions([]); $this->nodeDataRepository->update($rootNode); $this->output->outputLine('Removed content dimensions from root node'); } else { $this->output->outputLine('Found root node with content dimensions set.'); } } } /** @var \Neos\ContentRepository\Domain\Model\NodeData $sitesNode */ foreach ($sitesNodes as $sitesNode) { if ($sitesNode->getDimensionValues() !== []) { if ($dryRun === false) { $sitesNode->setDimensions([]); $this->nodeDataRepository->update($sitesNode); $this->output->outputLine('Removed content dimensions from node "/sites"'); } else { $this->output->outputLine('Found node "/sites"'); } } } }
/** * @param FinisherContext $finisherContext * @return void * @throws Exception */ public function importSite(FinisherContext $finisherContext) { $formValues = $finisherContext->getFormRuntime()->getFormState()->getFormValues(); if (isset($formValues['prune']) && intval($formValues['prune']) === 1) { $this->nodeDataRepository->removeAll(); $this->workspaceRepository->removeAll(); $this->domainRepository->removeAll(); $this->siteRepository->removeAll(); $this->persistenceManager->persistAll(); } if (!empty($formValues['packageKey'])) { if ($this->packageManager->isPackageAvailable($formValues['packageKey'])) { throw new Exception(sprintf('The package key "%s" already exists.', $formValues['packageKey']), 1346759486); } $packageKey = $formValues['packageKey']; $siteName = $formValues['siteName']; $generatorService = $this->objectManager->get(\Neos\SiteKickstarter\Service\GeneratorService::class); $generatorService->generateSitePackage($packageKey, $siteName); } elseif (!empty($formValues['site'])) { $packageKey = $formValues['site']; } $this->deactivateOtherSitePackages($packageKey); $this->packageManager->activatePackage($packageKey); if (!empty($packageKey)) { try { $contentContext = $this->contextFactory->create(array('workspaceName' => 'live')); $this->siteImportService->importFromPackage($packageKey, $contentContext); } catch (\Exception $exception) { $finisherContext->cancel(); $this->systemLogger->logException($exception); throw new SetupException(sprintf('Error: During the import of the "Sites.xml" from the package "%s" an exception occurred: %s', $packageKey, $exception->getMessage()), 1351000864); } } }
/** * 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; }
/** * @test */ public function findNodesByPropertyKeyAndValue() { $this->createNodesForNodeSearchTest(); $result = $this->nodeDataRepository->findByProperties(array('test2' => 'simpleTestValue'), 'Neos.ContentRepository.Testing:NodeType', $this->liveWorkspace, $this->context->getDimensions()); $this->assertCount(1, $result); $this->assertEquals('test-node-2', array_shift($result)->getName()); }
/** * Removes unused ImageVariants after a Node property changes to a different ImageVariant. * This is triggered via the nodePropertyChanged event. * * Note: This method it triggered by the "nodePropertyChanged" signal, @see \Neos\ContentRepository\Domain\Model\Node::emitNodePropertyChanged() * * @param NodeInterface $node the affected node * @param string $propertyName name of the property that has been changed/added * @param mixed $oldValue the property value before it was changed or NULL if the property is new * @param mixed $value the new property value * @return void */ public function removeUnusedImageVariant(NodeInterface $node, $propertyName, $oldValue, $value) { if ($oldValue === $value || !$oldValue instanceof ImageVariant) { return; } $identifier = $this->persistenceManager->getIdentifierByObject($oldValue); $results = $this->nodeDataRepository->findNodesByRelatedEntities(array(ImageVariant::class => [$identifier])); // This case shouldn't happen as the query will usually find at least the node that triggered this call, still if there is no relation we can remove the ImageVariant. if ($results === []) { $this->assetRepository->remove($oldValue); return; } // If the result contains exactly the node that got a new ImageVariant assigned then we are safe to remove the asset here. if ($results === [$node->getNodeData()]) { $this->assetRepository->remove($oldValue); } }
/** * @test */ public function sortByDateTimeDescending() { $nodesToSort = [$this->nodeDataRepository->findOneByIdentifier('c381f64d-4269-429a-9c21-6d846115addd', $this->context->getWorkspace(true), array()), $this->nodeDataRepository->findOneByIdentifier('c381f64d-4269-429a-9c21-6d846115adde', $this->context->getWorkspace(true), array()), $this->nodeDataRepository->findOneByIdentifier('c381f64d-4269-429a-9c21-6d846115addf', $this->context->getWorkspace(true), array())]; $correctOrder = [$this->nodeDataRepository->findOneByIdentifier('c381f64d-4269-429a-9c21-6d846115addd', $this->context->getWorkspace(true), array()), $this->nodeDataRepository->findOneByIdentifier('c381f64d-4269-429a-9c21-6d846115addf', $this->context->getWorkspace(true), array()), $this->nodeDataRepository->findOneByIdentifier('c381f64d-4269-429a-9c21-6d846115adde', $this->context->getWorkspace(true), array())]; $flowQuery = new \Neos\Eel\FlowQuery\FlowQuery($nodesToSort); $operation = new SortOperation(); $operation->evaluate($flowQuery, ['_lastPublicationDateTime', 'DESC']); $this->assertEquals($correctOrder, $flowQuery->getContext()); }
/** * Remove given site all nodes for that site and all domains associated. * * @param Site $site * @return void */ public function pruneSite(Site $site) { $siteNodePath = NodePaths::addNodePathSegment(static::SITES_ROOT_PATH, $site->getNodeName()); $this->nodeDataRepository->removeAllInPath($siteNodePath); $siteNodes = $this->nodeDataRepository->findByPath($siteNodePath); foreach ($siteNodes as $siteNode) { $this->nodeDataRepository->remove($siteNode); } $site->setPrimaryDomain(null); $this->siteRepository->update($site); $domainsForSite = $this->domainRepository->findBySite($site); foreach ($domainsForSite as $domain) { $this->domainRepository->remove($domain); } $this->persistenceManager->persistAll(); $this->siteRepository->remove($site); $this->emitSitePruned($site); }
/** * 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; }
/** * Change the property on the given node. * * @param NodeData $node * @return NodeData */ public function execute(NodeData $node) { $reference = (string) $node->getProperty('plugin'); $workspace = $node->getWorkspace(); do { if ($this->reverse === false && preg_match(NodeInterface::MATCH_PATTERN_PATH, $reference)) { $pluginNode = $this->nodeDataRepository->findOneByPath($reference, $node->getWorkspace()); } else { $pluginNode = $this->nodeDataRepository->findOneByIdentifier($reference, $node->getWorkspace()); } if (isset($pluginNode)) { break; } $workspace = $workspace->getBaseWorkspace(); } while ($workspace && $workspace->getName() !== 'live'); if (isset($pluginNode)) { $node->setProperty('plugin', $this->reverse === false ? $pluginNode->getIdentifier() : $pluginNode->getPath()); } return $node; }
/** * @test */ public function findByParentAndNodeTypeRemovesRemovedNodeInRepositoryAndRespectsWorkspaceAndDimensions() { $liveWorkspace = new Workspace('live'); $nodeData = $this->getMockBuilder(NodeData::class)->disableOriginalConstructor()->getMock(); $nodeData->expects($this->any())->method('getIdentifier')->will($this->returnValue('abcd-efgh-ijkl-mnop')); $nodeData->expects($this->any())->method('getPath')->will($this->returnValue('/foo/bar')); $nodeData->expects($this->any())->method('getDepth')->will($this->returnValue(2)); $this->nodeDataRepository->remove($nodeData); $dimensions = array('persona' => array('everybody'), 'language' => array('de_DE', 'mul_ZZ')); $nodeData->expects($this->atLeastOnce())->method('matchesWorkspaceAndDimensions')->with($liveWorkspace, $dimensions)->will($this->returnValue(true)); $this->nodeDataRepository->expects($this->any())->method('getNodeDataForParentAndNodeType')->will($this->returnValue(array('abcd-efgh-ijkl-mnop' => $nodeData))); $result = $this->nodeDataRepository->findByParentAndNodeType('/foo', null, $liveWorkspace, $dimensions); $this->assertCount(0, $result); }
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; }
/** * 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; }
/** * Returns all nodes that use the asset in a node property. * * @param AssetInterface $asset * @return array */ public function getRelatedNodes(AssetInterface $asset) { $relationMap = []; $relationMap[TypeHandling::getTypeForValue($asset)] = [$this->persistenceManager->getIdentifierByObject($asset)]; if ($asset instanceof Image) { foreach ($asset->getVariants() as $variant) { $type = TypeHandling::getTypeForValue($variant); if (!isset($relationMap[$type])) { $relationMap[$type] = []; } $relationMap[$type][] = $this->persistenceManager->getIdentifierByObject($variant); } } return $this->nodeDataRepository->findNodesByRelatedEntities($relationMap); }
/** * Materializes the original node data (of a different workspace) into the current * workspace. * * @return void */ protected function materializeNodeData() { $dimensions = $this->context->getTargetDimensionValues(); $newNodeData = new NodeData($this->nodeData->getPath(), $this->context->getWorkspace(), $this->nodeData->getIdentifier(), $dimensions); $this->nodeDataRepository->add($newNodeData); $newNodeData->similarize($this->nodeData); $this->nodeData = $newNodeData; $this->nodeDataIsMatchingContext = true; $nodeType = $this->getNodeType(); foreach ($nodeType->getAutoCreatedChildNodes() as $childNodeName => $childNodeConfiguration) { $childNode = $this->getNode($childNodeName); if ($childNode instanceof Node && !$childNode->isNodeDataMatchingContext()) { $childNode->materializeNodeData(); } } }
/** * @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()); }
/** * 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)); }
/** * Update a site * * @param Site $site A site to update * @param string $newSiteNodeName A new site node name * @return void * @Flow\Validate(argumentName="$site", type="UniqueEntity") * @Flow\Validate(argumentName="$newSiteNodeName", type="NotEmpty") * @Flow\Validate(argumentName="$newSiteNodeName", type="StringLength", options={ "minimum"=1, "maximum"=250 }) * @Flow\Validate(argumentName="$newSiteNodeName", type="Neos.Neos:NodeName") */ public function updateSiteAction(Site $site, $newSiteNodeName) { if ($site->getNodeName() !== $newSiteNodeName) { $oldSiteNodePath = NodePaths::addNodePathSegment(SiteService::SITES_ROOT_PATH, $site->getNodeName()); $newSiteNodePath = NodePaths::addNodePathSegment(SiteService::SITES_ROOT_PATH, $newSiteNodeName); /** @var $workspace Workspace */ foreach ($this->workspaceRepository->findAll() as $workspace) { $siteNode = $this->nodeDataRepository->findOneByPath($oldSiteNodePath, $workspace); if ($siteNode !== null) { $siteNode->setPath($newSiteNodePath); } } $site->setNodeName($newSiteNodeName); $this->nodeDataRepository->persistEntities(); } $this->siteRepository->update($site); $this->addFlashMessage('The site "%s" has been updated.', 'Update', null, array(htmlspecialchars($site->getName())), 1412371798); $this->unsetLastVisitedNodeAndRedirect('index'); }
/** * Collects all nodes with missing shadow nodes * * @param Workspace $workspace * @param boolean $dryRun * @param NodeType $nodeType * @return array */ protected function fixShadowNodesInWorkspace(Workspace $workspace, $dryRun, NodeType $nodeType = null) { $workspaces = array_merge([$workspace], $workspace->getBaseWorkspaces()); $fixedShadowNodes = 0; foreach ($workspaces as $workspace) { /** @var Workspace $workspace */ if ($workspace->getBaseWorkspace() === null) { continue; } /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->entityManager->createQueryBuilder(); $queryBuilder->select('n')->from(NodeData::class, 'n')->where('n.workspace = :workspace'); $queryBuilder->setParameter('workspace', $workspace->getName()); if ($nodeType !== null) { $queryBuilder->andWhere('n.nodeType = :nodeType'); $queryBuilder->setParameter('nodeType', $nodeType->getName()); } /** @var NodeData $nodeData */ foreach ($queryBuilder->getQuery()->getResult() as $nodeData) { $nodeDataSeenFromParentWorkspace = $this->nodeDataRepository->findOneByIdentifier($nodeData->getIdentifier(), $workspace->getBaseWorkspace(), $nodeData->getDimensionValues()); // This is the good case, either the node does not exist or was shadowed if ($nodeDataSeenFromParentWorkspace === null) { continue; } // Also good, the node was not moved at all. if ($nodeDataSeenFromParentWorkspace->getPath() === $nodeData->getPath()) { continue; } $nodeDataOnSamePath = $this->nodeDataRepository->findOneByPath($nodeData->getPath(), $workspace->getBaseWorkspace(), $nodeData->getDimensionValues(), null); // We cannot just put a shadow node in the path, something exists, but that should be fine. if ($nodeDataOnSamePath !== null) { continue; } if (!$dryRun) { $nodeData->createShadow($nodeDataSeenFromParentWorkspace->getPath()); } $fixedShadowNodes++; } } return $fixedShadowNodes; }
/** * Testcase for bug #34291 (ContentRepository reordering does not take unpersisted * node order changes into account) * * The error can be reproduced in the following way: * * - First, create some nodes, and persist. * - Then, move a node after another one, filling the LAST free sorting index between the nodes. Do NOT persist after that. * - After that, try to *again* move a node to this spot. In this case, we need to *renumber* * the node indices, and the system needs to take the before-moved node into account as well. * * The bug tested by this testcase led to wrong orderings on the floworg website in * the documentation part under some circumstances. * * @test */ public function renumberingTakesUnpersistedNodeOrderChangesIntoAccount() { $rootNode = $this->context->getRootNode(); $liveParentNode = $rootNode->createNode('parent-node'); $nodes = []; $nodes[1] = $liveParentNode->createNode('node001'); $nodes[1]->setIndex(1); $nodes[2] = $liveParentNode->createNode('node002'); $nodes[2]->setIndex(2); $nodes[3] = $liveParentNode->createNode('node003'); $nodes[3]->setIndex(4); $nodes[4] = $liveParentNode->createNode('node004'); $nodes[4]->setIndex(5); $this->nodeDataRepository->persistEntities(); $nodes[1]->moveAfter($nodes[2]); $nodes[3]->moveAfter($nodes[2]); $this->nodeDataRepository->persistEntities(); $actualChildNodes = $liveParentNode->getChildNodes(); $newNodeOrder = [$nodes[2], $nodes[3], $nodes[1], $nodes[4]]; $this->assertSameOrder($newNodeOrder, $actualChildNodes); }
/** * Delete an asset * * @param \Neos\Media\Domain\Model\Asset $asset * @return void */ public function deleteAction(\Neos\Media\Domain\Model\Asset $asset) { $relationMap = []; $relationMap[TypeHandling::getTypeForValue($asset)] = array($this->persistenceManager->getIdentifierByObject($asset)); if ($asset instanceof \Neos\Media\Domain\Model\Image) { foreach ($asset->getVariants() as $variant) { $type = TypeHandling::getTypeForValue($variant); if (!isset($relationMap[$type])) { $relationMap[$type] = []; } $relationMap[$type][] = $this->persistenceManager->getIdentifierByObject($variant); } } $relatedNodes = $this->nodeDataRepository->findNodesByRelatedEntities($relationMap); if (count($relatedNodes) > 0) { $this->addFlashMessage('Asset could not be deleted, because there are still Nodes using it.', '', Message::SEVERITY_WARNING, array(), 1412422767); $this->redirect('index'); } // FIXME: Resources are not deleted, because we cannot be sure that the resource isn't used anywhere else. $this->assetRepository->remove($asset); $this->addFlashMessage(sprintf('Asset "%s" has been deleted.', $asset->getLabel()), null, null, array(), 1412375050); $this->redirect('index'); }
/** * Returns the NodeData instance with the given identifier from the target workspace. * If no NodeData instance is found, null is returned. * * @param NodeInterface $node * @param Workspace $targetWorkspace * @return NodeData */ protected function findNodeDataInTargetWorkspace(NodeInterface $node, Workspace $targetWorkspace) { $nodeData = $this->nodeDataRepository->findOneByIdentifier($node->getIdentifier(), $targetWorkspace, $node->getDimensions()); return $nodeData === null || $nodeData->getWorkspace() === $targetWorkspace ? $nodeData : null; }
/** * {@inheritdoc} * * @param FlowQuery $flowQuery the FlowQuery object * @param array $arguments the arguments for this operation * @return void */ public function evaluate(FlowQuery $flowQuery, array $arguments) { $context = $flowQuery->getContext(); if (!isset($context[0]) || empty($arguments[0])) { return; } $result = array(); $selectorAndFilter = $arguments[0]; $parsedFilter = null; $parsedFilter = FizzleParser::parseFilterGroup($selectorAndFilter); if (isset($parsedFilter['Filters']) && $this->hasOnlyInstanceOfFilters($parsedFilter['Filters'])) { $nodeTypes = array(); foreach ($parsedFilter['Filters'] as $filter) { $nodeTypes[] = $filter['AttributeFilters'][0]['Operand']; } /** @var NodeInterface $contextNode */ foreach ($context as $contextNode) { $result = array_merge($result, $this->nodeDataRepository->findByParentAndNodeTypeInContext($contextNode->getPath(), implode(',', $nodeTypes), $contextNode->getContext(), true)); } } else { foreach ($parsedFilter['Filters'] as $filter) { $filterResults = array(); $generatedNodes = false; if (isset($filter['IdentifierFilter'])) { if (!preg_match(UuidValidator::PATTERN_MATCH_UUID, $filter['IdentifierFilter'])) { throw new FlowQueryException('find() requires a valid identifier', 1332492263); } /** @var NodeInterface $contextNode */ foreach ($context as $contextNode) { $filterResults = array($contextNode->getContext()->getNodeByIdentifier($filter['IdentifierFilter'])); } $generatedNodes = true; } elseif (isset($filter['PropertyNameFilter']) || isset($filter['PathFilter'])) { $nodePath = isset($filter['PropertyNameFilter']) ? $filter['PropertyNameFilter'] : $filter['PathFilter']; foreach ($context as $contextNode) { $node = $contextNode->getNode($nodePath); if ($node !== null) { array_push($filterResults, $node); } } $generatedNodes = true; } if (isset($filter['AttributeFilters']) && $filter['AttributeFilters'][0]['Operator'] === 'instanceof') { foreach ($context as $contextNode) { $filterResults = array_merge($filterResults, $this->nodeDataRepository->findByParentAndNodeTypeInContext($contextNode->getPath(), $filter['AttributeFilters'][0]['Operand'], $contextNode->getContext(), true)); } unset($filter['AttributeFilters'][0]); $generatedNodes = true; } if (isset($filter['AttributeFilters']) && count($filter['AttributeFilters']) > 0) { if (!$generatedNodes) { throw new FlowQueryException('find() needs an identifier, path or instanceof filter for the first filter part', 1436884196); } $filterQuery = new FlowQuery($filterResults); foreach ($filter['AttributeFilters'] as $attributeFilter) { $filterQuery->pushOperation('filter', array($attributeFilter['text'])); } $filterResults = $filterQuery->get(); } $result = array_merge($result, $filterResults); } } $flowQuery->setContext(array_unique($result)); }