]> git.immae.eu Git - github/wallabag/wallabag.git/blame - inc/3rdparty/htmlpurifier/HTMLPurifier/LanguageFactory.php
remove autoload section in composer.json
[github/wallabag/wallabag.git] / inc / 3rdparty / htmlpurifier / HTMLPurifier / LanguageFactory.php
CommitLineData
d4949327
NL
1<?php\r
2\r
3/**\r
4 * Class responsible for generating HTMLPurifier_Language objects, managing\r
5 * caching and fallbacks.\r
6 * @note Thanks to MediaWiki for the general logic, although this version\r
7 * has been entirely rewritten\r
8 * @todo Serialized cache for languages\r
9 */\r
10class HTMLPurifier_LanguageFactory\r
11{\r
12\r
13 /**\r
14 * Cache of language code information used to load HTMLPurifier_Language objects.\r
15 * Structure is: $factory->cache[$language_code][$key] = $value\r
16 * @type array\r
17 */\r
18 public $cache;\r
19\r
20 /**\r
21 * Valid keys in the HTMLPurifier_Language object. Designates which\r
22 * variables to slurp out of a message file.\r
23 * @type array\r
24 */\r
25 public $keys = array('fallback', 'messages', 'errorNames');\r
26\r
27 /**\r
28 * Instance to validate language codes.\r
29 * @type HTMLPurifier_AttrDef_Lang\r
30 *\r
31 */\r
32 protected $validator;\r
33\r
34 /**\r
35 * Cached copy of dirname(__FILE__), directory of current file without\r
36 * trailing slash.\r
37 * @type string\r
38 */\r
39 protected $dir;\r
40\r
41 /**\r
42 * Keys whose contents are a hash map and can be merged.\r
43 * @type array\r
44 */\r
45 protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true);\r
46\r
47 /**\r
48 * Keys whose contents are a list and can be merged.\r
49 * @value array lookup\r
50 */\r
51 protected $mergeable_keys_list = array();\r
52\r
53 /**\r
54 * Retrieve sole instance of the factory.\r
55 * @param HTMLPurifier_LanguageFactory $prototype Optional prototype to overload sole instance with,\r
56 * or bool true to reset to default factory.\r
57 * @return HTMLPurifier_LanguageFactory\r
58 */\r
59 public static function instance($prototype = null)\r
60 {\r
61 static $instance = null;\r
62 if ($prototype !== null) {\r
63 $instance = $prototype;\r
64 } elseif ($instance === null || $prototype == true) {\r
65 $instance = new HTMLPurifier_LanguageFactory();\r
66 $instance->setup();\r
67 }\r
68 return $instance;\r
69 }\r
70\r
71 /**\r
72 * Sets up the singleton, much like a constructor\r
73 * @note Prevents people from getting this outside of the singleton\r
74 */\r
75 public function setup()\r
76 {\r
77 $this->validator = new HTMLPurifier_AttrDef_Lang();\r
78 $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier';\r
79 }\r
80\r
81 /**\r
82 * Creates a language object, handles class fallbacks\r
83 * @param HTMLPurifier_Config $config\r
84 * @param HTMLPurifier_Context $context\r
85 * @param bool|string $code Code to override configuration with. Private parameter.\r
86 * @return HTMLPurifier_Language\r
87 */\r
88 public function create($config, $context, $code = false)\r
89 {\r
90 // validate language code\r
91 if ($code === false) {\r
92 $code = $this->validator->validate(\r
93 $config->get('Core.Language'),\r
94 $config,\r
95 $context\r
96 );\r
97 } else {\r
98 $code = $this->validator->validate($code, $config, $context);\r
99 }\r
100 if ($code === false) {\r
101 $code = 'en'; // malformed code becomes English\r
102 }\r
103\r
104 $pcode = str_replace('-', '_', $code); // make valid PHP classname\r
105 static $depth = 0; // recursion protection\r
106\r
107 if ($code == 'en') {\r
108 $lang = new HTMLPurifier_Language($config, $context);\r
109 } else {\r
110 $class = 'HTMLPurifier_Language_' . $pcode;\r
111 $file = $this->dir . '/Language/classes/' . $code . '.php';\r
112 if (file_exists($file) || class_exists($class, false)) {\r
113 $lang = new $class($config, $context);\r
114 } else {\r
115 // Go fallback\r
116 $raw_fallback = $this->getFallbackFor($code);\r
117 $fallback = $raw_fallback ? $raw_fallback : 'en';\r
118 $depth++;\r
119 $lang = $this->create($config, $context, $fallback);\r
120 if (!$raw_fallback) {\r
121 $lang->error = true;\r
122 }\r
123 $depth--;\r
124 }\r
125 }\r
126 $lang->code = $code;\r
127 return $lang;\r
128 }\r
129\r
130 /**\r
131 * Returns the fallback language for language\r
132 * @note Loads the original language into cache\r
133 * @param string $code language code\r
134 * @return string|bool\r
135 */\r
136 public function getFallbackFor($code)\r
137 {\r
138 $this->loadLanguage($code);\r
139 return $this->cache[$code]['fallback'];\r
140 }\r
141\r
142 /**\r
143 * Loads language into the cache, handles message file and fallbacks\r
144 * @param string $code language code\r
145 */\r
146 public function loadLanguage($code)\r
147 {\r
148 static $languages_seen = array(); // recursion guard\r
149\r
150 // abort if we've already loaded it\r
151 if (isset($this->cache[$code])) {\r
152 return;\r
153 }\r
154\r
155 // generate filename\r
156 $filename = $this->dir . '/Language/messages/' . $code . '.php';\r
157\r
158 // default fallback : may be overwritten by the ensuing include\r
159 $fallback = ($code != 'en') ? 'en' : false;\r
160\r
161 // load primary localisation\r
162 if (!file_exists($filename)) {\r
163 // skip the include: will rely solely on fallback\r
164 $filename = $this->dir . '/Language/messages/en.php';\r
165 $cache = array();\r
166 } else {\r
167 include $filename;\r
168 $cache = compact($this->keys);\r
169 }\r
170\r
171 // load fallback localisation\r
172 if (!empty($fallback)) {\r
173\r
174 // infinite recursion guard\r
175 if (isset($languages_seen[$code])) {\r
176 trigger_error(\r
177 'Circular fallback reference in language ' .\r
178 $code,\r
179 E_USER_ERROR\r
180 );\r
181 $fallback = 'en';\r
182 }\r
183 $language_seen[$code] = true;\r
184\r
185 // load the fallback recursively\r
186 $this->loadLanguage($fallback);\r
187 $fallback_cache = $this->cache[$fallback];\r
188\r
189 // merge fallback with current language\r
190 foreach ($this->keys as $key) {\r
191 if (isset($cache[$key]) && isset($fallback_cache[$key])) {\r
192 if (isset($this->mergeable_keys_map[$key])) {\r
193 $cache[$key] = $cache[$key] + $fallback_cache[$key];\r
194 } elseif (isset($this->mergeable_keys_list[$key])) {\r
195 $cache[$key] = array_merge($fallback_cache[$key], $cache[$key]);\r
196 }\r
197 } else {\r
198 $cache[$key] = $fallback_cache[$key];\r
199 }\r
200 }\r
201 }\r
202\r
203 // save to cache for later retrieval\r
204 $this->cache[$code] = $cache;\r
205 return;\r
206 }\r
207}\r
208\r
209// vim: et sw=4 sts=4\r