public static function translate(&$uri, $reverse = false) { if ($uri instanceof eZURI) { $uriString = $uri->elements(); } else { $uriString = $uri; } $uriString = eZURLAliasML::cleanURL($uriString); $internalURIString = $uriString; $originalURIString = $uriString; $ini = eZINI::instance(); $prefixAdded = false; $prefix = $ini->hasVariable('SiteAccessSettings', 'PathPrefix') && $ini->variable('SiteAccessSettings', 'PathPrefix') != '' ? eZURLAliasML::cleanURL($ini->variable('SiteAccessSettings', 'PathPrefix')) : false; if ($prefix) { $escapedPrefix = preg_quote($prefix, '#'); // Only prepend the path prefix if it's not already the first element of the url. if (!preg_match("#^{$escapedPrefix}(/.*)?\$#i", $uriString)) { $exclude = $ini->hasVariable('SiteAccessSettings', 'PathPrefixExclude') ? $ini->variable('SiteAccessSettings', 'PathPrefixExclude') : false; $breakInternalURI = false; foreach ($exclude as $item) { $escapedItem = preg_quote($item, '#'); if (preg_match("#^{$escapedItem}(/.*)?\$#i", $uriString)) { $breakInternalURI = true; break; } } if (!$breakInternalURI) { $internalURIString = $prefix . '/' . $uriString; $prefixAdded = true; } } } $db = eZDB::instance(); $elements = explode('/', $internalURIString); $len = count($elements); if ($reverse) { return eZURLAliasML::reverseTranslate($uri, $uriString, $internalURIString); } $i = 0; $selects = array(); $tables = array(); $conds = array(); foreach ($elements as $element) { $table = "e" . $i; $selectString = "{$table}.id AS {$table}_id, "; $selectString .= "{$table}.link AS {$table}_link, "; $selectString .= "{$table}.text AS {$table}_text, "; $selectString .= "{$table}.text_md5 AS {$table}_text_md5, "; $selectString .= "{$table}.is_alias AS {$table}_is_alias, "; if ($i == $len - 1) { $selectString .= "{$table}.action AS {$table}_action, "; } $selectString .= "{$table}.alias_redirects AS {$table}_alias_redirects"; $selects[] = $selectString; $tables[] = "ezurlalias_ml " . $table; $langMask = trim(eZContentLanguage::languagesSQLFilter($table, 'lang_mask')); if ($i == 0) { $conds[] = "{$table}.parent = 0 AND ({$langMask}) AND {$table}.text_md5 = " . eZURLAliasML::md5($db, $element); } else { $conds[] = "{$table}.parent = {$prevTable}.link AND ({$langMask}) AND {$table}.text_md5 = " . eZURLAliasML::md5($db, $element); } $prevTable = $table; ++$i; } $query = "SELECT " . join(", ", $selects) . " FROM " . join(", ", $tables) . " WHERE " . join(" AND ", $conds); $return = false; $urlAliasArray = $db->arrayQuery($query, array('limit' => 1)); if (count($urlAliasArray) > 0) { $pathRow = $urlAliasArray[0]; $l = count($pathRow); $redirectLink = false; $redirectAction = false; $lastID = false; $action = false; $verifiedPath = array(); $doRedirect = false; for ($i = 0; $i < $len; ++$i) { $table = "e" . $i; $id = $pathRow[$table . "_id"]; $link = $pathRow[$table . "_link"]; $text = $pathRow[$table . "_text"]; $isAlias = $pathRow[$table . '_is_alias']; $aliasRedirects = $pathRow[$table . '_alias_redirects']; $verifiedPath[] = $text; if ($i == $len - 1) { $action = $pathRow[$table . "_action"]; } if ($link != $id) { $doRedirect = true; } else { if ($isAlias && $action !== false) { if ($aliasRedirects) { // If the entry is an alias and we have an action we redirect to the original // url of that action. $redirectAction = $action; $doRedirect = true; } } } $lastID = $link; } if (!$doRedirect) { $verifiedPathString = implode('/', $verifiedPath); // Check for case difference if ($prefixAdded) { if (strcmp($originalURIString, substr($verifiedPathString, strlen($prefix) + 1)) != 0) { $doRedirect = true; } } else { if (strcmp($verifiedPathString, $internalURIString) != 0) { $doRedirect = true; } } } if (preg_match("#^module:(.+)\$#", $action, $matches) and $doRedirect) { $uriString = 'error/301'; $return = $matches[1]; } else { if ($doRedirect) { if ($redirectAction !== false) { $query = "SELECT id FROM ezurlalias_ml WHERE action = '" . $db->escapeString($action) . "' AND is_original = 1 AND is_alias = 0"; $rows = $db->arrayQuery($query); if (count($rows) > 0) { $id = (int) $rows[0]['id']; } else { $id = false; $uriString = 'error/301'; $return = join("/", $pathData); } } else { $id = (int) $lastID; } if ($id !== false) { $pathData = array(); // Figure out the correct path by iterating down the parents until we have all // elements figured out. while ($id != 0) { $query = "SELECT parent, lang_mask, text FROM ezurlalias_ml WHERE id={$id}"; $rows = $db->arrayQuery($query); if (count($rows) == 0) { break; } $result = eZURLAliasML::choosePrioritizedRow($rows); if (!$result) { $result = $rows[0]; } $id = (int) $result['parent']; array_unshift($pathData, $result['text']); } $uriString = 'error/301'; $return = join("/", $pathData); } // Remove prefix of redirect uri if needed if ($prefix && is_string($return)) { if (strncasecmp($return, $prefix . '/', strlen($prefix) + 1) == 0) { $return = substr($return, strlen($prefix) + 1); } } } else { // See http://issues.ez.no/19062 // If $uriString matches a nop action, we need to check if we also match a wildcard // since we might want to translate it. // Default action for nop actions is to display the root node "/" (see eZURLAliasML::actionToURL()) if (strpos($action, 'nop') !== false && eZURLWildcard::wildcardExists($uriString)) { $return = false; } else { $uriString = eZURLAliasML::actionToUrl($action); $return = true; } } } if ($uri instanceof eZURI) { $uri->setURIString($uriString, false); } else { $uri = $uriString; } } return $return; }
list($rows, $offset) = fetchHistoricWildcardChunk(0, $fetchLimit); if (!is_array($rows)) { break; } $count = count($rows); foreach ($rows as $key => $row) { $wildcardType = (int) $row['is_wildcard']; // 1 is forward, 2 is direct (alias) for now they are both treated as forwarding/redirect $sourceWildcard = $row['source_url']; $sourceWildcard = eZURLAliasML::sanitizeURL($sourceWildcard); $destinationWildcard = $row['destination_url']; $destinationWildcard = eZURLAliasML::sanitizeURL($destinationWildcard); if ($row['is_wildcard'] && $row['is_internal'] != 1) { // If the wildcard is made by a user we import using the new wildcard system. $row['type'] = (int) $row['is_wildcard']; $wildcard = new eZURLWildcard($row); $wildcard->store(); list($column, $counter) = displayProgress('.', $urlImportStartTime, $counter, $urlCount, $column); continue; } while (true) { // Validate the wildcards if (!preg_match("#^(.*)\\*\$#", $sourceWildcard, $matches)) { logError("Invalid source wildcard '{$sourceWildcard}', item is skipped, URL entry ID is " . $row['id']); list($column, $counter) = displayProgress('E', $urlImportStartTime, $counter, $urlCount, $column); continue 2; } $fromPath = $matches[1]; $fromPath = eZURLAliasML::sanitizeURL($fromPath); if (!preg_match("#^(.*)\\{1\\}\$#", $destinationWildcard, $matches)) { logError("Invalid destination wildcard '{$destinationWildcard}', item is skipped, URL entry ID is " . $row['id']);
/** * Expires the wildcard cache. This causes the wildcard cache to be * regenerated on the next page load. * @return void */ public static function expireCache() { $handler = eZExpiryHandler::instance(); $handler->setTimestamp( self::CACHE_SIGNATURE, time() ); $handler->store(); self::$wildcardsIndex = null; }
/** * Assign function names to input variables. Generates the wildcard cache if * expired. * * @return array The wildcards index, as an array of regexps */ protected static function wildcardsIndex() { if (self::$wildcardsIndex === null) { $cacheIndexFile = self::loadCacheFile(); // if NULL is returned, the cache doesn't exist or isn't valid self::$wildcardsIndex = $cacheIndexFile->processFile(array(__CLASS__, 'fetchCacheFile'), self::expiryTimestamp()); if (self::$wildcardsIndex === null) { // This will generate and return the index, and store the cache // files for the different wildcards for later use self::$wildcardsIndex = self::createWildcardsIndex(); } } return self::$wildcardsIndex; }
/** * Tests that wildcard matching is case insensitive. * * @link http://issues.ez.no/17524 */ public function testCaseInsensitiveMatch() { $uri = 'myROOTurl'; $this->assertTrue( eZURLWildcard::translate( $uri ) ); $this->assertEquals( 'content/view/full/2', $uri ); }
/** * Runs the dispatch loop */ protected function dispatchLoop() { $ini = eZINI::instance(); // Start the module loop while ($this->siteBasics['module-run-required']) { $objectHasMovedError = false; $objectHasMovedURI = false; $this->actualRequestedURI = $this->uri->uriString(); // Extract user specified parameters $userParameters = $this->uri->userParameters(); // Generate a URI which also includes the user parameters $this->completeRequestedURI = $this->uri->originalURIString(); // Check for URL translation if ($this->siteBasics['url-translator-allowed'] && eZURLAliasML::urlTranslationEnabledByUri($this->uri)) { $translateResult = eZURLAliasML::translate($this->uri); if (!is_string($translateResult) && $ini->variable('URLTranslator', 'WildcardTranslation') === 'enabled') { $translateResult = eZURLWildcard::translate($this->uri); } // Check if the URL has moved if (is_string($translateResult)) { $objectHasMovedURI = $translateResult; foreach ($userParameters as $name => $value) { $objectHasMovedURI .= '/(' . $name . ')/' . $value; } $objectHasMovedError = true; } } if ($this->uri->isEmpty()) { $tmp_uri = new eZURI($ini->variable("SiteSettings", "IndexPage")); $moduleCheck = eZModule::accessAllowed($tmp_uri); } else { $moduleCheck = eZModule::accessAllowed($this->uri); } if (!$moduleCheck['result']) { if ($ini->variable("SiteSettings", "ErrorHandler") == "defaultpage") { $defaultPage = $ini->variable("SiteSettings", "DefaultPage"); $this->uri->setURIString($defaultPage); $moduleCheck['result'] = true; } } $displayMissingModule = false; $this->oldURI = $this->uri; if ($this->uri->isEmpty()) { if (!fetchModule($tmp_uri, $this->check, $this->module, $moduleName, $functionName, $params)) { $displayMissingModule = true; } } else { if (!fetchModule($this->uri, $this->check, $this->module, $moduleName, $functionName, $params)) { if ($ini->variable("SiteSettings", "ErrorHandler") == "defaultpage") { $tmp_uri = new eZURI($ini->variable("SiteSettings", "DefaultPage")); if (!fetchModule($tmp_uri, $this->check, $this->module, $moduleName, $functionName, $params)) { $displayMissingModule = true; } } else { $displayMissingModule = true; } } } if (!$displayMissingModule && $moduleCheck['result'] && $this->module instanceof eZModule) { // Run the module/function eZDebug::addTimingPoint("Module start '" . $this->module->attribute('name') . "'"); $moduleAccessAllowed = true; $omitPolicyCheck = true; $runModuleView = true; $availableViewsInModule = $this->module->attribute('views'); if (!isset($availableViewsInModule[$functionName]) && !$objectHasMovedError && !isset($this->module->Module['function']['script'])) { $moduleResult = $this->module->handleError(eZError::KERNEL_MODULE_VIEW_NOT_FOUND, 'kernel', array("check" => $moduleCheck)); $runModuleView = false; $this->siteBasics['policy-check-required'] = false; $omitPolicyCheck = true; } if ($this->siteBasics['policy-check-required']) { $omitPolicyCheck = false; $moduleName = $this->module->attribute('name'); if (in_array($moduleName, $this->siteBasics['policy-check-omit-list'])) { $omitPolicyCheck = true; } else { $policyCheckViewMap = $this->getPolicyCheckViewMap($this->siteBasics['policy-check-omit-list']); if (isset($policyCheckViewMap[$moduleName][$functionName])) { $omitPolicyCheck = true; } } } if (!$omitPolicyCheck) { $currentUser = eZUser::currentUser(); $siteAccessResult = $currentUser->hasAccessTo('user', 'login'); $hasAccessToSite = false; if ($siteAccessResult['accessWord'] === 'limited') { $policyChecked = false; foreach (array_keys($siteAccessResult['policies']) as $key) { $policy = $siteAccessResult['policies'][$key]; if (isset($policy['SiteAccess'])) { $policyChecked = true; $crc32AccessName = eZSys::ezcrc32($this->access['name']); eZDebugSetting::writeDebug('kernel-siteaccess', $policy['SiteAccess'], $crc32AccessName); if (in_array($crc32AccessName, $policy['SiteAccess'])) { $hasAccessToSite = true; break; } } if ($hasAccessToSite) { break; } } if (!$policyChecked) { $hasAccessToSite = true; } } else { if ($siteAccessResult['accessWord'] === 'yes') { eZDebugSetting::writeDebug('kernel-siteaccess', "access is yes"); $hasAccessToSite = true; } else { if ($siteAccessResult['accessWord'] === 'no') { $accessList = $siteAccessResult['accessList']; } } } if ($hasAccessToSite) { $accessParams = array(); $moduleAccessAllowed = $currentUser->hasAccessToView($this->module, $functionName, $accessParams); if (isset($accessParams['accessList'])) { $accessList = $accessParams['accessList']; } } else { eZDebugSetting::writeDebug('kernel-siteaccess', $this->access, 'not able to get access to siteaccess'); $moduleAccessAllowed = false; if ($ini->variable("SiteAccessSettings", "RequireUserLogin") == "true") { $this->module = eZModule::exists('user'); if ($this->module instanceof eZModule) { $moduleResult = $this->module->run('login', array(), array('SiteAccessAllowed' => false, 'SiteAccessName' => $this->access['name'])); $runModuleView = false; } } } } $GLOBALS['eZRequestedModule'] = $this->module; if ($runModuleView) { if ($objectHasMovedError == true) { $moduleResult = $this->module->handleError(eZError::KERNEL_MOVED, 'kernel', array('new_location' => $objectHasMovedURI)); } else { if (!$moduleAccessAllowed) { if (isset($availableViewsInModule[$functionName]['default_navigation_part'])) { $defaultNavigationPart = $availableViewsInModule[$functionName]['default_navigation_part']; } if (isset($accessList)) { $moduleResult = $this->module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel', array('AccessList' => $accessList)); } else { $moduleResult = $this->module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel'); } if (isset($defaultNavigationPart)) { $moduleResult['navigation_part'] = $defaultNavigationPart; unset($defaultNavigationPart); } } else { if (!isset($userParameters)) { $userParameters = false; } // Check if we should switch access mode (http/https) for this module view. eZSSLZone::checkModuleView($this->module->attribute('name'), $functionName); $moduleResult = $this->module->run($functionName, $params, false, $userParameters); if ($this->module->exitStatus() == eZModule::STATUS_FAILED && $moduleResult == null) { $moduleResult = $this->module->handleError(eZError::KERNEL_MODULE_VIEW_NOT_FOUND, 'kernel', array('module' => $moduleName, 'view' => $functionName)); } } } } } else { if ($moduleCheck['result']) { eZDebug::writeError("Undefined module: {$moduleName}", "index"); $this->module = new eZModule("", "", $moduleName); $GLOBALS['eZRequestedModule'] = $this->module; $moduleResult = $this->module->handleError(eZError::KERNEL_MODULE_NOT_FOUND, 'kernel', array('module' => $moduleName)); } else { if ($moduleCheck['view_checked']) { eZDebug::writeError("View '" . $moduleCheck['view'] . "' in module '" . $moduleCheck['module'] . "' is disabled", "index"); } else { eZDebug::writeError("Module '" . $moduleCheck['module'] . "' is disabled", "index"); } $GLOBALS['eZRequestedModule'] = $this->module = new eZModule("", "", $moduleCheck['module']); $moduleResult = $this->module->handleError(eZError::KERNEL_MODULE_DISABLED, 'kernel', array('check' => $moduleCheck)); } } $this->siteBasics['module-run-required'] = false; if ($this->module->exitStatus() == eZModule::STATUS_RERUN) { if (isset($moduleResult['rerun_uri'])) { $this->uri = eZURI::instance($moduleResult['rerun_uri']); $this->siteBasics['module-run-required'] = true; } else { eZDebug::writeError('No rerun URI specified, cannot continue', 'index.php'); } } if (is_array($moduleResult)) { if (isset($moduleResult["pagelayout"])) { $this->siteBasics['show-page-layout'] = $moduleResult["pagelayout"]; $GLOBALS['eZCustomPageLayout'] = $moduleResult["pagelayout"]; } if (isset($moduleResult["external_css"])) { $this->siteBasics['external-css'] = $moduleResult["external_css"]; } } } return $moduleResult; }
// Start the module loop while ($moduleRunRequired) { $objectHasMovedError = false; $objectHasMovedURI = false; $actualRequestedURI = $uri->uriString(); // Extract user specified parameters $userParameters = $uri->userParameters(); // Generate a URI which also includes the user parameters $completeRequestedURI = $uri->originalURIString(); // Check for URL translation if ($urlTranslatorAllowed and eZURLAliasML::urlTranslationEnabledByUri($uri)) { $translateResult = eZURLAliasML::translate($uri); if (!is_string($translateResult)) { $useWildcardTranslation = $ini->variable('URLTranslator', 'WildcardTranslation') == 'enabled'; if ($useWildcardTranslation) { $translateResult = eZURLWildcard::translate($uri); } } // Check if the URL has moved if (is_string($translateResult)) { $objectHasMovedURI = $translateResult; foreach ($userParameters as $name => $value) { $objectHasMovedURI .= '/(' . $name . ')/' . $value; } $objectHasMovedError = true; } } if ($uri->isEmpty()) { $tmp_uri = new eZURI($ini->variable("SiteSettings", "IndexPage")); $moduleCheck = eZModule::accessAllowed($tmp_uri); } else {
/** * @covers eZURLWildcard::wildcardExists */ public function testWildcardExists() { self::assertFalse(eZURLWildcard::wildcardExists(__FUNCTION__ . md5(microtime()))); self::assertTrue(eZURLWildcard::wildcardExists($this->wildcardObjects['test/single-page']->attribute('source_url'))); self::assertTrue(eZURLWildcard::wildcardExists($this->wildcardObjects['is/it/working/*']->attribute('source_url'))); self::assertFalse(eZURLWildcard::wildcardExists('is/it/')); self::assertTrue(eZURLWildcard::wildcardExists('is/it/working/now')); self::assertTrue(eZURLWildcard::wildcardExists('is/it/working/now/yes')); }
/** * Helper function that removes all the wildcards from the database **/ public static function removeAllWildcards() { eZDB::instance()->query('DELETE FROM ezurlwildcard'); eZURLWildcard::expireCache(); clearstatcache(); sleep(1); }
/** * Helper method that creates a wildcard * * @param string $sourceURL * @param string $destinationURL * @param int $type * @return eZURLWildcard the created wildcard persistent object */ static public function createWildcard( $sourceURL, $destinationURL, $type ) { $row = array( 'source_url' => $sourceURL, 'destination_url' => $destinationURL, 'type' => $type ); $wildcard = new eZURLWildcard( $row ); $wildcard->store(); return $wildcard; }