You are here

public function BlazyFilter::process in Blazy 7

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

File

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

Class

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

Namespace

Drupal\blazy\Plugin\Filter

Code

public function process($text, $filter, $langcode) {
  $allowed_tags = array_values((array) $filter->settings['filter_tags']);
  if (empty($allowed_tags)) {
    return $text;
  }
  $dom = filter_dom_load($text);
  $settings = $this->manager
    ->getCommonSettings() + BlazyDefault::lazySettings();
  $settings['grid'] = stristr($text, 'data-grid') !== FALSE;
  $settings['column'] = stristr($text, 'data-column') !== FALSE;
  $settings['media_switch'] = $switch = $filter->settings['media_switch'];
  $settings['lightbox'] = $switch && in_array($switch, $this->manager
    ->getLightboxes()) ? $switch : FALSE;
  $settings['id'] = $settings['gallery_id'] = 'blazy-filter-' . drupal_random_key(8);
  $settings['plugin_id'] = 'blazy_filter';
  $settings['_grid'] = $settings['column'] || $settings['grid'];
  $settings['placeholder'] = $this->manager
    ->config('placeholder');
  $settings['use_data_uri'] = isset($filter->settings['media_switch']) ? $filter->settings['media_switch'] : FALSE;

  // At D7, BlazyFilter can only attach globally, prevents blocking.
  // Allows lightboxes to provide its own optionsets.
  if ($switch) {
    $settings[$switch] = empty($settings[$switch]) ? $switch : $settings[$switch];
  }

  // Provides alter like formatters to modify at one go, even clumsy here.
  $build = [
    'settings' => $settings,
  ];
  drupal_alter('blazy_settings', $build, $filter);
  $settings = array_merge($settings, $build['settings']);
  $valid_nodes = [];
  foreach ($allowed_tags as $allowed_tag) {
    $nodes = $dom
      ->getElementsByTagName($allowed_tag);
    if ($nodes->length > 0) {
      foreach ($nodes as $node) {
        if ($node
          ->hasAttribute('data-unblazy')) {
          continue;
        }
        $valid_nodes[] = $node;
      }
    }
  }
  if (count($valid_nodes) > 0) {
    $elements = $grid_nodes = [];
    $item_settings = $settings;
    $item_settings['count'] = $nodes->length;
    foreach ($valid_nodes as $delta => $node) {

      // Build Blazy elements with lazyloaded image, or iframe.
      $item_settings['uri'] = $item_settings['image_url'] = '';
      $item_settings['delta'] = $delta;
      $this
        ->buildSettings($item_settings, $node);
      $build = [
        'settings' => $item_settings,
      ];
      $this
        ->buildImageItem($build, $node);

      // Marks invalid/ unknown IMG or IFRAME for removal.
      if (empty($build['settings']['uri'])) {
        $node
          ->setAttribute('class', 'blazy-removed');
        continue;
      }
      $output = $this->manager
        ->getBlazy($build);
      if ($settings['_grid']) {
        $elements[] = $output;
        $grid_nodes[] = $node;
      }
      else {
        $altered_html = drupal_render($output);

        // Load the altered HTML into a new DOMDocument, retrieve element.
        $updated_nodes = filter_dom_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);
        }
      }
    }

    // Build the grids.
    if ($settings['_grid'] && !empty($elements[0])) {

      // @todo remove first_uri for _uri for consistency.
      $settings['_uri'] = $settings['first_uri'] = isset($elements[0]['#build']['settings']['uri']) ? $elements[0]['#build']['settings']['uri'] : '';
      $this
        ->buildGrid($dom, $settings, $elements, $grid_nodes);
    }

    // Cleans up invalid or moved nodes.
    $this
      ->cleanupNodes($dom);
  }
  $text = filter_dom_serialize($dom);
  return trim($text);
}