mustache_templates-8.x-1.0-beta4/src/Summable/SummableScripts.php

src/Summable/SummableScripts.php
<?php

namespace Drupal\mustache\Summable;

use Drupal\Core\Asset\LibraryDiscoveryInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Theme\ActiveTheme;
use Drupal\Core\Theme\ThemeInitializationInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\mustache\Exception\MustacheFileException;
use Drupal\mustache\Exception\MustacheTemplateNotFoundException;
use Drupal\mustache\Helpers\MustacheRenderTemplate;
use Drupal\mustache\MustacheTemplates;

/**
 * Class for providing Mustache templates as summable script files.
 */
class SummableScripts implements SummableScriptsInterface {

  /**
   * Whether the usage of summable script files is enabled or not.
   *
   * @var bool
   */
  protected $enabled;

  /**
   * The file path where to store generated script files.
   *
   * @var string
   */
  protected $jsPath;

  /**
   * The cache backend to store summable script information.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $cache;

  /**
   * The finder of Mustache templates.
   *
   * @var \Drupal\mustache\MustacheTemplates
   */
  protected $templates;

  /**
   * The library discovery service.
   *
   * @var \Drupal\Core\Asset\LibraryDiscoveryInterface
   */
  protected $libraryDiscovery;

  /**
   * The theme manager.
   *
   * @var \Drupal\Core\Theme\ThemeManagerInterface
   */
  protected $themeManager;

  /**
   * The theme initialization service.
   *
   * @var \Drupal\Core\Theme\ThemeInitializationInterface
   */
  protected $themeInitialization;

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected $fileSystem;

  /**
   * A list of libraries for every template as summable script file.
   *
   * @var array
   */
  protected $libraries;

  /**
   * A list of known template libraries currently being used per theme.
   *
   * @var array
   */
  protected $current;

  /**
   * SummableScripts constructor.
   *
   * @param bool $enabled
   *   Whether the usage of summable script files is enabled or not.
   * @param string $js_path
   *   The file path where to store generated script files.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   The cache backend to store summable script information.
   * @param \Drupal\mustache\MustacheTemplates $templates
   *   The finder of Mustache templates.
   * @param \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery
   *   The library discovery service.
   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
   *   The theme manager.
   * @param \Drupal\Core\Theme\ThemeInitializationInterface $theme_initialization
   *   The theme initialization service.
   * @param \Drupal\Core\File\FileSystemInterface $file_system
   *   The file system service.
   */
  public function __construct($enabled, $js_path, CacheBackendInterface $cache, MustacheTemplates $templates, LibraryDiscoveryInterface $library_discovery, ThemeManagerInterface $theme_manager, ThemeInitializationInterface $theme_initialization, FileSystemInterface $file_system) {
    $this->enabled = $enabled;
    $this->jsPath = $js_path;
    $this->cache = $cache;
    $this->templates = $templates;
    $this->libraryDiscovery = $library_discovery;
    $this->themeManager = $theme_manager;
    $this->themeInitialization = $theme_initialization;
    $this->fileSystem = $file_system;
  }

  /**
   * {@inheritdoc}
   */
  public function isEnabled() {
    return $this->enabled;
  }

  /**
   * {@inheritdoc}
   */
  public function getLibraryName($template, ActiveTheme $theme = NULL) {
    $library_name = FALSE;
    $theme = $theme ?: $this->themeManager->getActiveTheme();
    $theme_name = $theme->getName();

    $cid = 'mustache:libraries:' . $theme_name;
    $regenerate = FALSE;
    if (!isset($this->current[$theme_name])) {
      if ($cached = $this->cache->get($cid)) {
        $this->current[$theme_name] = $cached->data;
      }
    }
    if (isset($this->current[$theme_name][$template])) {
      $library_name = $this->current[$theme_name][$template];
    }
    else {
      $regenerate = TRUE;
      $candidates = ['template.' . $theme_name . '.' . $template];
      foreach ($theme->getBaseThemeExtensions() as $base_theme) {
        $candidates[] = 'template.' . $base_theme->getName() . '.' . $template;
      }
      $candidates[] = 'template.module.' . $template;
      foreach ($candidates as $candidate) {
        if ($this->libraryDiscovery->getLibraryByName('mustache', $candidate)) {
          $library_name = 'mustache/' . $candidate;
          break;
        }
      }
      $this->current[$theme_name][$template] = $library_name;
      $this->cache->set($cid, $this->current[$theme_name], CacheBackendInterface::CACHE_PERMANENT, ['mustache:libraries']);
    }
    if (!$library_name) {
      throw new MustacheFileException(t('Cannot provide summable script file, because no library has been found for template @template.', ['@template' => $template]));
    }

    // Make sure the script file has been generated and is available.
    if (!$this->generate($library_name, $regenerate)) {
      throw new MustacheFileException(t('Failed to generate summable script file for template @template', ['@template' => $template]));
    }

    return $library_name;
  }

  /**
   * {@inheritdoc}
   */
  public function getAllLibraries() {
    if (!isset($this->libraries)) {
      $cid = 'mustache:libraries';
      if ($cached = $this->cache->get($cid)) {
        $this->libraries = $cached->data;
      }
      else {
        $libraries = [];
        $with_partials = [];

        foreach ($this->templates->findAll() as $name => $items) {
          $defaults = $this->templates->getElementDefaults($name);
          foreach ($items as $item) {
            $library_name = 'template.' . $item['provider'] . '.' . $name;
            $js_file_uri = $this->buildUri($item['provider'], $name);
            $js_file_path = \Drupal::service('file_url_generator')->generateString($js_file_uri);
            $libraries[$library_name] = [
              'js' => [$js_file_path => []],
              'dependencies' => ['mustache/sync.now'],
            ];
            if (!empty($defaults['#partials'])) {
              $with_partials[$library_name] = [
                'provider' => $item['provider'],
                'partials' => $defaults['#partials'],
              ];
            }
          }
        }

        foreach ($with_partials as $library_name => $detail) {
          $candidates = [];
          if ($detail['provider'] !== 'module') {
            $candidates[] = $detail['provider'];
            $theme = $this->themeInitialization->getActiveThemeByName($detail['provider']);
            $candidates = array_merge($candidates, array_keys($theme->getBaseThemeExtensions()));
          }
          $candidates[] = 'module';
          foreach ($detail['partials'] as $partial_name) {
            $partial_defaults = $this->templates->getElementDefaults($partial_name);
            if (isset($partial_defaults['#summable']) && empty($partial_defaults['#summable'])) {
              continue;
            }
            foreach ($candidates as $candidate) {
              $partial_library_candidate = 'template.' . $candidate . '.' . $partial_name;
              if (isset($libraries[$partial_library_candidate])) {
                $libraries[$library_name]['dependencies'][] = $partial_library_candidate;
                break;
              }
            }
          }
        }

        $this->cache->set($cid, $libraries, CacheBackendInterface::CACHE_PERMANENT, ['mustache:libraries']);
        $this->libraries = $libraries;
      }
    }

    return $this->libraries;
  }

  /**
   * {@inheritdoc}
   */
  public function buildUri($provider, $template_name) {
    return str_replace('-', '_', $this->jsPath . '/' . $provider . '/' . $template_name . '.js');
  }

  /**
   * {@inheritdoc}
   */
  public function generate($library_name, $regenerate = FALSE) {
    $parts = explode('.', $library_name);
    // First part would always be "template".
    array_shift($parts);
    // The second part is either "module" or a theme name.
    $provider = array_shift($parts);
    // The rest is the actual name of the template.
    $template_name = implode('.', $parts);

    $script_file_uri = $this->buildUri($provider, $template_name);
    if (!$regenerate && file_exists($script_file_uri)) {
      return TRUE;
    }

    $template_content = NULL;
    if ($provider === 'module') {
      $module_templates = $this->templates->getModuleTemplates();
      if (isset($module_templates[$template_name]['file'])) {
        $template_content = @file_get_contents($module_templates[$template_name]['file']);
      }
    }
    else {
      $theme = $this->themeManager->getActiveTheme();
      if ($theme->getName() !== $provider) {
        $theme = $this->themeInitialization->getActiveThemeByName($provider);
      }
      $template_content = $this->templates->getContent($template_name, $theme);
    }
    if (!is_string($template_content)) {
      throw new MustacheTemplateNotFoundException(t('Defined template @template for library @library not found.',
        ['@template' => $template_name, '@library' => $library_name]));
    }

    $template_encoded = trim(substr(json_encode($template_content, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT), 1, -1));

    $build = MustacheRenderTemplate::build('summable')
      ->usingData([
        'name' => $template_name,
        'content' => $template_encoded,
      ])
      ->toRenderArray();
    $script_generated = trim((string) \Drupal::service('renderer')->render($build));

    $directory = $this->jsPath . '/' . $provider;
    $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);
    if ($this->fileSystem->saveData($script_generated, $script_file_uri, FileSystemInterface::EXISTS_REPLACE) === FALSE) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function clearCaches() {
    if ($this->cache instanceof CacheTagsInvalidatorInterface) {
      $this->cache->invalidateTags(['mustache:libraries']);
    }
    else {
      $this->cache->invalidateAll();
    }
    // The library discovery service holds a list of statically cached
    // definitions, and since we are adding a new definition here, it
    // needs to be reset. The clear method is the only known way to do so.
    $this->libraryDiscovery->clearCachedDefinitions();
    $this->libraries = NULL;
    $this->current = [];
  }

  /**
   * {@inheritdoc}
   */
  public function deleteAll() {
    return $this->fileSystem->deleteRecursive($this->jsPath);
  }

}

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

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