summaryrefslogtreecommitdiff
path: root/lib/htmlpurifier/library/HTMLPurifier/ConfigSchema.php
blob: 340ed7dbc67bf571767fc3beede44a1ff6b6882c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<?php

/**
 * Configuration definition, defines directives and their defaults.
 */
class HTMLPurifier_ConfigSchema {

    /**
     * Defaults of the directives and namespaces.
     * @note This shares the exact same structure as HTMLPurifier_Config::$conf
     */
    public $defaults = array();

    /**
     * The default property list. Do not edit this property list.
     */
    public $defaultPlist;

    /**
     * Definition of the directives. The structure of this is:
     *
     *  array(
     *      'Namespace' => array(
     *          'Directive' => new stdclass(),
     *      )
     *  )
     *
     * The stdclass may have the following properties:
     *
     *  - If isAlias isn't set:
     *      - type: Integer type of directive, see HTMLPurifier_VarParser for definitions
     *      - allow_null: If set, this directive allows null values
     *      - aliases: If set, an associative array of value aliases to real values
     *      - allowed: If set, a lookup array of allowed (string) values
     *  - If isAlias is set:
     *      - namespace: Namespace this directive aliases to
     *      - name: Directive name this directive aliases to
     *
     * In certain degenerate cases, stdclass will actually be an integer. In
     * that case, the value is equivalent to an stdclass with the type
     * property set to the integer. If the integer is negative, type is
     * equal to the absolute value of integer, and allow_null is true.
     *
     * This class is friendly with HTMLPurifier_Config. If you need introspection
     * about the schema, you're better of using the ConfigSchema_Interchange,
     * which uses more memory but has much richer information.
     */
    public $info = array();

    /**
     * Application-wide singleton
     */
    static protected $singleton;

    public function __construct() {
        $this->defaultPlist = new HTMLPurifier_PropertyList();
    }

    /**
     * Unserializes the default ConfigSchema.
     */
    public static function makeFromSerial() {
        return unserialize(file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'));
    }

    /**
     * Retrieves an instance of the application-wide configuration definition.
     */
    public static function instance($prototype = null) {
        if ($prototype !== null) {
            HTMLPurifier_ConfigSchema::$singleton = $prototype;
        } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) {
            HTMLPurifier_ConfigSchema::$singleton = HTMLPurifier_ConfigSchema::makeFromSerial();
        }
        return HTMLPurifier_ConfigSchema::$singleton;
    }

    /**
     * Defines a directive for configuration
     * @warning Will fail of directive's namespace is defined.
     * @warning This method's signature is slightly different from the legacy
     *          define() static method! Beware!
     * @param $namespace Namespace the directive is in
     * @param $name Key of directive
     * @param $default Default value of directive
     * @param $type Allowed type of the directive. See
     *      HTMLPurifier_DirectiveDef::$type for allowed values
     * @param $allow_null Whether or not to allow null values
     */
    public function add($namespace, $name, $default, $type, $allow_null) {
        $obj = new stdclass();
        $obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type];
        if ($allow_null) $obj->allow_null = true;
        $this->info[$namespace][$name] = $obj;
        $this->defaults[$namespace][$name] = $default;
        $this->defaultPlist->set("$namespace.$name", $default);
    }

    /**
     * Defines a namespace for directives to be put into.
     * @warning This is slightly different from the corresponding static
     *          method.
     * @param $namespace Namespace's name
     */
    public function addNamespace($namespace) {
        $this->info[$namespace] = array();
        $this->defaults[$namespace] = array();
    }

    /**
     * Defines a directive value alias.
     *
     * Directive value aliases are convenient for developers because it lets
     * them set a directive to several values and get the same result.
     * @param $namespace Directive's namespace
     * @param $name Name of Directive
     * @param $aliases Hash of aliased values to the real alias
     */
    public function addValueAliases($namespace, $name, $aliases) {
        if (!isset($this->info[$namespace][$name]->aliases)) {
            $this->info[$namespace][$name]->aliases = array();
        }
        foreach ($aliases as $alias => $real) {
            $this->info[$namespace][$name]->aliases[$alias] = $real;
        }
    }

    /**
     * Defines a set of allowed values for a directive.
     * @warning This is slightly different from the corresponding static
     *          method definition.
     * @param $namespace Namespace of directive
     * @param $name Name of directive
     * @param $allowed Lookup array of allowed values
     */
    public function addAllowedValues($namespace, $name, $allowed) {
        $this->info[$namespace][$name]->allowed = $allowed;
    }

    /**
     * Defines a directive alias for backwards compatibility
     * @param $namespace
     * @param $name Directive that will be aliased
     * @param $new_namespace
     * @param $new_name Directive that the alias will be to
     */
    public function addAlias($namespace, $name, $new_namespace, $new_name) {
        $obj = new stdclass;
        $obj->namespace = $new_namespace;
        $obj->name = $new_name;
        $obj->isAlias = true;
        $this->info[$namespace][$name] = $obj;
    }

    /**
     * Replaces any stdclass that only has the type property with type integer.
     */
    public function postProcess() {
        foreach ($this->info as $namespace => $info) {
            foreach ($info as $directive => $v) {
                if (count((array) $v) == 1) {
                    $this->info[$namespace][$directive] = $v->type;
                } elseif (count((array) $v) == 2 && isset($v->allow_null)) {
                    $this->info[$namespace][$directive] = -$v->type;
                }
            }
        }
    }

    // DEPRECATED METHODS

    /** @see HTMLPurifier_ConfigSchema->set() */
    public static function define($namespace, $name, $default, $type, $description) {
        HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
        $type_values = explode('/', $type, 2);
        $type = $type_values[0];
        $modifier = isset($type_values[1]) ? $type_values[1] : false;
        $allow_null = ($modifier === 'null');
        $def = HTMLPurifier_ConfigSchema::instance();
        $def->add($namespace, $name, $default, $type, $allow_null);
    }

    /** @see HTMLPurifier_ConfigSchema->addNamespace() */
    public static function defineNamespace($namespace, $description) {
        HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
        $def = HTMLPurifier_ConfigSchema::instance();
        $def->addNamespace($namespace);
    }

    /** @see HTMLPurifier_ConfigSchema->addValueAliases() */
    public static function defineValueAliases($namespace, $name, $aliases) {
        HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
        $def = HTMLPurifier_ConfigSchema::instance();
        $def->addValueAliases($namespace, $name, $aliases);
    }

    /** @see HTMLPurifier_ConfigSchema->addAllowedValues() */
    public static function defineAllowedValues($namespace, $name, $allowed_values) {
        HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
        $allowed = array();
        foreach ($allowed_values as $value) {
            $allowed[$value] = true;
        }
        $def = HTMLPurifier_ConfigSchema::instance();
        $def->addAllowedValues($namespace, $name, $allowed);
    }

    /** @see HTMLPurifier_ConfigSchema->addAlias() */
    public static function defineAlias($namespace, $name, $new_namespace, $new_name) {
        HTMLPurifier_ConfigSchema::deprecated(__METHOD__);
        $def = HTMLPurifier_ConfigSchema::instance();
        $def->addAlias($namespace, $name, $new_namespace, $new_name);
    }

    /** @deprecated, use HTMLPurifier_VarParser->parse() */
    public function validate($a, $b, $c = false) {
        trigger_error("HTMLPurifier_ConfigSchema->validate deprecated, use HTMLPurifier_VarParser->parse instead", E_USER_NOTICE);
        $parser = new HTMLPurifier_VarParser();
        return $parser->parse($a, $b, $c);
    }

    /**
     * Throws an E_USER_NOTICE stating that a method is deprecated.
     */
    private static function deprecated($method) {
        trigger_error("Static HTMLPurifier_ConfigSchema::$method deprecated, use add*() method instead", E_USER_NOTICE);
    }

}

// vim: et sw=4 sts=4