/*!
\private
\static
Perform reverse translation of uri, that is from system-url to url alias.
437042
static public function reverseTranslate( &$uri, $uriString, $internalURIString )
    {
        $db = eZDB::instance();

        $action = eZURLAliasML::urlToAction( $internalURIString );
        if ( $action !== false )
        {
            $langMask = trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) );
            $actionStr = $db->escapeString( $action );
            $query = "SELECT id, parent, lang_mask, text, action FROM ezurlalias_ml WHERE ($langMask) AND action='{$actionStr}' AND is_original = 1 AND is_alias = 0";
            $rows = $db->arrayQuery( $query );
            $path = array();
            $count = count( $rows );
            if ( $count != 0 )
            {
                $row = eZURLAliasML::choosePrioritizedRow( $rows );
                if ( $row === false )
                {
                    $row = $rows[0];
                }
                $paren = (int)$row['parent'];
                $path[] = $row['text'];
                // We have the parent so now do an iterative lookup until we have the top element
                while ( $paren != 0 )
                {
                    $query = "SELECT id, parent, lang_mask, text FROM ezurlalias_ml WHERE ($langMask) AND id=$paren AND is_original = 1 AND is_alias = 0";
                    $rows = $db->arrayQuery( $query );
                    $count = count( $rows );
                    if ( $count != 0 )
                    {
                        $row = eZURLAliasML::choosePrioritizedRow( $rows );
                        if ( $row === false )
                        {
                            $row = $rows[0];
                        }
                        $paren = (int)$row['parent'];
                        array_unshift( $path, $row['text'] );
                    }
                    else
                    {
                        eZDebug::writeError( "Lookup of parent ID $paren failed, cannot perform reverse lookup of alias." );
                        return false;
                    }
                }
                $uriString = join( '/', $path );
                $uriString = self::removePathPrefixFromURI( $uriString );
                if ( $uri instanceof eZURI )
                {
                    $uri->setURIString( $uriString, false );
                }
                else
                {
                    $uri = $uriString;
                }
                return true;
            }
            else
            {
                return false;
            }
        }
        return false;
    }
942328
function urlFor($internalUri, $locale = NULL){
        $internalUri= ltrim($internalUri, '/');
        if($locale == NULL)return $this->request->realBaseUrl . $internalUri;
        else return $this->request->realBaseUrl . $locale . '/' . $internalUri;
    }
115594
public function extract()
    {
        
        $this->setTranslationUnits(array());
        foreach ($this->getPaths() as $dir) {
        	// Directories should come with a trailing slash.
        	$d = strrev($dir);
        	if ($d[0] !== '/') {
        		$dir = $dir . '/';	
        	}
        	
        	$this->recursiveSearch($dir);
        }
        
    }
284009
private static function createUriString($scheme, $authority, $path, $query, $fragment)
    {
        $uri = '';

        if (!empty($scheme)) {
            $uri .= $scheme . '://';
        }

        if (!empty($authority)) {
            $uri .= $authority;
        }

        if ($path != null) {
            $uri .= $path;
        }

        if ($query != null) {
            $uri .= '?' . $query;
        }

        if ($fragment != null) {
            $uri .= '#' . $fragment;
        }

        return $uri;
    }
806121
function convertToAlias(id, paths) {
    var invertedPaths = _.invert(paths);
    if (invertedPaths[id]) {
        return invertedPaths[id];
    }
    else {
        return id;
    }
}
1239480
protected function relativeUrl($from='', $to='')
    {
        $from = explode('/', ltrim($from, '/'));
        $to   = explode('/', ltrim($to, '/'));
        $last = false;
        while (count($from) && count($to) && $from[0] === $to[0]) {
            $last = array_shift($from);
            array_shift($to);
        }
        if (count($from) == 0) {
            if ($last) array_unshift($to, $last);
            return './' . implode('/', $to);
        }
        else {
            return './' . str_repeat('../', count($from)-1) . implode('/', $to);
        }
    }
966343
protected function processUriCallback($matches)
    {
        $isImport = $matches[0][0] === '@';

        // Determine what the quote character and the URI is, if there is one.
        $quoteCharacter = $uri = null;

        if ($isImport)
        {
            $quoteCharater = $matches[1];

            $uri = $matches[2];
        }
        else
        {
            if ($matches[1][0] === "'" or $matches[1][0] === '"')
            {
                $quoteCharacter = $matches[1][0];
            }

            if ( ! $quoteCharacter)
            {
                $uri = $matches[1];
            }
            else
            {
                $uri = substr($matches[1], 1, strlen($matches[1]) - 2);
            }
        }

        // Analyze the URI
        if ($uri[0] !== '/' and strpos($uri, '//') === false and strpos($uri, 'data') !== 0)
        {
            $uri = $this->rewriteRelative($uri);
        }

        if ($isImport)
        {
            return "@import {$quoteCharacter}{$uri}{$quoteCharacter}";
        }

        return "url({$quoteCharacter}{$uri}{$quoteCharacter})";
    }
43249
function _fetch_uri_string() {
		$uri="";
		if ($this->uri_protocol == 'AUTO') {
			// Is the request coming from the command line?
			if (php_sapi_name() == 'cli' || defined('STDIN')) {
				$this->_set_uri_string($this->_parse_cli_args());
				return;
			}

			// Let's try the REQUEST_URI first, this will work in most situations
			if ($uri=$this->_detect_uri()) {
				$this->_set_uri_string($uri);
				return;
			}

			// Is there a PATH_INFO variable?
			// Note: some servers seem to have trouble with getenv() so we'll test it two ways
			$path=(isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
			if (trim($path, '/') != '' && $path != "/" . SELF) {
				$this->_set_uri_string($path);
				return;
			}

			// No PATH_INFO?... What about QUERY_STRING?
			$path=(isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
			if (trim($path, '/') != '') {
				$this->_set_uri_string($path);
				return;
			}

			// As a last ditch effort lets try using the $_GET array
			if (\is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '') {
				$this->_set_uri_string(key($_GET));
				return;
			}

			// We've exhausted all our options...
			$this->uri_string='';
			return;
		}

		if ($uri == 'REQUEST_URI') {
			$this->_set_uri_string($this->_detect_uri());
			return;
		}

		$path=(isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
		$this->_set_uri_string($path);
	}
1352618
public function composeUri($params)
    {
        $ret   = '';
        $first = true;

        foreach ($params as $param => $values) {
            if (!$first) {
                $ret .= $this->seperators['param'];
            }
            $first    = false;
            $internal = $param;
            if ($external = $this->translateKeyOutput($param)) {
                $param = $external;
            }
            $ret .= $param . $this->seperators['key_value'];
            $firstValue = true;
            foreach ($values as $value) {
                if ($external = $this->translateValueOutput($internal, $value)) {
                    $value = $external;
                }
                if (!$firstValue) {
                    $ret .= $this->seperators['value'];
                } else {
                    $firstValue = false;
                }
                $ret .= urlencode($value);
            }
        }

        return $ret;
    }
1242113
function relativeURI(uri, base) {
    
    // reduce base and uri strings to just their difference string
    var baseParts = base.split('/');
    baseParts.pop();
    base = baseParts.join('/') + '/';
    i = 0;
    while (base.substr(i, 1) == uri.substr(i, 1))
      i++;
    while (base.substr(i, 1) != '/')
      i--;
    base = base.substr(i + 1);
    uri = uri.substr(i + 1);

    // each base folder difference is thus a backtrack
    baseParts = base.split('/');
    var uriParts = uri.split('/');
    out = '';
    while (baseParts.shift())
      out += '../';
    
    // finally add uri parts
    while (curPart = uriParts.shift())
      out += curPart + '/';
    
    return out.substr(0, out.length - 1);
  }
462571
public function reverse($encoding = null)
    {
        $reversed = '';

        if (!$this->hasMbstring()) {
            $len = \strlen($this->string);
            for ($i = $len - 1; $i >= 0; --$i) {
                $reversed .= \substr($this->string, $i, 1);
            }
        } else {
            $encoding = $this->encoding($encoding);

            $len = \mb_strlen($this->string, $encoding);
            for ($i = $len - 1; $i >= 0; --$i) {
                $reversed .= \mb_substr($this->string, $i, 1, $encoding);
            }
        }

        $this->string = $reversed;
        return $this;
    }
296031
def _prefix_from_uri(self, uriname):
        
        uripart, tag = uriname.split('}', maxsplit=1)
        uri = uripart.replace('{', '')
        return self.REVERSE_NS[uri] + ':' + tag
288097
public function destinationUrl()
    {
        $nodeId = $this->origUrl;
        $urlAlias = '';

        if ( !is_numeric( $this->origUrl ) )
        {
            if ( !$this->isUrlPointingToModule( $this->origUrl ) )
            {
                $this->origUrl = self::addPathPrefixIfNeeded( $this->origUrl );
            }

            $nodeId = eZURLAliasML::fetchNodeIDByPath( $this->origUrl );
        }

        $siteLanguageList = $this->getSiteAccessIni()->variable( 'RegionalSettings', 'SiteLanguageList' );
        // set prioritized languages of destination SA, and fetch corresponding (prioritized) URL alias
        eZContentLanguage::setPrioritizedLanguages( $siteLanguageList );
        $destinationElement = eZURLAliasML::fetchByAction( 'eznode', $nodeId, false, true );

        eZContentLanguage::clearPrioritizedLanguages();

        if ( empty( $destinationElement ) || ( !isset( $destinationElement[0] ) && !( $destinationElement[0] instanceof eZURLAliasML ) ) )
        {
            // If the return of fetchByAction is empty, it can mean a couple
            // of different things:
            // Either we are looking at a module, and we should pass the
            // original URL on
            //
            // Or we are looking at URL which does not exist in the
            // destination siteaccess, for instance an untranslated object. In
            // which case we will point to the root of the site, unless it is
            // available as a fallback.
            if ( $nodeId )
            {
                $urlAlias = $this->origUrl;

                // if applicable, remove destination PathPrefix from url
                if ( !self::removePathPrefixIfNeeded( $this->getSiteAccessIni(), $urlAlias ) )
                {
                    // If destination siteaccess has a PathPrefix but url is not matched,
                    // also check current SA's prefix, and remove if it matches.
                    self::removePathPrefixIfNeeded( eZINI::instance( 'site.ini' ), $urlAlias );
                }
            }
            else
            {
                if ( $this->isUrlPointingToModule( $this->origUrl ) )
                {
                    $urlAlias = $this->origUrl;
                }
            }
        }
        else
        {
            // Translated object found, forwarding to new URL.
            $urlAlias = $destinationElement[0]->getPath( $this->destinationLocale, $siteLanguageList );

            // if applicable, remove destination PathPrefix from url
            self::removePathPrefixIfNeeded( $this->getSiteAccessIni(), $urlAlias );

            $urlAlias .= $this->userParamString;
        }

        $this->baseDestinationUrl = rtrim( $this->baseDestinationUrl, '/' );

        $ini = eZINI::instance();

        if ( $GLOBALS['eZCurrentAccess']['type'] === eZSiteAccess::TYPE_URI &&
             !( $ini->variable( 'SiteAccessSettings', 'RemoveSiteAccessIfDefaultAccess' ) === "enabled" &&
                $ini->variable( 'SiteSettings', 'DefaultAccess' ) == $this->destinationSiteAccess ) )
        {
            $finalUrl = $this->baseDestinationUrl . '/' . $this->destinationSiteAccess . '/' . $urlAlias;
        }
        else
        {
            $finalUrl = $this->baseDestinationUrl . '/' . $urlAlias;
        }
        if ( $this->queryString != '' )
        {
            $finalUrl .= '?' . $this->queryString;
        }
        return $finalUrl;
    }
1021258
public function resolveRelativeUri(string $uri): string
    {
        $parts = parse_url($uri);
        if (isset($parts['scheme'])) {
            // absolute URL
            return $uri;
        }

        $baseUri = $this->getUri();
        if (strncmp($baseUri, 'file://', 7) === 0) {
            if (isset($parts['path'][0]) && $parts['path'][0] === '/') {
                // absolute path
                return 'file://' . $parts['path'];
            }
            if (isset($parts['path'])) {
                // relative path
                return dirname($baseUri) . '/' . $parts['path'];
            }

            throw new UnresolvableReferenceException("Invalid URI: '$uri'");
        }

        $baseParts = parse_url($baseUri);
        $absoluteUri = implode('', [
            $baseParts['scheme'],
            '://',
            isset($baseParts['username']) ? $baseParts['username'] . (
                isset($baseParts['password']) ? ':' . $baseParts['password'] : ''
            ) . '@' : '',
            $baseParts['host'] ?? '',
            isset($baseParts['port']) ? ':' . $baseParts['port'] : '',
        ]);
        if (isset($parts['path'][0]) && $parts['path'][0] === '/') {
            $absoluteUri .= $parts['path'];
        } elseif (isset($parts['path'])) {
            $absoluteUri .= rtrim(dirname($baseParts['path'] ?? ''), '/') . '/' . $parts['path'];
        }
        return $absoluteUri
            . (isset($parts['query']) ? '?' . $parts['query'] : '')
            . (isset($parts['fragment']) ? '#' . $parts['fragment'] : '');
    }
1133113
public function reverse(): Utility
    {
        $string = '';

        for ($i = $this->length() - 1; $i >= 0; $i--) {
            $string .= \mb_substr($this->string, $i, 1, $this->encoding);
        }

        return new static($string, $this->encoding);
    }
703200
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;
    }
1156404
private function prepareUriForLocalhostAccess($uri)
    {
        $public = 'public';
        $index = 'index.php';

        if (strpos($uri, $index)) {
            return substr($uri, strpos($uri, $index) + strlen($index));
        } elseif (strpos($uri, $public)) {
            return substr($uri, strpos($uri, $public) + strlen($public));
        }

        return false;
    }