File indexing completed on 2024-12-22 05:36:21

0001 <?php
0002 
0003 /**
0004  * Represents a language and defines localizable string formatting and
0005  * other functions, as well as the localized messages for HTML Purifier.
0006  */
0007 class HTMLPurifier_Language
0008 {
0009 
0010     /**
0011      * ISO 639 language code of language. Prefers shortest possible version.
0012      * @type string
0013      */
0014     public $code = 'en';
0015 
0016     /**
0017      * Fallback language code.
0018      * @type bool|string
0019      */
0020     public $fallback = false;
0021 
0022     /**
0023      * Array of localizable messages.
0024      * @type array
0025      */
0026     public $messages = array();
0027 
0028     /**
0029      * Array of localizable error codes.
0030      * @type array
0031      */
0032     public $errorNames = array();
0033 
0034     /**
0035      * True if no message file was found for this language, so English
0036      * is being used instead. Check this if you'd like to notify the
0037      * user that they've used a non-supported language.
0038      * @type bool
0039      */
0040     public $error = false;
0041 
0042     /**
0043      * Has the language object been loaded yet?
0044      * @type bool
0045      * @todo Make it private, fix usage in HTMLPurifier_LanguageTest
0046      */
0047     public $_loaded = false;
0048 
0049     /**
0050      * @type HTMLPurifier_Config
0051      */
0052     protected $config;
0053 
0054     /**
0055      * @type HTMLPurifier_Context
0056      */
0057     protected $context;
0058 
0059     /**
0060      * @param HTMLPurifier_Config $config
0061      * @param HTMLPurifier_Context $context
0062      */
0063     public function __construct($config, $context)
0064     {
0065         $this->config  = $config;
0066         $this->context = $context;
0067     }
0068 
0069     /**
0070      * Loads language object with necessary info from factory cache
0071      * @note This is a lazy loader
0072      */
0073     public function load()
0074     {
0075         if ($this->_loaded) {
0076             return;
0077         }
0078         $factory = HTMLPurifier_LanguageFactory::instance();
0079         $factory->loadLanguage($this->code);
0080         foreach ($factory->keys as $key) {
0081             $this->$key = $factory->cache[$this->code][$key];
0082         }
0083         $this->_loaded = true;
0084     }
0085 
0086     /**
0087      * Retrieves a localised message.
0088      * @param string $key string identifier of message
0089      * @return string localised message
0090      */
0091     public function getMessage($key)
0092     {
0093         if (!$this->_loaded) {
0094             $this->load();
0095         }
0096         if (!isset($this->messages[$key])) {
0097             return "[$key]";
0098         }
0099         return $this->messages[$key];
0100     }
0101 
0102     /**
0103      * Retrieves a localised error name.
0104      * @param int $int error number, corresponding to PHP's error reporting
0105      * @return string localised message
0106      */
0107     public function getErrorName($int)
0108     {
0109         if (!$this->_loaded) {
0110             $this->load();
0111         }
0112         if (!isset($this->errorNames[$int])) {
0113             return "[Error: $int]";
0114         }
0115         return $this->errorNames[$int];
0116     }
0117 
0118     /**
0119      * Converts an array list into a string readable representation
0120      * @param array $array
0121      * @return string
0122      */
0123     public function listify($array)
0124     {
0125         $sep      = $this->getMessage('Item separator');
0126         $sep_last = $this->getMessage('Item separator last');
0127         $ret = '';
0128         for ($i = 0, $c = count($array); $i < $c; $i++) {
0129             if ($i == 0) {
0130             } elseif ($i + 1 < $c) {
0131                 $ret .= $sep;
0132             } else {
0133                 $ret .= $sep_last;
0134             }
0135             $ret .= $array[$i];
0136         }
0137         return $ret;
0138     }
0139 
0140     /**
0141      * Formats a localised message with passed parameters
0142      * @param string $key string identifier of message
0143      * @param array $args Parameters to substitute in
0144      * @return string localised message
0145      * @todo Implement conditionals? Right now, some messages make
0146      *     reference to line numbers, but those aren't always available
0147      */
0148     public function formatMessage($key, $args = array())
0149     {
0150         if (!$this->_loaded) {
0151             $this->load();
0152         }
0153         if (!isset($this->messages[$key])) {
0154             return "[$key]";
0155         }
0156         $raw = $this->messages[$key];
0157         $subst = array();
0158         $generator = false;
0159         foreach ($args as $i => $value) {
0160             if (is_object($value)) {
0161                 if ($value instanceof HTMLPurifier_Token) {
0162                     // factor this out some time
0163                     if (!$generator) {
0164                         $generator = $this->context->get('Generator');
0165                     }
0166                     if (isset($value->name)) {
0167                         $subst['$'.$i.'.Name'] = $value->name;
0168                     }
0169                     if (isset($value->data)) {
0170                         $subst['$'.$i.'.Data'] = $value->data;
0171                     }
0172                     $subst['$'.$i.'.Compact'] =
0173                     $subst['$'.$i.'.Serialized'] = $generator->generateFromToken($value);
0174                     // a more complex algorithm for compact representation
0175                     // could be introduced for all types of tokens. This
0176                     // may need to be factored out into a dedicated class
0177                     if (!empty($value->attr)) {
0178                         $stripped_token = clone $value;
0179                         $stripped_token->attr = array();
0180                         $subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token);
0181                     }
0182                     $subst['$'.$i.'.Line'] = $value->line ? $value->line : 'unknown';
0183                 }
0184                 continue;
0185             } elseif (is_array($value)) {
0186                 $keys = array_keys($value);
0187                 if (array_keys($keys) === $keys) {
0188                     // list
0189                     $subst['$'.$i] = $this->listify($value);
0190                 } else {
0191                     // associative array
0192                     // no $i implementation yet, sorry
0193                     $subst['$'.$i.'.Keys'] = $this->listify($keys);
0194                     $subst['$'.$i.'.Values'] = $this->listify(array_values($value));
0195                 }
0196                 continue;
0197             }
0198             $subst['$' . $i] = $value;
0199         }
0200         return strtr($raw, $subst);
0201     }
0202 }
0203 
0204 // vim: et sw=4 sts=4