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