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