Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402]
1 <?php 2 3 /** 4 * Represents an XHTML 1.1 module, with information on elements, tags 5 * and attributes. 6 * @note Even though this is technically XHTML 1.1, it is also used for 7 * regular HTML parsing. We are using modulization as a convenient 8 * way to represent the internals of HTMLDefinition, and our 9 * implementation is by no means conforming and does not directly 10 * use the normative DTDs or XML schemas. 11 * @note The public variables in a module should almost directly 12 * correspond to the variables in HTMLPurifier_HTMLDefinition. 13 * However, the prefix info carries no special meaning in these 14 * objects (include it anyway if that's the correspondence though). 15 * @todo Consider making some member functions protected 16 */ 17 18 class HTMLPurifier_HTMLModule 19 { 20 21 // -- Overloadable ---------------------------------------------------- 22 23 /** 24 * Short unique string identifier of the module. 25 * @type string 26 */ 27 public $name; 28 29 /** 30 * Informally, a list of elements this module changes. 31 * Not used in any significant way. 32 * @type array 33 */ 34 public $elements = array(); 35 36 /** 37 * Associative array of element names to element definitions. 38 * Some definitions may be incomplete, to be merged in later 39 * with the full definition. 40 * @type array 41 */ 42 public $info = array(); 43 44 /** 45 * Associative array of content set names to content set additions. 46 * This is commonly used to, say, add an A element to the Inline 47 * content set. This corresponds to an internal variable $content_sets 48 * and NOT info_content_sets member variable of HTMLDefinition. 49 * @type array 50 */ 51 public $content_sets = array(); 52 53 /** 54 * Associative array of attribute collection names to attribute 55 * collection additions. More rarely used for adding attributes to 56 * the global collections. Example is the StyleAttribute module adding 57 * the style attribute to the Core. Corresponds to HTMLDefinition's 58 * attr_collections->info, since the object's data is only info, 59 * with extra behavior associated with it. 60 * @type array 61 */ 62 public $attr_collections = array(); 63 64 /** 65 * Associative array of deprecated tag name to HTMLPurifier_TagTransform. 66 * @type array 67 */ 68 public $info_tag_transform = array(); 69 70 /** 71 * List of HTMLPurifier_AttrTransform to be performed before validation. 72 * @type array 73 */ 74 public $info_attr_transform_pre = array(); 75 76 /** 77 * List of HTMLPurifier_AttrTransform to be performed after validation. 78 * @type array 79 */ 80 public $info_attr_transform_post = array(); 81 82 /** 83 * List of HTMLPurifier_Injector to be performed during well-formedness fixing. 84 * An injector will only be invoked if all of it's pre-requisites are met; 85 * if an injector fails setup, there will be no error; it will simply be 86 * silently disabled. 87 * @type array 88 */ 89 public $info_injector = array(); 90 91 /** 92 * Boolean flag that indicates whether or not getChildDef is implemented. 93 * For optimization reasons: may save a call to a function. Be sure 94 * to set it if you do implement getChildDef(), otherwise it will have 95 * no effect! 96 * @type bool 97 */ 98 public $defines_child_def = false; 99 100 /** 101 * Boolean flag whether or not this module is safe. If it is not safe, all 102 * of its members are unsafe. Modules are safe by default (this might be 103 * slightly dangerous, but it doesn't make much sense to force HTML Purifier, 104 * which is based off of safe HTML, to explicitly say, "This is safe," even 105 * though there are modules which are "unsafe") 106 * 107 * @type bool 108 * @note Previously, safety could be applied at an element level granularity. 109 * We've removed this ability, so in order to add "unsafe" elements 110 * or attributes, a dedicated module with this property set to false 111 * must be used. 112 */ 113 public $safe = true; 114 115 /** 116 * Retrieves a proper HTMLPurifier_ChildDef subclass based on 117 * content_model and content_model_type member variables of 118 * the HTMLPurifier_ElementDef class. There is a similar function 119 * in HTMLPurifier_HTMLDefinition. 120 * @param HTMLPurifier_ElementDef $def 121 * @return HTMLPurifier_ChildDef subclass 122 */ 123 public function getChildDef($def) 124 { 125 return false; 126 } 127 128 // -- Convenience ----------------------------------------------------- 129 130 /** 131 * Convenience function that sets up a new element 132 * @param string $element Name of element to add 133 * @param string|bool $type What content set should element be registered to? 134 * Set as false to skip this step. 135 * @param string|HTMLPurifier_ChildDef $contents Allowed children in form of: 136 * "$content_model_type: $content_model" 137 * @param array|string $attr_includes What attribute collections to register to 138 * element? 139 * @param array $attr What unique attributes does the element define? 140 * @see HTMLPurifier_ElementDef:: for in-depth descriptions of these parameters. 141 * @return HTMLPurifier_ElementDef Created element definition object, so you 142 * can set advanced parameters 143 */ 144 public function addElement($element, $type, $contents, $attr_includes = array(), $attr = array()) 145 { 146 $this->elements[] = $element; 147 // parse content_model 148 list($content_model_type, $content_model) = $this->parseContents($contents); 149 // merge in attribute inclusions 150 $this->mergeInAttrIncludes($attr, $attr_includes); 151 // add element to content sets 152 if ($type) { 153 $this->addElementToContentSet($element, $type); 154 } 155 // create element 156 $this->info[$element] = HTMLPurifier_ElementDef::create( 157 $content_model, 158 $content_model_type, 159 $attr 160 ); 161 // literal object $contents means direct child manipulation 162 if (!is_string($contents)) { 163 $this->info[$element]->child = $contents; 164 } 165 return $this->info[$element]; 166 } 167 168 /** 169 * Convenience function that creates a totally blank, non-standalone 170 * element. 171 * @param string $element Name of element to create 172 * @return HTMLPurifier_ElementDef Created element 173 */ 174 public function addBlankElement($element) 175 { 176 if (!isset($this->info[$element])) { 177 $this->elements[] = $element; 178 $this->info[$element] = new HTMLPurifier_ElementDef(); 179 $this->info[$element]->standalone = false; 180 } else { 181 trigger_error("Definition for $element already exists in module, cannot redefine"); 182 } 183 return $this->info[$element]; 184 } 185 186 /** 187 * Convenience function that registers an element to a content set 188 * @param string $element Element to register 189 * @param string $type Name content set (warning: case sensitive, usually upper-case 190 * first letter) 191 */ 192 public function addElementToContentSet($element, $type) 193 { 194 if (!isset($this->content_sets[$type])) { 195 $this->content_sets[$type] = ''; 196 } else { 197 $this->content_sets[$type] .= ' | '; 198 } 199 $this->content_sets[$type] .= $element; 200 } 201 202 /** 203 * Convenience function that transforms single-string contents 204 * into separate content model and content model type 205 * @param string $contents Allowed children in form of: 206 * "$content_model_type: $content_model" 207 * @return array 208 * @note If contents is an object, an array of two nulls will be 209 * returned, and the callee needs to take the original $contents 210 * and use it directly. 211 */ 212 public function parseContents($contents) 213 { 214 if (!is_string($contents)) { 215 return array(null, null); 216 } // defer 217 switch ($contents) { 218 // check for shorthand content model forms 219 case 'Empty': 220 return array('empty', ''); 221 case 'Inline': 222 return array('optional', 'Inline | #PCDATA'); 223 case 'Flow': 224 return array('optional', 'Flow | #PCDATA'); 225 } 226 list($content_model_type, $content_model) = explode(':', $contents); 227 $content_model_type = strtolower(trim($content_model_type)); 228 $content_model = trim($content_model); 229 return array($content_model_type, $content_model); 230 } 231 232 /** 233 * Convenience function that merges a list of attribute includes into 234 * an attribute array. 235 * @param array $attr Reference to attr array to modify 236 * @param array $attr_includes Array of includes / string include to merge in 237 */ 238 public function mergeInAttrIncludes(&$attr, $attr_includes) 239 { 240 if (!is_array($attr_includes)) { 241 if (empty($attr_includes)) { 242 $attr_includes = array(); 243 } else { 244 $attr_includes = array($attr_includes); 245 } 246 } 247 $attr[0] = $attr_includes; 248 } 249 250 /** 251 * Convenience function that generates a lookup table with boolean 252 * true as value. 253 * @param string $list List of values to turn into a lookup 254 * @note You can also pass an arbitrary number of arguments in 255 * place of the regular argument 256 * @return array array equivalent of list 257 */ 258 public function makeLookup($list) 259 { 260 $args = func_get_args(); 261 if (is_string($list)) { 262 $list = $args; 263 } 264 $ret = array(); 265 foreach ($list as $value) { 266 if (is_null($value)) { 267 continue; 268 } 269 $ret[$value] = true; 270 } 271 return $ret; 272 } 273 274 /** 275 * Lazy load construction of the module after determining whether 276 * or not it's needed, and also when a finalized configuration object 277 * is available. 278 * @param HTMLPurifier_Config $config 279 */ 280 public function setup($config) 281 { 282 } 283 } 284 285 // vim: et sw=4 sts=4
title
Description
Body
title
Description
Body
title
Description
Body
title
Body