blazyloading-2.0.0/src/EventSubscriber/BlazyLoadingSubscriber.php

src/EventSubscriber/BlazyLoadingSubscriber.php
<?php

namespace Drupal\blazyloading\EventSubscriber;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\image\Entity\ImageStyle;
use Symfony\Component\HttpKernel\KernelEvents;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Cache\CacheableResponseInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * Event subscriber class BlazyLoadingSubscriber.
 */
class BlazyLoadingSubscriber implements EventSubscriberInterface {

  /**
   * Default class of the blazy loading.
   *
   * @var string
   */
  protected $blazyClass = 'b-lazy lazy_load_image';

  /**
   * Default Image url.
   *
   * @var string
   */
  protected $defaultImageUrl;

  /**
   * The current user service.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $blazyConfigFact;

  /**
   * The current user service.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a new DynamicPageCacheSubscriber object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   Object data.
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   Object data.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager service.
   */
  public function __construct(
    ConfigFactoryInterface $configFactory,
    AccountProxyInterface $currentUser,
    EntityTypeManagerInterface $entityTypeManager,
  ) {
    $this->blazyConfigFact = $configFactory->get('blazyloading_configuration.settings');
    $this->currentUser = $currentUser;
    $this->entityTypeManager = $entityTypeManager;

    // Load the loading image form the database.
    $this->defaultImageUrl = '/' . \Drupal::service('extension.list.module')->getPath('blazyloading') . '/images/loader.gif';
    if ($this->blazyConfigFact->get('loading_icon_file')) {
      $file = $this->entityTypeManager->getStorage('file')->load($this->blazyConfigFact->get('loading_icon_file'));
      if ($file) {
        $url = ImageStyle::load('medium')->buildUrl($file->getFileUri());
        $this->defaultImageUrl = $url;
      }
    }

    // Add the config css class to the blazy class.
    $this->blazyClass = $this->blazyClass . " " . $this->blazyConfigFact->get('css_class');
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['onResponse', 150];
    return $events;
  }

  /**
   * Replace all legacy,node/{nodeid} url to Drupal alias.
   *
   * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event
   *   Object of Response Event.
   */
  public function onResponse(ResponseEvent $event) {
    // Check the data in dynamic cache.
    $response = $event->getResponse();
    // Dynamic Page Cache only works with cacheable responses. It does not work
    // with plain Response objects. (Dynamic Page Cache needs to be able to
    // access and modify the cacheability metadata associated with the
    // response.)
    if (!$response instanceof CacheableResponseInterface) {
      return;
    }

    // Check the lazy loading configuration cache tag is set in
    // the drupal or not.
    $response_cacheability = $response->getCacheableMetadata()->getCacheTags();
    if (in_array('config:blazyloading.configuration', $response_cacheability)) {
      return;
    }

    // Check the lazy loading status.
    $blazy_loading_status = $this->blazyConfigFact->get('blazy_loading_status');
    $lazy_loading_status = FALSE;
    $image_url = [];
    if ($blazy_loading_status) {
      // Get the roles for which lazy loading should be work.
      $blazy_roles = $this->blazyConfigFact->get('blazy_roles');
      // Get the status of loading icon status.
      $loading_icon_status = $this->blazyConfigFact->get("loading_icon_status");
      // Get the image urls which should be removed from the blazy loading.
      $image_url = array_map('trim', explode("\n", $this->blazyConfigFact->get('image_urls')));

      if (empty($blazy_roles)) {
        $lazy_loading_status = TRUE;
      }
      else {
        foreach ($this->currentUser->getRoles() as $value) {
          if (in_array($value, $blazy_roles) && $blazy_roles[$value]) {
            $lazy_loading_status = TRUE;
            break;
          }
        }
      }
    }

    // Check that lazy loading status and apply blazy loading.
    if ($lazy_loading_status) {

      // Get the response of the all page.
      $content = $response->getContent();

      // Get all the image tag from the data.
      preg_match_all('/<img[^>]+>/i', $content, $result);
      foreach ($result[0] as $img_tags) {
        preg_match_all('/(class|src)=("[^"]*")/i', $img_tags, $all_image_url);
        if (!empty($all_image_url)) {
          $new_image_tag = $img_tags;
          // Get the key of the SRC attribute.
          $src_key = array_search("src", $all_image_url[1]);
          $src = (isset($all_image_url[1][$src_key]) && $all_image_url[1][$src_key] == 'src') ? TRUE : FALSE;

          // Get the key of the class attribute.
          $class_key = array_search("class", $all_image_url[1]);
          $class = (isset($all_image_url[1][$class_key]) && $all_image_url[1][$class_key] == 'class') ? TRUE : FALSE;

          $class_value = "";
          if (!$class) {
            $class_value = "class='" . $this->blazyClass . "'";
          }

          if ($src) {
            $old_src = str_replace('"', "", $all_image_url[2][$src_key]);
            if (in_array($old_src, $image_url)) {
              continue;
            }
            else {
              if ($loading_icon_status) {
                $src_value = "src='" . $this->defaultImageUrl . "'";
              }
              else {
                $src_value = "src=''";
              }

              $data_src_value = 'data-src="' . $old_src . '"';
              $new_image_tag = str_replace($all_image_url[0][$src_key], $src_value . " " . $data_src_value . " " . $class_value, $new_image_tag);
              if ($class) {
                $new_class_value = 'class="' . $this->blazyClass . ' ' . str_replace('"', "", $all_image_url[2][$class_key]) . '"';
                $new_image_tag = str_replace($all_image_url[0][$class_key], $new_class_value, $new_image_tag);
              }
              $content = str_replace($img_tags, $new_image_tag, $content);
            }
          }
        }
      }
      $response->setContent($content);
      $per_permissions_response_for_anon = new CacheableMetadata();
      $per_permissions_response_for_anon->setCacheTags(['config:blazyloading.configuration']);
      $response->addCacheableDependency($per_permissions_response_for_anon);
      $event->setResponse($response);
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc