[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Class responsible for generating HTMLPurifier_Language objects, managing 5 * caching and fallbacks. 6 * @note Thanks to MediaWiki for the general logic, although this version 7 * has been entirely rewritten 8 * @todo Serialized cache for languages 9 */ 10 class HTMLPurifier_LanguageFactory 11 { 12 13 /** 14 * Cache of language code information used to load HTMLPurifier_Language objects 15 * Structure is: $factory->cache[$language_code][$key] = $value 16 * @value array map 17 */ 18 public $cache; 19 20 /** 21 * Valid keys in the HTMLPurifier_Language object. Designates which 22 * variables to slurp out of a message file. 23 * @value array list 24 */ 25 public $keys = array('fallback', 'messages', 'errorNames'); 26 27 /** 28 * Instance of HTMLPurifier_AttrDef_Lang to validate language codes 29 * @value object HTMLPurifier_AttrDef_Lang 30 */ 31 protected $validator; 32 33 /** 34 * Cached copy of dirname(__FILE__), directory of current file without 35 * trailing slash 36 * @value string filename 37 */ 38 protected $dir; 39 40 /** 41 * Keys whose contents are a hash map and can be merged 42 * @value array lookup 43 */ 44 protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true); 45 46 /** 47 * Keys whose contents are a list and can be merged 48 * @value array lookup 49 */ 50 protected $mergeable_keys_list = array(); 51 52 /** 53 * Retrieve sole instance of the factory. 54 * @param $prototype Optional prototype to overload sole instance with, 55 * or bool true to reset to default factory. 56 */ 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 68 /** 69 * Sets up the singleton, much like a constructor 70 * @note Prevents people from getting this outside of the singleton 71 */ 72 public function setup() { 73 $this->validator = new HTMLPurifier_AttrDef_Lang(); 74 $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier'; 75 } 76 77 /** 78 * Creates a language object, handles class fallbacks 79 * @param $config Instance of HTMLPurifier_Config 80 * @param $context Instance of HTMLPurifier_Context 81 * @param $code Code to override configuration with. Private parameter. 82 */ 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 124 /** 125 * Returns the fallback language for language 126 * @note Loads the original language into cache 127 * @param $code string language code 128 */ 129 public function getFallbackFor($code) { 130 $this->loadLanguage($code); 131 return $this->cache[$code]['fallback']; 132 } 133 134 /** 135 * Loads language into the cache, handles message file and fallbacks 136 * @param $code string language code 137 */ 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
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |