Fix PHP 5.0 and other early version compatibility by removing use of __toString
[htmlpurifier.git] / library / HTMLPurifier / ConfigSchema / Validator.php
blob5130ad5217f8c903aaa45cb2e43d6464954e1757
1 <?php
3 /**
4 * Performs validations on HTMLPurifier_ConfigSchema_Interchange
6 * @note If you see '// handled by InterchangeBuilder', that means a
7 * design decision in that class would prevent this validation from
8 * ever being necessary. We have them anyway, however, for
9 * redundancy.
11 class HTMLPurifier_ConfigSchema_Validator
14 protected $interchange;
16 /**
17 * Context-stack to provide easy to read error messages.
19 protected $context = array();
21 /**
22 * HTMLPurifier_VarParser to test variable types.
24 protected $parser;
26 public function __construct() {
27 $this->parser = new HTMLPurifier_VarParser();
30 /**
31 * Validates a fully-formed interchange object. Throws an
32 * HTMLPurifier_ConfigSchema_Exception if there's a problem.
34 public function validate($interchange) {
35 $this->interchange = $interchange;
36 // PHP is a bit lax with integer <=> string conversions in
37 // arrays, so we don't use the identical !== comparison
38 foreach ($interchange->namespaces as $i => $namespace) {
39 if ($i != $namespace->namespace) $this->error(false, "Integrity violation: key '$i' does not match internal id '{$namespace->namespace}'");
40 $this->validateNamespace($namespace);
42 foreach ($interchange->directives as $i => $directive) {
43 $id = $directive->id->toString();
44 if ($i != $id) $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'");
45 $this->validateDirective($directive);
49 public function validateNamespace($n) {
50 $this->context[] = "namespace '{$n->namespace}'";
51 $this->with($n, 'namespace')
52 ->assertNotEmpty()
53 ->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
54 $this->with($n, 'description')
55 ->assertNotEmpty()
56 ->assertIsString(); // handled by InterchangeBuilder
57 array_pop($this->context);
60 public function validateId($id) {
61 $id_string = $id->toString();
62 $this->context[] = "id '$id_string'";
63 if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) {
64 // handled by InterchangeBuilder
65 $this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id');
67 if (!isset($this->interchange->namespaces[$id->namespace])) {
68 $this->error('namespace', 'does not exist'); // assumes that the namespace was validated already
70 $this->with($id, 'directive')
71 ->assertNotEmpty()
72 ->assertAlnum(); // implicit assertIsString handled by InterchangeBuilder
73 array_pop($this->context);
76 public function validateDirective($d) {
77 $id = $d->id->toString();
78 $this->context[] = "directive '$id'";
79 $this->validateId($d->id);
80 $this->with($d, 'description')
81 ->assertNotEmpty();
82 $this->with($d, 'type')
83 ->assertNotEmpty(); // handled by InterchangeBuilder
84 // Much stricter default check, since we're using the base implementation.
85 // handled by InterchangeBuilder
86 try {
87 $this->parser->parse($d->default, $d->type, $d->typeAllowsNull);
88 } catch (HTMLPurifier_VarParserException $e) {
89 $this->error('default', 'had error: ' . $e->getMessage());
92 array_pop($this->context);
95 // protected helper functions
97 protected function with($obj, $member) {
98 return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member);
101 protected function error($target, $msg) {
102 if ($target !== false) $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext();
103 else $prefix = ucfirst($this->getFormattedContext());
104 throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg));
107 protected function getFormattedContext() {
108 return implode(' in ', array_reverse($this->context));