You are here

public function BlazyFilter::process in Blazy 8.2

Same name and namespace in other branches
  1. 7 src/Plugin/Filter/BlazyFilter.php \Drupal\blazy\Plugin\Filter\BlazyFilter::process()

Performs the filter processing.

Parameters

string $text: The text string to be filtered.

string $langcode: The language code of the text to be filtered.

Return value

\Drupal\filter\FilterProcessResult The filtered text, wrapped in a FilterProcessResult object, and possibly with associated assets, cacheability metadata and placeholders.

Overrides FilterInterface::process

See also

\Drupal\filter\FilterProcessResult

File

src/Plugin/Filter/BlazyFilter.php, line 108

Class

BlazyFilter
Provides a filter to lazyload image, or iframe elements.

Namespace

Drupal\blazy\Plugin\Filter

Code

public function process($text, $langcode) {
  $result = new FilterProcessResult($text);
  $allowed_tags = array_values((array) $this->settings['filter_tags']);
  if (empty($allowed_tags)) {
    return $result;
  }
  $dom = Html::load($text);
  $attachments = [];
  $settings = $this
    ->buildSettings($text);
  $valid_nodes = $this
    ->validNodes($dom, $allowed_tags);
  if (count($valid_nodes) > 0) {
    $elements = $grid_nodes = [];
    foreach ($valid_nodes as $delta => $node) {

      // Build Blazy elements with lazyloaded image, or iframe.
      $item_settings = $settings;
      $item_settings['uri'] = $item_settings['image_url'] = '';
      $item_settings['delta'] = $delta;

      // Set an image style based on node data properties.
      // See https://www.drupal.org/project/drupal/issues/2061377,
      // https://www.drupal.org/project/drupal/issues/2822389, and
      // https://www.drupal.org/project/inline_responsive_images.
      if ($image_style = $node
        ->getAttribute('data-image-style')) {
        $item_settings['image_style'] = $image_style;
      }
      if ($responsive_image_style = $node
        ->getAttribute('data-responsive-image-style')) {
        $item_settings['responsive_image_style'] = $responsive_image_style;
      }
      if (!empty($settings['_resimage']) && !empty($item_settings['responsive_image_style'])) {
        $item_settings['resimage'] = $this->blazyManager
          ->entityLoad($item_settings['responsive_image_style'], 'responsive_image_style');
      }
      $this
        ->buildItemSettings($item_settings, $node);

      // Extracts image item from SRC attribute.
      $build = [
        'settings' => $item_settings,
      ];
      $this
        ->buildImageItem($build, $node);

      // Extracts image caption if available.
      $this
        ->buildImageCaption($build, $node);

      // Marks invalid, unknown, missing IMG or IFRAME for removal.
      // Be sure to not affect external images, only strip missing local URI.
      $uri = $build['settings']['uri'];
      $missing = BlazyUtil::isValidUri($uri) && !is_file($uri);
      if (empty($uri) || $missing) {
        $node
          ->setAttribute('class', 'blazy-removed');
        continue;
      }

      // Build valid nodes as structured render array.
      $output = $this->blazyManager
        ->getBlazy($build);
      if ($settings['_grid']) {
        $elements[] = $output;
        $grid_nodes[] = $node;
      }
      else {
        $altered_html = $this->blazyManager
          ->getRenderer()
          ->render($output);

        // Load the altered HTML into a new DOMDocument, retrieve element.
        $updated_nodes = Html::load($altered_html)
          ->getElementsByTagName('body')
          ->item(0)->childNodes;
        foreach ($updated_nodes as $updated_node) {

          // Import the updated from the new DOMDocument into the original
          // one, importing also the child nodes of the updated node.
          $updated_node = $dom
            ->importNode($updated_node, TRUE);
          $node->parentNode
            ->insertBefore($updated_node, $node);
        }

        // Finally, remove the original blazy node.
        if ($node->parentNode) {
          $node->parentNode
            ->removeChild($node);
        }
      }
    }

    // Prepares attachments.
    $all = [
      'blazy' => TRUE,
      'filter' => TRUE,
      'ratio' => TRUE,
    ];
    $all['media_switch'] = $switch = $settings['media_switch'];
    if (!empty($settings[$switch])) {
      $all[$switch] = $settings[$switch];
    }

    // Builds the grids if so provided via [data-column], or [data-grid].
    if ($settings['_grid'] && !empty($elements[0])) {
      $all['grid'] = $settings['grid'];
      $all['column'] = $settings['column'];
      $settings['_uri'] = isset($elements[0]['#build'], $elements[0]['#build']['settings']['uri']) ? $elements[0]['#build']['settings']['uri'] : '';
      $this
        ->buildGrid($dom, $settings, $elements, $grid_nodes);
    }

    // Adds the attachments.
    $attachments = $this->blazyManager
      ->attach($all);

    // Cleans up invalid, or moved nodes.
    $this
      ->cleanupNodes($dom);
  }

  // Attach Blazy component libraries.
  $result
    ->setProcessedText(Html::serialize($dom))
    ->addAttachments($attachments);
  return $result;
}