| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php 2 3 require_once 'HTMLPurifier/ConfigSchema.php'; 4 5 // member variables 6 require_once 'HTMLPurifier/HTMLDefinition.php'; 7 require_once 'HTMLPurifier/CSSDefinition.php'; 8 require_once 'HTMLPurifier/URIDefinition.php'; 9 require_once 'HTMLPurifier/Doctype.php'; 10 require_once 'HTMLPurifier/DefinitionCacheFactory.php'; 11 12 // accomodations for versions earlier than 4.3.10 and 5.0.2 13 // borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <aidan@php.net> 14 if (!defined('PHP_EOL')) { 15 switch (strtoupper(substr(PHP_OS, 0, 3))) { 16 case 'WIN': 17 define('PHP_EOL', "\r\n"); 18 break; 19 case 'DAR': 20 define('PHP_EOL', "\r"); 21 break; 22 default: 23 define('PHP_EOL', "\n"); 24 } 25 } 26 27 /** 28 * Configuration object that triggers customizable behavior. 29 * 30 * @warning This class is strongly defined: that means that the class 31 * will fail if an undefined directive is retrieved or set. 32 * 33 * @note Many classes that could (although many times don't) use the 34 * configuration object make it a mandatory parameter. This is 35 * because a configuration object should always be forwarded, 36 * otherwise, you run the risk of missing a parameter and then 37 * being stumped when a configuration directive doesn't work. 38 */ 39 class HTMLPurifier_Config 40 { 41 42 /** 43 * HTML Purifier's version 44 */ 45 var $version = '2.1.5'; 46 47 /** 48 * Two-level associative array of configuration directives 49 */ 50 var $conf; 51 52 /** 53 * Reference HTMLPurifier_ConfigSchema for value checking 54 */ 55 var $def; 56 57 /** 58 * Indexed array of definitions 59 */ 60 var $definitions; 61 62 /** 63 * Bool indicator whether or not config is finalized 64 */ 65 var $finalized = false; 66 67 /** 68 * Bool indicator whether or not to automatically finalize 69 * the object if a read operation is done 70 */ 71 var $autoFinalize = true; 72 73 /** 74 * Namespace indexed array of serials for specific namespaces (see 75 * getSerial for more info). 76 */ 77 var $serials = array(); 78 79 /** 80 * Serial for entire configuration object 81 */ 82 var $serial; 83 84 /** 85 * @param $definition HTMLPurifier_ConfigSchema that defines what directives 86 * are allowed. 87 */ 88 function HTMLPurifier_Config(&$definition) { 89 $this->conf = $definition->defaults; // set up, copy in defaults 90 $this->def = $definition; // keep a copy around for checking 91 } 92 93 /** 94 * Convenience constructor that creates a config object based on a mixed var 95 * @static 96 * @param mixed $config Variable that defines the state of the config 97 * object. Can be: a HTMLPurifier_Config() object, 98 * an array of directives based on loadArray(), 99 * or a string filename of an ini file. 100 * @return Configured HTMLPurifier_Config object 101 */ 102 function create($config) { 103 if (is_a($config, 'HTMLPurifier_Config')) { 104 // pass-through 105 return $config; 106 } 107 $ret = HTMLPurifier_Config::createDefault(); 108 if (is_string($config)) $ret->loadIni($config); 109 elseif (is_array($config)) $ret->loadArray($config); 110 return $ret; 111 } 112 113 /** 114 * Convenience constructor that creates a default configuration object. 115 * @static 116 * @return Default HTMLPurifier_Config object. 117 */ 118 function createDefault() { 119 $definition =& HTMLPurifier_ConfigSchema::instance(); 120 $config = new HTMLPurifier_Config($definition); 121 return $config; 122 } 123 124 /** 125 * Retreives a value from the configuration. 126 * @param $namespace String namespace 127 * @param $key String key 128 */ 129 function get($namespace, $key, $from_alias = false) { 130 if (!$this->finalized && $this->autoFinalize) $this->finalize(); 131 if (!isset($this->def->info[$namespace][$key])) { 132 // can't add % due to SimpleTest bug 133 trigger_error('Cannot retrieve value of undefined directive ' . htmlspecialchars("$namespace.$key"), 134 E_USER_WARNING); 135 return; 136 } 137 if ($this->def->info[$namespace][$key]->class == 'alias') { 138 $d = $this->def->info[$namespace][$key]; 139 trigger_error('Cannot get value from aliased directive, use real name ' . $d->namespace . '.' . $d->name, 140 E_USER_ERROR); 141 return; 142 } 143 return $this->conf[$namespace][$key]; 144 } 145 146 /** 147 * Retreives an array of directives to values from a given namespace 148 * @param $namespace String namespace 149 */ 150 function getBatch($namespace) { 151 if (!$this->finalized && $this->autoFinalize) $this->finalize(); 152 if (!isset($this->def->info[$namespace])) { 153 trigger_error('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace), 154 E_USER_WARNING); 155 return; 156 } 157 return $this->conf[$namespace]; 158 } 159 160 /** 161 * Returns a md5 signature of a segment of the configuration object 162 * that uniquely identifies that particular configuration 163 * @note Revision is handled specially and is removed from the batch 164 * before processing! 165 * @param $namespace Namespace to get serial for 166 */ 167 function getBatchSerial($namespace) { 168 if (empty($this->serials[$namespace])) { 169 $batch = $this->getBatch($namespace); 170 unset($batch['DefinitionRev']); 171 $this->serials[$namespace] = md5(serialize($batch)); 172 } 173 return $this->serials[$namespace]; 174 } 175 176 /** 177 * Returns a md5 signature for the entire configuration object 178 * that uniquely identifies that particular configuration 179 */ 180 function getSerial() { 181 if (empty($this->serial)) { 182 $this->serial = md5(serialize($this->getAll())); 183 } 184 return $this->serial; 185 } 186 187 /** 188 * Retrieves all directives, organized by namespace 189 */ 190 function getAll() { 191 if (!$this->finalized && $this->autoFinalize) $this->finalize(); 192 return $this->conf; 193 } 194 195 /** 196 * Sets a value to configuration. 197 * @param $namespace String namespace 198 * @param $key String key 199 * @param $value Mixed value 200 */ 201 function set($namespace, $key, $value, $from_alias = false) { 202 if ($this->isFinalized('Cannot set directive after finalization')) return; 203 if (!isset($this->def->info[$namespace][$key])) { 204 trigger_error('Cannot set undefined directive ' . htmlspecialchars("$namespace.$key") . ' to value', 205 E_USER_WARNING); 206 return; 207 } 208 if ($this->def->info[$namespace][$key]->class == 'alias') { 209 if ($from_alias) { 210 trigger_error('Double-aliases not allowed, please fix '. 211 'ConfigSchema bug with' . "$namespace.$key"); 212 } 213 $this->set($this->def->info[$namespace][$key]->namespace, 214 $this->def->info[$namespace][$key]->name, 215 $value, true); 216 return; 217 } 218 $value = $this->def->validate( 219 $value, 220 $type = $this->def->info[$namespace][$key]->type, 221 $this->def->info[$namespace][$key]->allow_null 222 ); 223 if (is_string($value)) { 224 // resolve value alias if defined 225 if (isset($this->def->info[$namespace][$key]->aliases[$value])) { 226 $value = $this->def->info[$namespace][$key]->aliases[$value]; 227 } 228 if ($this->def->info[$namespace][$key]->allowed !== true) { 229 // check to see if the value is allowed 230 if (!isset($this->def->info[$namespace][$key]->allowed[$value])) { 231 trigger_error('Value not supported, valid values are: ' . 232 $this->_listify($this->def->info[$namespace][$key]->allowed), E_USER_WARNING); 233 return; 234 } 235 } 236 } 237 if ($this->def->isError($value)) { 238 trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . $type, E_USER_WARNING); 239 return; 240 } 241 $this->conf[$namespace][$key] = $value; 242 243 // reset definitions if the directives they depend on changed 244 // this is a very costly process, so it's discouraged 245 // with finalization 246 if ($namespace == 'HTML' || $namespace == 'CSS') { 247 $this->definitions[$namespace] = null; 248 } 249 250 $this->serials[$namespace] = false; 251 } 252 253 /** 254 * Convenience function for error reporting 255 * @private 256 */ 257 function _listify($lookup) { 258 $list = array(); 259 foreach ($lookup as $name => $b) $list[] = $name; 260 return implode(', ', $list); 261 } 262 263 /** 264 * Retrieves reference to the HTML definition. 265 * @param $raw Return a copy that has not been setup yet. Must be 266 * called before it's been setup, otherwise won't work. 267 */ 268 function &getHTMLDefinition($raw = false) { 269 $def =& $this->getDefinition('HTML', $raw); 270 return $def; // prevent PHP 4.4.0 from complaining 271 } 272 273 /** 274 * Retrieves reference to the CSS definition 275 */ 276 function &getCSSDefinition($raw = false) { 277 $def =& $this->getDefinition('CSS', $raw); 278 return $def; 279 } 280 281 /** 282 * Retrieves a definition 283 * @param $type Type of definition: HTML, CSS, etc 284 * @param $raw Whether or not definition should be returned raw 285 */ 286 function &getDefinition($type, $raw = false) { 287 if (!$this->finalized && $this->autoFinalize) $this->finalize(); 288 $factory = HTMLPurifier_DefinitionCacheFactory::instance(); 289 $cache = $factory->create($type, $this); 290 if (!$raw) { 291 // see if we can quickly supply a definition 292 if (!empty($this->definitions[$type])) { 293 if (!$this->definitions[$type]->setup) { 294 $this->definitions[$type]->setup($this); 295 $cache->set($this->definitions[$type], $this); 296 } 297 return $this->definitions[$type]; 298 } 299 // memory check missed, try cache 300 $this->definitions[$type] = $cache->get($this); 301 if ($this->definitions[$type]) { 302 // definition in cache, return it 303 return $this->definitions[$type]; 304 } 305 } elseif ( 306 !empty($this->definitions[$type]) && 307 !$this->definitions[$type]->setup 308 ) { 309 // raw requested, raw in memory, quick return 310 return $this->definitions[$type]; 311 } 312 // quick checks failed, let's create the object 313 if ($type == 'HTML') { 314 $this->definitions[$type] = new HTMLPurifier_HTMLDefinition(); 315 } elseif ($type == 'CSS') { 316 $this->definitions[$type] = new HTMLPurifier_CSSDefinition(); 317 } elseif ($type == 'URI') { 318 $this->definitions[$type] = new HTMLPurifier_URIDefinition(); 319 } else { 320 trigger_error("Definition of $type type not supported"); 321 $false = false; 322 return $false; 323 } 324 // quick abort if raw 325 if ($raw) { 326 if (is_null($this->get($type, 'DefinitionID'))) { 327 // fatally error out if definition ID not set 328 trigger_error("Cannot retrieve raw version without specifying %$type.DefinitionID", E_USER_ERROR); 329 $false = new HTMLPurifier_Error(); 330 return $false; 331 } 332 return $this->definitions[$type]; 333 } 334 // set it up 335 $this->definitions[$type]->setup($this); 336 // save in cache 337 $cache->set($this->definitions[$type], $this); 338 return $this->definitions[$type]; 339 } 340 341 /** 342 * Loads configuration values from an array with the following structure: 343 * Namespace.Directive => Value 344 * @param $config_array Configuration associative array 345 */ 346 function loadArray($config_array) { 347 if ($this->isFinalized('Cannot load directives after finalization')) return; 348 foreach ($config_array as $key => $value) { 349 $key = str_replace('_', '.', $key); 350 if (strpos($key, '.') !== false) { 351 // condensed form 352 list($namespace, $directive) = explode('.', $key); 353 $this->set($namespace, $directive, $value); 354 } else { 355 $namespace = $key; 356 $namespace_values = $value; 357 foreach ($namespace_values as $directive => $value) { 358 $this->set($namespace, $directive, $value); 359 } 360 } 361 } 362 } 363 364 /** 365 * Returns a list of array(namespace, directive) for all directives 366 * that are allowed in a web-form context as per an allowed 367 * namespaces/directives list. 368 * @param $allowed List of allowed namespaces/directives 369 * @static 370 */ 371 function getAllowedDirectivesForForm($allowed) { 372 $schema = HTMLPurifier_ConfigSchema::instance(); 373 if ($allowed !== true) { 374 if (is_string($allowed)) $allowed = array($allowed); 375 $allowed_ns = array(); 376 $allowed_directives = array(); 377 $blacklisted_directives = array(); 378 foreach ($allowed as $ns_or_directive) { 379 if (strpos($ns_or_directive, '.') !== false) { 380 // directive 381 if ($ns_or_directive[0] == '-') { 382 $blacklisted_directives[substr($ns_or_directive, 1)] = true; 383 } else { 384 $allowed_directives[$ns_or_directive] = true; 385 } 386 } else { 387 // namespace 388 $allowed_ns[$ns_or_directive] = true; 389 } 390 } 391 } 392 $ret = array(); 393 foreach ($schema->info as $ns => $keypairs) { 394 foreach ($keypairs as $directive => $def) { 395 if ($allowed !== true) { 396 if (isset($blacklisted_directives["$ns.$directive"])) continue; 397 if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue; 398 } 399 if ($def->class == 'alias') continue; 400 if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue; 401 $ret[] = array($ns, $directive); 402 } 403 } 404 return $ret; 405 } 406 407 /** 408 * Loads configuration values from $_GET/$_POST that were posted 409 * via ConfigForm 410 * @param $array $_GET or $_POST array to import 411 * @param $index Index/name that the config variables are in 412 * @param $allowed List of allowed namespaces/directives 413 * @param $mq_fix Boolean whether or not to enable magic quotes fix 414 * @static 415 */ 416 function loadArrayFromForm($array, $index, $allowed = true, $mq_fix = true) { 417 $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix); 418 $config = HTMLPurifier_Config::create($ret); 419 return $config; 420 } 421 422 /** 423 * Merges in configuration values from $_GET/$_POST to object. NOT STATIC. 424 * @note Same parameters as loadArrayFromForm 425 */ 426 function mergeArrayFromForm($array, $index, $allowed = true, $mq_fix = true) { 427 $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix); 428 $this->loadArray($ret); 429 } 430 431 /** 432 * Prepares an array from a form into something usable for the more 433 * strict parts of HTMLPurifier_Config 434 * @static 435 */ 436 function prepareArrayFromForm($array, $index, $allowed = true, $mq_fix = true) { 437 $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array(); 438 $mq = get_magic_quotes_gpc() && $mq_fix; 439 440 $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed); 441 $ret = array(); 442 foreach ($allowed as $key) { 443 list($ns, $directive) = $key; 444 $skey = "$ns.$directive"; 445 if (!empty($array["Null_$skey"])) { 446 $ret[$ns][$directive] = null; 447 continue; 448 } 449 if (!isset($array[$skey])) continue; 450 $value = $mq ? stripslashes($array[$skey]) : $array[$skey]; 451 $ret[$ns][$directive] = $value; 452 } 453 return $ret; 454 } 455 456 /** 457 * Loads configuration values from an ini file 458 * @param $filename Name of ini file 459 */ 460 function loadIni($filename) { 461 if ($this->isFinalized('Cannot load directives after finalization')) return; 462 $array = parse_ini_file($filename, true); 463 $this->loadArray($array); 464 } 465 466 /** 467 * Checks whether or not the configuration object is finalized. 468 * @param $error String error message, or false for no error 469 */ 470 function isFinalized($error = false) { 471 if ($this->finalized && $error) { 472 trigger_error($error, E_USER_ERROR); 473 } 474 return $this->finalized; 475 } 476 477 /** 478 * Finalizes configuration only if auto finalize is on and not 479 * already finalized 480 */ 481 function autoFinalize() { 482 if (!$this->finalized && $this->autoFinalize) $this->finalize(); 483 } 484 485 /** 486 * Finalizes a configuration object, prohibiting further change 487 */ 488 function finalize() { 489 $this->finalized = true; 490 } 491 492 } 493 494
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 14 11:33:29 2009 | Cross-referenced by PHPXref 0.7 |