/**
* Renders the URI to a given node instance or -path.
*
* @param ControllerContext $controllerContext
* @param mixed $node A node object or a string node path, if a relative path is provided the baseNode argument is required
* @param NodeInterface $baseNode
* @param string $format Format to use for the URL, for example "html" or "json"
* @param boolean $absolute If set, an absolute URI is rendered
* @param array $arguments Additional arguments to be passed to the UriBuilder (for example pagination parameters)
* @param string $section
* @param boolean $addQueryString If set, the current query parameters will be kept in the URI
* @param array $argumentsToBeExcludedFromQueryString arguments to be removed from the URI. Only active if $addQueryString = TRUE
* @param boolean $resolveShortcuts INTERNAL Parameter - if FALSE, shortcuts are not redirected to their target. Only needed on rare backend occasions when we want to link to the shortcut itself.
* @return string The rendered URI
* @throws \InvalidArgumentException if the given node/baseNode is not valid
* @throws NeosException if no URI could be resolved for the given node
*/
public function createNodeUri(ControllerContext $controllerContext, $node = null, NodeInterface $baseNode = null, $format = null, $absolute = false, array $arguments = array(), $section = '', $addQueryString = false, array $argumentsToBeExcludedFromQueryString = array(), $resolveShortcuts = true)
{
$this->lastLinkedNode = null;
if (!($node instanceof NodeInterface || is_string($node) || $baseNode instanceof NodeInterface)) {
throw new \InvalidArgumentException('Expected an instance of NodeInterface or a string for the node argument, or alternatively a baseNode argument.', 1373101025);
}
if (is_string($node)) {
$nodeString = $node;
if ($nodeString === '') {
throw new NeosException(sprintf('Empty strings can not be resolved to nodes.', $nodeString), 1415709942);
}
preg_match(NodeInterface::MATCH_PATTERN_CONTEXTPATH, $nodeString, $matches);
if (isset($matches['WorkspaceName']) && $matches['WorkspaceName'] !== '') {
$node = $this->propertyMapper->convert($nodeString, NodeInterface::class);
} else {
if ($baseNode === null) {
throw new NeosException('The baseNode argument is required for linking to nodes with a relative path.', 1407879905);
}
/** @var ContentContext $contentContext */
$contentContext = $baseNode->getContext();
$normalizedPath = $this->nodeService->normalizePath($nodeString, $baseNode->getPath(), $contentContext->getCurrentSiteNode()->getPath());
$node = $contentContext->getNode($normalizedPath);
}
if (!$node instanceof NodeInterface) {
throw new NeosException(sprintf('The string "%s" could not be resolved to an existing node.', $nodeString), 1415709674);
}
} elseif (!$node instanceof NodeInterface) {
$node = $baseNode;
}
if (!$node instanceof NodeInterface) {
throw new NeosException(sprintf('Node must be an instance of NodeInterface or string, given "%s".', gettype($node)), 1414772029);
}
$this->lastLinkedNode = $node;
if ($resolveShortcuts === true) {
$resolvedNode = $this->nodeShortcutResolver->resolveShortcutTarget($node);
} else {
// this case is only relevant in extremely rare occasions in the Neos Backend, when we want to generate
// a link towards the *shortcut itself*, and not to its target.
$resolvedNode = $node;
}
if (is_string($resolvedNode)) {
return $resolvedNode;
}
if (!$resolvedNode instanceof NodeInterface) {
throw new NeosException(sprintf('Could not resolve shortcut target for node "%s"', $node->getPath()), 1414771137);
}
/** @var ActionRequest $request */
$request = $controllerContext->getRequest()->getMainRequest();
$uriBuilder = clone $controllerContext->getUriBuilder();
$uriBuilder->setRequest($request);
$uri = $uriBuilder->reset()->setSection($section)->setArguments($arguments)->setAddQueryString($addQueryString)->setArgumentsToBeExcludedFromQueryString($argumentsToBeExcludedFromQueryString)->setFormat($format ?: $request->getFormat())->uriFor('show', array('node' => $resolvedNode), 'Frontend\\Node', 'Neos.Neos');
$siteNode = $resolvedNode->getContext()->getCurrentSiteNode();
if (NodePaths::isSubPathOf($siteNode->getPath(), $resolvedNode->getPath())) {
/** @var Site $site */
$site = $resolvedNode->getContext()->getCurrentSite();
} else {
$nodePath = NodePaths::getRelativePathBetween(SiteService::SITES_ROOT_PATH, $resolvedNode->getPath());
list($siteNodeName) = explode('/', $nodePath);
$site = $this->siteRepository->findOneByNodeName($siteNodeName);
}
if ($site->hasActiveDomains()) {
$requestUriHost = $request->getHttpRequest()->getBaseUri()->getHost();
$activeHostPatterns = $site->getActiveDomains()->map(function ($domain) {
return $domain->getHostPattern();
})->toArray();
if (!in_array($requestUriHost, $activeHostPatterns, true)) {
$uri = $this->createSiteUri($controllerContext, $site) . '/' . ltrim($uri, '/');
} elseif ($absolute === true) {
$uri = $request->getHttpRequest()->getBaseUri() . ltrim($uri, '/');
}
} elseif ($absolute === true) {
$uri = $request->getHttpRequest()->getBaseUri() . ltrim($uri, '/');
}
return $uri;
}