/** * 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); }