HTMLPurifier 4.4.0
/home/ezyang/Dev/htmlpurifier/library/HTMLPurifier/AttrCollections.php
Go to the documentation of this file.
00001 <?php
00002 
00007 class HTMLPurifier_AttrCollections
00008 {
00009 
00013     public $info = array();
00014 
00022     public function __construct($attr_types, $modules) {
00023         // load extensions from the modules
00024         foreach ($modules as $module) {
00025             foreach ($module->attr_collections as $coll_i => $coll) {
00026                 if (!isset($this->info[$coll_i])) {
00027                     $this->info[$coll_i] = array();
00028                 }
00029                 foreach ($coll as $attr_i => $attr) {
00030                     if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) {
00031                         // merge in includes
00032                         $this->info[$coll_i][$attr_i] = array_merge(
00033                             $this->info[$coll_i][$attr_i], $attr);
00034                         continue;
00035                     }
00036                     $this->info[$coll_i][$attr_i] = $attr;
00037                 }
00038             }
00039         }
00040         // perform internal expansions and inclusions
00041         foreach ($this->info as $name => $attr) {
00042             // merge attribute collections that include others
00043             $this->performInclusions($this->info[$name]);
00044             // replace string identifiers with actual attribute objects
00045             $this->expandIdentifiers($this->info[$name], $attr_types);
00046         }
00047     }
00048 
00054     public function performInclusions(&$attr) {
00055         if (!isset($attr[0])) return;
00056         $merge = $attr[0];
00057         $seen  = array(); // recursion guard
00058         // loop through all the inclusions
00059         for ($i = 0; isset($merge[$i]); $i++) {
00060             if (isset($seen[$merge[$i]])) continue;
00061             $seen[$merge[$i]] = true;
00062             // foreach attribute of the inclusion, copy it over
00063             if (!isset($this->info[$merge[$i]])) continue;
00064             foreach ($this->info[$merge[$i]] as $key => $value) {
00065                 if (isset($attr[$key])) continue; // also catches more inclusions
00066                 $attr[$key] = $value;
00067             }
00068             if (isset($this->info[$merge[$i]][0])) {
00069                 // recursion
00070                 $merge = array_merge($merge, $this->info[$merge[$i]][0]);
00071             }
00072         }
00073         unset($attr[0]);
00074     }
00075 
00082     public function expandIdentifiers(&$attr, $attr_types) {
00083 
00084         // because foreach will process new elements we add, make sure we
00085         // skip duplicates
00086         $processed = array();
00087 
00088         foreach ($attr as $def_i => $def) {
00089             // skip inclusions
00090             if ($def_i === 0) continue;
00091 
00092             if (isset($processed[$def_i])) continue;
00093 
00094             // determine whether or not attribute is required
00095             if ($required = (strpos($def_i, '*') !== false)) {
00096                 // rename the definition
00097                 unset($attr[$def_i]);
00098                 $def_i = trim($def_i, '*');
00099                 $attr[$def_i] = $def;
00100             }
00101 
00102             $processed[$def_i] = true;
00103 
00104             // if we've already got a literal object, move on
00105             if (is_object($def)) {
00106                 // preserve previous required
00107                 $attr[$def_i]->required = ($required || $attr[$def_i]->required);
00108                 continue;
00109             }
00110 
00111             if ($def === false) {
00112                 unset($attr[$def_i]);
00113                 continue;
00114             }
00115 
00116             if ($t = $attr_types->get($def)) {
00117                 $attr[$def_i] = $t;
00118                 $attr[$def_i]->required = $required;
00119             } else {
00120                 unset($attr[$def_i]);
00121             }
00122         }
00123 
00124     }
00125 
00126 }
00127 
00128 // vim: et sw=4 sts=4