Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/**
4
 * @todo Unit test
5
 */
6
class HTMLPurifier_ContentSets
7
{
8
 
9
    /**
10
     * List of content set strings (pipe separators) indexed by name.
11
     * @type array
12
     */
13
    public $info = array();
14
 
15
    /**
16
     * List of content set lookups (element => true) indexed by name.
17
     * @type array
18
     * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets
19
     */
20
    public $lookup = array();
21
 
22
    /**
23
     * Synchronized list of defined content sets (keys of info).
24
     * @type array
25
     */
26
    protected $keys = array();
27
    /**
28
     * Synchronized list of defined content values (values of info).
29
     * @type array
30
     */
31
    protected $values = array();
32
 
33
    /**
34
     * Merges in module's content sets, expands identifiers in the content
35
     * sets and populates the keys, values and lookup member variables.
36
     * @param HTMLPurifier_HTMLModule[] $modules List of HTMLPurifier_HTMLModule
37
     */
38
    public function __construct($modules)
39
    {
40
        if (!is_array($modules)) {
41
            $modules = array($modules);
42
        }
43
        // populate content_sets based on module hints
44
        // sorry, no way of overloading
45
        foreach ($modules as $module) {
46
            foreach ($module->content_sets as $key => $value) {
47
                $temp = $this->convertToLookup($value);
48
                if (isset($this->lookup[$key])) {
49
                    // add it into the existing content set
50
                    $this->lookup[$key] = array_merge($this->lookup[$key], $temp);
51
                } else {
52
                    $this->lookup[$key] = $temp;
53
                }
54
            }
55
        }
56
        $old_lookup = false;
57
        while ($old_lookup !== $this->lookup) {
58
            $old_lookup = $this->lookup;
59
            foreach ($this->lookup as $i => $set) {
60
                $add = array();
61
                foreach ($set as $element => $x) {
62
                    if (isset($this->lookup[$element])) {
63
                        $add += $this->lookup[$element];
64
                        unset($this->lookup[$i][$element]);
65
                    }
66
                }
67
                $this->lookup[$i] += $add;
68
            }
69
        }
70
 
71
        foreach ($this->lookup as $key => $lookup) {
72
            $this->info[$key] = implode(' | ', array_keys($lookup));
73
        }
74
        $this->keys   = array_keys($this->info);
75
        $this->values = array_values($this->info);
76
    }
77
 
78
    /**
79
     * Accepts a definition; generates and assigns a ChildDef for it
80
     * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef reference
81
     * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef
82
     */
83
    public function generateChildDef(&$def, $module)
84
    {
85
        if (!empty($def->child)) { // already done!
86
            return;
87
        }
88
        $content_model = $def->content_model;
89
        if (is_string($content_model)) {
90
            // Assume that $this->keys is alphanumeric
91
            $def->content_model = preg_replace_callback(
92
                '/\b(' . implode('|', $this->keys) . ')\b/',
93
                array($this, 'generateChildDefCallback'),
94
                $content_model
95
            );
96
            //$def->content_model = str_replace(
97
            //    $this->keys, $this->values, $content_model);
98
        }
99
        $def->child = $this->getChildDef($def, $module);
100
    }
101
 
102
    public function generateChildDefCallback($matches)
103
    {
104
        return $this->info[$matches[0]];
105
    }
106
 
107
    /**
108
     * Instantiates a ChildDef based on content_model and content_model_type
109
     * member variables in HTMLPurifier_ElementDef
110
     * @note This will also defer to modules for custom HTMLPurifier_ChildDef
111
     *       subclasses that need content set expansion
112
     * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef to have ChildDef extracted
113
     * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef
114
     * @return HTMLPurifier_ChildDef corresponding to ElementDef
115
     */
116
    public function getChildDef($def, $module)
117
    {
118
        $value = $def->content_model;
119
        if (is_object($value)) {
120
            trigger_error(
121
                'Literal object child definitions should be stored in '.
122
                'ElementDef->child not ElementDef->content_model',
123
                E_USER_NOTICE
124
            );
125
            return $value;
126
        }
127
        switch ($def->content_model_type) {
128
            case 'required':
129
                return new HTMLPurifier_ChildDef_Required($value);
130
            case 'optional':
131
                return new HTMLPurifier_ChildDef_Optional($value);
132
            case 'empty':
133
                return new HTMLPurifier_ChildDef_Empty();
134
            case 'custom':
135
                return new HTMLPurifier_ChildDef_Custom($value);
136
        }
137
        // defer to its module
138
        $return = false;
139
        if ($module->defines_child_def) { // save a func call
140
            $return = $module->getChildDef($def);
141
        }
142
        if ($return !== false) {
143
            return $return;
144
        }
145
        // error-out
146
        trigger_error(
147
            'Could not determine which ChildDef class to instantiate',
148
            E_USER_ERROR
149
        );
150
        return false;
151
    }
152
 
153
    /**
154
     * Converts a string list of elements separated by pipes into
155
     * a lookup array.
156
     * @param string $string List of elements
157
     * @return array Lookup array of elements
158
     */
159
    protected function convertToLookup($string)
160
    {
161
        $array = explode('|', str_replace(' ', '', $string));
162
        $ret = array();
163
        foreach ($array as $k) {
164
            $ret[$k] = true;
165
        }
166
        return $ret;
167
    }
168
}
169
 
170
// vim: et sw=4 sts=4