]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - extlib/HTMLPurifier/HTMLPurifier/AttrCollections.php
Merge branch 'master' of git.gnu.io:gnu/gnu-social into mmn_fixes
[quix0rs-gnu-social.git] / extlib / HTMLPurifier / HTMLPurifier / AttrCollections.php
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