00001 <?php
00002
00010 class HTMLPurifier_LanguageFactory
00011 {
00012
00018 public $cache;
00019
00025 public $keys = array('fallback', 'messages', 'errorNames');
00026
00031 protected $validator;
00032
00038 protected $dir;
00039
00044 protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true);
00045
00050 protected $mergeable_keys_list = array();
00051
00057 public static function instance($prototype = null) {
00058 static $instance = null;
00059 if ($prototype !== null) {
00060 $instance = $prototype;
00061 } elseif ($instance === null || $prototype == true) {
00062 $instance = new HTMLPurifier_LanguageFactory();
00063 $instance->setup();
00064 }
00065 return $instance;
00066 }
00067
00072 public function setup() {
00073 $this->validator = new HTMLPurifier_AttrDef_Lang();
00074 $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier';
00075 }
00076
00083 public function create($config, $context, $code = false) {
00084
00085
00086 if ($code === false) {
00087 $code = $this->validator->validate(
00088 $config->get('Core', 'Language'), $config, $context
00089 );
00090 } else {
00091 $code = $this->validator->validate($code, $config, $context);
00092 }
00093 if ($code === false) $code = 'en';
00094
00095 $pcode = str_replace('-', '_', $code);
00096 static $depth = 0;
00097
00098 if ($code == 'en') {
00099 $lang = new HTMLPurifier_Language($config, $context);
00100 } else {
00101 $class = 'HTMLPurifier_Language_' . $pcode;
00102 $file = $this->dir . '/Language/classes/' . $code . '.php';
00103 if (file_exists($file) || class_exists($class, false)) {
00104 $lang = new $class($config, $context);
00105 } else {
00106
00107 $raw_fallback = $this->getFallbackFor($code);
00108 $fallback = $raw_fallback ? $raw_fallback : 'en';
00109 $depth++;
00110 $lang = $this->create($config, $context, $fallback);
00111 if (!$raw_fallback) {
00112 $lang->error = true;
00113 }
00114 $depth--;
00115 }
00116 }
00117
00118 $lang->code = $code;
00119
00120 return $lang;
00121
00122 }
00123
00129 public function getFallbackFor($code) {
00130 $this->loadLanguage($code);
00131 return $this->cache[$code]['fallback'];
00132 }
00133
00138 public function loadLanguage($code) {
00139 static $languages_seen = array();
00140
00141
00142 if (isset($this->cache[$code])) return;
00143
00144
00145 $filename = $this->dir . '/Language/messages/' . $code . '.php';
00146
00147
00148 $fallback = ($code != 'en') ? 'en' : false;
00149
00150
00151 if (!file_exists($filename)) {
00152
00153 $filename = $this->dir . '/Language/messages/en.php';
00154 $cache = array();
00155 } else {
00156 include $filename;
00157 $cache = compact($this->keys);
00158 }
00159
00160
00161 if (!empty($fallback)) {
00162
00163
00164 if (isset($languages_seen[$code])) {
00165 trigger_error('Circular fallback reference in language ' .
00166 $code, E_USER_ERROR);
00167 $fallback = 'en';
00168 }
00169 $language_seen[$code] = true;
00170
00171
00172 $this->loadLanguage($fallback);
00173 $fallback_cache = $this->cache[$fallback];
00174
00175
00176 foreach ( $this->keys as $key ) {
00177 if (isset($cache[$key]) && isset($fallback_cache[$key])) {
00178 if (isset($this->mergeable_keys_map[$key])) {
00179 $cache[$key] = $cache[$key] + $fallback_cache[$key];
00180 } elseif (isset($this->mergeable_keys_list[$key])) {
00181 $cache[$key] = array_merge( $fallback_cache[$key], $cache[$key] );
00182 }
00183 } else {
00184 $cache[$key] = $fallback_cache[$key];
00185 }
00186 }
00187
00188 }
00189
00190
00191 $this->cache[$code] = $cache;
00192
00193 return;
00194 }
00195
00196 }
00197