/** * Convert a page path to an ID. * * @param array $pathParts Array of segments from virtual path * @return integer Page ID * @see decodeSpURL_idFromPath() */ protected function pagePathtoID(&$pathParts) { $row = $postVar = false; $copy_pathParts = array(); // If pagePath cache is not disabled, look for entry if (!$this->conf['disablePathCache']) { // Work from outside-in to look up path in cache $postVar = false; $copy_pathParts = $pathParts; $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : $GLOBALS['TSFE']->defaultCharSet; foreach ($copy_pathParts as $key => $value) { $copy_pathParts[$key] = $GLOBALS['TSFE']->csConvObj->conv_case($charset, $value, 'toLower'); } while (count($copy_pathParts)) { // Using pathq1 index! /** @noinspection PhpUndefinedMethodInspection */ list($row) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('tx_realurl_pathcache.*', 'tx_realurl_pathcache,pages', 'tx_realurl_pathcache.page_id=pages.uid AND pages.deleted=0' . ' AND rootpage_id=' . intval($this->conf['rootpage_id']) . ' AND pagepath=' . $GLOBALS['TYPO3_DB']->fullQuoteStr(implode('/', $copy_pathParts), 'tx_realurl_pathcache'), '', 'expire', '1'); // This lookup does not include language and MP var since those are supposed to be fully reflected in the built url! if (is_array($row)) { break; } // If no row was found, we simply pop off one element of the path and try again until there are no more elements in the array - which means we didn't find a match! $postVar = array_pop($copy_pathParts); } } // It could be that entry point to a page but it is not in the cache. If we popped // any items from path parts, we need to check if they are defined as postSetVars or // fixedPostVars on this page. This does not guarantie 100% success. For example, // if path to page is /hello/world/how/are/you and hello/world found in cache and // there is a postVar 'how' on this page, the check below will not work. But it is still // better than nothing. if ($row && $postVar) { $postVars = $this->pObj->getPostVarSetConfig($row['page_id'], 'postVarSets'); if (!is_array($postVars) || !isset($postVars[$postVar])) { // Check fixed $postVars = $this->pObj->getPostVarSetConfig($row['page_id'], 'fixedPostVars'); if (!is_array($postVars) || !isset($postVars[$postVar])) { // Not a postVar, so page most likely in not in cache. Clear row. // TODO It would be great to update cache in this case but usually TYPO3 is not // complitely initialized at this place. So we do not do it... $row = false; } } } // Process row if found if ($row) { // We found it in the cache // Check for expiration. We can get one of three // 1. expire = 0 // 2. expire <= time() // 3. expire > time() // 1 is permanent, we do not process it. 2 is expired, we look for permanent or non-expired // (in this order!) entry for the same page od and redirect to corresponding path. 3 - same as // 1 but means that entry is going to expire eventually, nothing to do for us yet. if ($row['expire'] > 0) { $this->pObj->devLog('pagePathToId found row', $row); // 'expire' in the query is only for logging // Using pathq2 index! /** @noinspection PhpUndefinedMethodInspection */ list($newEntry) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('pagepath,expire', 'tx_realurl_pathcache', 'page_id=' . intval($row['page_id']) . ' AND language_id=' . intval($row['language_id']) . ' AND (expire=0 OR expire>' . $row['expire'] . ')', '', 'expire', '1'); $this->pObj->devLog('pagePathToId searched for new entry', $newEntry); // Redirect to new path immediately if it is found if ($newEntry) { // Replace path-segments with new ones $originalDirs = $this->pObj->dirParts; // All original $cp_pathParts = $pathParts; // Popping of pages of original dirs (as many as are remaining in $pathParts) for ($a = 0; $a < count($pathParts); $a++) { array_pop($originalDirs); // Finding all preVars here } for ($a = 0; $a < count($copy_pathParts); $a++) { array_shift($cp_pathParts); // Finding all postVars here } $newPathSegments = explode('/', $newEntry['pagepath']); // Split new pagepath into segments. $newUrlSegments = array_merge($originalDirs, $newPathSegments, $cp_pathParts); // Merge those segments. $this->pObj->appendFilePart($newUrlSegments); $redirectUrl = implode('/', $newUrlSegments); header('HTTP/1.1 301 TYPO3 RealURL Redirect A' . __LINE__); header('Location: ' . t3lib_div::locationHeaderUrl($redirectUrl)); exit; } $this->pObj->disableDecodeCache = true; // Do not cache this! } // Unshift the number of segments that must have defined the page $cc = count($copy_pathParts); for ($a = 0; $a < $cc; $a++) { array_shift($pathParts); } // Assume we can use this info at first $id = $row['page_id']; $GET_VARS = $row['mpvar'] ? array('MP' => $row['mpvar']) : ''; } else { // Find it list($id, $GET_VARS) = $this->findIDByURL($pathParts); } // Return found ID return array($id, $GET_VARS); }