File indexing completed on 2024-12-22 05:36:19
0001 <?php 0002 0003 /** 0004 * Definition that allows a set of elements, but disallows empty children. 0005 */ 0006 class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef 0007 { 0008 /** 0009 * Lookup table of allowed elements. 0010 * @type array 0011 */ 0012 public $elements = array(); 0013 0014 /** 0015 * Whether or not the last passed node was all whitespace. 0016 * @type bool 0017 */ 0018 protected $whitespace = false; 0019 0020 /** 0021 * @param array|string $elements List of allowed element names (lowercase). 0022 */ 0023 public function __construct($elements) 0024 { 0025 if (is_string($elements)) { 0026 $elements = str_replace(' ', '', $elements); 0027 $elements = explode('|', $elements); 0028 } 0029 $keys = array_keys($elements); 0030 if ($keys == array_keys($keys)) { 0031 $elements = array_flip($elements); 0032 foreach ($elements as $i => $x) { 0033 $elements[$i] = true; 0034 if (empty($i)) { 0035 unset($elements[$i]); 0036 } // remove blank 0037 } 0038 } 0039 $this->elements = $elements; 0040 } 0041 0042 /** 0043 * @type bool 0044 */ 0045 public $allow_empty = false; 0046 0047 /** 0048 * @type string 0049 */ 0050 public $type = 'required'; 0051 0052 /** 0053 * @param array $children 0054 * @param HTMLPurifier_Config $config 0055 * @param HTMLPurifier_Context $context 0056 * @return array 0057 */ 0058 public function validateChildren($children, $config, $context) 0059 { 0060 // Flag for subclasses 0061 $this->whitespace = false; 0062 0063 // if there are no tokens, delete parent node 0064 if (empty($children)) { 0065 return false; 0066 } 0067 0068 // the new set of children 0069 $result = array(); 0070 0071 // whether or not parsed character data is allowed 0072 // this controls whether or not we silently drop a tag 0073 // or generate escaped HTML from it 0074 $pcdata_allowed = isset($this->elements['#PCDATA']); 0075 0076 // a little sanity check to make sure it's not ALL whitespace 0077 $all_whitespace = true; 0078 0079 $stack = array_reverse($children); 0080 while (!empty($stack)) { 0081 $node = array_pop($stack); 0082 if (!empty($node->is_whitespace)) { 0083 $result[] = $node; 0084 continue; 0085 } 0086 $all_whitespace = false; // phew, we're not talking about whitespace 0087 0088 if (!isset($this->elements[$node->name])) { 0089 // special case text 0090 // XXX One of these ought to be redundant or something 0091 if ($pcdata_allowed && $node instanceof HTMLPurifier_Node_Text) { 0092 $result[] = $node; 0093 continue; 0094 } 0095 // spill the child contents in 0096 // ToDo: Make configurable 0097 if ($node instanceof HTMLPurifier_Node_Element) { 0098 for ($i = count($node->children) - 1; $i >= 0; $i--) { 0099 $stack[] = $node->children[$i]; 0100 } 0101 continue; 0102 } 0103 continue; 0104 } 0105 $result[] = $node; 0106 } 0107 if (empty($result)) { 0108 return false; 0109 } 0110 if ($all_whitespace) { 0111 $this->whitespace = true; 0112 return false; 0113 } 0114 return $result; 0115 } 0116 } 0117 0118 // vim: et sw=4 sts=4