/**
  * Resolves a shortcut node to the target. The return value can be
  *
  * * a NodeInterface instance if the target is a node or a node:// URI
  * * a string (in case the target is a plain text URI or an asset:// URI)
  * * NULL in case the shortcut cannot be resolved
  *
  * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $node
  * @return NodeInterface|string|NULL
  */
 public function resolveShortcutTarget(NodeInterface $node)
 {
     $infiniteLoopPrevention = 0;
     while ($node->getNodeType()->isOfType('TYPO3.Neos:Shortcut') && $infiniteLoopPrevention < 50) {
         $infiniteLoopPrevention++;
         switch ($node->getProperty('targetMode')) {
             case 'selectedTarget':
                 $target = $node->getProperty('target');
                 if ($this->linkingService->hasSupportedScheme($target)) {
                     $targetObject = $this->linkingService->convertUriToObject($target, $node);
                     if ($targetObject instanceof NodeInterface) {
                         $node = $targetObject;
                     } elseif ($targetObject instanceof AssetInterface) {
                         return $this->linkingService->resolveAssetUri($target);
                     }
                 } else {
                     return $target;
                 }
                 break;
             case 'parentNode':
                 $node = $node->getParent();
                 break;
             case 'firstChildNode':
             default:
                 $childNodes = $node->getChildNodes('TYPO3.Neos:Document');
                 if ($childNodes !== array()) {
                     $node = reset($childNodes);
                 } else {
                     return null;
                 }
         }
     }
     return $node;
 }
 /**
  * Redirects to the Neos backend on the given site, passing a one-time login token
  *
  * @param Site $site
  * @return void
  */
 public function switchSiteAction($site)
 {
     $token = Algorithms::generateRandomToken(32);
     $this->loginTokenCache->set($token, $this->currentSession->getId());
     $siteUri = $this->linkingService->createSiteUri($this->controllerContext, $site);
     $loginUri = $this->controllerContext->getUriBuilder()->reset()->uriFor('tokenLogin', ['token' => $token], 'Login', 'TYPO3.Neos');
     $this->redirectToUri($siteUri . $loginUri);
 }
示例#3
0
 public function uri(NodeInterface $node = null, ControllerContext $controllerContext)
 {
     if ($node === null) {
         // This happens when the document node os not published yet
         return '';
     }
     // Create an absolute URI without resolving shortcuts
     return $this->linkingService->createNodeUri($controllerContext, $node, null, null, true, array(), '', false, array(), false);
 }
 /**
  * @test
  */
 public function linkingServiceUnsetsLastLinkedNodeOnFailure()
 {
     $this->linkingService->createNodeUri($this->controllerContext, '/sites/example/home', $this->baseNode);
     $this->assertNotNull($this->linkingService->getLastLinkedNode());
     try {
         $this->linkingService->createNodeUri($this->controllerContext, '/sites/example/non-existing-node', $this->baseNode);
     } catch (NeosException $exception) {
     }
     $this->assertNull($this->linkingService->getLastLinkedNode());
 }
 private function sendNewsletter(NodeInterface $node, $previewEmail = NULL, $languageKey = NULL, array $languageConfiguration = NULL)
 {
     // The Receiver Group association is specified in each individual node dimension,
     // but as the user submitted it in a certain Node Dimension, we're using *exactly* this
     // $receiverGroup which the user has submitted.
     /* @var $receiverGroup \Sandstorm\Newsletter\Domain\Model\ReceiverGroup */
     $receiverGroup = $this->receiverGroupRepository->findByIdentifier($node->getProperty('receiverGroup'));
     if ($receiverGroup == NULL) {
         // TODO: log!
         return;
     }
     $context = ['workspaceName' => 'live'];
     if ($languageKey) {
         $context['dimensions'] = array('language' => $languageConfiguration['values']);
         $context['targetDimensions'] = array('language' => reset($languageConfiguration['values']));
     }
     /* @var $nodeInCorrectDimension NodeInterface */
     $nodeInCorrectDimension = (new FlowQuery(array($node)))->context($context)->get(0);
     if ($nodeInCorrectDimension == NULL) {
         // Skip un-existing nodes
         return;
     }
     $this->newsletterRenderingView->assign('value', $nodeInCorrectDimension);
     $html = $this->newsletterRenderingView->render();
     $html = $this->styleInliningService->inlineStyles($html);
     $newsletter = new Newsletter();
     $newsletterIdentifier = $node->getIdentifier();
     if ($languageKey) {
         $newsletterIdentifier .= '_' . $languageKey;
     }
     if ($previewEmail) {
         $newsletterIdentifier .= uniqid('__', true);
     }
     $newsletter->setIdentifier($newsletterIdentifier);
     $newsletter->setHtmlContent($html);
     $newsletter->setSubject($nodeInCorrectDimension->getProperty('subjectTemplate'));
     if ($previewEmail !== NULL) {
         $newsletter->setReceiverEmailTemplate($previewEmail);
         $newsletter->setReceiverGroup($receiverGroup->singlePersonReceiverGroup());
     } else {
         $newsletter->setReceiverEmailTemplate($nodeInCorrectDimension->getProperty('receiverEmailTemplate'));
         $newsletter->setReceiverGroup($receiverGroup);
     }
     $newsletter->setReceiverNameTemplate($nodeInCorrectDimension->getProperty('receiverNameTemplate'));
     $newsletter->setSenderEmailTemplate($nodeInCorrectDimension->getProperty('senderEmailTemplate'));
     $newsletter->setSenderNameTemplate($nodeInCorrectDimension->getProperty('senderNameTemplate'));
     $newsletter->setReplyToEmailTemplate($nodeInCorrectDimension->getProperty('replyToEmailTemplate'));
     $newsletter->setNewsletterLink($this->linkingService->createNodeUri($this->getControllerContext(), $nodeInCorrectDimension, NULL, NULL, TRUE));
     $unsubscribeListIdentifier = null;
     if ($receiverGroup->getUnsubscribeList()) {
         $unsubscribeListIdentifier = $this->persistenceManager->getIdentifierByObject($receiverGroup->getUnsubscribeList());
     }
     $newsletter->setUnsubscribeLink($this->uriBuilder->reset()->setCreateAbsoluteUri(TRUE)->uriFor('unsubscribe', array('unsubscribeList' => $unsubscribeListIdentifier), 'Unsubscribe', 'Sandstorm.Newsletter'));
     $this->newsletterSendingService->sendNewsletter($newsletter, $languageKey);
 }
示例#6
0
 /**
  * Resolve an URI for the given node in the live workspace (this is where analytics usually are collected)
  *
  * @param NodeInterface $node
  * @param ControllerContext $controllerContext
  * @return \TYPO3\Flow\Http\Uri
  * @throws StatisticsNotAvailableException If the node was not yet published and no live workspace URI can be resolved
  */
 protected function getLiveNodeUri(NodeInterface $node, ControllerContext $controllerContext)
 {
     $contextProperties = $node->getContext()->getProperties();
     $contextProperties['workspaceName'] = 'live';
     $liveContext = $this->contextFactory->create($contextProperties);
     $liveNode = $liveContext->getNodeByIdentifier($node->getIdentifier());
     if ($liveNode === NULL) {
         throw new StatisticsNotAvailableException('Piwik Statistics are only available on a published node', 1445812693);
     }
     $nodeUriString = $this->linkingService->createNodeUri($controllerContext, $liveNode, NULL, 'html', TRUE);
     $nodeUri = new \TYPO3\Flow\Http\Uri($nodeUriString);
     return $nodeUri;
 }
 /**
  * Render the Uri.
  *
  * @return string The rendered URI or NULL if no URI could be resolved for the given node
  * @throws NeosException
  */
 public function evaluate()
 {
     $baseNode = null;
     $baseNodeName = $this->getBaseNodeName() ?: 'documentNode';
     $currentContext = $this->tsRuntime->getCurrentContext();
     if (isset($currentContext[$baseNodeName])) {
         $baseNode = $currentContext[$baseNodeName];
     } else {
         throw new NeosException(sprintf('Could not find a node instance in TypoScript context with name "%s" and no node instance was given to the node argument. Set a node instance in the TypoScript context or pass a node object to resolve the URI.', $baseNodeName), 1373100400);
     }
     try {
         return $this->linkingService->createNodeUri($this->tsRuntime->getControllerContext(), $this->getNode(), $baseNode, $this->getFormat(), $this->isAbsolute(), $this->getAdditionalParams(), $this->getSection(), $this->getAddQueryString(), $this->getArgumentsToBeExcludedFromQueryString());
     } catch (NeosException $exception) {
         $this->systemLogger->logException($exception);
         return '';
     }
 }
 /**
  * This test checks that targets for resource links are correctly replaced
  *
  * @test
  */
 public function evaluateReplaceResourceLinkTargets()
 {
     $assetIdentifier = 'aeabe76a-551a-495f-a324-ad9a86b2aff8';
     $resourceLinkTarget = '_blank';
     $value = 'This string contains two asset links and an external link: one with a target set <a target="top" href="asset://' . $assetIdentifier . '">example</a> and one without a target <a href="asset://' . $assetIdentifier . '">example2</a> and an external link <a href="http://www.example.org">example3</a>';
     $this->addValueExpectation($value, null, false, null, $resourceLinkTarget);
     $this->mockWorkspace->expects($this->any())->method('getName')->will($this->returnValue('live'));
     $self = $this;
     $this->mockLinkingService->expects($this->atLeastOnce())->method('resolveAssetUri')->will($this->returnCallback(function ($assetUri) use($self, $assetIdentifier) {
         if ($assetUri !== 'asset://' . $assetIdentifier) {
             $self->fail('Unexpected asset URI "' . $assetUri . '"');
         }
         return 'http://localhost/_Resources/01';
     }));
     $expectedResult = 'This string contains two asset links and an external link: one with a target set <a target="' . $resourceLinkTarget . '" href="http://localhost/_Resources/01">example</a> and one without a target <a target="' . $resourceLinkTarget . '" href="http://localhost/_Resources/01">example2</a> and an external link <a href="http://www.example.org">example3</a>';
     $actualResult = $this->convertUrisImplementation->evaluate();
     $this->assertSame($expectedResult, $actualResult);
 }
示例#9
0
 /**
  * Build a json serializable tree structure containing node information
  *
  * @return array
  */
 public function build($includeRoot = false, $root = null, $depth = null)
 {
     $root = $root === null ? $this->getRoot() : $root;
     $depth = $depth === null ? $this->depth : $depth;
     $result = [];
     /** @var NodeInterface $childNode */
     foreach ($root->getChildNodes($this->nodeTypeFilter) as $childNode) {
         $hasChildNodes = $childNode->hasChildNodes($this->nodeTypeFilter);
         $shouldLoadChildNodes = $hasChildNodes && ($depth > 1 || $this->isInRootLine($this->active, $childNode));
         $result[$childNode->getName()] = ['label' => $childNode->getNodeType()->isOfType('TYPO3.Neos:Document') ? $childNode->getProperty('title') : $childNode->getLabel(), 'contextPath' => $childNode->getContextPath(), 'nodeType' => $childNode->getNodeType()->getName(), 'hasChildren' => $hasChildNodes, 'isActive' => $this->active && $childNode->getPath() === $this->active->getPath(), 'isFocused' => $this->active && $childNode->getPath() === $this->active->getPath(), 'isCollapsed' => !$shouldLoadChildNodes, 'isCollapsable' => $hasChildNodes];
         if ($shouldLoadChildNodes) {
             $result[$childNode->getName()]['children'] = $this->build(false, $childNode, $depth - 1);
         }
         if ($childNode->getNodeType()->isOfType('TYPO3.Neos:Document')) {
             $result[$childNode->getName()]['href'] = $this->linkingService->createNodeUri($this->controllerContext, $childNode, null, null, true, [], '', false, [], false);
         }
     }
     if ($includeRoot) {
         return [$root->getName() => ['label' => $root->getNodeType()->isOfType('TYPO3.Neos:Document') ? $root->getProperty('title') : $root->getLabel(), 'icon' => 'globe', 'contextPath' => $root->getContextPath(), 'nodeType' => $root->getNodeType()->getName(), 'hasChildren' => count($result), 'isCollapsed' => false, 'isActive' => $this->active && $root->getPath() === $this->active->getPath(), 'isFocused' => $this->active && $root->getPath() === $this->active->getPath(), 'children' => $result]];
     }
     return $result;
 }
 public function uri(NodeInterface $node, ControllerContext $controllerContext)
 {
     return $this->linkingService->createNodeUri($controllerContext, $node);
 }
示例#11
0
 public function uri(NodeInterface $node, ControllerContext $controllerContext)
 {
     // Create an absolute URI without resolving shortcuts
     return $this->linkingService->createNodeUri($controllerContext, $node, null, null, true, array(), '', false, array(), false);
 }
 /**
  * @param $pagenum
  */
 protected function buildUrl($pagenum)
 {
     $params = $this->controllerContext->getRequest()->getArguments();
     $params[$this->offsetParamName] = $this->itemsPerPage * ($pagenum - 1);
     return $this->linkingService->createNodeUri($this->controllerContext, $params['node'], null, null, $this->absoluteUrl, $params);
 }
 /**
  * @param string|Uri $uri
  * @param NodeInterface $contextNode
  * @return NodeInterface|AssetInterface|NULL
  */
 public function convertUriToObject($uri, NodeInterface $contextNode = null)
 {
     return $this->linkingService->convertUriToObject($uri, $contextNode);
 }
 /**
  * Renders the link. Renders the linked node's label if there's no child content.
  *
  * @param mixed $node A node object or a string node path or NULL to resolve the current document node
  * @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 The anchor to be added to the URI
  * @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 string $nodeVariableName The variable the node will be assigned to for the rendered child content
  * @param string $baseNodeName The name of the base node inside the TypoScript context to use for the ContentContext or resolving relative paths
  * @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 link
  * @throws ViewHelperException
  */
 public function render($node = NULL, $format = NULL, $absolute = FALSE, array $arguments = array(), $section = '', $addQueryString = FALSE, array $argumentsToBeExcludedFromQueryString = array(), $baseNodeName = 'documentNode', $nodeVariableName = 'linkedNode', $resolveShortcuts = TRUE)
 {
     $baseNode = NULL;
     if (!$node instanceof NodeInterface) {
         $view = $this->viewHelperVariableContainer->getView();
         if ($view instanceof TypoScriptAwareViewInterface) {
             $typoScriptObject = $view->getTypoScriptObject();
             $currentContext = $typoScriptObject->getTsRuntime()->getCurrentContext();
             if (isset($currentContext[$baseNodeName])) {
                 $baseNode = $currentContext[$baseNodeName];
             }
         }
     }
     try {
         $uri = $this->linkingService->createNodeUri($this->controllerContext, $node, $baseNode, $format, $absolute, $arguments, $section, $addQueryString, $argumentsToBeExcludedFromQueryString, $resolveShortcuts);
         $this->tag->addAttribute('href', $uri);
     } catch (NeosException $exception) {
         $this->systemLogger->logException($exception);
     }
     $linkedNode = $this->linkingService->getLastLinkedNode();
     $this->templateVariableContainer->add($nodeVariableName, $linkedNode);
     $content = $this->renderChildren();
     $this->templateVariableContainer->remove($nodeVariableName, $linkedNode);
     if ($content === NULL && $linkedNode !== NULL) {
         $content = $linkedNode->getLabel();
     }
     $this->tag->setContent($content);
     $this->tag->forceClosingTag(TRUE);
     return $this->tag->render();
 }
 /**
  * Renders the link. Renders the linked node's label if there's no child content.
  *
  * @param mixed $node A node object or a string node path or NULL to resolve the current document node
  * @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 The anchor to be added to the URI
  * @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 string $nodeVariableName The variable the node will be assigned to for the rendered child content
  * @param string $baseNodeName The name of the base node inside the TypoScript context to use for the ContentContext or resolving relative paths
  * @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 link
  * @throws ViewHelperException
  */
 public function render($node = null, $format = null, $absolute = false, array $arguments = array(), $section = '', $addQueryString = false, array $argumentsToBeExcludedFromQueryString = array(), $baseNodeName = 'documentNode', $nodeVariableName = 'linkedNode', $resolveShortcuts = true)
 {
     $baseNode = null;
     if (!$node instanceof NodeInterface) {
         $baseNode = $this->getContextVariable($baseNodeName);
     }
     try {
         $uri = $this->linkingService->createNodeUri($this->controllerContext, $node, $baseNode, $format, $absolute, $arguments, $section, $addQueryString, $argumentsToBeExcludedFromQueryString, $resolveShortcuts);
         $this->tag->addAttribute('href', $uri);
     } catch (NeosException $exception) {
         $this->systemLogger->logException($exception);
     } catch (NoMatchingRouteException $exception) {
         $this->systemLogger->logException($exception);
     }
     $linkedNode = $this->linkingService->getLastLinkedNode();
     $this->templateVariableContainer->add($nodeVariableName, $linkedNode);
     $content = $this->renderChildren();
     $this->templateVariableContainer->remove($nodeVariableName);
     if ($content === null && $linkedNode !== null) {
         $content = $linkedNode->getLabel();
     }
     $this->tag->setContent($content);
     $this->tag->forceClosingTag(true);
     return $this->tag->render();
 }
 /**
  * Renders the URI.
  *
  * @param mixed $node A node object or a string node path (absolute or relative) or NULL to resolve the current document node
  * @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 string $baseNodeName The name of the base node inside the TypoScript context to use for the ContentContext or resolving relative paths
  * @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 or NULL if no URI could be resolved for the given node
  * @throws ViewHelperException
  */
 public function render($node = null, $format = null, $absolute = false, array $arguments = array(), $section = '', $addQueryString = false, array $argumentsToBeExcludedFromQueryString = array(), $baseNodeName = 'documentNode', $resolveShortcuts = true)
 {
     $baseNode = null;
     if (!$node instanceof NodeInterface) {
         $view = $this->viewHelperVariableContainer->getView();
         if ($view instanceof TypoScriptAwareViewInterface) {
             /** @var TemplateImplementation $typoScriptObject */
             $typoScriptObject = $view->getTypoScriptObject();
             $currentContext = $typoScriptObject->getTsRuntime()->getCurrentContext();
             if (isset($currentContext[$baseNodeName])) {
                 $baseNode = $currentContext[$baseNodeName];
             }
         }
     }
     try {
         return $this->linkingService->createNodeUri($this->controllerContext, $node, $baseNode, $format, $absolute, $arguments, $section, $addQueryString, $argumentsToBeExcludedFromQueryString, $resolveShortcuts);
     } catch (NeosException $exception) {
         $this->systemLogger->logException($exception);
         return '';
     }
 }
 /**
  * Renders the URI.
  *
  * @param mixed $node A node object or a string node path (absolute or relative) or NULL to resolve the current document node
  * @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 string $baseNodeName The name of the base node inside the TypoScript context to use for the ContentContext or resolving relative paths
  * @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 or NULL if no URI could be resolved for the given node
  * @throws ViewHelperException
  */
 public function render($node = null, $format = null, $absolute = false, array $arguments = array(), $section = '', $addQueryString = false, array $argumentsToBeExcludedFromQueryString = array(), $baseNodeName = 'documentNode', $resolveShortcuts = true)
 {
     $baseNode = null;
     if (!$node instanceof NodeInterface) {
         $baseNode = $this->getContextVariable($baseNodeName);
     }
     try {
         return $this->linkingService->createNodeUri($this->controllerContext, $node, $baseNode, $format, $absolute, $arguments, $section, $addQueryString, $argumentsToBeExcludedFromQueryString, $resolveShortcuts);
     } catch (NeosException $exception) {
         $this->systemLogger->logException($exception);
     } catch (NoMatchingRouteException $exception) {
         $this->systemLogger->logException($exception);
     }
     return '';
 }