Search code examples
phphtmlhtmlpurifier

htmlpurifier allow scheme for specific tags


$config->set('URI.AllowedSchemes', array('data' => true, 'http' => true));

$config->set('HTML.AllowedElements', array(
    'a', 'img'
));

$config->set('HTML.AllowedAttributes', array(
    'a.href', 'img.src'
));

I have a htmlpurifier config like above. I want URI.AllowedSchemes to apply a specific html tag. For example img tag can only have data and a tag can only have http. Is there any way to achieve that?


Solution

  • Here's my solution;

    Filters;

    class ImgSrcTransform extends HTMLPurifier_AttrTransform
    {
        protected $parse;
    
        public function __construct(){
            $this->parser = new HTMLPurifier_URIParser();
        }
        public function transform($attr, $config, $context)
        {
            if(!isset($attr['src'])){
                return $attr;
            }
    
            $url = $this->parser->parse($attr['src']);
            if($url->scheme == 'http' || $url->scheme == 'https'){
                unset($attr['src']);
            }
    
            return $attr;
        }
    }
    
    class LinkHrefTransform extends HTMLPurifier_AttrTransform
    {
        protected $parse;
    
        public function __construct(){
            $this->parser = new HTMLPurifier_URIParser();
        }
        public function transform($attr, $config, $context)
        {
            if(!isset($attr['href'])){
                return $attr;
            }
    
            $url = $this->parser->parse($attr['href']);
    
    
            if($url->scheme == 'data'){
                unset($attr['href']);
            }
    
            return $attr;
        }
    }
    

    Using the filters;

    $config = HTMLPurifier_Config::createDefault();
    $config->set('URI.AllowedSchemes', array('data' => true, 'http' => true, 'https' => true));
    $config->set('HTML.AllowedElements', $elements);
    $config->set('HTML.AllowedAttributes', $attributes);
    
    $htmlDef = $config->getHTMLDefinition(true);
    
    $img = $htmlDef->addBlankElement('img');
    $img->attr_transform_pre[] = new ImgSrcTransform();
    
    $anchor = $htmlDef->addBlankElement('a');
    $anchor->attr_transform_pre[] = new LinkHrefTransform();
    
    $purifier = new HTMLPurifier($config);