]> git.mxchange.org Git - friendica.git/blob - library/HTMLPurifier/ContentSets.php
more friend suggestions
[friendica.git] / library / HTMLPurifier / ContentSets.php
1 <?php
2
3 /**
4  * @todo Unit test
5  */
6 class HTMLPurifier_ContentSets
7 {
8
9     /**
10      * List of content set strings (pipe seperators) indexed by name.
11      */
12     public $info = array();
13
14     /**
15      * List of content set lookups (element => true) indexed by name.
16      * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets
17      */
18     public $lookup = array();
19
20     /**
21      * Synchronized list of defined content sets (keys of info)
22      */
23     protected $keys = array();
24     /**
25      * Synchronized list of defined content values (values of info)
26      */
27     protected $values = array();
28
29     /**
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
33      */
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);
44                 } else {
45                     $this->lookup[$key] = $temp;
46                 }
47             }
48         }
49         $old_lookup = false;
50         while ($old_lookup !== $this->lookup) {
51             $old_lookup = $this->lookup;
52             foreach ($this->lookup as $i => $set) {
53                 $add = array();
54                 foreach ($set as $element => $x) {
55                     if (isset($this->lookup[$element])) {
56                         $add += $this->lookup[$element];
57                         unset($this->lookup[$i][$element]);
58                     }
59                 }
60                 $this->lookup[$i] += $add;
61             }
62         }
63
64         foreach ($this->lookup as $key => $lookup) {
65             $this->info[$key] = implode(' | ', array_keys($lookup));
66         }
67         $this->keys   = array_keys($this->info);
68         $this->values = array_values($this->info);
69     }
70
71     /**
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
75      */
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'),
84                 $content_model
85             );
86             //$def->content_model = str_replace(
87             //    $this->keys, $this->values, $content_model);
88         }
89         $def->child = $this->getChildDef($def, $module);
90     }
91
92     public function generateChildDefCallback($matches) {
93         return $this->info[$matches[0]];
94     }
95
96     /**
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
103      */
104     public function getChildDef($def, $module) {
105         $value = $def->content_model;
106         if (is_object($value)) {
107             trigger_error(
108                 'Literal object child definitions should be stored in '.
109                 'ElementDef->child not ElementDef->content_model',
110                 E_USER_NOTICE
111             );
112             return $value;
113         }
114         switch ($def->content_model_type) {
115             case 'required':
116                 return new HTMLPurifier_ChildDef_Required($value);
117             case 'optional':
118                 return new HTMLPurifier_ChildDef_Optional($value);
119             case 'empty':
120                 return new HTMLPurifier_ChildDef_Empty();
121             case 'custom':
122                 return new HTMLPurifier_ChildDef_Custom($value);
123         }
124         // defer to its module
125         $return = false;
126         if ($module->defines_child_def) { // save a func call
127             $return = $module->getChildDef($def);
128         }
129         if ($return !== false) return $return;
130         // error-out
131         trigger_error(
132             'Could not determine which ChildDef class to instantiate',
133             E_USER_ERROR
134         );
135         return false;
136     }
137
138     /**
139      * Converts a string list of elements separated by pipes into
140      * a lookup array.
141      * @param $string List of elements
142      * @return Lookup array of elements
143      */
144     protected function convertToLookup($string) {
145         $array = explode('|', str_replace(' ', '', $string));
146         $ret = array();
147         foreach ($array as $i => $k) {
148             $ret[$k] = true;
149         }
150         return $ret;
151     }
152
153 }
154
155 // vim: et sw=4 sts=4