mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-07-09 16:56:20 +02:00
Revamp configuration backend.
Signed-off-by: Edward Z. Yang <edwardzyang@thewritingpot.com>
This commit is contained in:
3
NEWS
3
NEWS
@ -10,6 +10,9 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
==========================
|
==========================
|
||||||
|
|
||||||
4.0.0, unknown release date
|
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=""
|
! More robust support for name="" and id=""
|
||||||
|
|
||||||
3.3.0, released 2009-02-16
|
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 $namespace String namespace
|
||||||
* @param $key String key
|
* @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 (!$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
|
// 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);
|
E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isset($this->def->info[$namespace][$key]->isAlias)) {
|
if (isset($this->def->info[$key]->isAlias)) {
|
||||||
$d = $this->def->info[$namespace][$key];
|
$d = $this->def->info[$key];
|
||||||
trigger_error('Cannot get value from aliased directive, use real name ' . $d->namespace . '.' . $d->name,
|
trigger_error('Cannot get value from aliased directive, use real name ' . $d->key,
|
||||||
E_USER_ERROR);
|
E_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return $this->plist->get("$namespace.$key");
|
return $this->plist->get($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -140,12 +141,12 @@ class HTMLPurifier_Config
|
|||||||
*/
|
*/
|
||||||
public function getBatch($namespace) {
|
public function getBatch($namespace) {
|
||||||
if (!$this->finalized) $this->autoFinalize ? $this->finalize() : $this->plist->squash(true);
|
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),
|
trigger_error('Cannot retrieve undefined namespace ' . htmlspecialchars($namespace),
|
||||||
E_USER_WARNING);
|
E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$full = $this->getAll();
|
|
||||||
return $full[$namespace];
|
return $full[$namespace];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,25 +196,26 @@ class HTMLPurifier_Config
|
|||||||
* @param $key String key
|
* @param $key String key
|
||||||
* @param $value Mixed value
|
* @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 ($this->isFinalized('Cannot set directive after finalization')) return;
|
||||||
if (!isset($this->def->info[$namespace][$key])) {
|
if (!isset($this->def->info[$key])) {
|
||||||
trigger_error('Cannot set undefined directive ' . htmlspecialchars("$namespace.$key") . ' to value',
|
trigger_error('Cannot set undefined directive ' . htmlspecialchars($key) . ' to value',
|
||||||
E_USER_WARNING);
|
E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$def = $this->def->info[$namespace][$key];
|
$def = $this->def->info[$key];
|
||||||
|
|
||||||
if (isset($def->isAlias)) {
|
if (isset($def->isAlias)) {
|
||||||
if ($from_alias) {
|
if ($from_alias) {
|
||||||
trigger_error('Double-aliases not allowed, please fix '.
|
trigger_error('Double-aliases not allowed, please fix '.
|
||||||
'ConfigSchema bug with' . "$namespace.$key", E_USER_ERROR);
|
'ConfigSchema bug with' . $key, E_USER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->set($new_ns = $def->namespace,
|
list($alias_namespace, $alias_directive) = explode('.', $def->key, 2);
|
||||||
$new_dir = $def->name,
|
$this->set($alias_namespace, $alias_directive,
|
||||||
$value, true);
|
$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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +233,7 @@ class HTMLPurifier_Config
|
|||||||
try {
|
try {
|
||||||
$value = $this->parser->parse($value, $type, $allow_null);
|
$value = $this->parser->parse($value, $type, $allow_null);
|
||||||
} catch (HTMLPurifier_VarParserException $e) {
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
if (is_string($value) && is_object($def)) {
|
if (is_string($value) && is_object($def)) {
|
||||||
@ -246,7 +248,7 @@ class HTMLPurifier_Config
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->plist->set("$namespace.$key", $value);
|
$this->plist->set($key, $value);
|
||||||
|
|
||||||
// reset definitions if the directives they depend on changed
|
// reset definitions if the directives they depend on changed
|
||||||
// this is a very costly process, so it's discouraged
|
// this is a very costly process, so it's discouraged
|
||||||
@ -351,8 +353,7 @@ class HTMLPurifier_Config
|
|||||||
foreach ($config_array as $key => $value) {
|
foreach ($config_array as $key => $value) {
|
||||||
$key = str_replace('_', '.', $key);
|
$key = str_replace('_', '.', $key);
|
||||||
if (strpos($key, '.') !== false) {
|
if (strpos($key, '.') !== false) {
|
||||||
// condensed form
|
list($namespace, $directive) = explode(".", $key, 2);
|
||||||
list($namespace, $directive) = explode('.', $key);
|
|
||||||
$this->set($namespace, $directive, $value);
|
$this->set($namespace, $directive, $value);
|
||||||
} else {
|
} else {
|
||||||
$namespace = $key;
|
$namespace = $key;
|
||||||
@ -394,16 +395,15 @@ class HTMLPurifier_Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$ret = array();
|
$ret = array();
|
||||||
foreach ($schema->info as $ns => $keypairs) {
|
foreach ($schema->info as $key => $def) {
|
||||||
foreach ($keypairs as $directive => $def) {
|
list($ns, $directive) = explode('.', $key, 2);
|
||||||
if ($allowed !== true) {
|
if ($allowed !== true) {
|
||||||
if (isset($blacklisted_directives["$ns.$directive"])) continue;
|
if (isset($blacklisted_directives["$ns.$directive"])) continue;
|
||||||
if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
|
if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) continue;
|
||||||
}
|
|
||||||
if (isset($def->isAlias)) continue;
|
|
||||||
if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
|
|
||||||
$ret[] = array($ns, $directive);
|
|
||||||
}
|
}
|
||||||
|
if (isset($def->isAlias)) continue;
|
||||||
|
if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') continue;
|
||||||
|
$ret[] = array($ns, $directive);
|
||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
@ -87,24 +87,13 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
* HTMLPurifier_DirectiveDef::$type for allowed values
|
* HTMLPurifier_DirectiveDef::$type for allowed values
|
||||||
* @param $allow_null Whether or not to allow null 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 = new stdclass();
|
||||||
$obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type];
|
$obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type];
|
||||||
if ($allow_null) $obj->allow_null = true;
|
if ($allow_null) $obj->allow_null = true;
|
||||||
$this->info[$namespace][$name] = $obj;
|
$this->info[$key] = $obj;
|
||||||
$this->defaults[$namespace][$name] = $default;
|
$this->defaults[$key] = $default;
|
||||||
$this->defaultPlist->set("$namespace.$name", $default);
|
$this->defaultPlist->set($key, $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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,12 +105,12 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
* @param $name Name of Directive
|
* @param $name Name of Directive
|
||||||
* @param $aliases Hash of aliased values to the real alias
|
* @param $aliases Hash of aliased values to the real alias
|
||||||
*/
|
*/
|
||||||
public function addValueAliases($namespace, $name, $aliases) {
|
public function addValueAliases($key, $aliases) {
|
||||||
if (!isset($this->info[$namespace][$name]->aliases)) {
|
if (!isset($this->info[$key]->aliases)) {
|
||||||
$this->info[$namespace][$name]->aliases = array();
|
$this->info[$key]->aliases = array();
|
||||||
}
|
}
|
||||||
foreach ($aliases as $alias => $real) {
|
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 $name Name of directive
|
||||||
* @param $allowed Lookup array of allowed values
|
* @param $allowed Lookup array of allowed values
|
||||||
*/
|
*/
|
||||||
public function addAllowedValues($namespace, $name, $allowed) {
|
public function addAllowedValues($key, $allowed) {
|
||||||
$this->info[$namespace][$name]->allowed = $allowed;
|
$this->info[$key]->allowed = $allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,88 +133,26 @@ class HTMLPurifier_ConfigSchema {
|
|||||||
* @param $new_namespace
|
* @param $new_namespace
|
||||||
* @param $new_name Directive that the alias will be to
|
* @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 = new stdclass;
|
||||||
$obj->namespace = $new_namespace;
|
$obj->key = $new_key;
|
||||||
$obj->name = $new_name;
|
|
||||||
$obj->isAlias = true;
|
$obj->isAlias = true;
|
||||||
$this->info[$namespace][$name] = $obj;
|
$this->info[$key] = $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces any stdclass that only has the type property with type integer.
|
* Replaces any stdclass that only has the type property with type integer.
|
||||||
*/
|
*/
|
||||||
public function postProcess() {
|
public function postProcess() {
|
||||||
foreach ($this->info as $namespace => $info) {
|
foreach ($this->info as $key => $v) {
|
||||||
foreach ($info as $directive => $v) {
|
if (count((array) $v) == 1) {
|
||||||
if (count((array) $v) == 1) {
|
$this->info[$key] = $v->type;
|
||||||
$this->info[$namespace][$directive] = $v->type;
|
} elseif (count((array) $v) == 2 && isset($v->allow_null)) {
|
||||||
} elseif (count((array) $v) == 2 && isset($v->allow_null)) {
|
$this->info[$key] = -$v->type;
|
||||||
$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
|
// vim: et sw=4 sts=4
|
||||||
|
@ -9,36 +9,28 @@ class HTMLPurifier_ConfigSchema_Builder_ConfigSchema
|
|||||||
|
|
||||||
public function build($interchange) {
|
public function build($interchange) {
|
||||||
$schema = new HTMLPurifier_ConfigSchema();
|
$schema = new HTMLPurifier_ConfigSchema();
|
||||||
foreach ($interchange->namespaces as $n) {
|
|
||||||
$schema->addNamespace($n->namespace);
|
|
||||||
}
|
|
||||||
foreach ($interchange->directives as $d) {
|
foreach ($interchange->directives as $d) {
|
||||||
$schema->add(
|
$schema->add(
|
||||||
$d->id->namespace,
|
$d->id->key,
|
||||||
$d->id->directive,
|
|
||||||
$d->default,
|
$d->default,
|
||||||
$d->type,
|
$d->type,
|
||||||
$d->typeAllowsNull
|
$d->typeAllowsNull
|
||||||
);
|
);
|
||||||
if ($d->allowed !== null) {
|
if ($d->allowed !== null) {
|
||||||
$schema->addAllowedValues(
|
$schema->addAllowedValues(
|
||||||
$d->id->namespace,
|
$d->id->key,
|
||||||
$d->id->directive,
|
|
||||||
$d->allowed
|
$d->allowed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
foreach ($d->aliases as $alias) {
|
foreach ($d->aliases as $alias) {
|
||||||
$schema->addAlias(
|
$schema->addAlias(
|
||||||
$alias->namespace,
|
$alias->key,
|
||||||
$alias->directive,
|
$d->id->key
|
||||||
$d->id->namespace,
|
|
||||||
$d->id->directive
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($d->valueAliases !== null) {
|
if ($d->valueAliases !== null) {
|
||||||
$schema->addValueAliases(
|
$schema->addValueAliases(
|
||||||
$d->id->namespace,
|
$d->id->key,
|
||||||
$d->id->directive,
|
|
||||||
$d->valueAliases
|
$d->valueAliases
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
|
|||||||
{
|
{
|
||||||
|
|
||||||
protected $interchange;
|
protected $interchange;
|
||||||
|
private $namespace;
|
||||||
|
|
||||||
protected function writeHTMLDiv($html) {
|
protected function writeHTMLDiv($html) {
|
||||||
$this->startElement('div');
|
$this->startElement('div');
|
||||||
@ -34,36 +35,33 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
|
|||||||
$this->startElement('configdoc');
|
$this->startElement('configdoc');
|
||||||
$this->writeElement('title', $interchange->name);
|
$this->writeElement('title', $interchange->name);
|
||||||
|
|
||||||
foreach ($interchange->namespaces as $namespace) {
|
foreach ($interchange->directives as $directive) {
|
||||||
$this->buildNamespace($namespace);
|
$this->buildDirective($directive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->namespace) $this->endElement(); // namespace
|
||||||
|
|
||||||
$this->endElement(); // configdoc
|
$this->endElement(); // configdoc
|
||||||
$this->flush();
|
$this->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildNamespace($namespace) {
|
public function buildDirective($directive) {
|
||||||
$this->startElement('namespace');
|
|
||||||
$this->writeAttribute('id', $namespace->namespace);
|
|
||||||
|
|
||||||
$this->writeElement('name', $namespace->namespace);
|
// Kludge, although I suppose having a notion of a "root namespace"
|
||||||
$this->startElement('description');
|
// certainly makes things look nicer when documentation is built.
|
||||||
$this->writeHTMLDiv($namespace->description);
|
// Depends on things being sorted.
|
||||||
$this->endElement(); // description
|
if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) {
|
||||||
|
if ($this->namespace) $this->endElement(); // namespace
|
||||||
foreach ($this->interchange->directives as $directive) {
|
$this->namespace = $directive->id->getRootNamespace();
|
||||||
if ($directive->id->namespace !== $namespace->namespace) continue;
|
$this->startElement('namespace');
|
||||||
$this->buildDirective($directive);
|
$this->writeAttribute('id', $this->namespace);
|
||||||
|
$this->writeElement('name', $this->namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->endElement(); // namespace
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildDirective($directive) {
|
|
||||||
$this->startElement('directive');
|
$this->startElement('directive');
|
||||||
$this->writeAttribute('id', $directive->id->toString());
|
$this->writeAttribute('id', $directive->id->toString());
|
||||||
|
|
||||||
$this->writeElement('name', $directive->id->directive);
|
$this->writeElement('name', $directive->id->getDirective());
|
||||||
|
|
||||||
$this->startElement('aliases');
|
$this->startElement('aliases');
|
||||||
foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString());
|
foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString());
|
||||||
|
@ -13,26 +13,11 @@ class HTMLPurifier_ConfigSchema_Interchange
|
|||||||
*/
|
*/
|
||||||
public $name;
|
public $name;
|
||||||
|
|
||||||
/**
|
|
||||||
* Array of Namespace ID => array(namespace info)
|
|
||||||
*/
|
|
||||||
public $namespaces = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of Directive ID => array(directive info)
|
* Array of Directive ID => array(directive info)
|
||||||
*/
|
*/
|
||||||
public $directives = array();
|
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
|
* Adds a directive array to $directives
|
||||||
*/
|
*/
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
class HTMLPurifier_ConfigSchema_Interchange_Id
|
class HTMLPurifier_ConfigSchema_Interchange_Id
|
||||||
{
|
{
|
||||||
|
|
||||||
public $namespace, $directive;
|
public $key;
|
||||||
|
|
||||||
public function __construct($namespace, $directive) {
|
public function __construct($key) {
|
||||||
$this->namespace = $namespace;
|
$this->key = $key;
|
||||||
$this->directive = $directive;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,12 +17,19 @@ class HTMLPurifier_ConfigSchema_Interchange_Id
|
|||||||
* cause problems for PHP 5.0 support.
|
* cause problems for PHP 5.0 support.
|
||||||
*/
|
*/
|
||||||
public function toString() {
|
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) {
|
public static function make($id) {
|
||||||
list($namespace, $directive) = explode('.', $id);
|
return new HTMLPurifier_ConfigSchema_Interchange_Id($id);
|
||||||
return new HTMLPurifier_ConfigSchema_Interchange_Id($namespace, $directive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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');
|
throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID');
|
||||||
}
|
}
|
||||||
if (strpos($hash['ID'], '.') === false) {
|
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 {
|
} else {
|
||||||
$this->buildDirective($interchange, $hash);
|
$this->buildDirective($interchange, $hash);
|
||||||
}
|
}
|
||||||
$this->_findUnused($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) {
|
public function buildDirective($interchange, $hash) {
|
||||||
$directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
$directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
||||||
|
|
||||||
|
@ -39,10 +39,6 @@ class HTMLPurifier_ConfigSchema_Validator
|
|||||||
$this->aliases = array();
|
$this->aliases = array();
|
||||||
// PHP is a bit lax with integer <=> string conversions in
|
// PHP is a bit lax with integer <=> string conversions in
|
||||||
// arrays, so we don't use the identical !== comparison
|
// 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) {
|
foreach ($interchange->directives as $i => $directive) {
|
||||||
$id = $directive->id->toString();
|
$id = $directive->id->toString();
|
||||||
if ($i != $id) $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'");
|
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;
|
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.
|
* Validates a HTMLPurifier_ConfigSchema_Interchange_Id object.
|
||||||
*/
|
*/
|
||||||
@ -75,12 +57,11 @@ class HTMLPurifier_ConfigSchema_Validator
|
|||||||
// handled by InterchangeBuilder
|
// handled by InterchangeBuilder
|
||||||
$this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id');
|
$this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id');
|
||||||
}
|
}
|
||||||
if (!isset($this->interchange->namespaces[$id->namespace])) {
|
// keys are now unconstrained (we might want to narrow down to A-Za-z0-9.)
|
||||||
$this->error('namespace', 'does not exist'); // assumes that the namespace was validated already
|
// we probably should check that it has at least one namespace
|
||||||
}
|
$this->with($id, 'key')
|
||||||
$this->with($id, 'directive')
|
|
||||||
->assertNotEmpty()
|
->assertNotEmpty()
|
||||||
->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
|
->assertIsString(); // implicit assertIsString handled by InterchangeBuilder
|
||||||
array_pop($this->context);
|
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->end('th');
|
||||||
|
|
||||||
$ret .= $this->start('td');
|
$ret .= $this->start('td');
|
||||||
$def = $this->config->def->info[$ns][$directive];
|
$def = $this->config->def->info["$ns.$directive"];
|
||||||
if (is_int($def)) {
|
if (is_int($def)) {
|
||||||
$allow_null = $def < 0;
|
$allow_null = $def < 0;
|
||||||
$type = abs($def);
|
$type = abs($def);
|
||||||
@ -248,7 +248,7 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer {
|
|||||||
$this->prepareGenerator($gen_config);
|
$this->prepareGenerator($gen_config);
|
||||||
// this should probably be split up a little
|
// this should probably be split up a little
|
||||||
$ret = '';
|
$ret = '';
|
||||||
$def = $config->def->info[$ns][$directive];
|
$def = $config->def->info["$ns.$directive"];
|
||||||
if (is_int($def)) {
|
if (is_int($def)) {
|
||||||
$type = abs($def);
|
$type = abs($def);
|
||||||
} else {
|
} else {
|
||||||
|
@ -9,16 +9,9 @@ class HTMLPurifier_ConfigSchema_InterchangeTest extends UnitTestCase
|
|||||||
$this->interchange = new HTMLPurifier_ConfigSchema_Interchange();
|
$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() {
|
function testAddDirective() {
|
||||||
$v = new HTMLPurifier_ConfigSchema_Interchange_Directive();
|
$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->interchange->addDirective($v);
|
||||||
$this->assertIdentical($v, $this->interchange->directives['Namespace.Directive']);
|
$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'
|
ERROR: Alias 'Ns.BothWantThisName' in aliases in directive 'Ns.Dir2' collides with alias for directive 'Ns.Dir'
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: int
|
TYPE: int
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Alias 'Ns.Innocent' in aliases in directive 'Ns.Dir' collides with another directive
|
ERROR: Alias 'Ns.Innocent' in aliases in directive 'Ns.Dir' collides with another directive
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Innocent
|
Ns.Innocent
|
||||||
DESCRIPTION: Innocent directive
|
DESCRIPTION: Innocent directive
|
||||||
TYPE: int
|
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
|
ERROR: Value 3 in allowed in directive 'Ns.Dir' must be a string
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Generic namespace.
|
|
||||||
----
|
|
||||||
ID: Ns.Dir
|
ID: Ns.Dir
|
||||||
TYPE: string
|
TYPE: string
|
||||||
DESCRIPTION: Description
|
DESCRIPTION: Description
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Allowed in directive 'Ns.Dir' must not be empty
|
ERROR: Allowed in directive 'Ns.Dir' must not be empty
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Generic namespace.
|
|
||||||
----
|
|
||||||
ID: Ns.Dir
|
ID: Ns.Dir
|
||||||
TYPE: string
|
TYPE: string
|
||||||
DESCRIPTION: Description
|
DESCRIPTION: Description
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Default in directive 'Ns.Dir' must be an allowed value
|
ERROR: Default in directive 'Ns.Dir' must be an allowed value
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string
|
TYPE: string
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string/null
|
TYPE: string/null
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Expected type string, got integer in DEFAULT in directive hash 'Ns.Dir'
|
ERROR: Expected type string, got integer in DEFAULT in directive hash 'Ns.Dir'
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string
|
TYPE: string
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Description in directive 'Ns.Dir' must not be empty
|
ERROR: Description in directive 'Ns.Dir' must not be empty
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Our namespace.
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
TYPE: int
|
TYPE: int
|
||||||
DEFAULT: 0
|
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
|
ERROR: TYPE in directive hash 'Ns.Dir' not defined
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Notice that TYPE is missing
|
DESCRIPTION: Notice that TYPE is missing
|
||||||
DEFAULT: 0
|
DEFAULT: 0
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Invalid type 'foobar' in DEFAULT in directive hash 'Ns.Dir'
|
ERROR: Invalid type 'foobar' in DEFAULT in directive hash 'Ns.Dir'
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: foobar
|
TYPE: foobar
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Type in directive 'Ns.Dir' must be a string type when used with allowed or value aliases
|
ERROR: Type in directive 'Ns.Dir' must be a string type when used with allowed or value aliases
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: int
|
TYPE: int
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Type in directive 'Ns.Dir' must be a string type when used with allowed or value aliases
|
ERROR: Type in directive 'Ns.Dir' must be a string type when used with allowed or value aliases
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: int
|
TYPE: int
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Alias 3 in valueAliases in directive 'Ns.Dir' must be a string
|
ERROR: Alias 3 in valueAliases in directive 'Ns.Dir' must be a string
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string
|
TYPE: string
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Alias 'b' in valueAliases in directive 'Ns.Dir' must not be an allowed value
|
ERROR: Alias 'b' in valueAliases in directive 'Ns.Dir' must not be an allowed value
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string
|
TYPE: string
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Alias 'bar' in valueAliases in directive 'Ns.Dir' must not be an alias to itself
|
ERROR: Alias 'bar' in valueAliases in directive 'Ns.Dir' must not be an alias to itself
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string
|
TYPE: string
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Alias 'c' in valueAliases in directive 'Ns.Dir' must be an alias to an allowed value
|
ERROR: Alias 'c' in valueAliases in directive 'Ns.Dir' must be an alias to an allowed value
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string
|
TYPE: string
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
ERROR: Alias target 3 from alias 'b' in valueAliases in directive 'Ns.Dir' must be a string
|
ERROR: Alias target 3 from alias 'b' in valueAliases in directive 'Ns.Dir' must be a string
|
||||||
----
|
----
|
||||||
Ns
|
|
||||||
DESCRIPTION: Namespace
|
|
||||||
----
|
|
||||||
Ns.Dir
|
Ns.Dir
|
||||||
DESCRIPTION: Directive
|
DESCRIPTION: Directive
|
||||||
TYPE: string
|
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();
|
$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() {
|
function testDirectiveIntegrityViolation() {
|
||||||
$d = $this->makeDirective('Ns', 'Dir');
|
$d = $this->makeDirective('Ns.Dir');
|
||||||
$d->id = new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir2');
|
$d->id = new HTMLPurifier_ConfigSchema_Interchange_Id('Ns.Dir2');
|
||||||
$this->expectValidationException("Integrity violation: key 'Ns.Dir' does not match internal id 'Ns.Dir2'");
|
$this->expectValidationException("Integrity violation: key 'Ns.Dir' does not match internal id 'Ns.Dir2'");
|
||||||
$this->validator->validate($this->interchange);
|
$this->validator->validate($this->interchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDirectiveTypeNotEmpty() {
|
function testDirectiveTypeNotEmpty() {
|
||||||
$this->makeNamespace('Ns');
|
$d = $this->makeDirective('Ns.Dir');
|
||||||
$d = $this->makeDirective('Ns', 'Dir');
|
|
||||||
$d->default = 0;
|
$d->default = 0;
|
||||||
$d->description = 'Description';
|
$d->description = 'Description';
|
||||||
|
|
||||||
@ -51,8 +30,7 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testDirectiveDefaultInvalid() {
|
function testDirectiveDefaultInvalid() {
|
||||||
$this->makeNamespace('Ns');
|
$d = $this->makeDirective('Ns.Dir');
|
||||||
$d = $this->makeDirective('Ns', 'Dir');
|
|
||||||
$d->default = 'asdf';
|
$d->default = 'asdf';
|
||||||
$d->type = 'int';
|
$d->type = 'int';
|
||||||
$d->description = 'Description';
|
$d->description = 'Description';
|
||||||
@ -61,20 +39,18 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
|||||||
$this->validator->validate($this->interchange);
|
$this->validator->validate($this->interchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDirectiveIdDirectiveIsString() {
|
function testDirectiveIdIsString() {
|
||||||
$this->makeNamespace('Ns');
|
$d = $this->makeDirective(3);
|
||||||
$d = $this->makeDirective('Ns', 3);
|
|
||||||
$d->default = 0;
|
$d->default = 0;
|
||||||
$d->type = 'int';
|
$d->type = 'int';
|
||||||
$d->description = 'Description';
|
$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);
|
$this->validator->validate($this->interchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDirectiveTypeAllowsNullIsBool() {
|
function testDirectiveTypeAllowsNullIsBool() {
|
||||||
$this->makeNamespace('Ns');
|
$d = $this->makeDirective('Ns.Dir');
|
||||||
$d = $this->makeDirective('Ns', 'Dir');
|
|
||||||
$d->default = 0;
|
$d->default = 0;
|
||||||
$d->type = 'int';
|
$d->type = 'int';
|
||||||
$d->description = 'Description';
|
$d->description = 'Description';
|
||||||
@ -85,8 +61,7 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testDirectiveValueAliasesIsArray() {
|
function testDirectiveValueAliasesIsArray() {
|
||||||
$this->makeNamespace('Ns');
|
$d = $this->makeDirective('Ns.Dir');
|
||||||
$d = $this->makeDirective('Ns', 'Dir');
|
|
||||||
$d->default = 'a';
|
$d->default = 'a';
|
||||||
$d->type = 'string';
|
$d->type = 'string';
|
||||||
$d->description = 'Description';
|
$d->description = 'Description';
|
||||||
@ -97,8 +72,7 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testDirectiveAllowedIsLookup() {
|
function testDirectiveAllowedIsLookup() {
|
||||||
$this->makeNamespace('Ns');
|
$d = $this->makeDirective('Ns.Dir');
|
||||||
$d = $this->makeDirective('Ns', 'Dir');
|
|
||||||
$d->default = 'foo';
|
$d->default = 'foo';
|
||||||
$d->type = 'string';
|
$d->type = 'string';
|
||||||
$d->description = 'Description';
|
$d->description = 'Description';
|
||||||
@ -110,17 +84,10 @@ class HTMLPurifier_ConfigSchema_ValidatorTest extends UnitTestCase
|
|||||||
|
|
||||||
// helper functions
|
// 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 = 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);
|
$this->interchange->addDirective($directive);
|
||||||
return $directive;
|
return $directive;
|
||||||
}
|
}
|
||||||
|
@ -9,41 +9,32 @@ class HTMLPurifier_ConfigSchemaTest extends HTMLPurifier_Harness
|
|||||||
$this->schema = new HTMLPurifier_ConfigSchema();
|
$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() {
|
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->schema->add('Car.Age', null, 'int', true);
|
||||||
$this->assertIdentical($this->schema->info['Car']['Seats']->type, HTMLPurifier_VarParser::INT);
|
|
||||||
|
|
||||||
$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() {
|
function test_defineAllowedValues() {
|
||||||
$this->schema->addNamespace('QuantumNumber', 'D');
|
$this->schema->add('QuantumNumber.Spin', 0.5, 'float', false);
|
||||||
$this->schema->add('QuantumNumber', 'Spin', 0.5, 'float', false);
|
$this->schema->add('QuantumNumber.Current', 's', 'string', false);
|
||||||
$this->schema->add('QuantumNumber', 'Current', 's', 'string', false);
|
$this->schema->add('QuantumNumber.Difficulty', null, 'string', true);
|
||||||
$this->schema->add('QuantumNumber', 'Difficulty', null, 'string', true);
|
|
||||||
|
|
||||||
$this->schema->addAllowedValues( // okay, since default is null
|
$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->defaults['QuantumNumber.Difficulty'], null);
|
||||||
$this->assertIdentical($this->schema->info['QuantumNumber']['Difficulty']->type, HTMLPurifier_VarParser::STRING);
|
$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']->allow_null, true);
|
||||||
$this->assertIdentical($this->schema->info['QuantumNumber']['Difficulty']->allowed,
|
$this->assertIdentical($this->schema->info['QuantumNumber.Difficulty']->allowed,
|
||||||
array(
|
array(
|
||||||
'easy' => true,
|
'easy' => true,
|
||||||
'medium' => true,
|
'medium' => true,
|
||||||
@ -54,37 +45,36 @@ class HTMLPurifier_ConfigSchemaTest extends HTMLPurifier_Harness
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_defineValueAliases() {
|
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(
|
$this->schema->addAllowedValues(
|
||||||
'Abbrev', 'HTH', array(
|
'Abbrev.HTH', array(
|
||||||
'Happy to Help' => true,
|
'Happy to Help' => true,
|
||||||
'Hope that Helps' => true,
|
'Hope that Helps' => true,
|
||||||
'HAIL THE HAND!' => true,
|
'HAIL THE HAND!' => true,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->schema->addValueAliases(
|
$this->schema->addValueAliases(
|
||||||
'Abbrev', 'HTH', array(
|
'Abbrev.HTH', array(
|
||||||
'happy' => 'Happy to Help',
|
'happy' => 'Happy to Help',
|
||||||
'hope' => 'Hope that Helps'
|
'hope' => 'Hope that Helps'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->schema->addValueAliases( // delayed addition
|
$this->schema->addValueAliases( // delayed addition
|
||||||
'Abbrev', 'HTH', array(
|
'Abbrev.HTH', array(
|
||||||
'hail' => 'HAIL THE HAND!'
|
'hail' => 'HAIL THE HAND!'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertIdentical($this->schema->defaults['Abbrev']['HTH'], 'Happy to Help');
|
$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']->type, HTMLPurifier_VarParser::STRING);
|
||||||
$this->assertIdentical($this->schema->info['Abbrev']['HTH']->allowed,
|
$this->assertIdentical($this->schema->info['Abbrev.HTH']->allowed,
|
||||||
array(
|
array(
|
||||||
'Happy to Help' => true,
|
'Happy to Help' => true,
|
||||||
'Hope that Helps' => true,
|
'Hope that Helps' => true,
|
||||||
'HAIL THE HAND!' => true
|
'HAIL THE HAND!' => true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->assertIdentical($this->schema->info['Abbrev']['HTH']->aliases,
|
$this->assertIdentical($this->schema->info['Abbrev.HTH']->aliases,
|
||||||
array(
|
array(
|
||||||
'happy' => 'Happy to Help',
|
'happy' => 'Happy to Help',
|
||||||
'hope' => 'Hope that Helps',
|
'hope' => 'Hope that Helps',
|
||||||
@ -95,14 +85,12 @@ class HTMLPurifier_ConfigSchemaTest extends HTMLPurifier_Harness
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testAlias() {
|
function testAlias() {
|
||||||
$this->schema->addNamespace('Home');
|
$this->schema->add('Home.Rug', 3, 'int', false);
|
||||||
$this->schema->add('Home', 'Rug', 3, 'int', false);
|
$this->schema->addAlias('Home.Carpet', 'Home.Rug');
|
||||||
$this->schema->addAlias('Home', 'Carpet', 'Home', 'Rug');
|
|
||||||
|
|
||||||
$this->assertTrue(!isset($this->schema->defaults['Home']['Carpet']));
|
$this->assertTrue(!isset($this->schema->defaults['Home.Carpet']));
|
||||||
$this->assertIdentical($this->schema->info['Home']['Carpet']->namespace, 'Home');
|
$this->assertIdentical($this->schema->info['Home.Carpet']->key, 'Home.Rug');
|
||||||
$this->assertIdentical($this->schema->info['Home']['Carpet']->name, 'Rug');
|
$this->assertIdentical($this->schema->info['Home.Carpet']->isAlias, true);
|
||||||
$this->assertIdentical($this->schema->info['Home']['Carpet']->isAlias, true);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,17 +13,15 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
// test functionality based on ConfigSchema
|
// test functionality based on ConfigSchema
|
||||||
|
|
||||||
function testNormal() {
|
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', 'Abbr', 'H', 'string', false);
|
$this->schema->add('Element.Number', 1, 'int', false);
|
||||||
$this->schema->add('Element', 'Name', 'hydrogen', 'istring', false);
|
$this->schema->add('Element.Mass', 1.00794, 'float', false);
|
||||||
$this->schema->add('Element', 'Number', 1, 'int', false);
|
$this->schema->add('Element.Radioactive', false, 'bool', false);
|
||||||
$this->schema->add('Element', 'Mass', 1.00794, 'float', false);
|
$this->schema->add('Element.Isotopes', array(1 => true, 2 => true, 3 => true), 'lookup', false);
|
||||||
$this->schema->add('Element', 'Radioactive', false, 'bool', false);
|
$this->schema->add('Element.Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', false);
|
||||||
$this->schema->add('Element', 'Isotopes', array(1 => true, 2 => true, 3 => true), 'lookup', false);
|
$this->schema->add('Element.IsotopeNames', array(1 => 'protium', 2 => 'deuterium', 3 => 'tritium'), 'hash', false);
|
||||||
$this->schema->add('Element', 'Traits', array('nonmetallic', 'odorless', 'flammable'), 'list', false);
|
$this->schema->add('Element.Object', new stdClass(), 'mixed', 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 = new HTMLPurifier_Config($this->schema);
|
||||||
$config->autoFinalize = false;
|
$config->autoFinalize = false;
|
||||||
@ -74,22 +72,20 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
function testEnumerated() {
|
function testEnumerated() {
|
||||||
|
|
||||||
$this->schema->addNamespace('Instrument', 'Of the musical type.');
|
|
||||||
|
|
||||||
// case sensitive
|
// case sensitive
|
||||||
$this->schema->add('Instrument', 'Manufacturer', 'Yamaha', 'string', false);
|
$this->schema->add('Instrument.Manufacturer', 'Yamaha', 'string', false);
|
||||||
$this->schema->addAllowedValues('Instrument', 'Manufacturer', array(
|
$this->schema->addAllowedValues('Instrument.Manufacturer', array(
|
||||||
'Yamaha' => true, 'Conn-Selmer' => true, 'Vandoren' => true,
|
'Yamaha' => true, 'Conn-Selmer' => true, 'Vandoren' => true,
|
||||||
'Laubin' => true, 'Buffet' => true, 'other' => true));
|
'Laubin' => true, 'Buffet' => true, 'other' => true));
|
||||||
$this->schema->addValueAliases('Instrument', 'Manufacturer', array(
|
$this->schema->addValueAliases('Instrument.Manufacturer', array(
|
||||||
'Selmer' => 'Conn-Selmer'));
|
'Selmer' => 'Conn-Selmer'));
|
||||||
|
|
||||||
// case insensitive
|
// case insensitive
|
||||||
$this->schema->add('Instrument', 'Family', 'woodwind', 'istring', false);
|
$this->schema->add('Instrument.Family', 'woodwind', 'istring', false);
|
||||||
$this->schema->addAllowedValues('Instrument', 'Family', array(
|
$this->schema->addAllowedValues('Instrument.Family', array(
|
||||||
'brass' => true, 'woodwind' => true, 'percussion' => true,
|
'brass' => true, 'woodwind' => true, 'percussion' => true,
|
||||||
'string' => true, 'keyboard' => true, 'electronic' => true));
|
'string' => true, 'keyboard' => true, 'electronic' => true));
|
||||||
$this->schema->addValueAliases('Instrument', 'Family', array(
|
$this->schema->addValueAliases('Instrument.Family', array(
|
||||||
'synth' => 'electronic'));
|
'synth' => 'electronic'));
|
||||||
|
|
||||||
$config = new HTMLPurifier_Config($this->schema);
|
$config = new HTMLPurifier_Config($this->schema);
|
||||||
@ -124,9 +120,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
function testNull() {
|
function testNull() {
|
||||||
|
|
||||||
$this->schema->addNamespace('ReportCard');
|
$this->schema->add('ReportCard.English', null, 'string', true);
|
||||||
$this->schema->add('ReportCard', 'English', null, 'string', true);
|
$this->schema->add('ReportCard.Absences', 0, 'int', false);
|
||||||
$this->schema->add('ReportCard', 'Absences', 0, 'int', false);
|
|
||||||
|
|
||||||
$config = new HTMLPurifier_Config($this->schema);
|
$config = new HTMLPurifier_Config($this->schema);
|
||||||
$config->autoFinalize = false;
|
$config->autoFinalize = false;
|
||||||
@ -145,9 +140,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
function testAliases() {
|
function testAliases() {
|
||||||
|
|
||||||
$this->schema->addNamespace('Home');
|
$this->schema->add('Home.Rug', 3, 'int', false);
|
||||||
$this->schema->add('Home', 'Rug', 3, 'int', false);
|
$this->schema->addAlias('Home.Carpet', 'Home.Rug');
|
||||||
$this->schema->addAlias('Home', 'Carpet', 'Home', 'Rug');
|
|
||||||
|
|
||||||
$config = new HTMLPurifier_Config($this->schema);
|
$config = new HTMLPurifier_Config($this->schema);
|
||||||
$config->autoFinalize = false;
|
$config->autoFinalize = false;
|
||||||
@ -167,9 +161,8 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
function test_getBatch() {
|
function test_getBatch() {
|
||||||
|
|
||||||
$this->schema->addNamespace('Variables');
|
$this->schema->add('Variables.TangentialAcceleration', 'a_tan', 'string', false);
|
||||||
$this->schema->add('Variables', 'TangentialAcceleration', 'a_tan', 'string', false);
|
$this->schema->add('Variables.AngularAcceleration', 'alpha', 'string', false);
|
||||||
$this->schema->add('Variables', 'AngularAcceleration', 'alpha', 'string', false);
|
|
||||||
|
|
||||||
$config = new HTMLPurifier_Config($this->schema);
|
$config = new HTMLPurifier_Config($this->schema);
|
||||||
$config->autoFinalize = false;
|
$config->autoFinalize = false;
|
||||||
@ -191,10 +184,9 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
function test_loadIni() {
|
function test_loadIni() {
|
||||||
|
|
||||||
$this->schema->addNamespace('Shortcut', 'Keyboard shortcuts for commands');
|
$this->schema->add('Shortcut.Copy', 'c', 'istring', false);
|
||||||
$this->schema->add('Shortcut', 'Copy', 'c', 'istring', false);
|
$this->schema->add('Shortcut.Paste', 'v', 'istring', false);
|
||||||
$this->schema->add('Shortcut', 'Paste', 'v', 'istring', false);
|
$this->schema->add('Shortcut.Cut', 'x', 'istring', false);
|
||||||
$this->schema->add('Shortcut', 'Cut', 'x', 'istring', false);
|
|
||||||
|
|
||||||
$config = new HTMLPurifier_Config($this->schema);
|
$config = new HTMLPurifier_Config($this->schema);
|
||||||
$config->autoFinalize = false;
|
$config->autoFinalize = false;
|
||||||
@ -259,9 +251,7 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_getDefinition() {
|
function test_getDefinition() {
|
||||||
$this->schema->addNamespace('Cache', 'Cache stuff');
|
$this->schema->add('Cache.DefinitionImpl', null, 'string', true);
|
||||||
$this->schema->add('Cache', 'DefinitionImpl', null, 'string', true);
|
|
||||||
$this->schema->addNamespace('Crust', 'Krusty Krabs');
|
|
||||||
$config = new HTMLPurifier_Config($this->schema);
|
$config = new HTMLPurifier_Config($this->schema);
|
||||||
$this->expectException(new HTMLPurifier_Exception("Definition of Crust type not supported"));
|
$this->expectException(new HTMLPurifier_Exception("Definition of Crust type not supported"));
|
||||||
$config->getDefinition('Crust');
|
$config->getDefinition('Crust');
|
||||||
@ -269,11 +259,10 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
function test_loadArray() {
|
function test_loadArray() {
|
||||||
// setup a few dummy namespaces/directives for our testing
|
// 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', 'Aadvark', 0, 'int', false);
|
$this->schema->add('Zoo.Boar', 0, 'int', false);
|
||||||
$this->schema->add('Zoo', 'Boar', 0, 'int', false);
|
$this->schema->add('Zoo.Camel', 0, 'int', false);
|
||||||
$this->schema->add('Zoo', 'Camel', 0, 'int', false);
|
$this->schema->add('Zoo.Others', array(), 'list', false);
|
||||||
$this->schema->add('Zoo', 'Others', array(), 'list', false);
|
|
||||||
|
|
||||||
$config_manual = new HTMLPurifier_Config($this->schema);
|
$config_manual = new HTMLPurifier_Config($this->schema);
|
||||||
$config_loadabbr = 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() {
|
function test_create() {
|
||||||
|
|
||||||
$this->schema->addNamespace('Cake');
|
$this->schema->add('Cake.Sprinkles', 666, 'int', false);
|
||||||
$this->schema->add('Cake', 'Sprinkles', 666, 'int', false);
|
$this->schema->add('Cake.Flavor', 'vanilla', 'string', false);
|
||||||
$this->schema->add('Cake', 'Flavor', 'vanilla', 'string', false);
|
|
||||||
|
|
||||||
$config = new HTMLPurifier_Config($this->schema);
|
$config = new HTMLPurifier_Config($this->schema);
|
||||||
$config->set('Cake', 'Sprinkles', 42);
|
$config->set('Cake', 'Sprinkles', 42);
|
||||||
@ -334,8 +322,7 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
// test finalization
|
// 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 = new HTMLPurifier_Config($this->schema);
|
||||||
$config->autoFinalize = false;
|
$config->autoFinalize = false;
|
||||||
@ -357,17 +344,15 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
|
|
||||||
function test_loadArrayFromForm() {
|
function test_loadArrayFromForm() {
|
||||||
|
|
||||||
$this->schema->addNamespace('Pancake');
|
$this->schema->add('Pancake.Mix', 'buttermilk', 'string', false);
|
||||||
$this->schema->add('Pancake', 'Mix', 'buttermilk', 'string', false);
|
$this->schema->add('Pancake.Served', true, 'bool', false);
|
||||||
$this->schema->add('Pancake', 'Served', true, 'bool', false);
|
$this->schema->add('Toppings.Syrup', true, 'bool', false);
|
||||||
$this->schema->addNamespace('Toppings', false);
|
$this->schema->add('Toppings.Flavor', 'maple', 'string', false);
|
||||||
$this->schema->add('Toppings', 'Syrup', true, 'bool', false);
|
$this->schema->add('Toppings.Strawberries', 3, 'int', false);
|
||||||
$this->schema->add('Toppings', 'Flavor', 'maple', 'string', false);
|
$this->schema->add('Toppings.Calories', 2000, 'int', true);
|
||||||
$this->schema->add('Toppings', 'Strawberries', 3, 'int', false);
|
$this->schema->add('Toppings.DefinitionID', null, 'string', true);
|
||||||
$this->schema->add('Toppings', 'Calories', 2000, 'int', true);
|
$this->schema->add('Toppings.DefinitionRev', 1, 'int', false);
|
||||||
$this->schema->add('Toppings', 'DefinitionID', null, 'string', true);
|
$this->schema->add('Toppings.Protected', 1, 'int', false);
|
||||||
$this->schema->add('Toppings', 'DefinitionRev', 1, 'int', false);
|
|
||||||
$this->schema->add('Toppings', 'Protected', 1, 'int', false);
|
|
||||||
|
|
||||||
$get = array(
|
$get = array(
|
||||||
'breakfast' => array(
|
'breakfast' => array(
|
||||||
@ -418,16 +403,13 @@ class HTMLPurifier_ConfigTest extends HTMLPurifier_Harness
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_getAllowedDirectivesForForm() {
|
function test_getAllowedDirectivesForForm() {
|
||||||
$this->schema->addNamespace('Unused');
|
$this->schema->add('Unused.Unused', 'Foobar', 'string', false);
|
||||||
$this->schema->add('Unused', 'Unused', 'Foobar', 'string', false);
|
$this->schema->add('Partial.Allowed', true, 'bool', false);
|
||||||
$this->schema->addNamespace('Partial');
|
$this->schema->add('Partial.Unused', 'Foobar', 'string', false);
|
||||||
$this->schema->add('Partial', 'Allowed', true, 'bool', false);
|
$this->schema->add('All.Allowed', true, 'bool', false);
|
||||||
$this->schema->add('Partial', 'Unused', 'Foobar', 'string', false);
|
$this->schema->add('All.Blacklisted', 'Foobar', 'string', false); // explicitly blacklisted
|
||||||
$this->schema->addNamespace('All');
|
$this->schema->add('All.DefinitionID', 'Foobar', 'string', true); // auto-blacklisted
|
||||||
$this->schema->add('All', 'Allowed', true, 'bool', false);
|
$this->schema->add('All.DefinitionRev', 2, 'int', false); // auto-blacklisted
|
||||||
$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');
|
$input = array('Partial.Allowed', 'All', '-All.Blacklisted');
|
||||||
$output = HTMLPurifier_Config::getAllowedDirectivesForForm($input, $this->schema);
|
$output = HTMLPurifier_Config::getAllowedDirectivesForForm($input, $this->schema);
|
||||||
|
Reference in New Issue
Block a user