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; }