diff options
Diffstat (limited to 'vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrCollections.php')
-rw-r--r-- | vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrCollections.php | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrCollections.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrCollections.php new file mode 100644 index 000000000..c7b17cf14 --- /dev/null +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrCollections.php @@ -0,0 +1,148 @@ +<?php + +/** + * Defines common attribute collections that modules reference + */ + +class HTMLPurifier_AttrCollections +{ + + /** + * Associative array of attribute collections, indexed by name. + * @type array + */ + public $info = array(); + + /** + * Performs all expansions on internal data for use by other inclusions + * It also collects all attribute collection extensions from + * modules + * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance + * @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members + */ + public function __construct($attr_types, $modules) + { + $this->doConstruct($attr_types, $modules); + } + + public function doConstruct($attr_types, $modules) + { + // load extensions from the modules + foreach ($modules as $module) { + foreach ($module->attr_collections as $coll_i => $coll) { + if (!isset($this->info[$coll_i])) { + $this->info[$coll_i] = array(); + } + foreach ($coll as $attr_i => $attr) { + if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) { + // merge in includes + $this->info[$coll_i][$attr_i] = array_merge( + $this->info[$coll_i][$attr_i], + $attr + ); + continue; + } + $this->info[$coll_i][$attr_i] = $attr; + } + } + } + // perform internal expansions and inclusions + foreach ($this->info as $name => $attr) { + // merge attribute collections that include others + $this->performInclusions($this->info[$name]); + // replace string identifiers with actual attribute objects + $this->expandIdentifiers($this->info[$name], $attr_types); + } + } + + /** + * Takes a reference to an attribute associative array and performs + * all inclusions specified by the zero index. + * @param array &$attr Reference to attribute array + */ + public function performInclusions(&$attr) + { + if (!isset($attr[0])) { + return; + } + $merge = $attr[0]; + $seen = array(); // recursion guard + // loop through all the inclusions + for ($i = 0; isset($merge[$i]); $i++) { + if (isset($seen[$merge[$i]])) { + continue; + } + $seen[$merge[$i]] = true; + // foreach attribute of the inclusion, copy it over + if (!isset($this->info[$merge[$i]])) { + continue; + } + foreach ($this->info[$merge[$i]] as $key => $value) { + if (isset($attr[$key])) { + continue; + } // also catches more inclusions + $attr[$key] = $value; + } + if (isset($this->info[$merge[$i]][0])) { + // recursion + $merge = array_merge($merge, $this->info[$merge[$i]][0]); + } + } + unset($attr[0]); + } + + /** + * Expands all string identifiers in an attribute array by replacing + * them with the appropriate values inside HTMLPurifier_AttrTypes + * @param array &$attr Reference to attribute array + * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance + */ + public function expandIdentifiers(&$attr, $attr_types) + { + // because foreach will process new elements we add, make sure we + // skip duplicates + $processed = array(); + + foreach ($attr as $def_i => $def) { + // skip inclusions + if ($def_i === 0) { + continue; + } + + if (isset($processed[$def_i])) { + continue; + } + + // determine whether or not attribute is required + if ($required = (strpos($def_i, '*') !== false)) { + // rename the definition + unset($attr[$def_i]); + $def_i = trim($def_i, '*'); + $attr[$def_i] = $def; + } + + $processed[$def_i] = true; + + // if we've already got a literal object, move on + if (is_object($def)) { + // preserve previous required + $attr[$def_i]->required = ($required || $attr[$def_i]->required); + continue; + } + + if ($def === false) { + unset($attr[$def_i]); + continue; + } + + if ($t = $attr_types->get($def)) { + $attr[$def_i] = $t; + $attr[$def_i]->required = $required; + } else { + unset($attr[$def_i]); + } + } + } +} + +// vim: et sw=4 sts=4 |