true) indexed by name.
* @type array
* @note This is in HTMLPurifier_HTMLDefinition->info_content_sets
*/
public $lookup = array ();
/**
* Synchronized list of defined content sets (keys of info).
* @type array
*/
protected $keys = array ();
/**
* Synchronized list of defined content values (values of info).
* @type array
*/
protected $values = array ();
/**
* Merges in module's content sets, expands identifiers in the content
* sets and populates the keys, values and lookup member variables.
*
* @param HTMLPurifier_HTMLModule[] $modules
* List of HTMLPurifier_HTMLModule
*/
public function __construct($modules) {
if (! is_array ( $modules )) {
$modules = array (
$modules
);
}
// populate content_sets based on module hints
// sorry, no way of overloading
foreach ( $modules as $module ) {
foreach ( $module->content_sets as $key => $value ) {
$temp = $this->convertToLookup ( $value );
if (isset ( $this->lookup [$key] )) {
// add it into the existing content set
$this->lookup [$key] = array_merge ( $this->lookup [$key], $temp );
} else {
$this->lookup [$key] = $temp;
}
}
}
$old_lookup = false;
while ( $old_lookup !== $this->lookup ) {
$old_lookup = $this->lookup;
foreach ( $this->lookup as $i => $set ) {
$add = array ();
foreach ( $set as $element => $x ) {
if (isset ( $this->lookup [$element] )) {
$add += $this->lookup [$element];
unset ( $this->lookup [$i] [$element] );
}
}
$this->lookup [$i] += $add;
}
}
foreach ( $this->lookup as $key => $lookup ) {
$this->info [$key] = implode ( ' | ', array_keys ( $lookup ) );
}
$this->keys = array_keys ( $this->info );
$this->values = array_values ( $this->info );
}
/**
* Accepts a definition; generates and assigns a ChildDef for it
*
* @param HTMLPurifier_ElementDef $def
* HTMLPurifier_ElementDef reference
* @param HTMLPurifier_HTMLModule $module
* Module that defined the ElementDef
*/
public function generateChildDef(&$def, $module) {
if (! empty ( $def->child )) { // already done!
return;
}
$content_model = $def->content_model;
if (is_string ( $content_model )) {
// Assume that $this->keys is alphanumeric
$def->content_model = preg_replace_callback ( '/\b(' . implode ( '|', $this->keys ) . ')\b/', array (
$this,
'generateChildDefCallback'
), $content_model );
// $def->content_model = str_replace(
// $this->keys, $this->values, $content_model);
}
$def->child = $this->getChildDef ( $def, $module );
}
public function generateChildDefCallback($matches) {
return $this->info [$matches [0]];
}
/**
* Instantiates a ChildDef based on content_model and content_model_type
* member variables in HTMLPurifier_ElementDef
* @note This will also defer to modules for custom HTMLPurifier_ChildDef
* subclasses that need content set expansion
*
* @param HTMLPurifier_ElementDef $def
* HTMLPurifier_ElementDef to have ChildDef extracted
* @param HTMLPurifier_HTMLModule $module
* Module that defined the ElementDef
* @return HTMLPurifier_ChildDef corresponding to ElementDef
*/
public function getChildDef($def, $module) {
$value = $def->content_model;
if (is_object ( $value )) {
trigger_error ( 'Literal object child definitions should be stored in ' . 'ElementDef->child not ElementDef->content_model', E_USER_NOTICE );
return $value;
}
switch ($def->content_model_type) {
case 'required' :
return new HTMLPurifier_ChildDef_Required ( $value );
case 'optional' :
return new HTMLPurifier_ChildDef_Optional ( $value );
case 'empty' :
return new HTMLPurifier_ChildDef_Empty ();
case 'custom' :
return new HTMLPurifier_ChildDef_Custom ( $value );
}
// defer to its module
$return = false;
if ($module->defines_child_def) { // save a func call
$return = $module->getChildDef ( $def );
}
if ($return !== false) {
return $return;
}
// error-out
trigger_error ( 'Could not determine which ChildDef class to instantiate', E_USER_ERROR );
return false;
}
/**
* Converts a string list of elements separated by pipes into
* a lookup array.
*
* @param string $string
* List of elements
* @return array Lookup array of elements
*/
protected function convertToLookup($string) {
$array = explode ( '|', str_replace ( ' ', '', $string ) );
$ret = array ();
foreach ( $array as $k ) {
$ret [$k] = true;
}
return $ret;
}
}
// vim: et sw=4 sts=4