diff options
Diffstat (limited to 'inc/3rdparty/htmlpurifier/HTMLPurifier/AttrCollections.php')
-rw-r--r-- | inc/3rdparty/htmlpurifier/HTMLPurifier/AttrCollections.php | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/inc/3rdparty/htmlpurifier/HTMLPurifier/AttrCollections.php b/inc/3rdparty/htmlpurifier/HTMLPurifier/AttrCollections.php new file mode 100644 index 00000000..2d2c7d28 --- /dev/null +++ b/inc/3rdparty/htmlpurifier/HTMLPurifier/AttrCollections.php | |||
@@ -0,0 +1,143 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Defines common attribute collections that modules reference | ||
5 | */ | ||
6 | |||
7 | class HTMLPurifier_AttrCollections | ||
8 | { | ||
9 | |||
10 | /** | ||
11 | * Associative array of attribute collections, indexed by name. | ||
12 | * @type array | ||
13 | */ | ||
14 | public $info = array(); | ||
15 | |||
16 | /** | ||
17 | * Performs all expansions on internal data for use by other inclusions | ||
18 | * It also collects all attribute collection extensions from | ||
19 | * modules | ||
20 | * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance | ||
21 | * @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members | ||
22 | */ | ||
23 | public function __construct($attr_types, $modules) | ||
24 | { | ||
25 | // load extensions from the modules | ||
26 | foreach ($modules as $module) { | ||
27 | foreach ($module->attr_collections as $coll_i => $coll) { | ||
28 | if (!isset($this->info[$coll_i])) { | ||
29 | $this->info[$coll_i] = array(); | ||
30 | } | ||
31 | foreach ($coll as $attr_i => $attr) { | ||
32 | if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) { | ||
33 | // merge in includes | ||
34 | $this->info[$coll_i][$attr_i] = array_merge( | ||
35 | $this->info[$coll_i][$attr_i], | ||
36 | $attr | ||
37 | ); | ||
38 | continue; | ||
39 | } | ||
40 | $this->info[$coll_i][$attr_i] = $attr; | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | // perform internal expansions and inclusions | ||
45 | foreach ($this->info as $name => $attr) { | ||
46 | // merge attribute collections that include others | ||
47 | $this->performInclusions($this->info[$name]); | ||
48 | // replace string identifiers with actual attribute objects | ||
49 | $this->expandIdentifiers($this->info[$name], $attr_types); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Takes a reference to an attribute associative array and performs | ||
55 | * all inclusions specified by the zero index. | ||
56 | * @param array &$attr Reference to attribute array | ||
57 | */ | ||
58 | public function performInclusions(&$attr) | ||
59 | { | ||
60 | if (!isset($attr[0])) { | ||
61 | return; | ||
62 | } | ||
63 | $merge = $attr[0]; | ||
64 | $seen = array(); // recursion guard | ||
65 | // loop through all the inclusions | ||
66 | for ($i = 0; isset($merge[$i]); $i++) { | ||
67 | if (isset($seen[$merge[$i]])) { | ||
68 | continue; | ||
69 | } | ||
70 | $seen[$merge[$i]] = true; | ||
71 | // foreach attribute of the inclusion, copy it over | ||
72 | if (!isset($this->info[$merge[$i]])) { | ||
73 | continue; | ||
74 | } | ||
75 | foreach ($this->info[$merge[$i]] as $key => $value) { | ||
76 | if (isset($attr[$key])) { | ||
77 | continue; | ||
78 | } // also catches more inclusions | ||
79 | $attr[$key] = $value; | ||
80 | } | ||
81 | if (isset($this->info[$merge[$i]][0])) { | ||
82 | // recursion | ||
83 | $merge = array_merge($merge, $this->info[$merge[$i]][0]); | ||
84 | } | ||
85 | } | ||
86 | unset($attr[0]); | ||
87 | } | ||
88 | |||
89 | /** | ||
90 | * Expands all string identifiers in an attribute array by replacing | ||
91 | * them with the appropriate values inside HTMLPurifier_AttrTypes | ||
92 | * @param array &$attr Reference to attribute array | ||
93 | * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance | ||
94 | */ | ||
95 | public function expandIdentifiers(&$attr, $attr_types) | ||
96 | { | ||
97 | // because foreach will process new elements we add, make sure we | ||
98 | // skip duplicates | ||
99 | $processed = array(); | ||
100 | |||
101 | foreach ($attr as $def_i => $def) { | ||
102 | // skip inclusions | ||
103 | if ($def_i === 0) { | ||
104 | continue; | ||
105 | } | ||
106 | |||
107 | if (isset($processed[$def_i])) { | ||
108 | continue; | ||
109 | } | ||
110 | |||
111 | // determine whether or not attribute is required | ||
112 | if ($required = (strpos($def_i, '*') !== false)) { | ||
113 | // rename the definition | ||
114 | unset($attr[$def_i]); | ||
115 | $def_i = trim($def_i, '*'); | ||
116 | $attr[$def_i] = $def; | ||
117 | } | ||
118 | |||
119 | $processed[$def_i] = true; | ||
120 | |||
121 | // if we've already got a literal object, move on | ||
122 | if (is_object($def)) { | ||
123 | // preserve previous required | ||
124 | $attr[$def_i]->required = ($required || $attr[$def_i]->required); | ||
125 | continue; | ||
126 | } | ||
127 | |||
128 | if ($def === false) { | ||
129 | unset($attr[$def_i]); | ||
130 | continue; | ||
131 | } | ||
132 | |||
133 | if ($t = $attr_types->get($def)) { | ||
134 | $attr[$def_i] = $t; | ||
135 | $attr[$def_i]->required = $required; | ||
136 | } else { | ||
137 | unset($attr[$def_i]); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
143 | // vim: et sw=4 sts=4 | ||