/**
  * @test
  */
 public function matchesWorkspaceAndDimensionsWithMatchingWorkspaceAndDimensionsReturnsTrue()
 {
     $this->nodeData = new NodeData('/foo/bar', $this->mockWorkspace, null, array('language' => array('mul_ZZ')));
     $this->mockWorkspace->expects($this->any())->method('getName')->will($this->returnValue('live'));
     $result = $this->nodeData->matchesWorkspaceAndDimensions($this->mockWorkspace, array('language' => array('de_DE', 'mul_ZZ')));
     $this->assertTrue($result);
 }
 /**
  * @test
  */
 public function publishNodePublishesTheNodeAndItsChildNodeCollectionsIfTheNodeTypeHasChildNodes()
 {
     $mockNode = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Model\\NodeInterface')->getMock();
     $mockChildNode = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Model\\NodeInterface')->getMock();
     $mockNodeType = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Model\\NodeType')->disableOriginalConstructor()->setMethods(array('hasConfiguration', 'isOfType'))->getMock();
     $mockNodeType->expects($this->atLeastOnce())->method('hasConfiguration')->with('childNodes')->will($this->returnValue(true));
     $mockNode->expects($this->atLeastOnce())->method('getNodeType')->will($this->returnValue($mockNodeType));
     $mockNode->expects($this->atLeastOnce())->method('getWorkspace')->will($this->returnValue($this->mockWorkspace));
     $mockNode->expects($this->atLeastOnce())->method('getChildNodes')->with('TYPO3.Neos:ContentCollection')->will($this->returnValue(array($mockChildNode)));
     $mockTargetWorkspace = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Model\\Workspace')->disableOriginalConstructor()->getMock();
     $this->mockWorkspace->expects($this->atLeastOnce())->method('publishNodes')->with(array($mockNode, $mockChildNode), $mockTargetWorkspace);
     $this->publishingService->publishNode($mockNode, $mockTargetWorkspace);
 }
 /**
  * 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);
 }
 /**
  * Find a single node by exact path.
  *
  * @param string $path Absolute path of the node
  * @param Workspace $workspace The containing workspace
  * @param array $dimensions An array of dimensions with array of ordered values to use for fallback matching
  * @param boolean|NULL $removedNodes Include removed nodes, NULL (all), FALSE (no removed nodes) or TRUE (only removed nodes)
  * @throws \InvalidArgumentException
  * @return NodeData The matching node if found, otherwise NULL
  */
 public function findOneByPath($path, Workspace $workspace, array $dimensions = null, $removedNodes = false)
 {
     $path = strtolower($path);
     if ($path === '' || $path !== '/' && ($path[0] !== '/' || substr($path, -1, 1) === '/')) {
         throw new \InvalidArgumentException('"' . $path . '" is not a valid path: must start but not end with a slash.', 1284985489);
     }
     if ($path === '/') {
         return $workspace->getRootNodeData();
     }
     $workspaces = array();
     while ($workspace !== null) {
         /** @var $node NodeData */
         foreach ($this->addedNodes as $node) {
             if ($node->getPath() === $path && $node->matchesWorkspaceAndDimensions($workspace, $dimensions)) {
                 return $node;
             }
         }
         foreach ($this->removedNodes as $node) {
             if ($node->getPath() === $path && $node->matchesWorkspaceAndDimensions($workspace, $dimensions)) {
                 return null;
             }
         }
         $workspaces[] = $workspace;
         $workspace = $workspace->getBaseWorkspace();
     }
     $queryBuilder = $this->createQueryBuilder($workspaces);
     if ($dimensions !== null) {
         $this->addDimensionJoinConstraintsToQueryBuilder($queryBuilder, $dimensions);
     } else {
         $dimensions = array();
     }
     $this->addPathConstraintToQueryBuilder($queryBuilder, $path);
     $query = $queryBuilder->getQuery();
     $nodes = $query->getResult();
     $foundNodes = $this->reduceNodeVariantsByWorkspacesAndDimensions($nodes, $workspaces, $dimensions);
     $foundNodes = $this->filterRemovedNodes($foundNodes, $removedNodes);
     if ($foundNodes !== array()) {
         return reset($foundNodes);
     }
     return null;
 }
 /**
  * Creates a new content context based on the given workspace and the NodeData object.
  *
  * @param Workspace $workspace Workspace for the new context
  * @param array $dimensionValues The dimension values for the new context
  * @param array $contextProperties Additional pre-defined context properties
  * @return Context
  */
 protected function createContext(Workspace $workspace, array $dimensionValues, array $contextProperties = array())
 {
     $contextProperties += array('workspaceName' => $workspace->getName(), 'inaccessibleContentShown' => TRUE, 'invisibleContentShown' => TRUE, 'removedContentShown' => TRUE, 'dimensions' => $dimensionValues);
     return $this->contextFactory->create($contextProperties);
 }
 /**
  * Collects all nodes with missing shadow nodes
  *
  * @param Workspace $workspace
  * @param boolean $dryRun
  * @param NodeType $nodeType
  * @return array
  */
 protected function fixShadowNodesInWorkspace(Workspace $workspace, $dryRun, NodeType $nodeType = null)
 {
     $workspaces = array_merge([$workspace], $workspace->getBaseWorkspaces());
     $fixedShadowNodes = 0;
     foreach ($workspaces as $workspace) {
         /** @var Workspace $workspace */
         if ($workspace->getBaseWorkspace() === null) {
             continue;
         }
         /** @var QueryBuilder $queryBuilder */
         $queryBuilder = $this->entityManager->createQueryBuilder();
         $queryBuilder->select('n')->from(NodeData::class, 'n')->where('n.workspace = :workspace');
         $queryBuilder->setParameter('workspace', $workspace->getName());
         if ($nodeType !== null) {
             $queryBuilder->andWhere('n.nodeType = :nodeType');
             $queryBuilder->setParameter('nodeType', $nodeType->getName());
         }
         /** @var NodeData $nodeData */
         foreach ($queryBuilder->getQuery()->getResult() as $nodeData) {
             $nodeDataSeenFromParentWorkspace = $this->nodeDataRepository->findOneByIdentifier($nodeData->getIdentifier(), $workspace->getBaseWorkspace(), $nodeData->getDimensionValues());
             // This is the good case, either the node does not exist or was shadowed
             if ($nodeDataSeenFromParentWorkspace === null) {
                 continue;
             }
             // Also good, the node was not moved at all.
             if ($nodeDataSeenFromParentWorkspace->getPath() === $nodeData->getPath()) {
                 continue;
             }
             $nodeDataOnSamePath = $this->nodeDataRepository->findOneByPath($nodeData->getPath(), $workspace->getBaseWorkspace(), $nodeData->getDimensionValues(), null);
             // We cannot just put a shadow node in the path, something exists, but that should be fine.
             if ($nodeDataOnSamePath !== null) {
                 continue;
             }
             if (!$dryRun) {
                 $nodeData->createShadow($nodeDataSeenFromParentWorkspace->getPath());
             }
             $fixedShadowNodes++;
         }
     }
     return $fixedShadowNodes;
 }
 /**
  *
  *
  * @param NodeInterface $node
  * @param Workspace $targetWorkspace
  * @return void
  */
 public function afterNodePublishing(NodeInterface $node, Workspace $targetWorkspace)
 {
     if (!$this->eventEmittingService->isEnabled()) {
         return;
     }
     $documentNode = NodeEvent::getClosestAggregateNode($node);
     if ($documentNode === null) {
         return;
     }
     $this->scheduledNodeEventUpdates[$documentNode->getContextPath()] = array('workspaceName' => $node->getContext()->getWorkspaceName(), 'nestedNodeIdentifiersWhichArePublished' => array(), 'targetWorkspace' => $targetWorkspace->getName(), 'documentNode' => $documentNode);
     $this->scheduledNodeEventUpdates[$documentNode->getContextPath()]['nestedNodeIdentifiersWhichArePublished'][] = $node->getIdentifier();
 }
 /**
  * Adds this node to the Node Repository or updates it if it has been added earlier
  *
  * @param NodeData $nodeData Other NodeData object to addOrUpdate
  * @throws \TYPO3\Flow\Persistence\Exception\IllegalObjectTypeException
  */
 protected function addOrUpdate(NodeData $nodeData = null)
 {
     $nodeData = $nodeData === null ? $this : $nodeData;
     // If this NodeData was previously removed and is in live workspace we don't want to add it again to persistence.
     if ($nodeData->isRemoved() && $this->workspace->getBaseWorkspace() === null) {
         // Actually it should be removed from the identity map here.
         if ($this->persistenceManager->isNewObject($nodeData) === false) {
             $this->nodeDataRepository->remove($nodeData);
         }
     } else {
         if ($this->persistenceManager->isNewObject($nodeData)) {
             $this->nodeDataRepository->add($nodeData);
         } else {
             $this->nodeDataRepository->update($nodeData);
         }
     }
 }
Exemplo n.º 9
0
 /**
  * Returns the NodeData instance with the given identifier from the target workspace.
  * If no NodeData instance is found, NULL is returned.
  *
  * @param NodeInterface $node
  * @param Workspace $targetWorkspace
  * @return NodeData
  */
 protected function findNodeDataInTargetWorkspace(NodeInterface $node, Workspace $targetWorkspace)
 {
     $properties = $node->getContext()->getProperties();
     $properties['workspaceName'] = $targetWorkspace->getName();
     $targetWorkspaceContext = $this->contextFactory->create($properties);
     $targetNodeInstance = $targetWorkspaceContext->getNodeByIdentifier($node->getIdentifier());
     $targetNode = $targetNodeInstance !== NULL ? $targetNodeInstance->getNodeData() : NULL;
     return $targetNode;
 }
Exemplo n.º 10
0
 /**
  * Sets the workspace of this node.
  *
  * This method is only for internal use by the content repository. Changing
  * the workspace of a node manually may lead to unexpected behavior.
  *
  * @param Workspace $workspace
  * @return void
  */
 public function setWorkspace(Workspace $workspace)
 {
     if (!$this->isNodeDataMatchingContext()) {
         $this->materializeNodeData();
     }
     if ($this->getWorkspace()->getName() === $workspace->getName()) {
         return;
     }
     $this->nodeData->setWorkspace($workspace);
     $this->context->getFirstLevelNodeCache()->flush();
     $this->emitNodeUpdated($this);
 }
 /**
  * @test
  */
 public function isPersonalWorkspaceChecksIfTheWorkspaceNameStartsWithUser()
 {
     $liveWorkspace = new Workspace('live');
     $personalWorkspace = new Workspace('user-admin', $liveWorkspace);
     $this->assertFalse($liveWorkspace->isPersonalWorkspace());
     $this->assertTrue($personalWorkspace->isPersonalWorkspace());
 }
Exemplo n.º 12
0
 /**
  * @test
  */
 public function publishNodeWithANodeInTheTargetWorkspaceShouldDoNothing()
 {
     $liveWorkspace = new Workspace('live');
     $personalWorkspace = new Workspace('user-admin', $liveWorkspace);
     $nodeDataRepository = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Repository\\NodeDataRepository')->disableOriginalConstructor()->getMock();
     $this->inject($liveWorkspace, 'nodeDataRepository', $nodeDataRepository);
     $node = $this->getMock('TYPO3\\TYPO3CR\\Domain\\Model\\NodeInterface');
     $node->expects($this->any())->method('getWorkspace')->will($this->returnValue($liveWorkspace));
     $nodeDataRepository->expects($this->never())->method('findOneByIdentifier');
     $personalWorkspace->publishNode($node, $liveWorkspace);
 }
 /**
  * Creates a personal workspace for the given user's account if it does not exist already.
  *
  * @param User $user The new user to create a workspace for
  * @param Account $account The user's backend account
  * @throws IllegalObjectTypeException
  */
 protected function createPersonalWorkspace(User $user, Account $account)
 {
     $userWorkspaceName = UserUtility::getPersonalWorkspaceNameForUsername($account->getAccountIdentifier());
     $userWorkspace = $this->workspaceRepository->findByIdentifier($userWorkspaceName);
     if ($userWorkspace === null) {
         $liveWorkspace = $this->workspaceRepository->findByIdentifier('live');
         if (!$liveWorkspace instanceof Workspace) {
             $liveWorkspace = new Workspace('live');
             $liveWorkspace->setTitle('Live');
             $this->workspaceRepository->add($liveWorkspace);
         }
         $userWorkspace = new Workspace($userWorkspaceName, $liveWorkspace, $user);
         $userWorkspace->setTitle((string) $user->getName());
         $this->workspaceRepository->add($userWorkspace);
     }
 }
 /**
  * Publishes the whole workspace
  *
  * @param Workspace $workspace
  * @return void
  */
 public function publishWorkspaceAction(Workspace $workspace)
 {
     $liveWorkspace = $this->workspaceRepository->findOneByName('live');
     $workspace->publish($liveWorkspace);
     $this->addFlashMessage('Changes in workspace "%s" have been published', 'Changes published', Message::SEVERITY_OK, array($workspace->getName()), 1412420808);
     $this->redirect('index');
 }
Exemplo n.º 15
0
 /**
  * When moving nodes which are inside live workspace to a personal workspace *across levels* (i.e. with different
  * parent node before and after), the system returned *both* the "new" node from the personal workspace (correct!),
  * and the "shined-through" version of the node from the "live" workspace (WRONG!).
  *
  * For all nodes not being in our base workspace, we need to check whether it is overlaid by a node in our base workspace
  * with the same identifier. If that's the case, we do not show the node.
  *
  * This is a bugfix for #48214.
  *
  * @param array $foundNodes
  * @param Workspace $baseWorkspace
  * @param array $dimensions
  * @return array
  */
 protected function filterNodesOverlaidInBaseWorkspace(array $foundNodes, Workspace $baseWorkspace, array $dimensions = NULL)
 {
     $identifiersOfNodesNotInBaseWorkspace = array();
     /** @var $foundNode NodeData */
     foreach ($foundNodes as $i => $foundNode) {
         if ($foundNode->getWorkspace()->getName() !== $baseWorkspace->getName()) {
             $identifiersOfNodesNotInBaseWorkspace[$foundNode->getIdentifier()] = $i;
         }
     }
     if (count($identifiersOfNodesNotInBaseWorkspace) === 0) {
         return $foundNodes;
     }
     /** @var \Doctrine\ORM\QueryBuilder $queryBuilder */
     $queryBuilder = $this->entityManager->createQueryBuilder();
     $queryBuilder->select('n.identifier')->distinct()->from('TYPO3\\TYPO3CR\\Domain\\Model\\NodeData', 'n')->where('n.workspace = :baseWorkspace')->andWhere('n.identifier IN (:identifierList)')->setParameter('baseWorkspace', $baseWorkspace)->setParameter('identifierList', array_keys($identifiersOfNodesNotInBaseWorkspace));
     if ($dimensions !== NULL) {
         $this->addDimensionJoinConstraintsToQueryBuilder($queryBuilder, $dimensions);
     }
     $results = $queryBuilder->getQuery()->getArrayResult();
     foreach ($results as $result) {
         $nodeIdentifierOfNodeInBaseWorkspace = $result['identifier'];
         $indexOfNodeNotInBaseWorkspaceWhichShouldBeRemoved = $identifiersOfNodesNotInBaseWorkspace[$nodeIdentifierOfNodeInBaseWorkspace];
         unset($foundNodes[$indexOfNodeNotInBaseWorkspaceWhichShouldBeRemoved]);
     }
     return $foundNodes;
 }
Exemplo n.º 16
0
 /**
  * Checks if this instance matches the given workspace and dimensions.
  *
  * @param Workspace $workspace
  * @param array $dimensions
  * @return boolean
  */
 public function matchesWorkspaceAndDimensions($workspace, array $dimensions = NULL)
 {
     if ($this->workspace->getName() !== $workspace->getName()) {
         return FALSE;
     }
     if ($dimensions !== NULL) {
         $nodeDimensionValues = $this->getDimensionValues();
         foreach ($dimensions as $dimensionName => $dimensionValues) {
             if (!isset($nodeDimensionValues[$dimensionName]) || array_intersect($nodeDimensionValues[$dimensionName], $dimensionValues) === array()) {
                 return FALSE;
             }
         }
     }
     return TRUE;
 }
 /**
  * This finds nodes by path and delivers a raw, unfiltered result.
  *
  * To get a "usable" set of nodes, filtering by workspaces, dimensions and
  * removed nodes must be done on the result.
  *
  * @param string $path
  * @param Workspace $workspace
  * @param array|null $dimensions
  * @param boolean $onlyShadowNodes
  * @return array
  * @throws \InvalidArgumentException
  */
 protected function findRawNodesByPath($path, Workspace $workspace, array $dimensions = null, $onlyShadowNodes = false)
 {
     $path = strtolower($path);
     if ($path === '' || $path !== '/' && ($path[0] !== '/' || substr($path, -1, 1) === '/')) {
         throw new \InvalidArgumentException('"' . $path . '" is not a valid path: must start but not end with a slash.', 1284985489);
     }
     if ($path === '/') {
         return [$workspace->getRootNodeData()];
     }
     $addedNodes = [];
     $workspaces = [];
     while ($workspace !== null) {
         /** @var $node NodeData */
         foreach ($this->addedNodes as $node) {
             if ($node->getPath() === $path && $node->matchesWorkspaceAndDimensions($workspace, $dimensions) && ($onlyShadowNodes === false || $node->isInternal())) {
                 $addedNodes[] = $node;
                 // removed nodes don't matter here because due to the identity map the right object will be returned from the query and will have "removed" set.
             }
         }
         $workspaces[] = $workspace;
         $workspace = $workspace->getBaseWorkspace();
     }
     $queryBuilder = $this->createQueryBuilder($workspaces);
     if ($dimensions !== null) {
         $this->addDimensionJoinConstraintsToQueryBuilder($queryBuilder, $dimensions);
     }
     $this->addPathConstraintToQueryBuilder($queryBuilder, $path);
     if ($onlyShadowNodes) {
         $queryBuilder->andWhere('n.movedTo IS NOT NULL AND n.removed = TRUE');
     }
     $query = $queryBuilder->getQuery();
     $nodes = $query->getResult();
     return array_merge($nodes, $addedNodes);
 }
 /**
  * Create a new workspace
  *
  * This command creates a new workspace.
  *
  * @param string $workspace Name of the workspace, for example "christmas-campaign"
  * @param string $baseWorkspace Name of the base workspace. If none is specified, "live" is assumed.
  * @param string $title Human friendly title of the workspace, for example "Christmas Campaign"
  * @param string $description A description explaining the purpose of the new workspace
  * @param string $owner The identifier of a User to own the workspace
  * @return void
  */
 public function createCommand($workspace, $baseWorkspace = 'live', $title = null, $description = null, $owner = '')
 {
     $workspaceName = $workspace;
     $workspace = $this->workspaceRepository->findOneByName($workspaceName);
     if ($workspace instanceof Workspace) {
         $this->outputLine('Workspace "%s" already exists', [$workspaceName]);
         $this->quit(1);
     }
     $baseWorkspaceName = $baseWorkspace;
     $baseWorkspace = $this->workspaceRepository->findOneByName($baseWorkspaceName);
     if (!$baseWorkspace instanceof Workspace) {
         $this->outputLine('The base workspace "%s" does not exist', [$baseWorkspaceName]);
         $this->quit(2);
     }
     if ($owner === '') {
         $owningUser = null;
     } else {
         $owningUser = $this->userService->getUser($owner);
         if ($owningUser === null) {
             $this->outputLine('The user "%s" specified as owner does not exist', [$owner]);
             $this->quit(3);
         }
     }
     if ($title === null) {
         $title = $workspaceName;
     }
     $workspace = new Workspace($workspaceName, $baseWorkspace, $owningUser);
     $workspace->setTitle($title);
     $workspace->setDescription($description);
     $this->workspaceRepository->add($workspace);
     if ($owningUser instanceof User) {
         $this->outputLine('Created a new workspace "%s", based on workspace "%s", owned by "%s".', [$workspaceName, $baseWorkspaceName, $owner]);
     } else {
         $this->outputLine('Created a new workspace "%s", based on workspace "%s".', [$workspaceName, $baseWorkspaceName]);
     }
 }
 /**
  * Creates a new content context based on the given workspace and the NodeData object.
  *
  * @param Workspace $workspace Workspace for the new context
  * @param array $dimensionValues The dimension values for the new context
  * @param array $contextProperties Additional pre-defined context properties
  * @return Context
  */
 protected function createContext(Workspace $workspace, array $dimensionValues, array $contextProperties = array())
 {
     $presetsMatchingDimensionValues = $this->contentDimensionPresetSource->findPresetsByTargetValues($dimensionValues);
     $dimensions = array_map(function ($preset) {
         return $preset['values'];
     }, $presetsMatchingDimensionValues);
     $contextProperties += array('workspaceName' => $workspace->getName(), 'inaccessibleContentShown' => true, 'invisibleContentShown' => true, 'removedContentShown' => true, 'dimensions' => $dimensions);
     return $this->contextFactory->create($contextProperties);
 }
 /**
  * Create a new workspace
  *
  * This command creates a new workspace.
  *
  * @param string $workspace Name of the workspace, for example "christmas-campaign"
  * @param string $baseWorkspace Name of the base workspace. If none is specified, "live" is assumed.
  * @param string $title Human friendly title of the workspace, for example "Christmas Campaign"
  * @param string $description A description explaining the purpose of the new workspace
  * @return void
  */
 public function createCommand($workspace, $baseWorkspace = 'live', $title = NULL, $description = NULL)
 {
     $workspaceName = $workspace;
     $workspace = $this->workspaceRepository->findOneByName($workspaceName);
     if ($workspace instanceof Workspace) {
         $this->outputLine('Workspace "%s" already exists', array($workspaceName));
         $this->quit(1);
     }
     $baseWorkspaceName = $baseWorkspace;
     $baseWorkspace = $this->workspaceRepository->findOneByName($baseWorkspaceName);
     if (!$baseWorkspace instanceof Workspace) {
         $this->outputLine('The base workspace "%s" does not exist', array($baseWorkspaceName));
         $this->quit(2);
     }
     if ($title === NULL) {
         $title = $workspaceName;
     }
     $workspace = new Workspace($workspaceName, $baseWorkspace);
     $workspace->setTitle($title);
     $workspace->setDescription($description);
     $this->workspaceRepository->add($workspace);
     $this->outputLine('Created a new workspace "%s", based on workspace "%s".', array($workspaceName, $baseWorkspaceName));
 }
 /**
  * Checks if this instance matches the given workspace and dimensions.
  *
  * @param Workspace $workspace
  * @param array $dimensions
  * @return boolean
  */
 public function matchesWorkspaceAndDimensions($workspace, array $dimensions = null)
 {
     if ($this->workspace->getName() !== $workspace->getName()) {
         return false;
     }
     if ($dimensions !== null) {
         $nodeDimensionValues = $this->dimensionValues;
         foreach ($dimensions as $dimensionName => $dimensionValues) {
             if (!isset($nodeDimensionValues[$dimensionName]) || array_intersect($nodeDimensionValues[$dimensionName], $dimensionValues) === array()) {
                 return false;
             }
         }
     }
     return true;
 }
 /**
  * Publishes the whole workspace
  *
  * @param Workspace $workspace
  * @return void
  */
 public function publishWorkspaceAction(Workspace $workspace)
 {
     if (($targetWorkspace = $workspace->getBaseWorkspace()) === null) {
         $targetWorkspace = $this->workspaceRepository->findOneByName('live');
     }
     $workspace->publish($targetWorkspace);
     $this->addFlashMessage($this->translator->translateById('workspaces.allChangesInWorkspaceHaveBeenPublished', [htmlspecialchars($workspace->getTitle()), htmlspecialchars($targetWorkspace->getTitle())], null, null, 'Modules', 'TYPO3.Neos'));
     $this->redirect('index');
 }
 /**
  * Checks if the specified workspace is a base workspace of this workspace
  * and if not, throws an exception
  *
  * @param Workspace $targetWorkspace The publishing target workspace
  * @return void
  * @throws WorkspaceException if the specified workspace is not a base workspace of this workspace
  */
 protected function verifyPublishingTargetWorkspace(Workspace $targetWorkspace)
 {
     $baseWorkspace = $this->baseWorkspace;
     while ($targetWorkspace !== $baseWorkspace) {
         if ($baseWorkspace === null) {
             throw new WorkspaceException(sprintf('The specified workspace "%s" is not a base workspace of "%s".', $targetWorkspace->getName(), $this->getName()), 1289499117);
         }
         $baseWorkspace = $baseWorkspace->getBaseWorkspace();
     }
 }
 /**
  * Adds this node to the Node Repository or updates it if it has been added earlier
  *
  * @param NodeData $nodeData Other NodeData object to addOrUpdate
  * @throws IllegalObjectTypeException
  */
 protected function addOrUpdate(NodeData $nodeData = null)
 {
     $nodeData = $nodeData === null ? $this : $nodeData;
     // If this NodeData was previously removed and is in live workspace we don't want to add it again to persistence.
     if ($nodeData->isRemoved() && $this->workspace->getBaseWorkspace() === null) {
         // Actually it should be removed from the identity map here.
         if ($this->persistenceManager->isNewObject($nodeData) === false) {
             $this->nodeDataRepository->remove($nodeData);
         }
         return;
     }
     // If the node is marked to be removed but didn't exist in a base workspace yet, we can delete it for real, without creating a shadow node:
     if ($nodeData->isRemoved() && $this->nodeDataRepository->findOneByIdentifier($nodeData->getIdentifier(), $this->workspace->getBaseWorkspace()) === null) {
         if ($this->persistenceManager->isNewObject($nodeData) === false) {
             $this->nodeDataRepository->remove($nodeData);
         }
         return;
     }
     if ($this->persistenceManager->isNewObject($nodeData)) {
         $this->nodeDataRepository->add($nodeData);
     } else {
         $this->nodeDataRepository->update($nodeData);
     }
 }