mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-11-09 15:28:40 +00:00
Revamp configuration backend.
Signed-off-by: Edward Z. Yang <edwardzyang@thewritingpot.com>
This commit is contained in:
parent
fcbf724e6e
commit
b107eec452
3
NEWS
3
NEWS
@ -10,6 +10,9 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
==========================
|
||||
|
||||
4.0.0, unknown release date
|
||||
# APIs for ConfigSchema subsystem have substantially changed. See
|
||||
docs/dev-config-bcbreaks.txt for details; in essence, anything that
|
||||
had both namespace and directive now have a single unified key.
|
||||
! More robust support for name="" and id=""
|
||||
|
||||
3.3.0, released 2009-02-16
|
||||
|
79
docs/dev-config-bcbreaks.txt
Normal file
79
docs/dev-config-bcbreaks.txt
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
Configuration Backwards-Compatibility Breaks
|
||||
|
||||
In version 3.3.0, the configuration subsystem (composed of the outwards
|
||||
facing Config class, as well as the ConfigSchema and ConfigSchema_Interchange
|
||||
subsystems), was significantly revamped to make use of property lists.
|
||||
While most of the changes are internal, some internal APIs were changed for the
|
||||
sake of clarity. HTMLPurifier_Config was kept completely backwards compatible,
|
||||
although some of the functions were retrofitted with an unambiguous alternate
|
||||
syntax. Both of these changes are discussed in this document.
|
||||
|
||||
|
||||
|
||||
1. Outwards Facing Changes
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The HTMLPurifier_Config class now takes an alternate syntax. The general rule
|
||||
is:
|
||||
|
||||
If you passed $namespace, $directive, pass "$namespace.$directive"
|
||||
instead.
|
||||
|
||||
An example:
|
||||
|
||||
$config->set('HTML', 'Allowed', 'p');
|
||||
|
||||
becomes:
|
||||
|
||||
$config->set('HTML.Allowed', 'p');
|
||||
|
||||
New configuration options may have more than one namespace, they might
|
||||
look something like %Filter.YouTube.Blacklist. While you could technically
|
||||
set it with ('HTML', 'YouTube.Blacklist'), the logical extension
|
||||
('HTML', 'YouTube', 'Blacklist') does not work.
|
||||
|
||||
[more changes coming]
|
||||
|
||||
|
||||
|
||||
2. Internal API Changes
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Some overarching notes: we've completely eliminated the notion of namespace;
|
||||
it's now an informal construct for organizing related configuration directives.
|
||||
|
||||
Also, the validation routines for keys (formerly "$namespace.$directive")
|
||||
have been completely relaxed. I don't think it really should be necessary.
|
||||
|
||||
2.1 HTMLPurifier_ConfigSchema
|
||||
|
||||
First off, if you're interfacing with this class, you really shouldn't.
|
||||
HTMLPurifier_ConfigSchema_Builder_ConfigSchema is really the only class that
|
||||
should ever be creating HTMLPurifier_ConfigSchema, and HTMLPurifier_Config the
|
||||
only class that should be reading it.
|
||||
|
||||
All namespace related methods were removed; they are completely unnecessary
|
||||
now. Any $namespace, $name arguments must be replaced with $key (where
|
||||
$key == "$namespace.$name"), including for addAlias().
|
||||
|
||||
The $info and $defaults member variables are no longer indexed as
|
||||
[$namespace][$name]; they are now indexed as ["$namespace.$name"].
|
||||
|
||||
All deprecated methods were finally removed, after having yelled at you as
|
||||
an E_USER_NOTICE for a while now.
|
||||
|
||||
2.2 HTMLPurifier_ConfigSchema_Interchange
|
||||
|
||||
Member variable $namespaces was removed.
|
||||
|
||||
2.3 HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
|
||||
Member variable $namespace and $directive removed; member variable $key added.
|
||||
Any method that took $namespace, $directive now takes $key.
|
||||
|
||||
2.4 HTMLPurifier_ConfigSchema_Interchange_Namespace
|
||||
|
||||
Removed.
|
||||
|
||||
|
217
docs/proposal-plists.txt
Normal file
217
docs/proposal-plists.txt
Normal file
@ -0,0 +1,217 @@
|
||||
THE UNIVERSAL DESIGN PATTERN: PROPERTIES
|
||||
Steve Yegge
|
||||
|
||||
Implementation:
|
||||
get(name)
|
||||
put(name, value)
|
||||
has(name)
|
||||
remove(name)
|
||||
iteration, with filtering [this will be our namespaces]
|
||||
parent
|
||||
|
||||
Representations:
|
||||
- Keys are strings
|
||||
- It's nice to not need to quote keys (if we formulate our own language,
|
||||
consider this)
|
||||
- Property not present representation (key missing)
|
||||
- Frequent removal/re-add may have null help. If null is valid, use
|
||||
another value. (PHP semantics are weird here)
|
||||
|
||||
Data structures:
|
||||
- LinkedHashMap is wonderful (O(1) access and maintains order)
|
||||
- Using a special property that points to the parent is usual
|
||||
- Multiple inheritance possible, need rules for which to lookup first
|
||||
- Iterative inheritance is best
|
||||
- Consider performance!
|
||||
|
||||
Deletion
|
||||
- Tricky problem with inheritance
|
||||
- Distinguish between "not found" and "look in my parent for the property"
|
||||
[Maybe HTML Purifier won't allow deletion]
|
||||
|
||||
Read/write asymmetry (it's correct!)
|
||||
|
||||
Read-only plists
|
||||
- Allow ability to freeze [this is what we have already]
|
||||
- Don't overuse it
|
||||
|
||||
Performance:
|
||||
- Intern strings (PHP does this already)
|
||||
- Don't be case-insensitive
|
||||
- If all properties in a plist are known a-priori, you can use a "perfect"
|
||||
hash function. Often overkill.
|
||||
- Copy-on-read caching "plundering" reduces lookup, but uses memory and can
|
||||
grow stale. Use as last resort.
|
||||
- Refactoring to fields. Watch for API compatibility, system complexity,
|
||||
and lack of flexibility.
|
||||
- Refrigerator: external data-structure to hold plists
|
||||
|
||||
Transient properties:
|
||||
[Don't need to worry about this]
|
||||
- Use a separate plist for transient properties
|
||||
- Non-numeric override; numeric should ADD
|
||||
- Deletion: removeTransientProperty() and transientlyRemoveProperty()
|
||||
|
||||
Persistence:
|
||||
- XML/JSON are good
|
||||
- Text-based is good for readability, maintainability and bootstrapping
|
||||
- Compressed binary format for network transport [not necessary]
|
||||
- RDBMS or XML database
|
||||
|
||||
Querying: [not relevant]
|
||||
- XML database is nice for XPath/XQuery
|
||||
- jQuery for JSON
|
||||
- Just load it all into a program
|
||||
|
||||
Backfills/Data integrity:
|
||||
- Use usual methods
|
||||
- Lazy backfill is a nice hack
|
||||
|
||||
Type systems:
|
||||
- Flags: ReadOnly, Permanent, DontEnum
|
||||
- Typed properties isn't that useful [It's also Not-PHP]
|
||||
- Seperate meta-list of directive properties IS useful
|
||||
- Duck typing is useful for systems designed fully around properties pattern
|
||||
|
||||
Trade-off:
|
||||
+ Flexibility
|
||||
+ Extensibility
|
||||
+ Unit-testing/prototype-speed
|
||||
- Performance
|
||||
- Data integrity
|
||||
- Navagability/Query-ability
|
||||
- Reversability (hard to go back)
|
||||
|
||||
HTML Purifier
|
||||
|
||||
We are not happy with our current system of defining configuration directives,
|
||||
because it has become clear that things will get a lot nicer if we allow
|
||||
multiple namespaces, and there are some features that naturally lend themselves
|
||||
to inheritance, which we do not really support well.
|
||||
|
||||
One of the considered implementation changes would be to go from a structure
|
||||
like:
|
||||
|
||||
array(
|
||||
'Namespace' => array(
|
||||
'Directive' => 'val1',
|
||||
'Directive2' => 'val2',
|
||||
)
|
||||
)
|
||||
|
||||
to:
|
||||
|
||||
array(
|
||||
'Namespace.Directive' => 'val1',
|
||||
'Namespace.Directive2' => 'val2',
|
||||
)
|
||||
|
||||
The below implementation takes more memory, however, and it makes it a bit
|
||||
complicated to grab all values from a namespace.
|
||||
|
||||
The alternate implementation choice is to allow nested plists. This keeps
|
||||
iteration easy, but is problematic for inheritance (it would be difficult
|
||||
to distinguish a plist from an array) and retrieval (when specifying multiple
|
||||
namespaces we would need some multiple de-referencing).
|
||||
|
||||
----
|
||||
|
||||
We can bite the performance hit, and just do iteration with filter
|
||||
(the strncmp call should be relatively cheap). Then, users should be able
|
||||
to optimize doing something like:
|
||||
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
if (!file_exists('config.php')) {
|
||||
// set up $config
|
||||
$config->save('config.php');
|
||||
} else {
|
||||
$config->load('config.php');
|
||||
}
|
||||
|
||||
Or maybe memcache, or something. This means that "// set up $config" must
|
||||
not have any dynamic parts, or the user has to invalidate the cache when
|
||||
they do update it. We have to think about this a little more carefully; the
|
||||
file call might be more expensive.
|
||||
|
||||
----
|
||||
|
||||
This might get expensive, however, when we actually care about iterating
|
||||
over the configuration and want the actual values. So what about nesting the
|
||||
lists?
|
||||
|
||||
"ns.sub.directive" => values['ns']['sub']['directive']
|
||||
|
||||
We can distinguish between plists and arrays by using ArrayObjects for the
|
||||
plists, and regular arrays for the arrays? Alternatively, use ArrayObjects
|
||||
for the arrays, and regular arrays for the plists.
|
||||
|
||||
----
|
||||
|
||||
Implementation demands, and what has caused them:
|
||||
|
||||
1. DefinitionCache, the HTML, CSS and URI namespaces have caches attached to them
|
||||
Results:
|
||||
- getBatchSerial()
|
||||
- getBatch() : in general, the ability to traverse just a namespace
|
||||
|
||||
2. AutoFormat/Filter, this is a plugin architecture, directives not hard-coded
|
||||
- getBatch()
|
||||
|
||||
3. Configuration form
|
||||
- Namespaces used to organize directives
|
||||
|
||||
Other than that, we have a pure plist. PERHAPS we should maintain separate things
|
||||
for these different demands.
|
||||
|
||||
Issue 2: Directives for configuring the plugins are regular plists, but
|
||||
when enabling them, while it's "plist-ish", what you're really doing is adding
|
||||
them to an array of "autoformatters"/"filters" to enable. We can setup
|
||||
magic BC as well as in the new interface, but there should also be an
|
||||
add('AutoFormat', 'AutoParagraph'); which does the right thing.
|
||||
|
||||
One thing to consider is whether or not inheritance rules will apply to these.
|
||||
I'd say yes. That means that they're still plisty, in fact, the underlying
|
||||
implementation will probably be a plist. However, they will get their OWN
|
||||
plists, and will NOT support nesting.
|
||||
|
||||
Issue 1: Our current implementation is generally not efficient; md5(serialize($foo))
|
||||
is pretty expensive. So, I don't think there will be any problems if it
|
||||
gets "less" efficient, as long as we give users a properly fast alternative;
|
||||
DefinitionRev gives us a way to do this, by simply telling the user they must
|
||||
update it whenever they update Configuration directives as well. (There are
|
||||
obvious BC concerns here).
|
||||
|
||||
In such a case, we simply iterate over our plist (performing full retrievals
|
||||
for each value), grab the entries we care about, and then serialize and hash.
|
||||
It's going to be slow either way, due to the ability of plists to inherit.
|
||||
If we ksort(), we don't have to traverse the entire array, however, the
|
||||
cost of a ksort() call may not be worth it.
|
||||
|
||||
At this point, last time, I started worrying about the performance implications
|
||||
of allowing inheritance, and wondering whether or not I wanted to squash
|
||||
the plist. At first blush, our code might be under the assumption that
|
||||
accessing properties is cheap; but actually we prefer to copy out the value
|
||||
into a member variable if it's going to be used many times. With this is mind
|
||||
I don't think CPU consumption from a few nested function calls is going to
|
||||
be a problem. We *are* going to enforce a function only interface.
|
||||
|
||||
The next issue at hand is how we're going to manage the "special" plists,
|
||||
which should still be able to be inherited. Basically, it means that multiple
|
||||
plists would be attached to the configuration object, which is not the
|
||||
best for memory performance. The alternative is to keep them all in one
|
||||
big plist, and then eat the one-time cost of traversing the entire plist
|
||||
to grab the appropriate values.
|
||||
|
||||
I think at this point we can write the generic interface, and then set up separate
|
||||
plists if that ends up being necessary for performance (it probably won't.) Now
|
||||
lets code our generic plist implementation.
|
||||
|
||||
----
|
||||
|
||||
Iterating over the plist presents some problems. The way we've chosen to solve
|
||||
this is to squash all of the parents.
|
||||
|
||||
----
|
||||
|
||||
But I don't need iteration.
|
||||
|
@ -117,21 +117,22 @@ class HTMLPurifier_Config
|
||||
* @param $namespace String namespace
|
||||
* @param $key String key
|
||||
*/
|
||||
public function get($namespace, $key) {
|
||||
public function get($namespace, $directive) {
|
||||
$key = "$namespace.$directive";
|
||||
if (!$this->finalized) $this->autoFinalize ? $this->finalize() : $this->plist->squash(true);
|
||||
if (!isset($this->def->info[$namespace][$key])) {
|
||||
if (!isset($this->def->info[$key])) {
|
||||
// can't add % due to SimpleTest bug
|
||||
trigger_error('Cannot retrieve value of undefined directive ' . htmlspecialchars("$namespace.$key"),
|
||||
trigger_error('Cannot retrieve value of undefined directive ' . htmlspecialchars($key),
|
||||
E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
if (isset($this->def->info[$namespace][$key]->isAlias)) {
|
||||
$d = $this->def->info[$namespace][$key];
|
||||
trigger_error('Cannot get value from aliased directive, use real name ' . $d->namespace . '.' . $d->name,
|
||||
if (isset($this->def->info[$key]->isAlias)) {
|
||||
$d = $this->def->info[$key];
|
||||
trigger_error('Cannot get value from aliased directive, use real name ' . $d->key,
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
return $this->plist->get("$namespace.$key");
|
||||
return $this->plist->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,12 +141,12 @@ class HTMLPurifier_Config
|
||||
*/
|
||||
public function getBatch($namespace) {
|
||||
if (!$this->finalized) $this->autoFinalize ? $this->finalize() : $this->plist->squash(true);
|
||||
if (!isset($this->def->info[$namespace])) {
|
||||
$full = $this->getAll();
|
||||
if (!isset($full[$namespace])) {
|
||||
trigger_error('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace),
|
||||
E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
$full = $this->getAll();
|
||||
return $full[$namespace];
|
||||
}
|
||||
|
||||
@ -195,25 +196,26 @@ class HTMLPurifier_Config
|
||||
* @param $key String key
|
||||
* @param $value Mixed value
|
||||
*/
|
||||
public function set($namespace, $key, $value, $from_alias = false) {
|
||||
public function set($namespace, $directive, $value, $from_alias = false) {
|
||||
$key = "$namespace.$directive";
|
||||
if ($this->isFinalized('Cannot set directive after finalization')) return;
|
||||
if (!isset($this->def->info[$namespace][$key])) {
|
||||
trigger_error('Cannot set undefined directive ' . htmlspecialchars("$namespace.$key") . ' to value',
|
||||
if (!isset($this->def->info[$key])) {
|
||||
trigger_error('Cannot set undefined directive ' . htmlspecialchars($key) . ' to value',
|
||||
E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
$def = $this->def->info[$namespace][$key];
|
||||
$def = $this->def->info[$key];
|
||||
|
||||
if (isset($def->isAlias)) {
|
||||
if ($from_alias) {
|
||||
trigger_error('Double-aliases not allowed, please fix '.
|
||||
'ConfigSchema bug with' . "$namespace.$key", E_USER_ERROR);
|
||||
'ConfigSchema bug with' . $key, E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
$this->set($new_ns = $def->namespace,
|
||||
$new_dir = $def->name,
|
||||
list($alias_namespace, $alias_directive) = explode('.', $def->key, 2);
|
||||
$this->set($alias_namespace, $alias_directive,
|
||||
$value, true);
|
||||
trigger_error("$namespace.$key is an alias, preferred directive name is $new_ns.$new_dir", E_USER_NOTICE);
|
||||
trigger_error("$key is an alias, preferred directive name is {$def->key}", E_USER_NOTICE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -231,7 +233,7 @@ class HTMLPurifier_Config
|
||||
try {
|
||||
$value = $this->parser->parse($value, $type, $allow_null);
|
||||
} catch (HTMLPurifier_VarParserException $e) {
|
||||
trigger_error('Value for ' . "$namespace.$key" . ' is of invalid type, should be ' . HTMLPurifier_VarParser::getTypeName($type), E_USER_WARNING);
|
||||
trigger_error('Value for ' . $key . ' is of invalid type, should be ' . HTMLPurifier_VarParser::getTypeName($type), E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
if (is_string($value) && is_object($def)) {
|
||||
@ -246,7 +248,7 @@ class HTMLPurifier_Config
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->plist->set("$namespace.$key", $value);
|
||||
$this->plist->set($key, $value);
|
||||
|
||||
// reset definitions if the directives they depend on changed
|
||||
// this is a very costly process, so it's discouraged
|
||||
@ -351,8 +353,7 @@ class HTMLPurifier_Config
|
||||
foreach ($config_array as $key => $value) {
|
||||
$key = str_replace('_', '.', $key);
|
||||
if (strpos($key, '.') !== false) {
|
||||
// condensed form
|
||||
list($namespace, $directive) = explode('.', $key);
|
||||
list($namespace, $directive) = explode(".", $key, 2);
|
||||
$this->set($namespace, $directive, $value);
|
||||
} else {
|
||||
$namespace = $key;
|
||||
@ -394,8 +395,8 @@ class HTMLPurifier_Config
|
||||
}
|
||||
}
|
||||
$ret = array();
|
||||
foreach ($schema->info as $ns => $keypairs) {
|
||||
foreach ($keypairs as $directive => $def) {
|
||||
foreach ($schema->info as $key => $def) {
|
||||
list($ns, $directive) = explode('.', $key, 2);
|
||||
if ($allowed !== true) {
|
||||
if (isset($blacklisted_directives["$ns.$directive"])) continue;
|
||||
if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
|
||||
@ -404,7 +405,6 @@ class HTMLPurifier_Config
|
||||
if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
|
||||
$ret[] = array($ns, $directive);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
@ -87,24 +87,13 @@ class HTMLPurifier_ConfigSchema {
|
||||
* 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) {
|
||||
public function add($key, $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();
|
||||
$this->info[$key] = $obj;
|
||||
$this->defaults[$key] = $default;
|
||||
$this->defaultPlist->set($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,12 +105,12 @@ class HTMLPurifier_ConfigSchema {
|
||||
* @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();
|
||||
public function addValueAliases($key, $aliases) {
|
||||
if (!isset($this->info[$key]->aliases)) {
|
||||
$this->info[$key]->aliases = array();
|
||||
}
|
||||
foreach ($aliases as $alias => $real) {
|
||||
$this->info[$namespace][$name]->aliases[$alias] = $real;
|
||||
$this->info[$key]->aliases[$alias] = $real;
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,8 +122,8 @@ class HTMLPurifier_ConfigSchema {
|
||||
* @param $name Name of directive
|
||||
* @param $allowed Lookup array of allowed values
|
||||
*/
|
||||
public function addAllowedValues($namespace, $name, $allowed) {
|
||||
$this->info[$namespace][$name]->allowed = $allowed;
|
||||
public function addAllowedValues($key, $allowed) {
|
||||
$this->info[$key]->allowed = $allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,87 +133,25 @@ class HTMLPurifier_ConfigSchema {
|
||||
* @param $new_namespace
|
||||
* @param $new_name Directive that the alias will be to
|
||||
*/
|
||||
public function addAlias($namespace, $name, $new_namespace, $new_name) {
|
||||
public function addAlias($key, $new_key) {
|
||||
$obj = new stdclass;
|
||||
$obj->namespace = $new_namespace;
|
||||
$obj->name = $new_name;
|
||||
$obj->key = $new_key;
|
||||
$obj->isAlias = true;
|
||||
$this->info[$namespace][$name] = $obj;
|
||||
$this->info[$key] = $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) {
|
||||
foreach ($this->info as $key => $v) {
|
||||
if (count((array) $v) == 1) {
|
||||
$this->info[$namespace][$directive] = $v->type;
|
||||
$this->info[$key] = $v->type;
|
||||
} elseif (count((array) $v) == 2 && isset($v->allow_null)) {
|
||||
$this->info[$namespace][$directive] = -$v->type;
|
||||
$this->info[$key] = -$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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -9,36 +9,28 @@ class HTMLPurifier_ConfigSchema_Builder_ConfigSchema
|
||||
|
||||
public function build($interchange) {
|
||||
$schema = new HTMLPurifier_ConfigSchema();
|
||||
foreach ($interchange->namespaces as $n) {
|
||||
$schema->addNamespace($n->namespace);
|
||||
}
|
||||
foreach ($interchange->directives as $d) {
|
||||
$schema->add(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->id->key,
|
||||
$d->default,
|
||||
$d->type,
|
||||
$d->typeAllowsNull
|
||||
);
|
||||
if ($d->allowed !== null) {
|
||||
$schema->addAllowedValues(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->id->key,
|
||||
$d->allowed
|
||||
);
|
||||
}
|
||||
foreach ($d->aliases as $alias) {
|
||||
$schema->addAlias(
|
||||
$alias->namespace,
|
||||
$alias->directive,
|
||||
$d->id->namespace,
|
||||
$d->id->directive
|
||||
$alias->key,
|
||||
$d->id->key
|
||||
);
|
||||
}
|
||||
if ($d->valueAliases !== null) {
|
||||
$schema->addValueAliases(
|
||||
$d->id->namespace,
|
||||
$d->id->directive,
|
||||
$d->id->key,
|
||||
$d->valueAliases
|
||||
);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
|
||||
{
|
||||
|
||||
protected $interchange;
|
||||
private $namespace;
|
||||
|
||||
protected function writeHTMLDiv($html) {
|
||||
$this->startElement('div');
|
||||
@ -34,36 +35,33 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
|
||||
$this->startElement('configdoc');
|
||||
$this->writeElement('title', $interchange->name);
|
||||
|
||||
foreach ($interchange->namespaces as $namespace) {
|
||||
$this->buildNamespace($namespace);
|
||||
foreach ($interchange->directives as $directive) {
|
||||
$this->buildDirective($directive);
|
||||
}
|
||||
|
||||
if ($this->namespace) $this->endElement(); // namespace
|
||||
|
||||
$this->endElement(); // configdoc
|
||||
$this->flush();
|
||||
}
|
||||
|
||||
public function buildNamespace($namespace) {
|
||||
$this->startElement('namespace');
|
||||
$this->writeAttribute('id', $namespace->namespace);
|
||||
|
||||
$this->writeElement('name', $namespace->namespace);
|
||||
$this->startElement('description');
|
||||
$this->writeHTMLDiv($namespace->description);
|
||||
$this->endElement(); // description
|
||||
|
||||
foreach ($this->interchange->directives as $directive) {
|
||||
if ($directive->id->namespace !== $namespace->namespace) continue;
|
||||
$this->buildDirective($directive);
|
||||
}
|
||||
|
||||
$this->endElement(); // namespace
|
||||
}
|
||||
|
||||
public function buildDirective($directive) {
|
||||
|
||||
// Kludge, although I suppose having a notion of a "root namespace"
|
||||
// certainly makes things look nicer when documentation is built.
|
||||
// Depends on things being sorted.
|
||||
if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) {
|
||||
if ($this->namespace) $this->endElement(); // namespace
|
||||
$this->namespace = $directive->id->getRootNamespace();
|
||||
$this->startElement('namespace');
|
||||
$this->writeAttribute('id', $this->namespace);
|
||||
$this->writeElement('name', $this->namespace);
|
||||
}
|
||||
|
||||
$this->startElement('directive');
|
||||
$this->writeAttribute('id', $directive->id->toString());
|
||||
|
||||
$this->writeElement('name', $directive->id->directive);
|
||||
$this->writeElement('name', $directive->id->getDirective());
|
||||
|
||||
$this->startElement('aliases');
|
||||
foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString());
|
||||
|
@ -13,26 +13,11 @@ class HTMLPurifier_ConfigSchema_Interchange
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Array of Namespace ID => array(namespace info)
|
||||
*/
|
||||
public $namespaces = array();
|
||||
|
||||
/**
|
||||
* Array of Directive ID => array(directive info)
|
||||
*/
|
||||
public $directives = array();
|
||||
|
||||
/**
|
||||
* Adds a namespace array to $namespaces
|
||||
*/
|
||||
public function addNamespace($namespace) {
|
||||
if (isset($this->namespaces[$i = $namespace->namespace])) {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine namespace '$i'");
|
||||
}
|
||||
$this->namespaces[$i] = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a directive array to $directives
|
||||
*/
|
||||
|
@ -6,11 +6,10 @@
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
{
|
||||
|
||||
public $namespace, $directive;
|
||||
public $key;
|
||||
|
||||
public function __construct($namespace, $directive) {
|
||||
$this->namespace = $namespace;
|
||||
$this->directive = $directive;
|
||||
public function __construct($key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -18,12 +17,19 @@ class HTMLPurifier_ConfigSchema_Interchange_Id
|
||||
* cause problems for PHP 5.0 support.
|
||||
*/
|
||||
public function toString() {
|
||||
return $this->namespace . '.' . $this->directive;
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getRootNamespace() {
|
||||
return substr($this->key, 0, strpos($this->key, "."));
|
||||
}
|
||||
|
||||
public function getDirective() {
|
||||
return substr($this->key, strpos($this->key, ".") + 1);
|
||||
}
|
||||
|
||||
public static function make($id) {
|
||||
list($namespace, $directive) = explode('.', $id);
|
||||
return new HTMLPurifier_ConfigSchema_Interchange_Id($namespace, $directive);
|
||||
return new HTMLPurifier_ConfigSchema_Interchange_Id($id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interchange component class describing namespaces.
|
||||
*/
|
||||
class HTMLPurifier_ConfigSchema_Interchange_Namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of namespace defined.
|
||||
*/
|
||||
public $namespace;
|
||||
|
||||
/**
|
||||
* HTML description.
|
||||
*/
|
||||
public $description;
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -55,22 +55,17 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
|
||||
throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID');
|
||||
}
|
||||
if (strpos($hash['ID'], '.') === false) {
|
||||
$this->buildNamespace($interchange, $hash);
|
||||
if (count($hash) == 2 && isset($hash['DESCRIPTION'])) {
|
||||
$hash->offsetGet('DESCRIPTION'); // prevent complaining
|
||||
} else {
|
||||
throw new HTMLPurifier_ConfigSchema_Exception('All directives must have a namespace');
|
||||
}
|
||||
} else {
|
||||
$this->buildDirective($interchange, $hash);
|
||||
}
|
||||
$this->_findUnused($hash);
|
||||
}
|
||||
|
||||
public function buildNamespace($interchange, $hash) {
|
||||
$namespace = new HTMLPurifier_ConfigSchema_Interchange_Namespace();
|
||||
$namespace->namespace = $hash->offsetGet('ID');
|
||||
if (isset($hash['DESCRIPTION'])) {
|
||||
$namespace->description = $hash->offsetGet('DESCRIPTION');
|
||||
}
|
||||
$interchange->addNamespace($namespace);
|
||||
}
|
||||
|
||||
public function buildDirective($interchange, $hash) {
|
||||
$directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
||||
|
||||
|
@ -39,10 +39,6 @@ class HTMLPurifier_ConfigSchema_Validator
|
||||
$this->aliases = array();
|
||||
// PHP is a bit lax with integer <=> string conversions in
|
||||
// arrays, so we don't use the identical !== comparison
|
||||
foreach ($interchange->namespaces as $i => $namespace) {
|
||||
if ($i != $namespace->namespace) $this->error(false, "Integrity violation: key '$i' does not match internal id '{$namespace->namespace}'");
|
||||
$this->validateNamespace($namespace);
|
||||
}
|
||||
foreach ($interchange->directives as $i => $directive) {
|
||||
$id = $directive->id->toString();
|
||||
if ($i != $id) $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'");
|
||||
@ -51,20 +47,6 @@ class HTMLPurifier_ConfigSchema_Validator
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a HTMLPurifier_ConfigSchema_Interchange_Namespace object.
|
||||
*/
|
||||
public function validateNamespace($n) {
|
||||
$this->context[] = "namespace '{$n->namespace}'";
|
||||
$this->with($n, 'namespace')
|
||||
->assertNotEmpty()
|
||||
->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
|
||||
$this->with($n, 'description')
|
||||
->assertNotEmpty()
|
||||
->assertIsString(); // handled by InterchangeBuilder
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a HTMLPurifier_ConfigSchema_Interchange_Id object.
|
||||
*/
|
||||
@ -75,12 +57,11 @@ class HTMLPurifier_ConfigSchema_Validator
|
||||
// handled by InterchangeBuilder
|
||||
$this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id');
|
||||
}
|
||||
if (!isset($this->interchange->namespaces[$id->namespace])) {
|
||||
$this->error('namespace', 'does not exist'); // assumes that the namespace was validated already
|
||||
}
|
||||
$this->with($id, 'directive')
|
||||
// keys are now unconstrained (we might want to narrow down to A-Za-z0-9.)
|
||||
// we probably should check that it has at least one namespace
|
||||
$this->with($id, 'key')
|
||||
->assertNotEmpty()
|
||||
->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
|
||||
->assertIsString(); // implicit assertIsString handled by InterchangeBuilder
|
||||
array_pop($this->context);
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
Attr
|
||||
DESCRIPTION: Features regarding attribute validation.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
AutoFormat
|
||||
DESCRIPTION: Configuration for activating auto-formatting functionality (also known as <code>Injector</code>s)
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
AutoFormatParam
|
||||
DESCRIPTION: Configuration for customizing auto-formatting functionality
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
CSS
|
||||
DESCRIPTION: Configuration regarding allowed CSS.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Cache
|
||||
DESCRIPTION: Configuration for DefinitionCache and related subclasses.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Core
|
||||
DESCRIPTION: Core features that are always available.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Filter
|
||||
DESCRIPTION: Directives for turning filters on and off, or specifying custom filters.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
FilterParam
|
||||
DESCRIPTION: Configuration for filters.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
HTML
|
||||
DESCRIPTION: Configuration regarding allowed HTML.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Output
|
||||
DESCRIPTION: Configuration relating to the generation of (X)HTML.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
Test
|
||||
DESCRIPTION: Developer testing configuration for our unit tests.
|
||||
--# vim: et sw=4 sts=4
|
@ -1,3 +0,0 @@
|
||||
URI
|
||||
DESCRIPTION: Features regarding Uniform Resource Identifiers.
|
||||
--# vim: et sw=4 sts=4
|
@ -159,7 +159,7 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
|
||||
$ret .= $this->end('th');
|
||||
|
||||
$ret .= $this->start('td');
|
||||
$def = $this->config->def->info[$ns][$directive];
|
||||
$def = $this->config->def->info["$ns.$directive"];
|
||||
if (is_int($def)) {
|
||||
$allow_null = $def < 0;
|
||||
$type = abs($def);
|
||||
@ -248,7 +248,7 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer {
|
||||
$this->prepareGenerator($gen_config);
|
||||
// this should probably be split up a little
|
||||
$ret = '';
|
||||
$def = $config->def->info[$ns][$directive];
|
||||
$def = $config->def->info["$ns.$directive"];
|
||||
if (is_int($def)) {
|
||||
$type = abs($def);
|
||||
} else {
|
||||
|
@ -9,16 +9,9 @@ class HTMLPurifier_ConfigSchema_InterchangeTest extends UnitTestCase
|
||||
$this->interchange = new HTMLPurifier_ConfigSchema_Interchange();
|
||||
}
|
||||
|
||||
function testAddNamespace() {
|
||||
$v = new HTMLPurifier_ConfigSchema_Interchange_Namespace();
|
||||
$v->namespace = 'Namespace';
|
||||
$this->interchange->addNamespace($v);
|
||||
$this->assertIdentical($v, $this->interchange->namespaces['Namespace']);
|
||||
}
|
||||
|
||||
function testAddDirective() {
|
||||
$v = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
||||
$v->id = new HTMLPurifier_ConfigSchema_Interchange_Id('Namespace', 'Directive');
|
||||
$v->id = new HTMLPurifier_ConfigSchema_Interchange_Id('Namespace.Directive');
|
||||
$this->interchange->addDirective($v);
|
||||
$this->assertIdentical($v, $this->interchange->directives['Namespace.Directive']);
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Alias 'Ns.BothWantThisName' in aliases in directive 'Ns.Dir2' collides with alias for directive 'Ns.Dir'
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: int
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Alias 'Ns.Innocent' in aliases in directive 'Ns.Dir' collides with another directive
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Innocent
|
||||
DESCRIPTION: Innocent directive
|
||||
TYPE: int
|
||||
|
@ -1,10 +0,0 @@
|
||||
ERROR: Directive in id 'Ns.R&D' in aliases in directive 'Ns.Dir' must be alphanumeric
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
DEFAULT: 'a'
|
||||
ALIASES: Ns.R&D
|
@ -1,8 +1,5 @@
|
||||
ERROR: Value 3 in allowed in directive 'Ns.Dir' must be a string
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Generic namespace.
|
||||
----
|
||||
ID: Ns.Dir
|
||||
TYPE: string
|
||||
DESCRIPTION: Description
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Allowed in directive 'Ns.Dir' must not be empty
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Generic namespace.
|
||||
----
|
||||
ID: Ns.Dir
|
||||
TYPE: string
|
||||
DESCRIPTION: Description
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Default in directive 'Ns.Dir' must be an allowed value
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
|
@ -1,6 +1,3 @@
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string/null
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Expected type string, got integer in DEFAULT in directive hash 'Ns.Dir'
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Description in directive 'Ns.Dir' must not be empty
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Our namespace.
|
||||
----
|
||||
Ns.Dir
|
||||
TYPE: int
|
||||
DEFAULT: 0
|
||||
|
@ -1,9 +0,0 @@
|
||||
ERROR: Directive in id 'Ns.+' in directive 'Ns.+' must be alphanumeric
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Generic namespace.
|
||||
----
|
||||
ID: Ns.+
|
||||
TYPE: int
|
||||
DESCRIPTION: Description
|
||||
DEFAULT: 0
|
@ -1,9 +0,0 @@
|
||||
ERROR: Directive in id 'Ns.' in directive 'Ns.' must not be empty
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Our namespace
|
||||
----
|
||||
ID: Ns.
|
||||
TYPE: int
|
||||
DESCRIPTION: Description.
|
||||
DEFAULT: 0
|
@ -1,6 +0,0 @@
|
||||
ERROR: Namespace in id 'Rd.Dir' in directive 'Rd.Dir' does not exist
|
||||
----
|
||||
ID: Rd.Dir
|
||||
TYPE: int
|
||||
DESCRIPTION: Description
|
||||
DEFAULT: 0
|
@ -0,0 +1,3 @@
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: TYPE in directive hash 'Ns.Dir' not defined
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Notice that TYPE is missing
|
||||
DEFAULT: 0
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Invalid type 'foobar' in DEFAULT in directive hash 'Ns.Dir'
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: foobar
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Type in directive 'Ns.Dir' must be a string type when used with allowed or value aliases
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: int
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Type in directive 'Ns.Dir' must be a string type when used with allowed or value aliases
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: int
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Alias 3 in valueAliases in directive 'Ns.Dir' must be a string
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Alias 'b' in valueAliases in directive 'Ns.Dir' must not be an allowed value
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Alias 'bar' in valueAliases in directive 'Ns.Dir' must not be an alias to itself
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Alias 'c' in valueAliases in directive 'Ns.Dir' must be an alias to an allowed value
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
|
@ -1,8 +1,5 @@
|
||||
ERROR: Alias target 3 from alias 'b' in valueAliases in directive 'Ns.Dir' must be a string
|
||||
----
|
||||
Ns
|
||||
DESCRIPTION: Namespace
|
||||
----
|
||||
Ns.Dir
|
||||
DESCRIPTION: Directive
|
||||
TYPE: string
|
||||
|
@ -1,3 +0,0 @@
|
||||
ERROR: Description in namespace 'Ns' must not be empty
|
||||
----
|
||||
ID: Ns
|
@ -1,4 +0,0 @@
|
||||
ERROR: Namespace in namespace 'R&D' must be alphanumeric
|
||||
----
|
||||
ID: R&D
|
||||
DESCRIPTION: ctype_alnum($ID) === false
|
@ -1,4 +0,0 @@
|
||||
ERROR: Namespace in namespace '0' must not be empty
|
||||
----
|
||||
ID: 0
|
||||
DESCRIPTION: empty($ID) === true
|
@ -1,2 +0,0 @@
|
||||
Namespace
|
||||
DESCRIPTION: This is a generic namespace.
|
@ -1,7 +0,0 @@
|
||||
ERROR: Cannot redefine namespace 'Ns'
|
||||
----
|
||||
ID: Ns
|
||||
DESCRIPTION: Version 1
|
||||
----
|
||||
ID: Ns
|
||||
DESCRIPTION: Version 2
|
@ -13,36 +13,15 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
||||
$this->interchange = new HTMLPurifier_ConfigSchema_Interchange();
|
||||
}
|
||||
|
||||
function testNamespaceIntegrityViolation() {
|
||||
$ns = $this->makeNamespace('Ns');
|
||||
$ns->namespace = 'AltNs';
|
||||
$this->expectValidationException("Integrity violation: key 'Ns' does not match internal id 'AltNs'");
|
||||
$this->validator->validate($this->interchange);
|
||||
}
|
||||
|
||||
function testNamespaceNamespaceIsString() {
|
||||
$this->makeNamespace(3);
|
||||
$this->expectValidationException("Namespace in namespace '3' must be a string");
|
||||
$this->validator->validate($this->interchange);
|
||||
}
|
||||
|
||||
function testNamespaceDescriptionIsString() {
|
||||
$ns = $this->makeNamespace('Ns');
|
||||
$ns->description = 3;
|
||||
$this->expectValidationException("Description in namespace 'Ns' must be a string");
|
||||
$this->validator->validate($this->interchange);
|
||||
}
|
||||
|
||||
function testDirectiveIntegrityViolation() {
|
||||
$d = $this->makeDirective('Ns', 'Dir');
|
||||
$d->id = new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir2');
|
||||
$d = $this->makeDirective('Ns.Dir');
|
||||
$d->id = new HTMLPurifier_ConfigSchema_Interchange_Id('Ns.Dir2');
|
||||
$this->expectValidationException("Integrity violation: key 'Ns.Dir' does not match internal id 'Ns.Dir2'");
|
||||
$this->validator->validate($this->interchange);
|
||||
}
|
||||
|
||||
function testDirectiveTypeNotEmpty() {
|
||||
$this->makeNamespace('Ns');
|
||||
$d = $this->makeDirective('Ns', 'Dir');
|
||||
$d = $this->makeDirective('Ns.Dir');
|
||||
$d->default = 0;
|
||||
$d->description = 'Description';
|
||||
|
||||
@ -51,8 +30,7 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
||||
}
|
||||
|
||||
function testDirectiveDefaultInvalid() {
|
||||
$this->makeNamespace('Ns');
|
||||
$d = $this->makeDirective('Ns', 'Dir');
|
||||
$d = $this->makeDirective('Ns.Dir');
|
||||
$d->default = 'asdf';
|
||||
$d->type = 'int';
|
||||
$d->description = 'Description';
|
||||
@ -61,20 +39,18 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
||||
$this->validator->validate($this->interchange);
|
||||
}
|
||||
|
||||
function testDirectiveIdDirectiveIsString() {
|
||||
$this->makeNamespace('Ns');
|
||||
$d = $this->makeDirective('Ns', 3);
|
||||
function testDirectiveIdIsString() {
|
||||
$d = $this->makeDirective(3);
|
||||
$d->default = 0;
|
||||
$d->type = 'int';
|
||||
$d->description = 'Description';
|
||||
|
||||
$this->expectValidationException("Directive in id 'Ns.3' in directive 'Ns.3' must be a string");
|
||||
$this->expectValidationException("Key in id '3' in directive '3' must be a string");
|
||||
$this->validator->validate($this->interchange);
|
||||
}
|
||||
|
||||
function testDirectiveTypeAllowsNullIsBool() {
|
||||
$this->makeNamespace('Ns');
|
||||
$d = $this->makeDirective('Ns', 'Dir');
|
||||
$d = $this->makeDirective('Ns.Dir');
|
||||
$d->default = 0;
|
||||
$d->type = 'int';
|
||||
$d->description = 'Description';
|
||||
@ -85,8 +61,7 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
||||
}
|
||||
|
||||
function testDirectiveValueAliasesIsArray() {
|
||||
$this->makeNamespace('Ns');
|
||||
$d = $this->makeDirective('Ns', 'Dir');
|
||||
$d = $this->makeDirective('Ns.Dir');
|
||||
$d->default = 'a';
|
||||
$d->type = 'string';
|
||||
$d->description = 'Description';
|
||||
@ -97,8 +72,7 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
||||
}
|
||||
|
||||
function testDirectiveAllowedIsLookup() {
|
||||
$this->makeNamespace('Ns');
|
||||
$d = $this->makeDirective('Ns', 'Dir');
|
||||
$d = $this->makeDirective('Ns.Dir');
|
||||
$d->default = 'foo';
|
||||
$d->type = 'string';
|
||||
$d->description = 'Description';
|
||||
@ -110,17 +84,10 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
||||
|
||||
// helper functions
|
||||
|
||||
protected function makeNamespace($n) {
|
||||
$namespace = new HTMLPurifier_ConfigSchema_Interchange_Namespace();
|
||||
$namespace->namespace = $n;
|
||||
$namespace->description = 'Description'; // non-essential, but we won't set it most of the time
|
||||
$this->interchange->addNamespace($namespace);
|
||||
return $namespace;
|
||||
}
|
||||
|
||||
protected function makeDirective($n, $d) {
|
||||
protected function makeDirective($key) {
|
||||
$directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
||||
$directive->id = new HTMLPurifier_ConfigSchema_Interchange_Id($n, $d);
|
||||
$directive->id = new HTMLPurifier_ConfigSchema_Interchange_Id($key);
|
||||
$this->interchange->addDirective($directive);
|
||||
return $directive;
|
||||
}
|
||||
|
@ -9,41 +9,32 @@ class HTMLPurifier_ConfigSchemaTest extends HTMLPurifier_Harness
|
||||
$this->schema = new HTMLPurifier_ConfigSchema();
|
||||
}
|
||||
|
||||
function test_defineNamespace() {
|
||||
$this->schema->addNamespace('http');
|
||||
$this->assertIdentical($this->schema->info['http'], array());
|
||||
$this->assertIdentical($this->schema->defaults['http'], array());
|
||||
}
|
||||
|
||||
function test_define() {
|
||||
$this->schema->addNamespace('Car');
|
||||
$this->schema->add('Car.Seats', 5, 'int', false);
|
||||
|
||||
$this->schema->add('Car', 'Seats', 5, 'int', false);
|
||||
$this->assertIdentical($this->schema->defaults['Car.Seats'], 5);
|
||||
$this->assertIdentical($this->schema->info['Car.Seats']->type, HTMLPurifier_VarParser::INT);
|
||||
|
||||
$this->assertIdentical($this->schema->defaults['Car']['Seats'], 5);
|
||||
$this->assertIdentical($this->schema->info['Car']['Seats']->type, HTMLPurifier_VarParser::INT);
|
||||
$this->schema->add('Car.Age', null, 'int', true);
|
||||
|
||||
$this->schema->add('Car', 'Age', null, 'int', true);
|
||||
|
||||
$this->assertIdentical($this->schema->defaults['Car']['Age'], null);
|
||||
$this->assertIdentical($this->schema->info['Car']['Age']->type, HTMLPurifier_VarParser::INT);
|
||||
$this->assertIdentical($this->schema->defaults['Car.Age'], null);
|
||||
$this->assertIdentical($this->schema->info['Car.Age']->type, HTMLPurifier_VarParser::INT);
|
||||
|
||||
}
|
||||
|
||||
function test_defineAllowedValues() {
|
||||
$this->schema->addNamespace('QuantumNumber', 'D');
|
||||
$this->schema->add('QuantumNumber', 'Spin', 0.5, 'float', false);
|
||||
$this->schema->add('QuantumNumber', 'Current', 's', 'string', false);
|
||||
$this->schema->add('QuantumNumber', 'Difficulty', null, 'string', true);
|
||||
$this->schema->add('QuantumNumber.Spin', 0.5, 'float', false);
|
||||
$this->schema->add('QuantumNumber.Current', 's', 'string', false);
|
||||
$this->schema->add('QuantumNumber.Difficulty', null, 'string', true);
|
||||
|
||||
$this->schema->addAllowedValues( // okay, since default is null
|
||||
'QuantumNumber', 'Difficulty', array('easy' => true, 'medium' => true, 'hard' => true)
|
||||
'QuantumNumber.Difficulty', array('easy' => true, 'medium' => true, 'hard' => true)
|
||||
);
|
||||
|
||||
$this->assertIdentical($this->schema->defaults['QuantumNumber']['Difficulty'], null);
|
||||
$this->assertIdentical($this->schema->info['QuantumNumber']['Difficulty']->type, HTMLPurifier_VarParser::STRING);
|
||||
$this->assertIdentical($this->schema->info['QuantumNumber']['Difficulty']->allow_null, true);
|
||||
$this->assertIdentical($this->schema->info['QuantumNumber']['Difficulty']->allowed,
|
||||
$this->assertIdentical($this->schema->defaults['QuantumNumber.Difficulty'], null);
|
||||
$this->assertIdentical($this->schema->info['QuantumNumber.Difficulty']->type, HTMLPurifier_VarParser::STRING);
|
||||
$this->assertIdentical($this->schema->info['QuantumNumber.Difficulty']->allow_null, true);
|
||||
$this->assertIdentical($this->schema->info['QuantumNumber.Difficulty']->allowed,
|
||||
array(
|
||||
'easy' => true,
|
||||
'medium' => true,
|
||||
@ -54,37 +45,36 @@ class HTMLPurifier_ConfigSchemaTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function test_defineValueAliases() {
|
||||
$this->schema->addNamespace('Abbrev', 'Stuff on abbreviations.');
|
||||
$this->schema->add('Abbrev', 'HTH', 'Happy to Help', 'string', false);
|
||||
$this->schema->add('Abbrev.HTH', 'Happy to Help', 'string', false);
|
||||
$this->schema->addAllowedValues(
|
||||
'Abbrev', 'HTH', array(
|
||||
'Abbrev.HTH', array(
|
||||
'Happy to Help' => true,
|
||||
'Hope that Helps' => true,
|
||||
'HAIL THE HAND!' => true,
|
||||
)
|
||||
);
|
||||
$this->schema->addValueAliases(
|
||||
'Abbrev', 'HTH', array(
|
||||
'Abbrev.HTH', array(
|
||||
'happy' => 'Happy to Help',
|
||||
'hope' => 'Hope that Helps'
|
||||
)
|
||||
);
|
||||
$this->schema->addValueAliases( // delayed addition
|
||||
'Abbrev', 'HTH', array(
|
||||
'Abbrev.HTH', array(
|
||||
'hail' => 'HAIL THE HAND!'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertIdentical($this->schema->defaults['Abbrev']['HTH'], 'Happy to Help');
|
||||
$this->assertIdentical($this->schema->info['Abbrev']['HTH']->type, HTMLPurifier_VarParser::STRING);
|
||||
$this->assertIdentical($this->schema->info['Abbrev']['HTH']->allowed,
|
||||
$this->assertIdentical($this->schema->defaults['Abbrev.HTH'], 'Happy to Help');
|
||||
$this->assertIdentical($this->schema->info['Abbrev.HTH']->type, HTMLPurifier_VarParser::STRING);
|
||||
$this->assertIdentical($this->schema->info['Abbrev.HTH']->allowed,
|
||||
array(
|
||||
'Happy to Help' => true,
|
||||
'Hope that Helps' => true,
|
||||
'HAIL THE HAND!' => true
|
||||
)
|
||||
);
|
||||
$this->assertIdentical($this->schema->info['Abbrev']['HTH']->aliases,
|
||||
$this->assertIdentical($this->schema->info['Abbrev.HTH']->aliases,
|
||||
array(
|
||||
'happy' => 'Happy to Help',
|
||||
'hope' => 'Hope that Helps',
|
||||
@ -95,14 +85,12 @@ class HTMLPurifier_ConfigSchemaTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function testAlias() {
|
||||
$this->schema->addNamespace('Home');
|
||||
$this->schema->add('Home', 'Rug', 3, 'int', false);
|
||||
$this->schema->addAlias('Home', 'Carpet', 'Home', 'Rug');
|
||||
$this->schema->add('Home.Rug', 3, 'int', false);
|
||||
$this->schema->addAlias('Home.Carpet', 'Home.Rug');
|
||||
|
||||
$this->assertTrue(!isset($this->schema->defaults['Home']['Carpet']));
|
||||
$this->assertIdentical($this->schema->info['Home']['Carpet']->namespace, 'Home');
|
||||
$this->assertIdentical($this->schema->info['Home']['Carpet']->name, 'Rug');
|
||||
$this->assertIdentical($this->schema->info['Home']['Carpet']->isAlias, true);
|
||||
$this->assertTrue(!isset($this->schema->defaults['Home.Carpet']));
|
||||
$this->assertIdentical($this->schema->info['Home.Carpet']->key, 'Home.Rug');
|
||||
$this->assertIdentical($this->schema->info['Home.Carpet']->isAlias, true);
|
||||
|
||||
}
|
||||
|
||||
|
@ -13,17 +13,15 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
// test functionality based on ConfigSchema
|
||||
|
||||
function testNormal() {
|
||||
$this->schema->addNamespace('Element');
|
||||
|
||||
$this->schema->add('Element', 'Abbr', 'H', 'string', false);
|
||||
$this->schema->add('Element', 'Name', 'hydrogen', 'istring', false);
|
||||
$this->schema->add('Element', 'Number', 1, 'int', false);
|
||||
$this->schema->add('Element', 'Mass', 1.00794, 'float', false);
|
||||
$this->schema->add('Element', 'Radioactive', false, 'bool', false);
|
||||
$this->schema->add('Element', 'Isotopes', array(1 => true, 2 => true, 3 => true), 'lookup', false);
|
||||
$this->schema->add('Element', 'Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', false);
|
||||
$this->schema->add('Element', 'IsotopeNames', array(1 => 'protium', 2 => 'deuterium', 3 => 'tritium'), 'hash', false);
|
||||
$this->schema->add('Element', 'Object', new stdClass(), 'mixed', false);
|
||||
$this->schema->add('Element.Abbr', 'H', 'string', false);
|
||||
$this->schema->add('Element.Name', 'hydrogen', 'istring', false);
|
||||
$this->schema->add('Element.Number', 1, 'int', false);
|
||||
$this->schema->add('Element.Mass', 1.00794, 'float', false);
|
||||
$this->schema->add('Element.Radioactive', false, 'bool', false);
|
||||
$this->schema->add('Element.Isotopes', array(1 => true, 2 => true, 3 => true), 'lookup', false);
|
||||
$this->schema->add('Element.Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', false);
|
||||
$this->schema->add('Element.IsotopeNames', array(1 => 'protium', 2 => 'deuterium', 3 => 'tritium'), 'hash', false);
|
||||
$this->schema->add('Element.Object', new stdClass(), 'mixed', false);
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$config->autoFinalize = false;
|
||||
@ -74,22 +72,20 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function testEnumerated() {
|
||||
|
||||
$this->schema->addNamespace('Instrument', 'Of the musical type.');
|
||||
|
||||
// case sensitive
|
||||
$this->schema->add('Instrument', 'Manufacturer', 'Yamaha', 'string', false);
|
||||
$this->schema->addAllowedValues('Instrument', 'Manufacturer', array(
|
||||
$this->schema->add('Instrument.Manufacturer', 'Yamaha', 'string', false);
|
||||
$this->schema->addAllowedValues('Instrument.Manufacturer', array(
|
||||
'Yamaha' => true, 'Conn-Selmer' => true, 'Vandoren' => true,
|
||||
'Laubin' => true, 'Buffet' => true, 'other' => true));
|
||||
$this->schema->addValueAliases('Instrument', 'Manufacturer', array(
|
||||
$this->schema->addValueAliases('Instrument.Manufacturer', array(
|
||||
'Selmer' => 'Conn-Selmer'));
|
||||
|
||||
// case insensitive
|
||||
$this->schema->add('Instrument', 'Family', 'woodwind', 'istring', false);
|
||||
$this->schema->addAllowedValues('Instrument', 'Family', array(
|
||||
$this->schema->add('Instrument.Family', 'woodwind', 'istring', false);
|
||||
$this->schema->addAllowedValues('Instrument.Family', array(
|
||||
'brass' => true, 'woodwind' => true, 'percussion' => true,
|
||||
'string' => true, 'keyboard' => true, 'electronic' => true));
|
||||
$this->schema->addValueAliases('Instrument', 'Family', array(
|
||||
$this->schema->addValueAliases('Instrument.Family', array(
|
||||
'synth' => 'electronic'));
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
@ -124,9 +120,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function testNull() {
|
||||
|
||||
$this->schema->addNamespace('ReportCard');
|
||||
$this->schema->add('ReportCard', 'English', null, 'string', true);
|
||||
$this->schema->add('ReportCard', 'Absences', 0, 'int', false);
|
||||
$this->schema->add('ReportCard.English', null, 'string', true);
|
||||
$this->schema->add('ReportCard.Absences', 0, 'int', false);
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$config->autoFinalize = false;
|
||||
@ -145,9 +140,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function testAliases() {
|
||||
|
||||
$this->schema->addNamespace('Home');
|
||||
$this->schema->add('Home', 'Rug', 3, 'int', false);
|
||||
$this->schema->addAlias('Home', 'Carpet', 'Home', 'Rug');
|
||||
$this->schema->add('Home.Rug', 3, 'int', false);
|
||||
$this->schema->addAlias('Home.Carpet', 'Home.Rug');
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$config->autoFinalize = false;
|
||||
@ -167,9 +161,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function test_getBatch() {
|
||||
|
||||
$this->schema->addNamespace('Variables');
|
||||
$this->schema->add('Variables', 'TangentialAcceleration', 'a_tan', 'string', false);
|
||||
$this->schema->add('Variables', 'AngularAcceleration', 'alpha', 'string', false);
|
||||
$this->schema->add('Variables.TangentialAcceleration', 'a_tan', 'string', false);
|
||||
$this->schema->add('Variables.AngularAcceleration', 'alpha', 'string', false);
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$config->autoFinalize = false;
|
||||
@ -191,10 +184,9 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function test_loadIni() {
|
||||
|
||||
$this->schema->addNamespace('Shortcut', 'Keyboard shortcuts for commands');
|
||||
$this->schema->add('Shortcut', 'Copy', 'c', 'istring', false);
|
||||
$this->schema->add('Shortcut', 'Paste', 'v', 'istring', false);
|
||||
$this->schema->add('Shortcut', 'Cut', 'x', 'istring', false);
|
||||
$this->schema->add('Shortcut.Copy', 'c', 'istring', false);
|
||||
$this->schema->add('Shortcut.Paste', 'v', 'istring', false);
|
||||
$this->schema->add('Shortcut.Cut', 'x', 'istring', false);
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$config->autoFinalize = false;
|
||||
@ -259,9 +251,7 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function test_getDefinition() {
|
||||
$this->schema->addNamespace('Cache', 'Cache stuff');
|
||||
$this->schema->add('Cache', 'DefinitionImpl', null, 'string', true);
|
||||
$this->schema->addNamespace('Crust', 'Krusty Krabs');
|
||||
$this->schema->add('Cache.DefinitionImpl', null, 'string', true);
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$this->expectException(new HTMLPurifier_Exception("Definition of Crust type not supported"));
|
||||
$config->getDefinition('Crust');
|
||||
@ -269,11 +259,10 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function test_loadArray() {
|
||||
// setup a few dummy namespaces/directives for our testing
|
||||
$this->schema->addNamespace('Zoo');
|
||||
$this->schema->add('Zoo', 'Aadvark', 0, 'int', false);
|
||||
$this->schema->add('Zoo', 'Boar', 0, 'int', false);
|
||||
$this->schema->add('Zoo', 'Camel', 0, 'int', false);
|
||||
$this->schema->add('Zoo', 'Others', array(), 'list', false);
|
||||
$this->schema->add('Zoo.Aadvark', 0, 'int', false);
|
||||
$this->schema->add('Zoo.Boar', 0, 'int', false);
|
||||
$this->schema->add('Zoo.Camel', 0, 'int', false);
|
||||
$this->schema->add('Zoo.Others', array(), 'list', false);
|
||||
|
||||
$config_manual = new HTMLPurifier_Config($this->schema);
|
||||
$config_loadabbr = new HTMLPurifier_Config($this->schema);
|
||||
@ -309,9 +298,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function test_create() {
|
||||
|
||||
$this->schema->addNamespace('Cake');
|
||||
$this->schema->add('Cake', 'Sprinkles', 666, 'int', false);
|
||||
$this->schema->add('Cake', 'Flavor', 'vanilla', 'string', false);
|
||||
$this->schema->add('Cake.Sprinkles', 666, 'int', false);
|
||||
$this->schema->add('Cake.Flavor', 'vanilla', 'string', false);
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$config->set('Cake', 'Sprinkles', 42);
|
||||
@ -334,8 +322,7 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
// test finalization
|
||||
|
||||
$this->schema->addNamespace('Poem');
|
||||
$this->schema->add('Poem', 'Meter', 'iambic', 'string', false);
|
||||
$this->schema->add('Poem.Meter', 'iambic', 'string', false);
|
||||
|
||||
$config = new HTMLPurifier_Config($this->schema);
|
||||
$config->autoFinalize = false;
|
||||
@ -357,17 +344,15 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
|
||||
function test_loadArrayFromForm() {
|
||||
|
||||
$this->schema->addNamespace('Pancake');
|
||||
$this->schema->add('Pancake', 'Mix', 'buttermilk', 'string', false);
|
||||
$this->schema->add('Pancake', 'Served', true, 'bool', false);
|
||||
$this->schema->addNamespace('Toppings', false);
|
||||
$this->schema->add('Toppings', 'Syrup', true, 'bool', false);
|
||||
$this->schema->add('Toppings', 'Flavor', 'maple', 'string', false);
|
||||
$this->schema->add('Toppings', 'Strawberries', 3, 'int', false);
|
||||
$this->schema->add('Toppings', 'Calories', 2000, 'int', true);
|
||||
$this->schema->add('Toppings', 'DefinitionID', null, 'string', true);
|
||||
$this->schema->add('Toppings', 'DefinitionRev', 1, 'int', false);
|
||||
$this->schema->add('Toppings', 'Protected', 1, 'int', false);
|
||||
$this->schema->add('Pancake.Mix', 'buttermilk', 'string', false);
|
||||
$this->schema->add('Pancake.Served', true, 'bool', false);
|
||||
$this->schema->add('Toppings.Syrup', true, 'bool', false);
|
||||
$this->schema->add('Toppings.Flavor', 'maple', 'string', false);
|
||||
$this->schema->add('Toppings.Strawberries', 3, 'int', false);
|
||||
$this->schema->add('Toppings.Calories', 2000, 'int', true);
|
||||
$this->schema->add('Toppings.DefinitionID', null, 'string', true);
|
||||
$this->schema->add('Toppings.DefinitionRev', 1, 'int', false);
|
||||
$this->schema->add('Toppings.Protected', 1, 'int', false);
|
||||
|
||||
$get = array(
|
||||
'breakfast' => array(
|
||||
@ -418,16 +403,13 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
||||
}
|
||||
|
||||
function test_getAllowedDirectivesForForm() {
|
||||
$this->schema->addNamespace('Unused');
|
||||
$this->schema->add('Unused', 'Unused', 'Foobar', 'string', false);
|
||||
$this->schema->addNamespace('Partial');
|
||||
$this->schema->add('Partial', 'Allowed', true, 'bool', false);
|
||||
$this->schema->add('Partial', 'Unused', 'Foobar', 'string', false);
|
||||
$this->schema->addNamespace('All');
|
||||
$this->schema->add('All', 'Allowed', true, 'bool', false);
|
||||
$this->schema->add('All', 'Blacklisted', 'Foobar', 'string', false); // explicitly blacklisted
|
||||
$this->schema->add('All', 'DefinitionID', 'Foobar', 'string', true); // auto-blacklisted
|
||||
$this->schema->add('All', 'DefinitionRev', 2, 'int', false); // auto-blacklisted
|
||||
$this->schema->add('Unused.Unused', 'Foobar', 'string', false);
|
||||
$this->schema->add('Partial.Allowed', true, 'bool', false);
|
||||
$this->schema->add('Partial.Unused', 'Foobar', 'string', false);
|
||||
$this->schema->add('All.Allowed', true, 'bool', false);
|
||||
$this->schema->add('All.Blacklisted', 'Foobar', 'string', false); // explicitly blacklisted
|
||||
$this->schema->add('All.DefinitionID', 'Foobar', 'string', true); // auto-blacklisted
|
||||
$this->schema->add('All.DefinitionRev', 2, 'int', false); // auto-blacklisted
|
||||
|
||||
$input = array('Partial.Allowed', 'All', '-All.Blacklisted');
|
||||
$output = HTMLPurifier_Config::getAllowedDirectivesForForm($input, $this->schema);
|
||||
|
Loading…
Reference in New Issue
Block a user