/**
  * 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;
 }
Example #12
0
 /**
  * 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;
 }
Example #15
0
 /**
  * Finds all nodes lying on the path specified by (and including) the given
  * starting point and end point.
  *
  * @param mixed $startingPoint Either an absolute path or an actual node specifying the starting point, for example /sites/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]);
 }