/** * Add the current node and all parent identifiers to be used for cache entry tagging * * @Flow\Before("method(TYPO3\Flow\Mvc\Routing\RouterCachingService->extractUuids())") * @param \TYPO3\Flow\Aop\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); }); }
/** * Converts a given context path to a node object * * @param string $contextPath * @return NodeInterface */ public function getNodeFromContextPath($contextPath, Site $site = null, Domain $domain = null) { $nodePathAndContext = NodePaths::explodeContextPath($contextPath); $nodePath = $nodePathAndContext['nodePath']; $workspaceName = $nodePathAndContext['workspaceName']; $dimensions = $nodePathAndContext['dimensions']; $contextProperties = $this->prepareContextProperties($workspaceName, $dimensions); if ($site === null) { list(, , $siteNodeName) = explode('/', $nodePath); $site = $this->siteRepository->findOneByNodeName($siteNodeName); } if ($domain === null) { $domain = $this->domainRepository->findOneBySite($site); } $contextProperties['currentSite'] = $site; $contextProperties['currentDomain'] = $domain; $context = $this->contextFactory->create($contextProperties); $workspace = $context->getWorkspace(false); if (!$workspace) { return new \TYPO3\Flow\Error\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), 1451392329); } return $context->getNode($nodePath); }
/** * @param string $path an absolute or relative node path which possibly contains context information, for example "/sites/somesite/the/node/path@some-workspace" * @return string the same path without context information */ protected function removeContextFromPath($path) { if ($path === '' || NodePaths::isContextPath($path) === FALSE) { return $path; } try { $nodePathAndContext = NodePaths::explodeContextPath($path); return $nodePathAndContext['nodePath']; } catch (\InvalidArgumentException $exception) { } return NULL; }
/** * @param string $path an absolute or relative node path which possibly contains context information, for example "/sites/somesite/the/node/path@some-workspace" * @return string the same path without context information */ protected function removeContextFromPath($path) { if ($path === '' || NodePaths::isContextPath($path) === false) { return $path; } try { $nodePathAndContext = NodePaths::explodeContextPath($path); // This is a workaround as we potentially prepend the context path with "/" in buildContextFromRequestPath to create a valid context path, // the code in this class expects an empty nodePath though for the site node, so we remove it again at this point. return $nodePathAndContext['nodePath'] === '/' ? '' : $nodePathAndContext['nodePath']; } catch (\InvalidArgumentException $exception) { } return null; }
/** * 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 \TYPO3\Flow\Error\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; }