]>
Commit | Line | Data |
---|---|---|
010efc9b AD |
1 | <?php |
2 | ||
3 | /** | |
4 | * Represents a language and defines localizable string formatting and | |
5 | * other functions, as well as the localized messages for HTML Purifier. | |
6 | */ | |
7 | class HTMLPurifier_Language | |
8 | { | |
9 | ||
10 | /** | |
11 | * ISO 639 language code of language. Prefers shortest possible version | |
12 | */ | |
13 | public $code = 'en'; | |
14 | ||
15 | /** | |
16 | * Fallback language code | |
17 | */ | |
18 | public $fallback = false; | |
19 | ||
20 | /** | |
21 | * Array of localizable messages | |
22 | */ | |
23 | public $messages = array(); | |
24 | ||
25 | /** | |
26 | * Array of localizable error codes | |
27 | */ | |
28 | public $errorNames = array(); | |
29 | ||
30 | /** | |
31 | * True if no message file was found for this language, so English | |
32 | * is being used instead. Check this if you'd like to notify the | |
33 | * user that they've used a non-supported language. | |
34 | */ | |
35 | public $error = false; | |
36 | ||
37 | /** | |
38 | * Has the language object been loaded yet? | |
39 | * @todo Make it private, fix usage in HTMLPurifier_LanguageTest | |
40 | */ | |
41 | public $_loaded = false; | |
42 | ||
43 | /** | |
44 | * Instances of HTMLPurifier_Config and HTMLPurifier_Context | |
45 | */ | |
46 | protected $config, $context; | |
47 | ||
48 | public function __construct($config, $context) { | |
49 | $this->config = $config; | |
50 | $this->context = $context; | |
51 | } | |
52 | ||
53 | /** | |
54 | * Loads language object with necessary info from factory cache | |
55 | * @note This is a lazy loader | |
56 | */ | |
57 | public function load() { | |
58 | if ($this->_loaded) return; | |
59 | $factory = HTMLPurifier_LanguageFactory::instance(); | |
60 | $factory->loadLanguage($this->code); | |
61 | foreach ($factory->keys as $key) { | |
62 | $this->$key = $factory->cache[$this->code][$key]; | |
63 | } | |
64 | $this->_loaded = true; | |
65 | } | |
66 | ||
67 | /** | |
68 | * Retrieves a localised message. | |
69 | * @param $key string identifier of message | |
70 | * @return string localised message | |
71 | */ | |
72 | public function getMessage($key) { | |
73 | if (!$this->_loaded) $this->load(); | |
74 | if (!isset($this->messages[$key])) return "[$key]"; | |
75 | return $this->messages[$key]; | |
76 | } | |
77 | ||
78 | /** | |
79 | * Retrieves a localised error name. | |
80 | * @param $int integer error number, corresponding to PHP's error | |
81 | * reporting | |
82 | * @return string localised message | |
83 | */ | |
84 | public function getErrorName($int) { | |
85 | if (!$this->_loaded) $this->load(); | |
86 | if (!isset($this->errorNames[$int])) return "[Error: $int]"; | |
87 | return $this->errorNames[$int]; | |
88 | } | |
89 | ||
90 | /** | |
91 | * Converts an array list into a string readable representation | |
92 | */ | |
93 | public function listify($array) { | |
94 | $sep = $this->getMessage('Item separator'); | |
95 | $sep_last = $this->getMessage('Item separator last'); | |
96 | $ret = ''; | |
97 | for ($i = 0, $c = count($array); $i < $c; $i++) { | |
98 | if ($i == 0) { | |
99 | } elseif ($i + 1 < $c) { | |
100 | $ret .= $sep; | |
101 | } else { | |
102 | $ret .= $sep_last; | |
103 | } | |
104 | $ret .= $array[$i]; | |
105 | } | |
106 | return $ret; | |
107 | } | |
108 | ||
109 | /** | |
110 | * Formats a localised message with passed parameters | |
111 | * @param $key string identifier of message | |
112 | * @param $args Parameters to substitute in | |
113 | * @return string localised message | |
114 | * @todo Implement conditionals? Right now, some messages make | |
115 | * reference to line numbers, but those aren't always available | |
116 | */ | |
117 | public function formatMessage($key, $args = array()) { | |
118 | if (!$this->_loaded) $this->load(); | |
119 | if (!isset($this->messages[$key])) return "[$key]"; | |
120 | $raw = $this->messages[$key]; | |
121 | $subst = array(); | |
122 | $generator = false; | |
123 | foreach ($args as $i => $value) { | |
124 | if (is_object($value)) { | |
125 | if ($value instanceof HTMLPurifier_Token) { | |
126 | // factor this out some time | |
127 | if (!$generator) $generator = $this->context->get('Generator'); | |
128 | if (isset($value->name)) $subst['$'.$i.'.Name'] = $value->name; | |
129 | if (isset($value->data)) $subst['$'.$i.'.Data'] = $value->data; | |
130 | $subst['$'.$i.'.Compact'] = | |
131 | $subst['$'.$i.'.Serialized'] = $generator->generateFromToken($value); | |
132 | // a more complex algorithm for compact representation | |
133 | // could be introduced for all types of tokens. This | |
134 | // may need to be factored out into a dedicated class | |
135 | if (!empty($value->attr)) { | |
136 | $stripped_token = clone $value; | |
137 | $stripped_token->attr = array(); | |
138 | $subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token); | |
139 | } | |
140 | $subst['$'.$i.'.Line'] = $value->line ? $value->line : 'unknown'; | |
141 | } | |
142 | continue; | |
143 | } elseif (is_array($value)) { | |
144 | $keys = array_keys($value); | |
145 | if (array_keys($keys) === $keys) { | |
146 | // list | |
147 | $subst['$'.$i] = $this->listify($value); | |
148 | } else { | |
149 | // associative array | |
150 | // no $i implementation yet, sorry | |
151 | $subst['$'.$i.'.Keys'] = $this->listify($keys); | |
152 | $subst['$'.$i.'.Values'] = $this->listify(array_values($value)); | |
153 | } | |
154 | continue; | |
155 | } | |
156 | $subst['$' . $i] = $value; | |
157 | } | |
158 | return strtr($raw, $subst); | |
159 | } | |
160 | ||
161 | } | |
162 | ||
163 | // vim: et sw=4 sts=4 |