Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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