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