protected function getNearestDocumentByPath($path, $ignoreHardlinks = false, $types = [])
{
$cacheKey = $ignoreHardlinks . implode("-", $types);
$document = null;
if (isset($this->nearestDocumentByPath[$cacheKey])) {
$document = $this->nearestDocumentByPath[$cacheKey];
} else {
$pathes = [];
$pathes[] = "/";
$pathParts = explode("/", $path);
$tmpPathes = [];
foreach ($pathParts as $pathPart) {
$tmpPathes[] = $pathPart;
$t = implode("/", $tmpPathes);
if (!empty($t)) {
$pathes[] = $t;
}
}
$pathes = array_reverse($pathes);
foreach ($pathes as $p) {
if ($document = Document::getByPath($p)) {
if (empty($types) || in_array($document->getType(), $types)) {
$this->nearestDocumentByPath[$cacheKey] = $document;
break;
}
} elseif (Site::isSiteRequest()) {
// also check for a pretty url in a site
$site = Site::getCurrentSite();
$documentService = new Document\Service();
// undo the changed made by the site detection in self::match()
$originalPath = preg_replace("@^" . $site->getRootPath() . "@", "", $p);
$sitePrettyDocId = $documentService->getDocumentIdByPrettyUrlInSite($site, $originalPath);
if ($sitePrettyDocId) {
if ($sitePrettyDoc = Document::getById($sitePrettyDocId)) {
$this->nearestDocumentByPath[$cacheKey] = $sitePrettyDoc;
break;
}
}
}
}
}
if ($document) {
if (!$ignoreHardlinks) {
if ($document instanceof Document\Hardlink) {
if ($hardLinkedDocument = Document\Hardlink\Service::getNearestChildByPath($document, $path)) {
$document = $hardLinkedDocument;
} else {
$document = Document\Hardlink\Service::wrap($document);
}
}
}
return $document;
}
return null;
}