HTMLPurifier 4.4.0
|
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 // validate language code 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'; // malformed code becomes English 00094 00095 $pcode = str_replace('-', '_', $code); // make valid PHP classname 00096 static $depth = 0; // recursion protection 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 // Go fallback 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(); // recursion guard 00140 00141 // abort if we've already loaded it 00142 if (isset($this->cache[$code])) return; 00143 00144 // generate filename 00145 $filename = $this->dir . '/Language/messages/' . $code . '.php'; 00146 00147 // default fallback : may be overwritten by the ensuing include 00148 $fallback = ($code != 'en') ? 'en' : false; 00149 00150 // load primary localisation 00151 if (!file_exists($filename)) { 00152 // skip the include: will rely solely on fallback 00153 $filename = $this->dir . '/Language/messages/en.php'; 00154 $cache = array(); 00155 } else { 00156 include $filename; 00157 $cache = compact($this->keys); 00158 } 00159 00160 // load fallback localisation 00161 if (!empty($fallback)) { 00162 00163 // infinite recursion guard 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 // load the fallback recursively 00172 $this->loadLanguage($fallback); 00173 $fallback_cache = $this->cache[$fallback]; 00174 00175 // merge fallback with current language 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 // save to cache for later retrieval 00191 $this->cache[$code] = $cache; 00192 00193 return; 00194 } 00195 00196 } 00197 00198 // vim: et sw=4 sts=4