You are here

public function FilterFormat::getHtmlRestrictions in Drupal 10

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

Retrieve all HTML restrictions (tags and attributes) for the text format.

Note that restrictions applied to the "*" tag (the wildcard tag, i.e. all tags) are treated just like any other HTML tag. That means that any restrictions applied to it are not automatically applied to all other tags. It is up to the caller to handle this in whatever way it sees fit; this way no information granularity is lost.

Return value

array|false A structured array as returned by FilterInterface::getHTMLRestrictions(), but with the intersection of all filters in this text format. FALSE means there are no HTML restrictions.

Overrides FilterFormatInterface::getHtmlRestrictions

File

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

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;
  }
}