/** * {@inheritdoc} */ public function createRedirectsForPublishedNode(NodeInterface $node, Workspace $targetWorkspace) { $nodeType = $node->getNodeType(); if ($targetWorkspace->getName() !== 'live' || !$nodeType->isOfType('Neos.Neos:Document')) { return; } $context = $this->contextFactory->create(['workspaceName' => 'live', 'invisibleContentShown' => true, 'dimensions' => $node->getContext()->getDimensions()]); $targetNode = $context->getNodeByIdentifier($node->getIdentifier()); if ($targetNode === null) { // The page has been added return; } $targetNodeUriPath = $this->buildUriPathForNodeContextPath($targetNode->getContextPath()); if ($targetNodeUriPath === null) { throw new Exception('The target URI path of the node could not be resolved', 1451945358); } $hosts = $this->getHostnames($node->getContext()); // The page has been removed if ($node->isRemoved()) { $this->flushRoutingCacheForNode($targetNode); $statusCode = (int) $this->defaultStatusCode['gone']; $this->redirectStorage->addRedirect($targetNodeUriPath, '', $statusCode, $hosts); return; } // compare the "old" node URI to the new one $nodeUriPath = $this->buildUriPathForNodeContextPath($node->getContextPath()); // use the same regexp than the ContentContextBar Ember View $nodeUriPath = preg_replace('/@[A-Za-z0-9;&,\\-_=]+/', '', $nodeUriPath); if ($nodeUriPath === null || $nodeUriPath === $targetNodeUriPath) { // The page node path has not been changed return; } $this->flushRoutingCacheForNode($targetNode); $statusCode = (int) $this->defaultStatusCode['redirect']; $this->redirectStorage->addRedirect($targetNodeUriPath, $nodeUriPath, $statusCode, $hosts); $q = new FlowQuery([$node]); foreach ($q->children('[instanceof Neos.Neos:Document]') as $childrenNode) { $this->createRedirectsForPublishedNode($childrenNode, $targetWorkspace); } }
/** * Filter a node by the current context. * Will either return the node or NULL if it is not permitted in current context. * * @param NodeInterface $node * @param Context $context * @return NodeInterface|NULL */ protected function filterNodeByContext(NodeInterface $node, Context $context) { $this->securityContext->withoutAuthorizationChecks(function () use(&$node, $context) { if (!$context->isRemovedContentShown() && $node->isRemoved()) { $node = null; return; } if (!$context->isInvisibleContentShown() && !$node->isVisible()) { $node = null; return; } if (!$context->isInaccessibleContentShown() && !$node->isAccessible()) { $node = null; } }); return $node; }
/** * Collects CSS class names used for styling editable elements in the Neos backend. * * @param NodeInterface $node * @return array */ protected function collectEditingClassNames(NodeInterface $node) { $classNames = []; if ($node->getNodeType()->isOfType('Neos.Neos:ContentCollection')) { // This is needed since the backend relies on this class (should not be necessary) $classNames[] = 'neos-contentcollection'; } else { $classNames[] = 'neos-contentelement'; } if ($node->isRemoved()) { $classNames[] = 'neos-contentelement-removed'; } if ($node->isHidden()) { $classNames[] = 'neos-contentelement-hidden'; } if ($this->isInlineEditable($node) === false) { $classNames[] = 'neos-not-inline-editable'; } return $classNames; }