Вход Регистрация
Файл: library/XenForo/Phrase.php
Строк: 244
<?php

/**
* Phrase rendering class.
*
* @package XenForo_Core
*/
class XenForo_Phrase
{
    
/**
    * Cached phrase data. Key is the phrase name; value is the phrase text.
    *
    * @var array
    */
    
protected static $_phraseCache = array();

    
/**
    * A list of phrases that still need to be loaded. Key is the phrase name.
    *
    * @var array
    */
    
protected static $_toLoad = array();

    
/**
     * The function that should be called to escape phrase parameters. This should
     * be set by the view renderer. Set it to false to disable escaping completely.
     *
     * @param false|callback
     */
    
protected static $_escapeCallback 'htmlspecialchars';

    
/**
    * Name of the phrase to load.
    *
    * @var string
    */
    
protected $_phraseName;

    
/**
    * Key-value params to make available in the phrase.
    *
    * @var array
    */
    
protected $_params = array();

    
/**
    * Whether the params should be inserted into the phrase raw or escaped.
    * If this is true or false, it applies to all params. If it is an array,
    * the individual params are looked up as keys and the value is treated as a
    * a boolean; params that aren't set will be escaped.
    *
    * @var boolean|array
    */
    
protected $_insertParamsEscaped true;

    
/**
     * Controls whether the phrase name should be output when the value is invalid.
     *
     * @var boolean
     */
    
protected $_phraseNameOnInvalid true;

    
/**
     * The ID of the language that phrases will be retrieved from.
     *
     * @var integer
     */
    
protected static $_languageId 0;

    
/**
    * Constructor
    *
    * @param string|array  Phrase name (or, array(phraseName, arg1 => x, arg2 => y...)
    * @param array         Key-value parameters
    * @param boolean|array See {@link $_insertParamsEscaped}
    */
    
public function __construct($phraseName, array $params = array(), $insertParamsEscaped true)
    {
        
// deal with all data being passed through the $phraseName parameter
        
if (is_array($phraseName))
        {
            
$phraseKey $phraseName[0];
                unset(
$phraseName[0]);

            
$params array_merge($phraseName$params);

            
$phraseName $phraseKey;
        }
        else if (
$phraseName instanceof XenForo_Phrase)
        {
            
$phraseKey $phraseName->getPhraseName();
            
$params array_merge($phraseName->getParams(), $params);

            
$phraseName $phraseKey;
        }

        
$this->_phraseName $phraseName;
        if (
$params)
        {
            
$this->setParams($params);
        }

        
$this->setInsertParamsEscaped($insertParamsEscaped);

        
self::preloadPhrase($phraseName);
    }

    
/**
     * Sets the language ID that phrases will be retrieved from.
     *
     * @param integer $languageId
     */
    
public static function setLanguageId($languageId)
    {
        
self::$_languageId intval($languageId);
    }

    
/**
     * Gets the language ID that phrases will be retrieived from.
     *
     * @return integer
     */
    
public static function getLanguageId()
    {
        return 
self::$_languageId;
    }

    
/**
    * Add an array of params to the phrase. Overwrites parameters with the same name.
    *
    * @param array
    */
    
public function setParams(array $params)
    {
        
$this->_params array_merge($this->_params$params);
    }

    
/**
     * Gets the params.
     *
     * @return array
     */
    
public function getParams()
    {
        return 
$this->_params;
    }

    
/**
     * Gets the phrase name.
     *
     * @return string
     */
    
public function getPhraseName()
    {
        return 
$this->_phraseName;
    }

    
/**
    * Sets whether inserted parameters should be automatically escaped.
    * @see $_insertParamsEscaped
    *
    * @param array|boolean
    */
    
public function setInsertParamsEscaped($insertParamsEscaped)
    {
        if (
is_array($insertParamsEscaped))
        {
            if (
is_array($this->_insertParamsEscaped))
            {
                
$this->_insertParamsEscaped array_merge($this->_insertParamsEscaped$insertParamsEscaped);
            }
            else
            {
                
$this->_insertParamsEscaped $insertParamsEscaped;
            }
        }
        else
        {
            
$this->_insertParamsEscaped = (bool)$insertParamsEscaped;
        }
    }

    
/**
     * Sets the value for the phrase name on invalid setting. This controls the behavior
     * with an invalid phrase name. If true, output phrase name; otherwise, nothing.
     *
     * @param boolean $value
     */
    
public function setPhraseNameOnInvalid($value)
    {
        
$this->_phraseNameOnInvalid = (bool)$value;
    }

    
/**
    * Renders the specified phrase and returns the output.
    *
    * @param boolean|null $phraseNameOnInvalid If the phrase is invalid, return the phrase name (otherwise, empty string); if null, use default setting
    *
    * @return string
    */
    
public function render($phraseNameOnInvalid null)
    {
        
$phrase self::_loadPhrase($this->_phraseName);
        if (!
is_string($phrase))
        {
            if (
$phraseNameOnInvalid === null)
            {
                
$phraseNameOnInvalid $this->_phraseNameOnInvalid;
            }
            return (
$phraseNameOnInvalid $this->_phraseName '');
        }

        if (empty(
$this->_params))
        {
            return 
$phrase;
        }

        
$phrase preg_replace_callback('/{([a-z0-9_-]+)}/i', array($this'_replaceParam'), $phrase);

        return 
$phrase;
    }

    
/**
    * Callback function for regular expression to replace a named parameter with a value.
    *
    * @param array Match array. Looks in key "param".
    *
    * @return string Replaced value
    */
    
protected function _replaceParam($match)
    {
        
$paramName $match[1];

        if (!
array_key_exists($paramName$this->_params))
        {
            return 
$match[0];
        }

        return 
$this->_escapeParam($paramName$this->_params[$paramName]);
    }

    
/**
    * Escapes the named parameter if necessary, based on {@link $_insertParamsEscaped).
    *
    * @param string Name of parameter
    * @param string Value of parameter
    *
    * @return string Escaped parameter
    */
    
protected function _escapeParam($paramName$paramValue)
    {
        if (!
self::$_escapeCallback || $paramValue instanceof XenForo_Phrase)
        {
            return 
$paramValue;
        }

        if (
is_array($this->_insertParamsEscaped))
        {
            if (!isset(
$this->_insertParamsEscaped[$paramName]) || $this->_insertParamsEscaped[$paramName] !== false)
            {
                
// escape selective and this one is to be escaped or wasn't explicitly disabled
                
$paramValue call_user_func(self::$_escapeCallback$paramValue);
            }
        }
        else if (
$this->_insertParamsEscaped !== false)
        {
            
// escape all
            
$paramValue call_user_func(self::$_escapeCallback$paramValue);
        }

        return 
$paramValue;
    }

    
/**
    * Implicit string cast renders the phrase.
    *
    * @return string
    */
    
public function __toString()
    {
        try
        {
            return 
$this->render();
        }
        catch (
Exception $e)
        {
            
XenForo_Error::logException($efalse"Phrase to string error:");
            
XenForo_Error::unexpectedException($e);
        }
    }

    
/**
    * Load the named phrase.
    *
    * @param string Phrase name
    *
    * @return string Compiled version of the phrase
    */
    
protected static function _loadPhrase($phraseName)
    {
        if (!isset(
self::$_phraseCache[$phraseName]))
        {
            
self::loadPhrases();

            if (!isset(
self::$_phraseCache[$phraseName]))
            {
                
// couldn't find this phrase
                
self::$_phraseCache[$phraseName] = false;
            }
        }

        return 
self::$_phraseCache[$phraseName];
    }

    
/**
    * Bulk load all phrases that are required.
    */
    
public static function loadPhrases()
    {
        if (!
self::$_toLoad)
        {
            return;
        }

        
$db XenForo_Application::getDb();

        
$phrases $db->fetchPairs('
            SELECT title, phrase_text
            FROM xf_phrase_compiled
            WHERE language_id = ?
                AND title IN (' 
$db->quote(array_keys(self::$_toLoad)) . ')
        '
self::$_languageId);

        
self::$_phraseCache array_merge(self::$_phraseCache$phrases);
        
self::$_toLoad = array();
    }

    
/**
    * Specify a phrase that needs to be preloaded for use later. This is useful
    * if you think a render is going to be called before the phrase you require
    * is to be used.
    *
    * @param string Phrase to preload
    */
    
public static function preloadPhrase($phraseName)
    {
        if (!isset(
self::$_phraseCache[$phraseName]))
        {
            
self::$_toLoad[$phraseName] = true;
        }
    }

    
/**
    * Manually sets a phrase. This is primarily useful for testing.
    *
    * @param string Name of the phrase
    * @param string Value for the phrase
    */
    
public static function setPhrase($phraseName$phraseValue)
    {
        
self::$_phraseCache[$phraseName] = $phraseValue;
    }

    
/**
     * Manually sets the cache values for collection of phrases.
     *
     * @param array $phrases
     */
    
public static function setPhrases(array $phrases)
    {
        
self::$_phraseCache array_merge(self::$_phraseCache$phrases);
    }

    
/**
    * Resets the phrase system state.
    */
    
public static function reset()
    {
        
self::$_phraseCache = array();
        
self::$_toLoad = array();
    }

    
/**
     * Sets the param escaping callback function.
     *
     * @param false|callback $callback
     */
    
public static function setEscapeCallback($callback)
    {
        
self::$_escapeCallback $callback;
    }
}
Онлайн: 1
Реклама