ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
LanguageFactory.php
Go to the documentation of this file.
1 <?php
2 
11 {
12 
18  public $cache;
19 
25  public $keys = array('fallback', 'messages', 'errorNames');
26 
32  protected $validator;
33 
39  protected $dir;
40 
45  protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true);
46 
51  protected $mergeable_keys_list = array();
52 
59  public static function instance($prototype = null)
60  {
61  static $instance = null;
62  if ($prototype !== null) {
63  $instance = $prototype;
64  } elseif ($instance === null || $prototype == true) {
65  $instance = new HTMLPurifier_LanguageFactory();
66  $instance->setup();
67  }
68  return $instance;
69  }
70 
75  public function setup()
76  {
77  $this->validator = new HTMLPurifier_AttrDef_Lang();
78  $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier';
79  }
80 
88  public function create($config, $context, $code = false)
89  {
90  // validate language code
91  if ($code === false) {
92  $code = $this->validator->validate(
93  $config->get('Core.Language'),
94  $config,
95  $context
96  );
97  } else {
98  $code = $this->validator->validate($code, $config, $context);
99  }
100  if ($code === false) {
101  $code = 'en'; // malformed code becomes English
102  }
103 
104  $pcode = str_replace('-', '_', $code); // make valid PHP classname
105  static $depth = 0; // recursion protection
106 
107  if ($code == 'en') {
108  $lang = new HTMLPurifier_Language($config, $context);
109  } else {
110  $class = 'HTMLPurifier_Language_' . $pcode;
111  $file = $this->dir . '/Language/classes/' . $code . '.php';
112  if (file_exists($file) || class_exists($class, false)) {
113  $lang = new $class($config, $context);
114  } else {
115  // Go fallback
116  $raw_fallback = $this->getFallbackFor($code);
117  $fallback = $raw_fallback ? $raw_fallback : 'en';
118  $depth++;
119  $lang = $this->create($config, $context, $fallback);
120  if (!$raw_fallback) {
121  $lang->error = true;
122  }
123  $depth--;
124  }
125  }
126  $lang->code = $code;
127  return $lang;
128  }
129 
136  public function getFallbackFor($code)
137  {
138  $this->loadLanguage($code);
139  return $this->cache[$code]['fallback'];
140  }
141 
146  public function loadLanguage($code)
147  {
148  static $languages_seen = array(); // recursion guard
149 
150  // abort if we've already loaded it
151  if (isset($this->cache[$code])) {
152  return;
153  }
154 
155  // generate filename
156  $filename = $this->dir . '/Language/messages/' . $code . '.php';
157 
158  // default fallback : may be overwritten by the ensuing include
159  $fallback = ($code != 'en') ? 'en' : false;
160 
161  // load primary localisation
162  if (!file_exists($filename)) {
163  // skip the include: will rely solely on fallback
164  $filename = $this->dir . '/Language/messages/en.php';
165  $cache = array();
166  } else {
167  include $filename;
168  $cache = compact($this->keys);
169  }
170 
171  // load fallback localisation
172  if (!empty($fallback)) {
173 
174  // infinite recursion guard
175  if (isset($languages_seen[$code])) {
176  trigger_error(
177  'Circular fallback reference in language ' .
178  $code,
179  E_USER_ERROR
180  );
181  $fallback = 'en';
182  }
183  $language_seen[$code] = true;
184 
185  // load the fallback recursively
186  $this->loadLanguage($fallback);
187  $fallback_cache = $this->cache[$fallback];
188 
189  // merge fallback with current language
190  foreach ($this->keys as $key) {
191  if (isset($cache[$key]) && isset($fallback_cache[$key])) {
192  if (isset($this->mergeable_keys_map[$key])) {
193  $cache[$key] = $cache[$key] + $fallback_cache[$key];
194  } elseif (isset($this->mergeable_keys_list[$key])) {
195  $cache[$key] = array_merge($fallback_cache[$key], $cache[$key]);
196  }
197  } else {
198  $cache[$key] = $fallback_cache[$key];
199  }
200  }
201  }
202 
203  // save to cache for later retrieval
204  $this->cache[$code] = $cache;
205  return;
206  }
207 }
208 
209 // vim: et sw=4 sts=4