6 class HTMLPurifier_ContentSets
10 * List of content set strings (pipe seperators) indexed by name.
12 public $info = array();
15 * List of content set lookups (element => true) indexed by name.
16 * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets
18 public $lookup = array();
21 * Synchronized list of defined content sets (keys of info)
23 protected $keys = array();
25 * Synchronized list of defined content values (values of info)
27 protected $values = array();
30 * Merges in module's content sets, expands identifiers in the content
31 * sets and populates the keys, values and lookup member variables.
32 * @param $modules List of HTMLPurifier_HTMLModule
34 public function __construct($modules) {
35 if (!is_array($modules)) $modules = array($modules);
36 // populate content_sets based on module hints
37 // sorry, no way of overloading
38 foreach ($modules as $module_i => $module) {
39 foreach ($module->content_sets as $key => $value) {
40 $temp = $this->convertToLookup($value);
41 if (isset($this->lookup[$key])) {
42 // add it into the existing content set
43 $this->lookup[$key] = array_merge($this->lookup[$key], $temp);
45 $this->lookup[$key] = $temp;
50 while ($old_lookup !== $this->lookup) {
51 $old_lookup = $this->lookup;
52 foreach ($this->lookup as $i => $set) {
54 foreach ($set as $element => $x) {
55 if (isset($this->lookup[$element])) {
56 $add += $this->lookup[$element];
57 unset($this->lookup[$i][$element]);
60 $this->lookup[$i] += $add;
64 foreach ($this->lookup as $key => $lookup) {
65 $this->info[$key] = implode(' | ', array_keys($lookup));
67 $this->keys = array_keys($this->info);
68 $this->values = array_values($this->info);
72 * Accepts a definition; generates and assigns a ChildDef for it
73 * @param $def HTMLPurifier_ElementDef reference
74 * @param $module Module that defined the ElementDef
76 public function generateChildDef(&$def, $module) {
77 if (!empty($def->child)) return; // already done!
78 $content_model = $def->content_model;
79 if (is_string($content_model)) {
80 // Assume that $this->keys is alphanumeric
81 $def->content_model = preg_replace_callback(
82 '/\b(' . implode('|', $this->keys) . ')\b/',
83 array($this, 'generateChildDefCallback'),
86 //$def->content_model = str_replace(
87 // $this->keys, $this->values, $content_model);
89 $def->child = $this->getChildDef($def, $module);
92 public function generateChildDefCallback($matches) {
93 return $this->info[$matches[0]];
97 * Instantiates a ChildDef based on content_model and content_model_type
98 * member variables in HTMLPurifier_ElementDef
99 * @note This will also defer to modules for custom HTMLPurifier_ChildDef
100 * subclasses that need content set expansion
101 * @param $def HTMLPurifier_ElementDef to have ChildDef extracted
102 * @return HTMLPurifier_ChildDef corresponding to ElementDef
104 public function getChildDef($def, $module) {
105 $value = $def->content_model;
106 if (is_object($value)) {
108 'Literal object child definitions should be stored in '.
109 'ElementDef->child not ElementDef->content_model',
114 switch ($def->content_model_type) {
116 return new HTMLPurifier_ChildDef_Required($value);
118 return new HTMLPurifier_ChildDef_Optional($value);
120 return new HTMLPurifier_ChildDef_Empty();
122 return new HTMLPurifier_ChildDef_Custom($value);
124 // defer to its module
126 if ($module->defines_child_def) { // save a func call
127 $return = $module->getChildDef($def);
129 if ($return !== false) return $return;
132 'Could not determine which ChildDef class to instantiate',
139 * Converts a string list of elements separated by pipes into
141 * @param $string List of elements
142 * @return Lookup array of elements
144 protected function convertToLookup($string) {
145 $array = explode('|', str_replace(' ', '', $string));
147 foreach ($array as $i => $k) {
155 // vim: et sw=4 sts=4