Differences Between: [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
1 <?php 2 3 /** 4 * Abstract class for a set of proprietary modules that clean up (tidy) 5 * poorly written HTML. 6 * @todo Figure out how to protect some of these methods/properties 7 */ 8 class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule 9 { 10 /** 11 * List of supported levels. 12 * Index zero is a special case "no fixes" level. 13 * @type array 14 */ 15 public $levels = array(0 => 'none', 'light', 'medium', 'heavy'); 16 17 /** 18 * Default level to place all fixes in. 19 * Disabled by default. 20 * @type string 21 */ 22 public $defaultLevel = null; 23 24 /** 25 * Lists of fixes used by getFixesForLevel(). 26 * Format is: 27 * HTMLModule_Tidy->fixesForLevel[$level] = array('fix-1', 'fix-2'); 28 * @type array 29 */ 30 public $fixesForLevel = array( 31 'light' => array(), 32 'medium' => array(), 33 'heavy' => array() 34 ); 35 36 /** 37 * Lazy load constructs the module by determining the necessary 38 * fixes to create and then delegating to the populate() function. 39 * @param HTMLPurifier_Config $config 40 * @todo Wildcard matching and error reporting when an added or 41 * subtracted fix has no effect. 42 */ 43 public function setup($config) 44 { 45 // create fixes, initialize fixesForLevel 46 $fixes = $this->makeFixes(); 47 $this->makeFixesForLevel($fixes); 48 49 // figure out which fixes to use 50 $level = $config->get('HTML.TidyLevel'); 51 $fixes_lookup = $this->getFixesForLevel($level); 52 53 // get custom fix declarations: these need namespace processing 54 $add_fixes = $config->get('HTML.TidyAdd'); 55 $remove_fixes = $config->get('HTML.TidyRemove'); 56 57 foreach ($fixes as $name => $fix) { 58 // needs to be refactored a little to implement globbing 59 if (isset($remove_fixes[$name]) || 60 (!isset($add_fixes[$name]) && !isset($fixes_lookup[$name]))) { 61 unset($fixes[$name]); 62 } 63 } 64 65 // populate this module with necessary fixes 66 $this->populate($fixes); 67 } 68 69 /** 70 * Retrieves all fixes per a level, returning fixes for that specific 71 * level as well as all levels below it. 72 * @param string $level level identifier, see $levels for valid values 73 * @return array Lookup up table of fixes 74 */ 75 public function getFixesForLevel($level) 76 { 77 if ($level == $this->levels[0]) { 78 return array(); 79 } 80 $activated_levels = array(); 81 for ($i = 1, $c = count($this->levels); $i < $c; $i++) { 82 $activated_levels[] = $this->levels[$i]; 83 if ($this->levels[$i] == $level) { 84 break; 85 } 86 } 87 if ($i == $c) { 88 trigger_error( 89 'Tidy level ' . htmlspecialchars($level) . ' not recognized', 90 E_USER_WARNING 91 ); 92 return array(); 93 } 94 $ret = array(); 95 foreach ($activated_levels as $level) { 96 foreach ($this->fixesForLevel[$level] as $fix) { 97 $ret[$fix] = true; 98 } 99 } 100 return $ret; 101 } 102 103 /** 104 * Dynamically populates the $fixesForLevel member variable using 105 * the fixes array. It may be custom overloaded, used in conjunction 106 * with $defaultLevel, or not used at all. 107 * @param array $fixes 108 */ 109 public function makeFixesForLevel($fixes) 110 { 111 if (!isset($this->defaultLevel)) { 112 return; 113 } 114 if (!isset($this->fixesForLevel[$this->defaultLevel])) { 115 trigger_error( 116 'Default level ' . $this->defaultLevel . ' does not exist', 117 E_USER_ERROR 118 ); 119 return; 120 } 121 $this->fixesForLevel[$this->defaultLevel] = array_keys($fixes); 122 } 123 124 /** 125 * Populates the module with transforms and other special-case code 126 * based on a list of fixes passed to it 127 * @param array $fixes Lookup table of fixes to activate 128 */ 129 public function populate($fixes) 130 { 131 foreach ($fixes as $name => $fix) { 132 // determine what the fix is for 133 list($type, $params) = $this->getFixType($name); 134 switch ($type) { 135 case 'attr_transform_pre': 136 case 'attr_transform_post': 137 $attr = $params['attr']; 138 if (isset($params['element'])) { 139 $element = $params['element']; 140 if (empty($this->info[$element])) { 141 $e = $this->addBlankElement($element); 142 } else { 143 $e = $this->info[$element]; 144 } 145 } else { 146 $type = "info_$type"; 147 $e = $this; 148 } 149 // PHP does some weird parsing when I do 150 // $e->$type[$attr], so I have to assign a ref. 151 $f =& $e->$type; 152 $f[$attr] = $fix; 153 break; 154 case 'tag_transform': 155 $this->info_tag_transform[$params['element']] = $fix; 156 break; 157 case 'child': 158 case 'content_model_type': 159 $element = $params['element']; 160 if (empty($this->info[$element])) { 161 $e = $this->addBlankElement($element); 162 } else { 163 $e = $this->info[$element]; 164 } 165 $e->$type = $fix; 166 break; 167 default: 168 trigger_error("Fix type $type not supported", E_USER_ERROR); 169 break; 170 } 171 } 172 } 173 174 /** 175 * Parses a fix name and determines what kind of fix it is, as well 176 * as other information defined by the fix 177 * @param $name String name of fix 178 * @return array(string $fix_type, array $fix_parameters) 179 * @note $fix_parameters is type dependant, see populate() for usage 180 * of these parameters 181 */ 182 public function getFixType($name) 183 { 184 // parse it 185 $property = $attr = null; 186 if (strpos($name, '#') !== false) { 187 list($name, $property) = explode('#', $name); 188 } 189 if (strpos($name, '@') !== false) { 190 list($name, $attr) = explode('@', $name); 191 } 192 193 // figure out the parameters 194 $params = array(); 195 if ($name !== '') { 196 $params['element'] = $name; 197 } 198 if (!is_null($attr)) { 199 $params['attr'] = $attr; 200 } 201 202 // special case: attribute transform 203 if (!is_null($attr)) { 204 if (is_null($property)) { 205 $property = 'pre'; 206 } 207 $type = 'attr_transform_' . $property; 208 return array($type, $params); 209 } 210 211 // special case: tag transform 212 if (is_null($property)) { 213 return array('tag_transform', $params); 214 } 215 216 return array($property, $params); 217 218 } 219 220 /** 221 * Defines all fixes the module will perform in a compact 222 * associative array of fix name to fix implementation. 223 * @return array 224 */ 225 public function makeFixes() 226 { 227 } 228 } 229 230 // vim: et sw=4 sts=4
title
Description
Body
title
Description
Body
title
Description
Body
title
Body