/**
* Split the current request into fragments, strip the URL suffix, recreate the $_GET array and return the page ID
*
* @return mixed
*/
public static function getPageIdFromUrl()
{
$strRequest = \Environment::get('relativeRequest');
if ($strRequest == '') {
return null;
}
// Get the request without the query string
list($strRequest) = explode('?', $strRequest, 2);
// URL decode here (see #6232)
$strRequest = rawurldecode($strRequest);
// The request string must not contain "auto_item" (see #4012)
if (strpos($strRequest, '/auto_item/') !== false) {
return false;
}
// Remove the URL suffix if not just a language root (e.g. en/) is requested
if ($strRequest != '' && (!\Config::get('addLanguageToUrl') || !preg_match('@^[a-z]{2}(-[A-Z]{2})?/$@', $strRequest))) {
$intSuffixLength = strlen(\Config::get('urlSuffix'));
// Return false if the URL suffix does not match (see #2864)
if ($intSuffixLength > 0) {
if (substr($strRequest, -$intSuffixLength) != \Config::get('urlSuffix')) {
return false;
}
$strRequest = substr($strRequest, 0, -$intSuffixLength);
}
}
// Extract the language
if (\Config::get('addLanguageToUrl')) {
$arrMatches = array();
// Use the matches instead of substr() (thanks to Mario Müller)
if (preg_match('@^([a-z]{2}(-[A-Z]{2})?)/(.*)$@', $strRequest, $arrMatches)) {
\Input::setGet('language', $arrMatches[1]);
// Trigger the root page if only the language was given
if ($arrMatches[3] == '') {
return null;
}
$strRequest = $arrMatches[3];
} else {
return false;
// Language not provided
}
}
$arrFragments = null;
// Use folder-style URLs
if (\Config::get('folderUrl') && strpos($strRequest, '/') !== false) {
$strAlias = $strRequest;
$arrOptions = array($strAlias);
// Compile all possible aliases by applying dirname() to the request (e.g. news/archive/item, news/archive, news)
while ($strAlias != '/' && strpos($strAlias, '/') !== false) {
$strAlias = dirname($strAlias);
$arrOptions[] = $strAlias;
}
// Check if there are pages with a matching alias
$objPages = \PageModel::findByAliases($arrOptions);
if ($objPages !== null) {
$arrPages = array();
// Order by domain and language
while ($objPages->next()) {
/** @var PageModel $objModel */
$objModel = $objPages->current();
$objPage = $objModel->loadDetails();
$domain = $objPage->domain ?: '*';
$arrPages[$domain][$objPage->rootLanguage][] = $objPage;
// Also store the fallback language
if ($objPage->rootIsFallback) {
$arrPages[$domain]['*'][] = $objPage;
}
}
$strHost = \Environment::get('host');
// Look for a root page whose domain name matches the host name
if (isset($arrPages[$strHost])) {
$arrLangs = $arrPages[$strHost];
} else {
$arrLangs = $arrPages['*'] ?: array();
// empty domain
}
$arrAliases = array();
// Use the first result (see #4872)
if (!\Config::get('addLanguageToUrl')) {
$arrAliases = current($arrLangs);
} elseif (($lang = \Input::get('language')) != '' && isset($arrLangs[$lang])) {
$arrAliases = $arrLangs[$lang];
}
// Return if there are no matches
if (empty($arrAliases)) {
return false;
}
$objPage = $arrAliases[0];
// The request consists of the alias only
if ($strRequest == $objPage->alias) {
$arrFragments = array($strRequest);
} else {
$arrFragments = explode('/', substr($strRequest, strlen($objPage->alias) + 1));
array_unshift($arrFragments, $objPage->alias);
}
}
}
// If folderUrl is deactivated or did not find a matching page
if ($arrFragments === null) {
if ($strRequest == '/') {
return false;
} else {
$arrFragments = explode('/', $strRequest);
}
}
// Add the second fragment as auto_item if the number of fragments is even
if (\Config::get('useAutoItem') && count($arrFragments) % 2 == 0) {
array_insert($arrFragments, 1, array('auto_item'));
}
// HOOK: add custom logic
if (isset($GLOBALS['TL_HOOKS']['getPageIdFromUrl']) && is_array($GLOBALS['TL_HOOKS']['getPageIdFromUrl'])) {
foreach ($GLOBALS['TL_HOOKS']['getPageIdFromUrl'] as $callback) {
$arrFragments = static::importStatic($callback[0])->{$callback[1]}($arrFragments);
}
}
// Return if the alias is empty (see #4702 and #4972)
if ($arrFragments[0] == '' && count($arrFragments) > 1) {
return false;
}
// Add the fragments to the $_GET array
for ($i = 1, $c = count($arrFragments); $i < $c; $i += 2) {
// Skip key value pairs if the key is empty (see #4702)
if ($arrFragments[$i] == '') {
continue;
}
// Return false if there is a duplicate parameter (duplicate content) (see #4277)
if (isset($_GET[$arrFragments[$i]])) {
return false;
}
// Return false if the request contains an auto_item keyword (duplicate content) (see #4012)
if (\Config::get('useAutoItem') && in_array($arrFragments[$i], $GLOBALS['TL_AUTO_ITEM'])) {
return false;
}
\Input::setGet(urldecode($arrFragments[$i]), urldecode($arrFragments[$i + 1]), true);
}
return $arrFragments[0] ?: null;
}