Вход Регистрация
Файл: contao-3.5.8/system/modules/core/library/Contao/Environment.php
Строк: 518
<?php

/**
 * Contao Open Source CMS
 *
 * Copyright (c) 2005-2016 Leo Feyer
 *
 * @license LGPL-3.0+
 */

namespace Contao;


/**
 * Reads the environment variables
 *
 * The class returns the environment variables (which are stored in the PHP
 * $_SERVER array) independent of the operating system.
 *
 * Usage:
 *
 *     echo Environment::get('scriptName');
 *     echo Environment::get('requestUri');
 *
 * @author Leo Feyer <https://github.com/leofeyer>
 */
class Environment
{

    
/**
     * Object instance (Singleton)
     * @var Environment
     */
    
protected static $objInstance;

    
/**
     * Cache
     * @var array
     */
    
protected static $arrCache = array();


    
/**
     * Return an environment variable
     *
     * @param string $strKey The variable name
     *
     * @return mixed The variable value
     */
    
public static function get($strKey)
    {
        if (isset(static::
$arrCache[$strKey]))
        {
            return static::
$arrCache[$strKey];
        }

        if (
in_array($strKey, get_class_methods('Environment')))
        {
            static::
$arrCache[$strKey] = static::$strKey();
        }
        else
        {
            
$arrChunks = preg_split('/([A-Z][a-z]*)/', $strKey, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
            
$strServerKey = strtoupper(implode('_', $arrChunks));
            static::
$arrCache[$strKey] = $_SERVER[$strServerKey];
        }

        return static::
$arrCache[$strKey];
    }


    
/**
     * Set an environment variable
     *
     * @param string $strKey   The variable name
     * @param mixed  $varValue The variable value
     */
    
public static function set($strKey, $varValue)
    {
        static::
$arrCache[$strKey] = $varValue;
    }


    
/**
     * Return the absolute path to the script (e.g. /home/www/html/website/index.php)
     *
     * @return string The absolute path to the script
     */
    
protected static function scriptFilename()
    {
        return 
str_replace('//', '/', str_replace('\', '/', (PHP_SAPI == 'cgi' || PHP_SAPI == 'isapi' || PHP_SAPI == 'cgi-fcgi' || PHP_SAPI == 'fpm-fcgi') && ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) ? ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) : ($_SERVER['ORIG_SCRIPT_FILENAME'] ? $_SERVER['ORIG_SCRIPT_FILENAME'] : $_SERVER['SCRIPT_FILENAME'])));
    }


    /**
     * Return the relative path to the script (e.g. /website/index.php)
     *
     * @return string The relative path to the script
     */
    protected static function scriptName()
    {
        return (PHP_SAPI == '
cgi' || PHP_SAPI == 'isapi' || PHP_SAPI == 'cgi-fcgi' || PHP_SAPI == 'fpm-fcgi') && ($_SERVER['ORIG_PATH_INFO'] ? $_SERVER['ORIG_PATH_INFO'] : $_SERVER['PATH_INFO']) ? ($_SERVER['ORIG_PATH_INFO'] ? $_SERVER['ORIG_PATH_INFO'] : $_SERVER['PATH_INFO']) : ($_SERVER['ORIG_SCRIPT_NAME'] ? $_SERVER['ORIG_SCRIPT_NAME'] : $_SERVER['SCRIPT_NAME']);
    }


    /**
     * Alias for scriptName()
     *
     * @return string The script name
     */
    protected static function phpSelf()
    {
        return static::scriptName();
    }


    /**
     * Return the document root (e.g. /home/www/user/)
     *
     * Calculated as SCRIPT_FILENAME minus SCRIPT_NAME as some CGI versions
     * and mod-rewrite rules might return an incorrect DOCUMENT_ROOT.
     *
     * @return string The document root
     */
    protected static function documentRoot()
    {
        $strDocumentRoot = '';
        $arrUriSegments = array();
        $scriptName = static::get('
scriptName');
        $scriptFilename = static::get('
scriptFilename');

        // Fallback to DOCUMENT_ROOT if SCRIPT_FILENAME and SCRIPT_NAME point to different files
        if (basename($scriptName) != basename($scriptFilename))
        {
            return str_replace('
//', '/', str_replace('\', '/', realpath($_SERVER['DOCUMENT_ROOT'])));
        
}

        if (
substr($scriptFilename, 0, 1) == '/')
        {
            
$strDocumentRoot = '/';
        }

        
$arrSnSegments = explode('/', strrev($scriptName));
        
$arrSfnSegments = explode('/', strrev($scriptFilename));

        foreach (
$arrSfnSegments as $k=>$v)
        {
            if (
$arrSnSegments[$k] != $v)
            {
                
$arrUriSegments[] = $v;
            }
        }

        
$strDocumentRoot .= strrev(implode('/', $arrUriSegments));

        if (
strlen($strDocumentRoot) < 2)
        {
            
$strDocumentRoot = substr($scriptFilename, 0, -(strlen($strDocumentRoot) + 1));
        }

        return 
str_replace('//', '/', str_replace('\', '/', realpath($strDocumentRoot)));
    }


    /**
     * Return the query string (e.g. id=2)
     *
     * @return string The query string
     */
    protected static function queryString()
    {
        if (!isset($_SERVER['
QUERY_STRING']))
        {
            return '';
        }

        return static::encodeRequestString($_SERVER['
QUERY_STRING']);
    }


    /**
     * Return the request URI [path]?[query] (e.g. /contao/index.php?id=2)
     *
     * @return string The request URI
     */
    protected static function requestUri()
    {
        if (!empty($_SERVER['
REQUEST_URI']))
        {
            $strRequest = $_SERVER['
REQUEST_URI'];
        }
        else
        {
            $strRequest = '
/' . preg_replace('/^//', '', static::get('scriptName')) . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '');
        
}

        return static::
encodeRequestString($strRequest);
    }


    
/**
     * Return the first eight accepted languages as array
     *
     * @return array The languages array
     *
     * @author Leo Unglaub <https://github.com/LeoUnglaub>
     */
    
protected static function httpAcceptLanguage()
    {
        
$arrAccepted = array();
        
$arrLanguages = array();

        
// The implementation differs from the original implementation and also works with .jp browsers
        
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)s*(;s*qs*=s*(1|0.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $arrAccepted);

        
// Remove all invalid locales
        
foreach ($arrAccepted[1] as $v)
        {
            
$chunks = explode('-', $v);

            
// Language plus dialect, e.g. en-US or fr-FR
            
if (isset($chunks[1]))
            {
                
$locale = $chunks[0] . '-' . strtoupper($chunks[1]);

                if (
preg_match('/^[a-z]{2}(-[A-Z]{2})?$/', $locale))
                {
                    
$arrLanguages[] = $locale;
                }
            }

            
$locale = $chunks[0];

            
// Language only, e.g. en or fr (see #29)
            
if (preg_match('/^[a-z]{2}$/', $locale))
            {
                
$arrLanguages[] = $locale;
            }
        }

        return 
array_slice(array_unique($arrLanguages), 0, 8);
    }


    
/**
     * Return accepted encoding types as array
     *
     * @return array The encoding types array
     */
    
protected static function httpAcceptEncoding()
    {
        return 
array_values(array_unique(explode(',', strtolower($_SERVER['HTTP_ACCEPT_ENCODING']))));
    }


    
/**
     * Return the user agent as string
     *
     * @return string The user agent string
     */
    
protected static function httpUserAgent()
    {
        
$ua = strip_tags($_SERVER['HTTP_USER_AGENT']);
        
$ua = preg_replace('/javascript|vbscri?pt|script|applet|alert|document|write|cookie/i', '', $ua);

        return 
substr($ua, 0, 255);
    }


    
/**
     * Return the HTTP Host
     *
     * @return string The host name
     */
    
protected static function httpHost()
    {
        if (!empty(
$_SERVER['HTTP_HOST']))
        {
            
$host = $_SERVER['HTTP_HOST'];
        }
        else
        {
            
$host = $_SERVER['SERVER_NAME'];

            if (
$_SERVER['SERVER_PORT'] != 80)
            {
                
$host .= ':' . $_SERVER['SERVER_PORT'];
            }
        }

        return 
preg_replace('/[^A-Za-z0-9[].:-]/', '', $host);
    }


    
/**
     * Return the HTTP X-Forwarded-Host
     *
     * @return string The name of the X-Forwarded-Host
     */
    
protected static function httpXForwardedHost()
    {
        return 
preg_replace('/[^A-Za-z0-9[].:-]/', '', $_SERVER['HTTP_X_FORWARDED_HOST']);
    }


    
/**
     * Return true if the current page was requested via an SSL connection
     *
     * @return boolean True if SSL is enabled
     */
    
protected static function ssl()
    {
        return (
$_SERVER['SSL_SESSION_ID'] || $_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1);
    }


    
/**
     * Return the current URL without path or query string
     *
     * @return string The URL
     */
    
protected static function url()
    {
        
$host = static::get('httpHost');
        
$xhost = static::get('httpXForwardedHost');

        
// SSL proxy
        
if ($xhost != '' && $xhost == Config::get('sslProxyDomain'))
        {
            return 
'https://' .  $xhost . '/' . $host;
        }

        return (static::
get('ssl') ? 'https://' : 'http://') . $host;
    }


    
/**
     * Return the current URL with path or query string
     *
     * @return string The URL
     */
    
protected static function uri()
    {
        return static::
get('url') . static::get('requestUri');
    }


    
/**
     * Return the real REMOTE_ADDR even if a proxy server is used
     *
     * @return string The IP address of the client
     */
    
protected static function ip()
    {
        
// No X-Forwarded-For IP
        
if (empty($_SERVER['HTTP_X_FORWARDED_FOR']) || !preg_match('/^[A-Fa-f0-9, .:]+$/', $_SERVER['HTTP_X_FORWARDED_FOR']))
        {
            return 
substr($_SERVER['REMOTE_ADDR'], 0, 64);
        }

        
$strXip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        
$arrTrusted = trimsplit(',', Config::get('proxyServerIps'));

        
// Generate an array of X-Forwarded-For IPs
        
if (strpos($strXip, ',') !== false)
        {
            
$arrIps = trimsplit(',', $strXip);
        }
        else
        {
            
$arrIps = array($strXip);
        }

        
$arrIps = array_reverse($arrIps);

        
// Return the first untrusted IP address (see #5830)
        
foreach ($arrIps as $strIp)
        {
            if (!
in_array($strIp, $arrTrusted))
            {
                return 
substr($strIp, 0, 64);
            }
        }

        
// If all X-Forward-For IPs are trusted, return the remote address
        
return substr($_SERVER['REMOTE_ADDR'], 0, 64);
    }


    
/**
     * Return the SERVER_ADDR
     *
     * @return string The IP address of the server
     */
    
protected static function server()
    {
        
$strServer = !empty($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : $_SERVER['LOCAL_ADDR'];

        
// Special workaround for Strato users
        
if (empty($strServer))
        {
            
$strServer = @gethostbyname($_SERVER['SERVER_NAME']);
        }

        return 
$strServer;
    }


    
/**
     * Return the relative path to the base directory (e.g. /path)
     *
     * @return string The relative path to the installation
     */
    
protected static function path()
    {
        return 
TL_PATH;
    }


    
/**
     * Return the relativ path to the script (e.g. index.php)
     *
     * @return string The relative path to the script
     */
    
protected static function script()
    {
        return 
preg_replace('/^' . preg_quote(TL_PATH, '/') . '/?/', '', static::get('scriptName'));
    }


    
/**
     * Return the relativ path to the script and include the request (e.g. index.php?id=2)
     *
     * @return string The relative path to the script including the request string
     */
    
protected static function request()
    {
        return 
preg_replace('/^' . preg_quote(TL_PATH, '/') . '/?/', '', static::get('requestUri'));
    }


    
/**
     * Return the request string without the index.php fragment
     *
     * @return string The request string without the index.php fragment
     */
    
protected static function indexFreeRequest()
    {
        
$strRequest = static::get('request');

        if (
$strRequest == 'index.php')
        {
            return 
'';
        }

        return 
$strRequest;
    }


    
/**
     * Return the URL and path that can be used in a <base> tag
     *
     * @return string The base URL
     */
    
protected static function base()
    {
        return static::
get('url') . TL_PATH . '/';
    }


    
/**
     * Return the host name
     *
     * @return string The host name
     */
    
protected static function host()
    {
        return static::
get('httpHost');
    }


    
/**
     * Return true on Ajax requests
     *
     * @return boolean True if it is an Ajax request
     */
    
protected static function isAjaxRequest()
    {
        return (isset(
$_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest');
    }


    
/**
     * Return the operating system and the browser name and version
     *
     * @return object The agent information
     */
    
protected static function agent()
    {
        
$ua = static::get('httpUserAgent');

        
$return = new stdClass();
        
$return->string = $ua;

        
$os = 'unknown';
        
$mobile = false;
        
$browser = 'other';
        
$shorty = '';
        
$version = '';
        
$engine = '';

        
// Operating system
        
foreach (Config::get('os') as $k=>$v)
        {
            if (
stripos($ua, $k) !== false)
            {
                
$os = $v['os'];
                
$mobile = $v['mobile'];
                break;
            }
        }

        
$return->os = $os;

        
// Browser and version
        
foreach (Config::get('browser') as $k=>$v)
        {
            if (
stripos($ua, $k) !== false)
            {
                
$browser = $v['browser'];
                
$shorty  = $v['shorty'];
                
$version = preg_replace($v['version'], '$1', $ua);
                
$engine  = $v['engine'];
                break;
            }
        }

        
$versions = explode('.', $version);
        
$version  = $versions[0];

        
$return->class = $os . ' ' . $browser . ' ' . $engine;

        
// Add the version number if available
        
if ($version != '')
        {
            
$return->class .= ' ' . $shorty . $version;
        }

        
// Android tablets are not mobile (see #4150 and #5869)
        
if ($os == 'android' && $engine != 'presto' && stripos($ua, 'mobile') === false)
        {
            
$mobile = false;
        }

        
// Mark mobile devices
        
if ($mobile)
        {
            
$return->class .= ' mobile';
        }

        
$return->browser  = $browser;
        
$return->shorty   = $shorty;
        
$return->version  = $version;
        
$return->engine   = $engine;
        
$return->versions = $versions;
        
$return->mobile   = $mobile;

        return 
$return;
    }


    
/**
     * Encode a request string preserving certain reserved characters
     *
     * @param string $strRequest The request string
     *
     * @return string The encoded request string
     */
    
protected static function encodeRequestString($strRequest)
    {
        return 
preg_replace_callback('/[^A-Za-z0-9-_.~&=+,/?%[]]+/', function($matches) { return rawurlencode($matches[0]); }, $strRequest);
    }


    
/**
     * Prevent direct instantiation (Singleton)
     *
     * @deprecated Environment is now a static class
     */
    
protected function __construct() {}


    
/**
     * Prevent cloning of the object (Singleton)
     *
     * @deprecated Environment is now a static class
     */
    
final public function __clone() {}


    
/**
     * Return an environment variable
     *
     * @param string $strKey The variable name
     *
     * @return string The variable value
     *
     * @deprecated Use Environment::get() instead
     */
    
public function __get($strKey)
    {
        return static::
get($strKey);
    }


    
/**
     * Set an environment variable
     *
     * @param string $strKey   The variable name
     * @param mixed  $varValue The variable value
     *
     * @deprecated Use Environment::set() instead
     */
    
public function __set($strKey, $varValue)
    {
        static::
set($strKey, $varValue);
    }


    
/**
     * Return the object instance (Singleton)
     *
     * @return Environment The object instance
     *
     * @deprecated Environment is now a static class
     */
    
public static function getInstance()
    {
        if (static::
$objInstance === null)
        {
            static::
$objInstance = new static();
        }

        return static::
$objInstance;
    }
}
Онлайн: 3
Реклама