function FilterHtml::filterAttributes

Same name and namespace in other branches
  1. 9 core/modules/filter/src/Plugin/Filter/FilterHtml.php \Drupal\filter\Plugin\Filter\FilterHtml::filterAttributes()
  2. 8.9.x core/modules/filter/src/Plugin/Filter/FilterHtml.php \Drupal\filter\Plugin\Filter\FilterHtml::filterAttributes()
  3. 10 core/modules/filter/src/Plugin/Filter/FilterHtml.php \Drupal\filter\Plugin\Filter\FilterHtml::filterAttributes()

Provides filtering of tag attributes into accepted HTML.

Parameters

string $text: The HTML text string to be filtered.

Return value

string Filtered HTML with attributes filtered according to the settings.

1 call to FilterHtml::filterAttributes()
FilterHtml::process in core/modules/filter/src/Plugin/Filter/FilterHtml.php
Performs the filter processing.

File

core/modules/filter/src/Plugin/Filter/FilterHtml.php, line 106

Class

FilterHtml
Provides a filter to limit allowed HTML tags.

Namespace

Drupal\filter\Plugin\Filter

Code

public function filterAttributes($text) {
    $restrictions = $this->getHTMLRestrictions();
    $global_allowed_attributes = array_filter($restrictions['allowed']['*']);
    unset($restrictions['allowed']['*']);
    // Apply attribute restrictions to tags.
    $html_dom = Html::load($text);
    $xpath = new \DOMXPath($html_dom);
    foreach ($restrictions['allowed'] as $allowed_tag => $tag_attributes) {
        // By default, no attributes are allowed for a tag, but due to the
        // globally allowed attributes, it is impossible for a tag to actually
        // completely disallow attributes.
        if ($tag_attributes === FALSE) {
            $tag_attributes = [];
        }
        $allowed_attributes = [
            'exact' => [],
            'prefix' => [],
        ];
        foreach ($global_allowed_attributes + $tag_attributes as $name => $values) {
            // A trailing * indicates wildcard, but it must have some prefix.
            if (str_ends_with($name, '*') && $name[0] !== '*') {
                $allowed_attributes['prefix'][str_replace('*', '', $name)] = $this->prepareAttributeValues($values);
            }
            else {
                $allowed_attributes['exact'][$name] = $this->prepareAttributeValues($values);
            }
        }
        krsort($allowed_attributes['prefix']);
        // Find all matching elements that have any attributes and filter the
        // attributes by name and value.
        foreach ($xpath->query('//' . $allowed_tag . '[@*]') as $element) {
            $this->filterElementAttributes($element, $allowed_attributes);
        }
    }
    if ($this->settings['filter_html_nofollow']) {
        $links = $html_dom->getElementsByTagName('a');
        foreach ($links as $link) {
            $link->setAttribute('rel', 'nofollow');
        }
    }
    $text = Html::serialize($html_dom);
    return trim($text);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.