getContext() публичный Метод

Return the context of the node
public getContext ( ) : Context
Результат Neos\ContentRepository\Domain\Service\Context
 /**
  * Shows the specified node and takes visibility and access restrictions into
  * account.
  *
  * @param NodeInterface $node
  * @return string View output for the specified node
  * @Flow\SkipCsrfProtection We need to skip CSRF protection here because this action could be called with unsafe requests from widgets or plugins that are rendered on the node - For those the CSRF token is validated on the sub-request, so it is safe to be skipped here
  * @Flow\IgnoreValidation("node")
  * @throws NodeNotFoundException
  */
 public function showAction(NodeInterface $node = null)
 {
     if ($node === null) {
         throw new NodeNotFoundException('The requested node does not exist or isn\'t accessible to the current user', 1430218623);
     }
     $inBackend = $node->getContext()->isInBackend();
     if ($node->getNodeType()->isOfType('Neos.Neos:Shortcut') && !$inBackend) {
         $this->handleShortcutNode($node);
     }
     $this->view->assign('value', $node);
     if ($inBackend) {
         $this->overrideViewVariablesFromInternalArguments();
         /** @var UserInterfaceMode $renderingMode */
         $renderingMode = $node->getContext()->getCurrentRenderingMode();
         $this->response->setHeader('Cache-Control', 'no-cache');
         if ($renderingMode !== null) {
             // Deprecated TypoScript context variable from version 2.0.
             $this->view->assign('editPreviewMode', $renderingMode->getTypoScriptPath());
         }
         if (!$this->view->canRenderWithNodeAndPath()) {
             $this->view->setTypoScriptPath('rawContent');
         }
     }
     if ($this->session->isStarted() && $inBackend) {
         $this->session->putData('lastVisitedNode', $node->getContextPath());
     }
 }
 /**
  * Generates a URI path segment for a given node taking it's language dimension into account
  *
  * @param NodeInterface $node Optional node to determine language dimension
  * @param string $text Optional text
  * @return string
  */
 public function generateUriPathSegment(NodeInterface $node = null, $text = null)
 {
     if ($node) {
         $text = $text ?: $node->getLabel() ?: $node->getName();
         $dimensions = $node->getContext()->getDimensions();
         if (array_key_exists('language', $dimensions) && $dimensions['language'] !== array()) {
             $locale = new Locale($dimensions['language'][0]);
             $language = $locale->getLanguage();
         }
     } elseif (strlen($text) === 0) {
         throw new Exception('Given text was empty.', 1457591815);
     }
     $text = $this->transliterationService->transliterate($text, isset($language) ? $language : null);
     return Transliterator::urlize($text);
 }
 /**
  * Wrap the $content identified by $node with the needed markup for the backend.
  *
  * @param NodeInterface $node
  * @param string $property
  * @param string $content
  * @return string
  */
 public function wrapContentProperty(NodeInterface $node, $property, $content)
 {
     /** @var $contentContext ContentContext */
     $contentContext = $node->getContext();
     if ($contentContext->getWorkspaceName() === 'live' || !$this->privilegeManager->isPrivilegeTargetGranted('Neos.Neos:Backend.GeneralAccess')) {
         return $content;
     }
     if (!$this->nodeAuthorizationService->isGrantedToEditNode($node)) {
         return $content;
     }
     $attributes = array();
     $attributes['class'] = 'neos-inline-editable';
     $attributes['property'] = 'typo3:' . $property;
     $attributes['data-neos-node-type'] = $node->getNodeType()->getName();
     return $this->htmlAugmenter->addAttributes($content, $attributes, 'span');
 }
 /**
  * Matches if the currently-selected preset in the passed $dimensionName is one of $presets.
  *
  * Example: isInDimensionPreset('language', 'de') checks whether the currently-selected language
  * preset (in the Neos backend) is "de".
  *
  * Implementation Note: We deliberately work on the Dimension Preset Name, and not on the
  * dimension values itself; as the preset is user-visible and the actual dimension-values
  * for a preset are just implementation details.
  *
  * @param string $dimensionName
  * @param string|array $presets
  * @return boolean
  */
 public function isInDimensionPreset($dimensionName, $presets)
 {
     if ($this->node === null) {
         return true;
     }
     $dimensionValues = $this->node->getContext()->getDimensions();
     if (!isset($dimensionValues[$dimensionName])) {
         return false;
     }
     $preset = $this->contentDimensionPresetSource->findPresetByDimensionValues($dimensionName, $dimensionValues[$dimensionName]);
     if ($preset === null) {
         return false;
     }
     $presetIdentifier = $preset['identifier'];
     if (!is_array($presets)) {
         $presets = array($presets);
     }
     return in_array($presetIdentifier, $presets);
 }
Пример #5
0
 /**
  * Returns the rendered content of this plugin
  *
  * @return string The rendered content as a string
  * @throws StopActionException
  */
 public function evaluate()
 {
     $currentContext = $this->tsRuntime->getCurrentContext();
     $this->pluginViewNode = $currentContext['node'];
     /** @var $parentResponse Response */
     $parentResponse = $this->tsRuntime->getControllerContext()->getResponse();
     $pluginResponse = new Response($parentResponse);
     $pluginRequest = $this->buildPluginRequest();
     if ($pluginRequest->getControllerObjectName() === '') {
         $message = 'Master View not selected';
         if ($this->pluginViewNode->getProperty('plugin')) {
             $message = 'Plugin View not selected';
         }
         if ($this->pluginViewNode->getProperty('view')) {
             $message = 'Master View or Plugin View not found';
         }
         return $this->pluginViewNode->getContext()->getWorkspaceName() !== 'live' || $this->objectManager->getContext()->isDevelopment() ? '<p>' . $message . '</p>' : '<!-- ' . $message . '-->';
     }
     $this->dispatcher->dispatch($pluginRequest, $pluginResponse);
     return $pluginResponse->getContent();
 }
 /**
  * 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;
 }
Пример #7
0
 /**
  * Node Level relative to site root node.
  * 0 = Site root node
  *
  * @param NodeInterface $node
  * @return integer
  */
 protected function getNodeLevelInSite(NodeInterface $node)
 {
     $siteNode = $this->currentNode->getContext()->getCurrentSiteNode();
     return $node->getDepth() - $siteNode->getDepth();
 }
 /**
  * returns a specific view node of an master plugin
  * or NULL if it does not exist
  *
  * @param NodeInterface $node
  * @param string $viewName
  * @return NodeInterface
  */
 public function getPluginViewNodeByMasterPlugin(NodeInterface $node, $viewName)
 {
     /** @var $context ContentContext */
     $context = $node->getContext();
     foreach ($this->getNodes(['Neos.Neos:PluginView'], $context) as $pluginViewNode) {
         /** @var NodeInterface $pluginViewNode */
         if ($pluginViewNode->isRemoved()) {
             continue;
         }
         if ($pluginViewNode->getProperty('plugin') === $node->getIdentifier() && $pluginViewNode->getProperty('view') === $viewName) {
             return $pluginViewNode;
         }
     }
     return null;
 }
Пример #9
0
 /**
  * Returns a merged TypoScript object tree in the context of the given nodes
  *
  * @param \Neos\ContentRepository\Domain\Model\NodeInterface $startNode Node marking the starting point
  * @return array The merged object tree as of the given node
  * @throws \Neos\Neos\Domain\Exception
  */
 public function getMergedTypoScriptObjectTree(NodeInterface $startNode)
 {
     $contentContext = $startNode->getContext();
     $siteResourcesPackageKey = $contentContext->getCurrentSite()->getSiteResourcesPackageKey();
     $siteRootTypoScriptPathAndFilename = sprintf($this->siteRootTypoScriptPattern, $siteResourcesPackageKey);
     $siteRootTypoScriptCode = $this->readExternalTypoScriptFile($siteRootTypoScriptPathAndFilename);
     if ($siteRootTypoScriptCode === '') {
         $siteRootTypoScriptPathAndFilename = sprintf($this->legacySiteRootTypoScriptPattern, $siteResourcesPackageKey);
         $siteRootTypoScriptCode = $this->readExternalTypoScriptFile($siteRootTypoScriptPathAndFilename);
     }
     $mergedTypoScriptCode = '';
     $mergedTypoScriptCode .= $this->generateNodeTypeDefinitions();
     $mergedTypoScriptCode .= $this->getTypoScriptIncludes($this->prepareAutoIncludeTypoScript());
     $mergedTypoScriptCode .= $this->getTypoScriptIncludes($this->prependTypoScriptIncludes);
     $mergedTypoScriptCode .= $siteRootTypoScriptCode;
     $mergedTypoScriptCode .= $this->getTypoScriptIncludes($this->appendTypoScriptIncludes);
     return $this->typoScriptParser->parse($mergedTypoScriptCode, $siteRootTypoScriptPathAndFilename);
 }
Пример #10
0
 /**
  * Adopts a node from a (possibly) different context to this context
  *
  * Checks if a node variant matching the exact dimensions already exists for this context and
  * return it if found. Otherwise a new node variant for this context is created.
  *
  * In case the node already exists in the context but does not match the target dimensions a
  * new, more specific node is created and returned.
  *
  * @param NodeInterface $node The node with a different context. If the context of the given node is the same as this context the operation will have no effect.
  * @param boolean $recursive If TRUE also adopt all descendant nodes which are non-aggregate
  * @return NodeInterface A new or existing node that matches this context
  */
 public function adoptNode(NodeInterface $node, $recursive = false)
 {
     if ($node->getContext() === $this && $node->dimensionsAreMatchingTargetDimensionValues()) {
         return $node;
     }
     $this->emitBeforeAdoptNode($node, $this, $recursive);
     $existingNode = $this->getNodeByIdentifier($node->getIdentifier());
     if ($existingNode !== null) {
         if ($existingNode->dimensionsAreMatchingTargetDimensionValues()) {
             $adoptedNode = $existingNode;
         } else {
             $adoptedNode = $existingNode->createVariantForContext($this);
         }
     } else {
         $adoptedNode = $node->createVariantForContext($this);
     }
     $this->firstLevelNodeCache->setByIdentifier($adoptedNode->getIdentifier(), $adoptedNode);
     if ($recursive) {
         $childNodes = $node->getChildNodes();
         /** @var NodeInterface $childNode */
         foreach ($childNodes as $childNode) {
             if (!$childNode->getNodeType()->isAggregate()) {
                 $this->adoptNode($childNode, true);
             }
         }
     }
     $this->emitAfterAdoptNode($node, $this, $recursive);
     return $adoptedNode;
 }
 /**
  * @param NodeInterface $node
  * @param boolean $renderCurrentDocumentMetadata
  * @return boolean
  */
 protected function needsMetadata(NodeInterface $node, $renderCurrentDocumentMetadata)
 {
     /** @var $contentContext ContentContext */
     $contentContext = $node->getContext();
     return $contentContext->isInBackend() === true && ($renderCurrentDocumentMetadata === true || $this->nodeAuthorizationService->isGrantedToEditNode($node) === true);
 }
 /**
  * {@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);
     }
 }
Пример #13
0
 /**
  * Create a recursive copy of this node below $referenceNode with $nodeName.
  *
  * $detachedCopy only has an influence if we are copying from one dimension to the other, possibly creating a new
  * node variant:
  *
  * - If $detachedCopy is TRUE, the whole (recursive) copy is done without connecting original and copied node,
  *   so NOT CREATING a new node variant.
  * - If $detachedCopy is FALSE, and the node does not yet have a variant in the target dimension, we are CREATING
  *   a new node variant.
  *
  * As a caller of this method, $detachedCopy should be TRUE if $this->getNodeType()->isAggregate() is TRUE, and FALSE
  * otherwise.
  *
  * @param NodeInterface $referenceNode
  * @param boolean $detachedCopy
  * @param string $nodeName
  * @return NodeInterface
  */
 protected function createRecursiveCopy(NodeInterface $referenceNode, $nodeName, $detachedCopy)
 {
     $identifier = null;
     $referenceNodeDimensions = $referenceNode->getDimensions();
     $referenceNodeDimensionsHash = Utility::sortDimensionValueArrayAndReturnDimensionsHash($referenceNodeDimensions);
     $thisDimensions = $this->getDimensions();
     $thisNodeDimensionsHash = Utility::sortDimensionValueArrayAndReturnDimensionsHash($thisDimensions);
     if ($detachedCopy === false && $referenceNodeDimensionsHash !== $thisNodeDimensionsHash && $referenceNode->getContext()->getNodeByIdentifier($this->getIdentifier()) === null) {
         // If the target dimensions are different than this one, and there is no node shadowing this one in the target dimension yet, we use the same
         // node identifier, effectively creating a new node variant.
         $identifier = $this->getIdentifier();
     }
     $copiedNode = $referenceNode->createSingleNode($nodeName, null, $identifier);
     $copiedNode->similarize($this, true);
     /** @var $childNode Node */
     foreach ($this->getChildNodes() as $childNode) {
         // Prevent recursive copy when copying into itself
         if ($childNode->getIdentifier() !== $copiedNode->getIdentifier()) {
             $childNode->copyIntoInternal($copiedNode, $childNode->getName(), $detachedCopy);
         }
     }
     return $copiedNode;
 }
 /**
  * Resolves the request path, also known as route path, identifying the given node.
  *
  * A path is built, based on the uri path segment properties of the parents of and the given node itself.
  * If content dimensions are configured, the first path segment will the identifiers of the dimension
  * values according to the current context.
  *
  * @param NodeInterface $node The node where the generated path should lead to
  * @return string The relative route path, possibly prefixed with a segment for identifying the current content dimension values
  */
 protected function resolveRoutePathForNode(NodeInterface $node)
 {
     $workspaceName = $node->getContext()->getWorkspaceName();
     $nodeContextPath = $node->getContextPath();
     $nodeContextPathSuffix = $workspaceName !== 'live' ? substr($nodeContextPath, strpos($nodeContextPath, '@')) : '';
     $currentNodeIsSiteNode = $node->getParentPath() === SiteService::SITES_ROOT_PATH;
     $dimensionsUriSegment = $this->getUriSegmentForDimensions($node->getContext()->getDimensions(), $currentNodeIsSiteNode);
     $requestPath = $this->getRequestPathByNode($node);
     return trim($dimensionsUriSegment . $requestPath, '/') . $nodeContextPathSuffix;
 }
 /**
  * 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 \Neos\ContentRepository\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);
 }
Пример #16
0
 /**
  * Set the "context node" this operation was working on.
  *
  * @param NodeInterface $node
  * @return void
  */
 public function setNode(NodeInterface $node)
 {
     $this->nodeIdentifier = $node->getIdentifier();
     $this->workspaceName = $node->getContext()->getWorkspaceName();
     $this->dimension = $node->getContext()->getDimensions();
     $context = $node->getContext();
     if ($context instanceof ContentContext && $context->getCurrentSite() !== null) {
         $siteIdentifier = $this->persistenceManager->getIdentifierByObject($context->getCurrentSite());
     } else {
         $siteIdentifier = null;
     }
     $this->data = Arrays::arrayMergeRecursiveOverrule($this->data, array('nodeContextPath' => $node->getContextPath(), 'nodeLabel' => $node->getLabel(), 'nodeType' => $node->getNodeType()->getName(), 'site' => $siteIdentifier));
     $node = self::getClosestAggregateNode($node);
     if ($node !== null) {
         $this->documentNodeIdentifier = $node->getIdentifier();
         $this->data = Arrays::arrayMergeRecursiveOverrule($this->data, array('documentNodeContextPath' => $node->getContextPath(), 'documentNodeLabel' => $node->getLabel(), 'documentNodeType' => $node->getNodeType()->getName()));
     }
 }
 /**
  * Retrieves the given node's corresponding node in the base workspace (that is, which would be overwritten if the
  * given node would be published)
  *
  * @param NodeInterface $modifiedNode
  * @return NodeInterface
  */
 protected function getOriginalNode(NodeInterface $modifiedNode)
 {
     $baseWorkspaceName = $modifiedNode->getWorkspace()->getBaseWorkspace()->getName();
     $contextProperties = $modifiedNode->getContext()->getProperties();
     $contextProperties['workspaceName'] = $baseWorkspaceName;
     $contentContext = $this->contextFactory->create($contextProperties);
     return $contentContext->getNodeByIdentifier($modifiedNode->getIdentifier());
 }