HTMLPurifier 4.4.0
/home/ezyang/Dev/htmlpurifier/library/HTMLPurifier/HTMLModule/Tidy.php
Go to the documentation of this file.
00001 <?php
00002 
00008 class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
00009 {
00010 
00015     public $levels = array(0 => 'none', 'light', 'medium', 'heavy');
00016 
00020     public $defaultLevel = null;
00021 
00026     public $fixesForLevel = array(
00027         'light'  => array(),
00028         'medium' => array(),
00029         'heavy'  => array()
00030     );
00031 
00038     public function setup($config) {
00039 
00040         // create fixes, initialize fixesForLevel
00041         $fixes = $this->makeFixes();
00042         $this->makeFixesForLevel($fixes);
00043 
00044         // figure out which fixes to use
00045         $level = $config->get('HTML.TidyLevel');
00046         $fixes_lookup = $this->getFixesForLevel($level);
00047 
00048         // get custom fix declarations: these need namespace processing
00049         $add_fixes    = $config->get('HTML.TidyAdd');
00050         $remove_fixes = $config->get('HTML.TidyRemove');
00051 
00052         foreach ($fixes as $name => $fix) {
00053             // needs to be refactored a little to implement globbing
00054             if (
00055                 isset($remove_fixes[$name]) ||
00056                 (!isset($add_fixes[$name]) && !isset($fixes_lookup[$name]))
00057             ) {
00058                 unset($fixes[$name]);
00059             }
00060         }
00061 
00062         // populate this module with necessary fixes
00063         $this->populate($fixes);
00064 
00065     }
00066 
00073     public function getFixesForLevel($level) {
00074         if ($level == $this->levels[0]) {
00075             return array();
00076         }
00077         $activated_levels = array();
00078         for ($i = 1, $c = count($this->levels); $i < $c; $i++) {
00079             $activated_levels[] = $this->levels[$i];
00080             if ($this->levels[$i] == $level) break;
00081         }
00082         if ($i == $c) {
00083             trigger_error(
00084                 'Tidy level ' . htmlspecialchars($level) . ' not recognized',
00085                 E_USER_WARNING
00086             );
00087             return array();
00088         }
00089         $ret = array();
00090         foreach ($activated_levels as $level) {
00091             foreach ($this->fixesForLevel[$level] as $fix) {
00092                 $ret[$fix] = true;
00093             }
00094         }
00095         return $ret;
00096     }
00097 
00103     public function makeFixesForLevel($fixes) {
00104         if (!isset($this->defaultLevel)) return;
00105         if (!isset($this->fixesForLevel[$this->defaultLevel])) {
00106             trigger_error(
00107                 'Default level ' . $this->defaultLevel . ' does not exist',
00108                 E_USER_ERROR
00109             );
00110             return;
00111         }
00112         $this->fixesForLevel[$this->defaultLevel] = array_keys($fixes);
00113     }
00114 
00120     public function populate($fixes) {
00121         foreach ($fixes as $name => $fix) {
00122             // determine what the fix is for
00123             list($type, $params) = $this->getFixType($name);
00124             switch ($type) {
00125                 case 'attr_transform_pre':
00126                 case 'attr_transform_post':
00127                     $attr = $params['attr'];
00128                     if (isset($params['element'])) {
00129                         $element = $params['element'];
00130                         if (empty($this->info[$element])) {
00131                             $e = $this->addBlankElement($element);
00132                         } else {
00133                             $e = $this->info[$element];
00134                         }
00135                     } else {
00136                         $type = "info_$type";
00137                         $e = $this;
00138                     }
00139                     // PHP does some weird parsing when I do
00140                     // $e->$type[$attr], so I have to assign a ref.
00141                     $f =& $e->$type;
00142                     $f[$attr] = $fix;
00143                     break;
00144                 case 'tag_transform':
00145                     $this->info_tag_transform[$params['element']] = $fix;
00146                     break;
00147                 case 'child':
00148                 case 'content_model_type':
00149                     $element = $params['element'];
00150                     if (empty($this->info[$element])) {
00151                         $e = $this->addBlankElement($element);
00152                     } else {
00153                         $e = $this->info[$element];
00154                     }
00155                     $e->$type = $fix;
00156                     break;
00157                 default:
00158                     trigger_error("Fix type $type not supported", E_USER_ERROR);
00159                     break;
00160             }
00161         }
00162     }
00163 
00172     public function getFixType($name) {
00173         // parse it
00174         $property = $attr = null;
00175         if (strpos($name, '#') !== false) list($name, $property) = explode('#', $name);
00176         if (strpos($name, '@') !== false) list($name, $attr)     = explode('@', $name);
00177 
00178         // figure out the parameters
00179         $params = array();
00180         if ($name !== '')    $params['element'] = $name;
00181         if (!is_null($attr)) $params['attr'] = $attr;
00182 
00183         // special case: attribute transform
00184         if (!is_null($attr)) {
00185             if (is_null($property)) $property = 'pre';
00186             $type = 'attr_transform_' . $property;
00187             return array($type, $params);
00188         }
00189 
00190         // special case: tag transform
00191         if (is_null($property)) {
00192             return array('tag_transform', $params);
00193         }
00194 
00195         return array($property, $params);
00196 
00197     }
00198 
00203     public function makeFixes() {}
00204 
00205 }
00206 
00207 // vim: et sw=4 sts=4