6 class HTMLPurifier_ContentSets
10 * List of content set strings (pipe separators) indexed by name.
13 public $info = array();
16 * List of content set lookups (element => true) indexed by name.
18 * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets
20 public $lookup = array();
23 * Synchronized list of defined content sets (keys of info).
26 protected $keys = array();
28 * Synchronized list of defined content values (values of info).
31 protected $values = array();
34 * Merges in module's content sets, expands identifiers in the content
35 * sets and populates the keys, values and lookup member variables.
36 * @param HTMLPurifier_HTMLModule[] $modules List of HTMLPurifier_HTMLModule
38 public function __construct($modules)
40 if (!is_array($modules)) {
41 $modules = array($modules);
43 // populate content_sets based on module hints
44 // sorry, no way of overloading
45 foreach ($modules as $module) {
46 foreach ($module->content_sets
as $key => $value) {
47 $temp = $this->convertToLookup($value);
48 if (isset($this->lookup
[$key])) {
49 // add it into the existing content set
50 $this->lookup
[$key] = array_merge($this->lookup
[$key], $temp);
52 $this->lookup
[$key] = $temp;
57 while ($old_lookup !== $this->lookup
) {
58 $old_lookup = $this->lookup
;
59 foreach ($this->lookup
as $i => $set) {
61 foreach ($set as $element => $x) {
62 if (isset($this->lookup
[$element])) {
63 $add +
= $this->lookup
[$element];
64 unset($this->lookup
[$i][$element]);
67 $this->lookup
[$i] +
= $add;
71 foreach ($this->lookup
as $key => $lookup) {
72 $this->info
[$key] = implode(' | ', array_keys($lookup));
74 $this->keys
= array_keys($this->info
);
75 $this->values
= array_values($this->info
);
79 * Accepts a definition; generates and assigns a ChildDef for it
80 * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef reference
81 * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef
83 public function generateChildDef(&$def, $module)
85 if (!empty($def->child
)) { // already done!
88 $content_model = $def->content_model
;
89 if (is_string($content_model)) {
90 // Assume that $this->keys is alphanumeric
91 $def->content_model
= preg_replace_callback(
92 '/\b(' . implode('|', $this->keys
) . ')\b/',
93 array($this, 'generateChildDefCallback'),
96 //$def->content_model = str_replace(
97 // $this->keys, $this->values, $content_model);
99 $def->child
= $this->getChildDef($def, $module);
102 public function generateChildDefCallback($matches)
104 return $this->info
[$matches[0]];
108 * Instantiates a ChildDef based on content_model and content_model_type
109 * member variables in HTMLPurifier_ElementDef
110 * @note This will also defer to modules for custom HTMLPurifier_ChildDef
111 * subclasses that need content set expansion
112 * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef to have ChildDef extracted
113 * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef
114 * @return HTMLPurifier_ChildDef corresponding to ElementDef
116 public function getChildDef($def, $module)
118 $value = $def->content_model
;
119 if (is_object($value)) {
121 'Literal object child definitions should be stored in '.
122 'ElementDef->child not ElementDef->content_model',
127 switch ($def->content_model_type
) {
129 return new HTMLPurifier_ChildDef_Required($value);
131 return new HTMLPurifier_ChildDef_Optional($value);
133 return new HTMLPurifier_ChildDef_Empty();
135 return new HTMLPurifier_ChildDef_Custom($value);
137 // defer to its module
139 if ($module->defines_child_def
) { // save a func call
140 $return = $module->getChildDef($def);
142 if ($return !== false) {
147 'Could not determine which ChildDef class to instantiate',
154 * Converts a string list of elements separated by pipes into
156 * @param string $string List of elements
157 * @return array Lookup array of elements
159 protected function convertToLookup($string)
161 $array = explode('|', str_replace(' ', '', $string));
163 foreach ($array as $k) {
170 // vim: et sw=4 sts=4