aboutsummaryrefslogtreecommitdiffstats
path: root/lib/htmlpurifier/library/HTMLPurifier/ContentSets.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/htmlpurifier/library/HTMLPurifier/ContentSets.php')
-rw-r--r--lib/htmlpurifier/library/HTMLPurifier/ContentSets.php155
1 files changed, 155 insertions, 0 deletions
diff --git a/lib/htmlpurifier/library/HTMLPurifier/ContentSets.php b/lib/htmlpurifier/library/HTMLPurifier/ContentSets.php
new file mode 100644
index 000000000..3b6e96f5f
--- /dev/null
+++ b/lib/htmlpurifier/library/HTMLPurifier/ContentSets.php
@@ -0,0 +1,155 @@
+<?php
+
+/**
+ * @todo Unit test
+ */
+class HTMLPurifier_ContentSets
+{
+
+ /**
+ * List of content set strings (pipe seperators) indexed by name.
+ */
+ public $info = array();
+
+ /**
+ * List of content set lookups (element => true) indexed by name.
+ * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets
+ */
+ public $lookup = array();
+
+ /**
+ * Synchronized list of defined content sets (keys of info)
+ */
+ protected $keys = array();
+ /**
+ * Synchronized list of defined content values (values of info)
+ */
+ protected $values = array();
+
+ /**
+ * Merges in module's content sets, expands identifiers in the content
+ * sets and populates the keys, values and lookup member variables.
+ * @param $modules List of HTMLPurifier_HTMLModule
+ */
+ public function __construct($modules) {
+ if (!is_array($modules)) $modules = array($modules);
+ // populate content_sets based on module hints
+ // sorry, no way of overloading
+ foreach ($modules as $module_i => $module) {
+ foreach ($module->content_sets as $key => $value) {
+ $temp = $this->convertToLookup($value);
+ if (isset($this->lookup[$key])) {
+ // add it into the existing content set
+ $this->lookup[$key] = array_merge($this->lookup[$key], $temp);
+ } else {
+ $this->lookup[$key] = $temp;
+ }
+ }
+ }
+ $old_lookup = false;
+ while ($old_lookup !== $this->lookup) {
+ $old_lookup = $this->lookup;
+ foreach ($this->lookup as $i => $set) {
+ $add = array();
+ foreach ($set as $element => $x) {
+ if (isset($this->lookup[$element])) {
+ $add += $this->lookup[$element];
+ unset($this->lookup[$i][$element]);
+ }
+ }
+ $this->lookup[$i] += $add;
+ }
+ }
+
+ foreach ($this->lookup as $key => $lookup) {
+ $this->info[$key] = implode(' | ', array_keys($lookup));
+ }
+ $this->keys = array_keys($this->info);
+ $this->values = array_values($this->info);
+ }
+
+ /**
+ * Accepts a definition; generates and assigns a ChildDef for it
+ * @param $def HTMLPurifier_ElementDef reference
+ * @param $module Module that defined the ElementDef
+ */
+ public function generateChildDef(&$def, $module) {
+ if (!empty($def->child)) return; // already done!
+ $content_model = $def->content_model;
+ if (is_string($content_model)) {
+ // Assume that $this->keys is alphanumeric
+ $def->content_model = preg_replace_callback(
+ '/\b(' . implode('|', $this->keys) . ')\b/',
+ array($this, 'generateChildDefCallback'),
+ $content_model
+ );
+ //$def->content_model = str_replace(
+ // $this->keys, $this->values, $content_model);
+ }
+ $def->child = $this->getChildDef($def, $module);
+ }
+
+ public function generateChildDefCallback($matches) {
+ return $this->info[$matches[0]];
+ }
+
+ /**
+ * Instantiates a ChildDef based on content_model and content_model_type
+ * member variables in HTMLPurifier_ElementDef
+ * @note This will also defer to modules for custom HTMLPurifier_ChildDef
+ * subclasses that need content set expansion
+ * @param $def HTMLPurifier_ElementDef to have ChildDef extracted
+ * @return HTMLPurifier_ChildDef corresponding to ElementDef
+ */
+ public function getChildDef($def, $module) {
+ $value = $def->content_model;
+ if (is_object($value)) {
+ trigger_error(
+ 'Literal object child definitions should be stored in '.
+ 'ElementDef->child not ElementDef->content_model',
+ E_USER_NOTICE
+ );
+ return $value;
+ }
+ switch ($def->content_model_type) {
+ case 'required':
+ return new HTMLPurifier_ChildDef_Required($value);
+ case 'optional':
+ return new HTMLPurifier_ChildDef_Optional($value);
+ case 'empty':
+ return new HTMLPurifier_ChildDef_Empty();
+ case 'custom':
+ return new HTMLPurifier_ChildDef_Custom($value);
+ }
+ // defer to its module
+ $return = false;
+ if ($module->defines_child_def) { // save a func call
+ $return = $module->getChildDef($def);
+ }
+ if ($return !== false) return $return;
+ // error-out
+ trigger_error(
+ 'Could not determine which ChildDef class to instantiate',
+ E_USER_ERROR
+ );
+ return false;
+ }
+
+ /**
+ * Converts a string list of elements separated by pipes into
+ * a lookup array.
+ * @param $string List of elements
+ * @return Lookup array of elements
+ */
+ protected function convertToLookup($string) {
+ $array = explode('|', str_replace(' ', '', $string));
+ $ret = array();
+ foreach ($array as $i => $k) {
+ $ret[$k] = true;
+ }
+ return $ret;
+ }
+
+}
+
+// vim: et sw=4 sts=4