library/HTMLPurifier/AttrValidator.php

Go to the documentation of this file.
00001 <?php
00002 
00008 class HTMLPurifier_AttrValidator
00009 {
00010     
00021     public function validateToken(&$token, &$config, $context) {
00022             
00023         $definition = $config->getHTMLDefinition();
00024         $e =& $context->get('ErrorCollector', true);
00025         
00026         // initialize IDAccumulator if necessary
00027         $ok =& $context->get('IDAccumulator', true);
00028         if (!$ok) {
00029             $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context);
00030             $context->register('IDAccumulator', $id_accumulator);
00031         }
00032         
00033         // initialize CurrentToken if necessary
00034         $current_token =& $context->get('CurrentToken', true);
00035         if (!$current_token) $context->register('CurrentToken', $token);
00036         
00037         if (
00038           !$token instanceof HTMLPurifier_Token_Start &&
00039           !$token instanceof HTMLPurifier_Token_Empty
00040         ) return $token;
00041         
00042         // create alias to global definition array, see also $defs
00043         // DEFINITION CALL
00044         $d_defs = $definition->info_global_attr;
00045         
00046         // don't update token until the very end, to ensure an atomic update
00047         $attr = $token->attr;
00048         
00049         // do global transformations (pre)
00050         // nothing currently utilizes this
00051         foreach ($definition->info_attr_transform_pre as $transform) {
00052             $attr = $transform->transform($o = $attr, $config, $context);
00053             if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
00054         }
00055         
00056         // do local transformations only applicable to this element (pre)
00057         // ex. <p align="right"> to <p style="text-align:right;">
00058         foreach ($definition->info[$token->name]->attr_transform_pre as $transform) {
00059             $attr = $transform->transform($o = $attr, $config, $context);
00060             if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
00061         }
00062         
00063         // create alias to this element's attribute definition array, see
00064         // also $d_defs (global attribute definition array)
00065         // DEFINITION CALL
00066         $defs = $definition->info[$token->name]->attr;
00067         
00068         $attr_key = false;
00069         $context->register('CurrentAttr', $attr_key);
00070         
00071         // iterate through all the attribute keypairs
00072         // Watch out for name collisions: $key has previously been used
00073         foreach ($attr as $attr_key => $value) {
00074             
00075             // call the definition
00076             if ( isset($defs[$attr_key]) ) {
00077                 // there is a local definition defined
00078                 if ($defs[$attr_key] === false) {
00079                     // We've explicitly been told not to allow this element.
00080                     // This is usually when there's a global definition
00081                     // that must be overridden.
00082                     // Theoretically speaking, we could have a
00083                     // AttrDef_DenyAll, but this is faster!
00084                     $result = false;
00085                 } else {
00086                     // validate according to the element's definition
00087                     $result = $defs[$attr_key]->validate(
00088                                     $value, $config, $context
00089                                );
00090                 }
00091             } elseif ( isset($d_defs[$attr_key]) ) {
00092                 // there is a global definition defined, validate according
00093                 // to the global definition
00094                 $result = $d_defs[$attr_key]->validate(
00095                                 $value, $config, $context
00096                            );
00097             } else {
00098                 // system never heard of the attribute? DELETE!
00099                 $result = false;
00100             }
00101             
00102             // put the results into effect
00103             if ($result === false || $result === null) {
00104                 // this is a generic error message that should replaced
00105                 // with more specific ones when possible
00106                 if ($e) $e->send(E_ERROR, 'AttrValidator: Attribute removed');
00107                 
00108                 // remove the attribute
00109                 unset($attr[$attr_key]);
00110             } elseif (is_string($result)) {
00111                 // generally, if a substitution is happening, there
00112                 // was some sort of implicit correction going on. We'll
00113                 // delegate it to the attribute classes to say exactly what.
00114                 
00115                 // simple substitution
00116                 $attr[$attr_key] = $result;
00117             }
00118             
00119             // we'd also want slightly more complicated substitution
00120             // involving an array as the return value,
00121             // although we're not sure how colliding attributes would
00122             // resolve (certain ones would be completely overriden,
00123             // others would prepend themselves).
00124         }
00125         
00126         $context->destroy('CurrentAttr');
00127         
00128         // post transforms
00129         
00130         // global (error reporting untested)
00131         foreach ($definition->info_attr_transform_post as $transform) {
00132             $attr = $transform->transform($o = $attr, $config, $context);
00133             if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
00134         }
00135         
00136         // local (error reporting untested)
00137         foreach ($definition->info[$token->name]->attr_transform_post as $transform) {
00138             $attr = $transform->transform($o = $attr, $config, $context);
00139             if ($e && ($attr != $o)) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr);
00140         }
00141         
00142         $token->attr = $attr;
00143         
00144         // destroy CurrentToken if we made it ourselves
00145         if (!$current_token) $context->destroy('CurrentToken');
00146         
00147     }
00148     
00149     
00150 }
00151 

Generated on Thu Jun 19 18:47:25 2008 for HTMLPurifier by  doxygen 1.5.3