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; }
/** * Transforms the URI if there exists an alias for it. * * @param eZURI|string $uri * @return mixed The translated URI if the resource has moved, or true|false * if translation was (un)successful */ public static function translate( &$uri ) { $result = false; // get uri string $uriString = ( $uri instanceof eZURI ) ? $uri->elements() : $uri; $uriString = eZURLAliasML::cleanURL( $uriString ); eZDebugSetting::writeDebug( 'kernel-urltranslator', "input uriString: '$uriString'", __METHOD__ ); if ( !$wildcards = self::wildcardsIndex() ) { eZDebugSetting::writeDebug( 'kernel-urltranslator', "no match callbacks", __METHOD__ ); return false; } $ini = eZINI::instance(); $iteration = $ini->variable( 'URLTranslator', 'MaximumWildcardIterations' ); eZDebugSetting::writeDebug( 'kernel-urltranslator', "MaximumWildcardIterations: '$iteration'", __METHOD__ ); // translate $urlTranslated = false; while ( !$urlTranslated && $iteration >= 0 ) { foreach ( $wildcards as $wildcardNum => $wildcard ) { if ( preg_match( $wildcard, $uriString ) ) { eZDebugSetting::writeDebug( 'kernel-urltranslator', "matched with: '$wildcard'", __METHOD__ ); // get new $uriString from wildcard self::translateWithCache( $wildcardNum, $uriString, $wildcardInfo, $wildcard ); eZDebugSetting::writeDebug( 'kernel-urltranslator', "new uri string: '$uriString'", __METHOD__ ); // optimization: don't try further translation if wildcard type is 'forward' if ( $wildcardInfo['type'] == self::TYPE_FORWARD ) { $urlTranslated = true; break; } // try to tranlsate if ( $urlTranslated = eZURLAliasML::translate( $uriString ) ) { // success eZDebugSetting::writeDebug( 'kernel-urltranslator', "uri is translated to '$uriString' with result '$urlTranslated'", __METHOD__ ); break; } eZDebugSetting::writeDebug( 'kernel-urltranslator', "uri is not translated, trying another wildcard", __METHOD__ ); // translation failed. Try to match new $uriString with another wildcard. --$iteration; continue 2; } } // we here if non of the wildcards is matched break; } // check translation result // NOTE: 'eZURLAliasML::translate'(see above) can return 'true', 'false' or new url(in case of 'error/301'). // $urlTranslated can also be 'false' if no wildcard is matched. if ( $urlTranslated ) { // check wildcard type and set appropriate $result and $uriString $wildcardType = $wildcardInfo['type']; eZDebugSetting::writeDebug( 'kernel-urltranslator', "wildcard type: $wildcardType", __METHOD__ ); switch ( $wildcardType ) { case self::TYPE_FORWARD: { // do redirect: // => set $result to translated uri // => set uri string to a MOVED PERMANENTLY HTTP code $result = $uriString; $uriString = 'error/301'; } break; default: { eZDebug::writeError( 'Invalid wildcard type.', __METHOD__ ); // no break, using eZURLWildcard::TYPE_DIRECT as fallback } case self::TYPE_DIRECT: { $result = $urlTranslated; // $uriString already has correct value break; } } } else { // we are here if: // - input url is not matched with any wildcard; // - url is matched with wildcard and: // - points to module // - invalide url eZDebugSetting::writeDebug( 'kernel-urltranslator', "wildcard is not translated", __METHOD__ ); $result = false; } // set value back to $uri if ( $uri instanceof eZURI ) { $uri->setURIString( $uriString, false ); } else { $uri = $uriString; } eZDebugSetting::writeDebug( 'kernel-urltranslator', "finished with url '$uriString' and result '$result'", __METHOD__ ); return $result; }
static function headerOverrideArray( $uri ) { $headerArray = array(); if ( !eZHTTPHeader::enabled() ) { return $headerArray; } $contentView = false; $uriString = eZURLAliasML::cleanURL( $uri->uriString() ); // If content/view used, get url alias for node if ( strpos( $uriString, 'content/view/' ) === 0 ) { $urlParts = explode( '/', $uriString ); $nodeID = $urlParts[3]; if ( !$nodeID ) { return $headerArray; } $node = eZContentObjectTreeNode::fetch( $nodeID ); if ( !$node ) { return $headerArray; } $uriString = $node->pathWithNames(); $contentView = true; } else { $uriCopy = clone $uri; eZURLAliasML::translate( $uriCopy ); if ( strpos( $uriCopy->uriString(), 'content/view' ) === 0 ) { $contentView = true; } } $uriString = '/' . eZURLAliasML::cleanURL( $uriString ); $ini = eZINI::instance(); foreach( $ini->variable( 'HTTPHeaderSettings', 'HeaderList' ) as $header ) { foreach( $ini->variable( 'HTTPHeaderSettings', $header ) as $path => $value ) { $path = '/' . eZURLAliasML::cleanURL( $path ); if ( strlen( $path ) == 1 && ( !$contentView && ( $ini->variable( 'HTTPHeaderSettings', 'OnlyForContent' ) === 'enabled' ) ) && $uriString != '/' ) { continue; } if ( strpos( $uriString, $path ) === 0 ) { @list( $headerValue, $depth, $level ) = explode( ';', $value ); if ( $header == 'Expires' ) { $headerValue = gmdate( 'D, d M Y H:i:s', time() + $headerValue ) . ' GMT'; } if ( $depth === null ) { $headerArray[$header] = $headerValue; } else { $pathLevel = count( explode( '/', $path ) ); $uriLevel = count( explode( '/', $uriString ) ); if ( $level === null ) { if ( $uriLevel <= $pathLevel + $depth ) { $headerArray[$header] = $headerValue; } } else { if ( $uriLevel <= $pathLevel + $depth && $uriLevel >= $pathLevel + $level ) { $headerArray[$header] = $headerValue; } } } } } } return $headerArray; }
public function testCleanURL() { $url1 = "/content/view/full/2"; $url2 = "/////content/view/full/2/"; $url3 = "/content/view/full/2///"; $url4 = "///content/view/full/2///"; $url5 = "/content/view//full/2/"; self::assertEquals("content/view/full/2", eZURLAliasML::cleanURL($url1)); self::assertEquals("content/view/full/2", eZURLAliasML::cleanURL($url2)); self::assertEquals("content/view/full/2", eZURLAliasML::cleanURL($url3)); self::assertEquals("content/view/full/2", eZURLAliasML::cleanURL($url4)); self::assertEquals("content/view//full/2", eZURLAliasML::cleanURL($url5)); // Make sure funky characters doesn't get messed up $invalidUrl = "/ウーラ/"; self::assertEquals("ウーラ", eZURLAliasML::cleanURL($invalidUrl)); }
/** * Returns the node's url alias * * @return string */ function urlAlias() { $useURLAlias =& $GLOBALS['eZContentObjectTreeNodeUseURLAlias']; $ini = eZINI::instance(); $cleanURL = ''; if (!isset($useURLAlias)) { $useURLAlias = $ini->variable('URLTranslator', 'Translation') == 'enabled'; } if ($useURLAlias) { $path = $this->pathWithNames(); if ($ini->hasVariable('SiteAccessSettings', 'PathPrefix') && $ini->variable('SiteAccessSettings', 'PathPrefix') != '') { $prepend = $ini->variable('SiteAccessSettings', 'PathPrefix'); $pathIdenStr = substr($prepend, strlen($prepend) - 1) == '/' ? $path . '/' : $path; if (strncasecmp($pathIdenStr, $prepend, strlen($prepend)) == 0) { $cleanURL = eZURLAliasML::cleanURL(substr($path, strlen($prepend))); } else { $cleanURL = eZURLAliasML::cleanURL($path); } } else { $cleanURL = eZURLAliasML::cleanURL($path); } } else { $cleanURL = eZURLAliasML::cleanURL('content/view/full/' . $this->NodeID); } return $cleanURL; }
/** * Handles collections on the virtual folder level, if no virtual folder * elements are accessed it lists the virtual folders. * * An entry in the the returned array is of this form: * <code> * array( 'name' => node name (eg. 'Group picture'), * 'size' => storage size of the_node in bytes (eg. 57123), * 'mimetype' => mime type of the node (eg. 'image/jpeg'), * 'ctime' => creation time as timestamp, * 'mtime' => latest modification time as timestamp, * 'href' => the path to the node (eg. '/plain_site_user/Content/Folder1/file1.jpg') * </code> * * @param string $site Eg. 'plain_site_user * @param string $collection Eg. 'Folder1' * @param string $fullPath Eg. '/plain_site_user/Content/Folder1' * @param string $depth One of -1 (infinite), 0, 1 * @param array(string) $properties Currently not used * @return array(array(string=>mixed)) */ protected function getVirtualFolderCollection($currentSite, $collection, $fullPath, $depth, $properties) { if (!$collection) { // We are inside a site so we display the virtual folder for the site $entries = $this->fetchVirtualSiteContent($fullPath, $currentSite, $depth, $properties); return $entries; } $collection = $this->splitFirstPathElement($collection, $virtualFolder); if (!in_array($virtualFolder, array(self::virtualContentFolderName(), self::virtualMediaFolderName()))) { return false; // self::FAILED_NOT_FOUND; } // added by @ds 2008-12-07 to fix problems with IE6 SP2 $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", $collection)) { $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", $collection)) { $breakInternalURI = true; break; } } if (!$breakInternalURI) { $collection = $prefix . '/' . $collection; $prefixAdded = true; } } } return $this->getContentTreeCollection($currentSite, $virtualFolder, $collection, $fullPath, $depth, $properties); }