| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | /** |
|---|
| 4 | * Injects tokens into the document while parsing for well-formedness. |
|---|
| 5 | * This enables "formatter-like" functionality such as auto-paragraphing, |
|---|
| 6 | * smiley-ification and linkification to take place. |
|---|
| 7 | * |
|---|
| 8 | * @todo Allow injectors to request a re-run on their output. This |
|---|
| 9 | * would help if an operation is recursive. |
|---|
| 10 | */ |
|---|
| 11 | abstract class HTMLPurifier_Injector |
|---|
| 12 | { |
|---|
| 13 | |
|---|
| 14 | /** |
|---|
| 15 | * Advisory name of injector, this is for friendly error messages |
|---|
| 16 | */ |
|---|
| 17 | public $name; |
|---|
| 18 | |
|---|
| 19 | /** |
|---|
| 20 | * Amount of tokens the injector needs to skip + 1. Because |
|---|
| 21 | * the decrement is the first thing that happens, this needs to |
|---|
| 22 | * be one greater than the "real" skip count. |
|---|
| 23 | */ |
|---|
| 24 | public $skip = 1; |
|---|
| 25 | |
|---|
| 26 | /** |
|---|
| 27 | * Instance of HTMLPurifier_HTMLDefinition |
|---|
| 28 | */ |
|---|
| 29 | protected $htmlDefinition; |
|---|
| 30 | |
|---|
| 31 | /** |
|---|
| 32 | * Reference to CurrentNesting variable in Context. This is an array |
|---|
| 33 | * list of tokens that we are currently "inside" |
|---|
| 34 | */ |
|---|
| 35 | protected $currentNesting; |
|---|
| 36 | |
|---|
| 37 | /** |
|---|
| 38 | * Reference to InputTokens variable in Context. This is an array |
|---|
| 39 | * list of the input tokens that are being processed. |
|---|
| 40 | */ |
|---|
| 41 | protected $inputTokens; |
|---|
| 42 | |
|---|
| 43 | /** |
|---|
| 44 | * Reference to InputIndex variable in Context. This is an integer |
|---|
| 45 | * array index for $this->inputTokens that indicates what token |
|---|
| 46 | * is currently being processed. |
|---|
| 47 | */ |
|---|
| 48 | protected $inputIndex; |
|---|
| 49 | |
|---|
| 50 | /** |
|---|
| 51 | * Array of elements and attributes this injector creates and therefore |
|---|
| 52 | * need to be allowed by the definition. Takes form of |
|---|
| 53 | * array('element' => array('attr', 'attr2'), 'element2') |
|---|
| 54 | */ |
|---|
| 55 | public $needed = array(); |
|---|
| 56 | |
|---|
| 57 | /** |
|---|
| 58 | * Prepares the injector by giving it the config and context objects: |
|---|
| 59 | * this allows references to important variables to be made within |
|---|
| 60 | * the injector. This function also checks if the HTML environment |
|---|
| 61 | * will work with the Injector: if p tags are not allowed, the |
|---|
| 62 | * Auto-Paragraphing injector should not be enabled. |
|---|
| 63 | * @param $config Instance of HTMLPurifier_Config |
|---|
| 64 | * @param $context Instance of HTMLPurifier_Context |
|---|
| 65 | * @return Boolean false if success, string of missing needed element/attribute if failure |
|---|
| 66 | */ |
|---|
| 67 | public function prepare($config, $context) { |
|---|
| 68 | $this->htmlDefinition = $config->getHTMLDefinition(); |
|---|
| 69 | // perform $needed checks |
|---|
| 70 | foreach ($this->needed as $element => $attributes) { |
|---|
| 71 | if (is_int($element)) $element = $attributes; |
|---|
| 72 | if (!isset($this->htmlDefinition->info[$element])) return $element; |
|---|
| 73 | if (!is_array($attributes)) continue; |
|---|
| 74 | foreach ($attributes as $name) { |
|---|
| 75 | if (!isset($this->htmlDefinition->info[$element]->attr[$name])) return "$element.$name"; |
|---|
| 76 | } |
|---|
| 77 | } |
|---|
| 78 | $this->currentNesting =& $context->get('CurrentNesting'); |
|---|
| 79 | $this->inputTokens =& $context->get('InputTokens'); |
|---|
| 80 | $this->inputIndex =& $context->get('InputIndex'); |
|---|
| 81 | return false; |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | /** |
|---|
| 85 | * Tests if the context node allows a certain element |
|---|
| 86 | * @param $name Name of element to test for |
|---|
| 87 | * @return True if element is allowed, false if it is not |
|---|
| 88 | */ |
|---|
| 89 | public function allowsElement($name) { |
|---|
| 90 | if (!empty($this->currentNesting)) { |
|---|
| 91 | $parent_token = array_pop($this->currentNesting); |
|---|
| 92 | $this->currentNesting[] = $parent_token; |
|---|
| 93 | $parent = $this->htmlDefinition->info[$parent_token->name]; |
|---|
| 94 | } else { |
|---|
| 95 | $parent = $this->htmlDefinition->info_parent_def; |
|---|
| 96 | } |
|---|
| 97 | if (!isset($parent->child->elements[$name]) || isset($parent->excludes[$name])) { |
|---|
| 98 | return false; |
|---|
| 99 | } |
|---|
| 100 | return true; |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | /** |
|---|
| 104 | * Handler that is called when a text token is processed |
|---|
| 105 | */ |
|---|
| 106 | public function handleText(&$token) {} |
|---|
| 107 | |
|---|
| 108 | /** |
|---|
| 109 | * Handler that is called when a start or empty token is processed |
|---|
| 110 | */ |
|---|
| 111 | public function handleElement(&$token) {} |
|---|
| 112 | |
|---|
| 113 | /** |
|---|
| 114 | * Notifier that is called when an end token is processed |
|---|
| 115 | * @note This differs from handlers in that the token is read-only |
|---|
| 116 | */ |
|---|
| 117 | public function notifyEnd($token) {} |
|---|
| 118 | |
|---|
| 119 | |
|---|
| 120 | } |
|---|
| 121 | |
|---|