ILIAS  Release_4_4_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 
31  protected $validator;
32 
38  protected $dir;
39 
44  protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true);
45 
50  protected $mergeable_keys_list = array();
51 
57  public static function instance($prototype = null) {
58  static $instance = null;
59  if ($prototype !== null) {
60  $instance = $prototype;
61  } elseif ($instance === null || $prototype == true) {
62  $instance = new HTMLPurifier_LanguageFactory();
63  $instance->setup();
64  }
65  return $instance;
66  }
67 
72  public function setup() {
73  $this->validator = new HTMLPurifier_AttrDef_Lang();
74  $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier';
75  }
76 
83  public function create($config, $context, $code = false) {
84 
85  // validate language code
86  if ($code === false) {
87  $code = $this->validator->validate(
88  $config->get('Core.Language'), $config, $context
89  );
90  } else {
91  $code = $this->validator->validate($code, $config, $context);
92  }
93  if ($code === false) $code = 'en'; // malformed code becomes English
94 
95  $pcode = str_replace('-', '_', $code); // make valid PHP classname
96  static $depth = 0; // recursion protection
97 
98  if ($code == 'en') {
99  $lang = new HTMLPurifier_Language($config, $context);
100  } else {
101  $class = 'HTMLPurifier_Language_' . $pcode;
102  $file = $this->dir . '/Language/classes/' . $code . '.php';
103  if (file_exists($file) || class_exists($class, false)) {
104  $lang = new $class($config, $context);
105  } else {
106  // Go fallback
107  $raw_fallback = $this->getFallbackFor($code);
108  $fallback = $raw_fallback ? $raw_fallback : 'en';
109  $depth++;
110  $lang = $this->create($config, $context, $fallback);
111  if (!$raw_fallback) {
112  $lang->error = true;
113  }
114  $depth--;
115  }
116  }
117 
118  $lang->code = $code;
119 
120  return $lang;
121 
122  }
123 
129  public function getFallbackFor($code) {
130  $this->loadLanguage($code);
131  return $this->cache[$code]['fallback'];
132  }
133 
138  public function loadLanguage($code) {
139  static $languages_seen = array(); // recursion guard
140 
141  // abort if we've already loaded it
142  if (isset($this->cache[$code])) return;
143 
144  // generate filename
145  $filename = $this->dir . '/Language/messages/' . $code . '.php';
146 
147  // default fallback : may be overwritten by the ensuing include
148  $fallback = ($code != 'en') ? 'en' : false;
149 
150  // load primary localisation
151  if (!file_exists($filename)) {
152  // skip the include: will rely solely on fallback
153  $filename = $this->dir . '/Language/messages/en.php';
154  $cache = array();
155  } else {
156  include $filename;
157  $cache = compact($this->keys);
158  }
159 
160  // load fallback localisation
161  if (!empty($fallback)) {
162 
163  // infinite recursion guard
164  if (isset($languages_seen[$code])) {
165  trigger_error('Circular fallback reference in language ' .
166  $code, E_USER_ERROR);
167  $fallback = 'en';
168  }
169  $language_seen[$code] = true;
170 
171  // load the fallback recursively
172  $this->loadLanguage($fallback);
173  $fallback_cache = $this->cache[$fallback];
174 
175  // merge fallback with current language
176  foreach ( $this->keys as $key ) {
177  if (isset($cache[$key]) && isset($fallback_cache[$key])) {
178  if (isset($this->mergeable_keys_map[$key])) {
179  $cache[$key] = $cache[$key] + $fallback_cache[$key];
180  } elseif (isset($this->mergeable_keys_list[$key])) {
181  $cache[$key] = array_merge( $fallback_cache[$key], $cache[$key] );
182  }
183  } else {
184  $cache[$key] = $fallback_cache[$key];
185  }
186  }
187 
188  }
189 
190  // save to cache for later retrieval
191  $this->cache[$code] = $cache;
192 
193  return;
194  }
195 
196 }
197 
198 // vim: et sw=4 sts=4