function FilterFormat::getHtmlRestrictions

Same name and namespace in other branches
  1. 9 core/modules/filter/src/Entity/FilterFormat.php \Drupal\filter\Entity\FilterFormat::getHtmlRestrictions()
  2. 8.9.x core/modules/filter/src/Entity/FilterFormat.php \Drupal\filter\Entity\FilterFormat::getHtmlRestrictions()
  3. 11.x core/modules/filter/src/Entity/FilterFormat.php \Drupal\filter\Entity\FilterFormat::getHtmlRestrictions()

Overrides FilterFormatInterface::getHtmlRestrictions

File

core/modules/filter/src/Entity/FilterFormat.php, line 287

Class

FilterFormat
Represents a text format.

Namespace

Drupal\filter\Entity

Code

public function getHtmlRestrictions() {
    // Ignore filters that are disabled or don't have HTML restrictions.
    $filters = array_filter($this->filters()
        ->getAll(), function ($filter) {
        if (!$filter->status) {
            return FALSE;
        }
        if ($filter->getType() === FilterInterface::TYPE_HTML_RESTRICTOR && $filter->getHTMLRestrictions() !== FALSE) {
            return TRUE;
        }
        return FALSE;
    });
    if (empty($filters)) {
        return FALSE;
    }
    else {
        // From the set of remaining filters (they were filtered by array_filter()
        // above), collect the list of tags and attributes that are allowed by all
        // filters, i.e. the intersection of all allowed tags and attributes.
        $restrictions = array_reduce($filters, function ($restrictions, $filter) {
            $new_restrictions = $filter->getHTMLRestrictions();
            // The first filter with HTML restrictions provides the initial set.
            if (!isset($restrictions)) {
                return $new_restrictions;
            }
            else {
                // Track the intersection of allowed tags.
                if (isset($restrictions['allowed'])) {
                    $intersection = $restrictions['allowed'];
                    foreach ($intersection as $tag => $attributes) {
                        // If the current tag is not allowed by the new filter, then it's
                        // outside of the intersection.
                        if (!array_key_exists($tag, $new_restrictions['allowed'])) {
                            // The exception is the asterisk (which applies to all tags): it
                            // does not need to be allowed by every filter in order to be
                            // used; not every filter needs attribute restrictions on all tags.
                            if ($tag === '*') {
                                continue;
                            }
                            unset($intersection[$tag]);
                        }
                        else {
                            $current_attributes = $intersection[$tag];
                            $new_attributes = $new_restrictions['allowed'][$tag];
                            // The current intersection does not allow any attributes, never
                            // allow.
                            if (!is_array($current_attributes) && $current_attributes == FALSE) {
                                continue;
                            }
                            elseif (!is_array($current_attributes) && $current_attributes == TRUE && ($new_attributes == FALSE || is_array($new_attributes))) {
                                $intersection[$tag] = $new_attributes;
                            }
                            elseif (is_array($current_attributes) && $new_attributes == FALSE) {
                                $intersection[$tag] = $new_attributes;
                            }
                            elseif (is_array($current_attributes) && $new_attributes == TRUE) {
                                continue;
                            }
                            elseif ($current_attributes == $new_attributes) {
                                continue;
                            }
                            else {
                                $intersection[$tag] = array_intersect_key($intersection[$tag], $new_attributes);
                                foreach (array_keys($intersection[$tag]) as $attribute_value) {
                                    $intersection[$tag][$attribute_value] = $intersection[$tag][$attribute_value] && $new_attributes[$attribute_value];
                                }
                            }
                        }
                    }
                    $restrictions['allowed'] = $intersection;
                }
                // Simplification: if the only remaining allowed tag is the asterisk
                // (which contains attribute restrictions that apply to all tags),
                // then effectively nothing is allowed.
                if (count($restrictions['allowed']) === 1 && array_key_exists('*', $restrictions['allowed'])) {
                    $restrictions['allowed'] = [];
                }
                return $restrictions;
            }
        }, NULL);
        return $restrictions;
    }
}

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