You are here

public static function InsertUtility::addAllowedHtml in Insert 8.2

Adds allowed HTML tags and attributes to a HTML validation string.

Additional validation for the filter format edit form. This function is supposed to alter the allowed HTML filter tags and attributes settings as to what is required for the Insert module to work properly. To prevent confusion, this should be done minimally invasive. The tag an attribute detection logic is copied over from \Drupal\filter\Plugin\Filter\FilterHtml. A cleaner, though rather less usable, method would be an individual Filter extending FilterHtml overwriting FilterHtml::getHtmlRestrictions with adding necessary tags and attributes to $restrictions['allowed'].

Parameters

string $value:

array $tags:

array $attributes:

Return value

string

See also

\Drupal\filter\Plugin\Filter\FilterHtml::prepareAttributeValues

1 call to InsertUtility::addAllowedHtml()
_insert_allowed_html_validate in ./insert.module

File

src/Utility/InsertUtility.php, line 195

Class

InsertUtility

Namespace

Drupal\insert\Utility

Code

public static function addAllowedHtml($value, array $tags, array $attributes) {

  // See \Drupal\filter\Plugin\Filter\FilterHtml::prepareAttributeValues.
  $html = str_replace('>', ' />', $value);
  $star_protector = '__zqh6vxfbk3cg__';
  $html = str_replace('*', $star_protector, $html);
  $body_child_nodes = Html::load($html)
    ->getElementsByTagName('body')
    ->item(0)->childNodes;

  // Detect which tags an attributes are allowed already.
  foreach ($body_child_nodes as $node) {
    if ($node->nodeType !== XML_ELEMENT_NODE) {
      continue;
    }
    $tag = $node->tagName;
    if (array_key_exists($tag, $tags)) {
      $tags[$tag] = TRUE;
    }
    else {
      continue;
    }

    /** @var \DOMNode $node */
    if ($node
      ->hasAttributes()) {
      foreach ($node->attributes as $name => $attribute) {

        // See \Drupal\filter\Plugin\Filter\FilterHtml::prepareAttributeValues.
        $name = str_replace($star_protector, '*', $name);
        $allowed_attribute_values = preg_split('/\\s+/', str_replace($star_protector, '*', $attribute->value), -1, PREG_SPLIT_NO_EMPTY);
        $allowed_attribute_values = array_filter($allowed_attribute_values, function ($value) {
          return $value !== '*';
        });

        // $allowed_attribute_values needs to be empty to allow all values.
        if (array_key_exists($name, $attributes[$tag])) {
          $attributes[$tag][$name] = empty($allowed_attribute_values);
        }
      }
    }
  }

  // Add missing tags and attributes required by the Insert module. This is done
  // using string parsing as the actually saved string should be altered as
  // minimally as possible.
  foreach ($tags as $tag => $found_tag) {
    if (!$found_tag) {
      $value .= ' <' . $tag . '>';
    }
    foreach ($attributes[$tag] as $name => $found_attribute) {
      if ($found_attribute === TRUE) {

        // The attribute is set already and allows all values.
        continue;
      }
      elseif ($found_attribute === NULL) {

        // The attribute is not yet set, just add it.
        $value = preg_replace('/<' . $tag . '/', '<' . $tag . ' ' . $name, $value);
      }
      else {

        // The attribute is set but limited to particular values; Remove that
        // limitation.
        $value = preg_replace('/(<' . $tag . '[^>]+' . $name . ')(=("|\')[^"\']+("|\'))/', '$1', $value);
      }
    }
  }
  return $value;
}