0

Is it possible to configure HTMLPurifier to allow all classes with a certain prefix? For example, I'm using FontAwesome and would like to give the user the ability to use its icons, but there are too many to reasonably hardcode in an array.

This is what I'd like to do, but it doesn't work this way:

$config = HTMLPurifier_Config::createDefault() ;
$config->set('Attr.AllowedClasses', array('fa', 'fa-*')) ;

I found this example, which suggests that it is possible, but the code on that page doesn't actually seem to do as advertised, and some parts look wrong to me. From what I can understand of it, it only allows a tags with a target attribute, but not a class attribute even though it supposedly checks for prefixed classes.

  • Hmm. See if this question and its answers helps you? http://stackoverflow.com/questions/2638640/html-purifier-removing-an-element-conditionally-based-on-its-attributes - it goes a step further, but I always go back to it as a cheat sheet when I just want to handle attributes, as well. (See "Point of reference: Handling attributes") – pinkgothic Jul 20 '14 at 15:57

1 Answers1

0

Using the example from the link in the question as a base, I managed to hack together this solution. It seems to work like a charm. It is limited to a per-element basis, but that's actually great for my purposes.

I don't know if this is the best solution, but it works for me.

class CustomClassDef extends HTMLPurifier_AttrDef {
    private $classes, $prefixes ;

    public function __construct($classes, $prefixes) {
        $this->classes = $classes ;
        $this->prefixes = is_array($prefixes) ? join('|', $prefixes) : $prefixes ;
    }

    public function validate($string, $config, $context) {
        $classes = preg_split('/\s+/', $string) ;
        $validclasses = array() ;

        foreach ($classes as $class) {
            if (in_array($class, $this->classes) or
                preg_match("/^({$this->prefixes})/i", $class)) {

                $validclasses[] = $class ;
            }
        }

        return join(' ', $validclasses) ;
    }
}

$config = HTMLPurifier_Config::createDefault() ;
// Allow no classes by default
$config->set('Attr.AllowedClasses', array()) ;

$def = $config->getHTMLDefinition(true) ;
// Allow the class 'fa', and classes prefixed 'fa-' or 'foo-', on i tags
$def->addAttribute('i', 'class', new CustomClassDef(array('fa'), array('fa-', 'foo-'))) ;

// Allow classes prefixed 'language-' on code tags
$def->addAttribute('code', 'class', new CustomClassDef(array(), 'language-')) ;

$purifier = new HTMLPurifier($config) ;