mustache_templates-8.x-1.0-beta4/modules/mustache_views/src/MustacheViews.php

modules/mustache_views/src/MustacheViews.php
<?php

namespace Drupal\mustache_views;

use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\Render\RendererInterface;
use Drupal\mustache\Helpers\Mustache;
use Drupal\mustache\Helpers\MustacheRenderTemplate;
use Drupal\views\ViewExecutable;

/**
 * Service for integration of Mustache templates in Views.
 */
class MustacheViews {

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * The MustacheViews constructor.
   *
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   */
  public function __construct(RendererInterface $renderer) {
    $this->renderer = $renderer;
  }

  /**
   * Query alteration that evaluates any Mustache template syntax.
   *
   * @param \Drupal\Core\Database\Query\AlterableInterface $query
   *   A Query object describing the composite parts of a SQL query.
   */
  public function alterQuery(AlterableInterface $query) {
    $to_evaluate = [];
    $view = $query->getMetaData('view');
    if (!($view instanceof ViewExecutable)) {
      return;
    }
    $this->collectTemplates($query, $to_evaluate);
    if (empty($to_evaluate)) {
      return;
    }

    $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($view->element);
    $previous_cache_contexts = $bubbleable_metadata->getCacheContexts();
    foreach ($to_evaluate as &$text) {
      $template = MustacheRenderTemplate::build(hash('md4', $text), $text)
        ->withTokens();
      $build = $template->toRenderArray();
      $this->renderer->executeInRenderContext(new RenderContext(), function () use (&$build) {
        $this->renderer->render($build);
      });
      $bubbleable_metadata
        ->addCacheableDependency(BubbleableMetadata::createFromRenderArray($build));
      if (isset($build['#content'])) {
        $trimmed = trim((string) $build['#content']);
        if ($trimmed !== '') {
          $text = $trimmed;
        }
      }
    }
    // @todo Resolve this to be cacheable by respecting cache contexts within
    // \Drupal\views\Plugin\views\cache\CachePluginBase::generateResultsKey().
    // @see https://www.drupal.org/project/mustache_templates/issues/3253881
    if (array_diff($bubbleable_metadata->getCacheContexts(), $previous_cache_contexts)) {
      $bubbleable_metadata->mergeCacheMaxAge(0);
    }
    $bubbleable_metadata->applyTo($view->element);
  }

  /**
   * Collects templates from the given query.
   *
   * @param \Drupal\Core\Database\Query\AlterableInterface $query
   *   A Query object describing the composite parts of a SQL query.
   * @param array &$to_evaluate
   *   A list of already collected templates to evaluate.
   */
  protected function collectTemplates(AlterableInterface $query, array &$to_evaluate) {
    /** @var \Drupal\Core\Database\Query\Select $query */
    $tables = &$query->getTables();
    $conditions = &$query->conditions();

    foreach ($tables as $table_name => $table_metadata) {
      if (empty($table_metadata['arguments'])) {
        continue;
      }
      foreach ($table_metadata['arguments'] as $replacement_key => $value) {
        if (is_array($value)) {
          foreach ($value as $sub_key => $sub_value) {
            if (Mustache::containsSyntax($sub_value) || Mustache::containsToken($sub_value)) {
              $to_evaluate[] = &$tables[$table_name]['arguments'][$replacement_key][$sub_key];
            }
          }
        }
        elseif (Mustache::containsSyntax($value) || Mustache::containsToken($value)) {
          $to_evaluate[] = &$tables[$table_name]['arguments'][$replacement_key];
        }
      }
    }

    $this->collectFromConditions($query, $conditions, $to_evaluate);
  }

  /**
   * Sub-method to collect templates from conditions.
   *
   * @param \Drupal\Core\Database\Query\AlterableInterface $query
   *   A Query object describing the composite parts of a SQL query.
   * @param mixed &$conditions
   *   The conditions.
   * @param array &$to_evaluate
   *   A list of already collected templates to evaluate.
   */
  protected function collectFromConditions(AlterableInterface $query, &$conditions, array &$to_evaluate) {
    foreach ($conditions as $condition_id => &$condition) {
      if (!is_numeric($condition_id)) {
        continue;
      }
      if (is_string($condition['field']) && (Mustache::containsSyntax($condition['field']) || Mustache::containsToken($condition['field']))) {
        $to_evaluate[] = &$condition['field'];
      }
      elseif (is_object($condition['field'])) {
        $sub_conditions = &$condition['field']->conditions();
        $this->collectFromConditions($query, $sub_conditions, $to_evaluate);
      }
      if (is_object($condition['value'])) {
        $this->collectTemplates($condition['value'], $to_evaluate);
      }
      elseif (isset($condition['value'])) {
        if (is_array($condition['value'])) {
          foreach ($condition['value'] as $key => $value) {
            if (is_string($value) && (Mustache::containsSyntax($value) || Mustache::containsToken($value))) {
              $to_evaluate[] = &$condition['value'][$key];
            }
          }
        }
        elseif (is_string($condition['value']) && (Mustache::containsSyntax($condition['value']) || Mustache::containsToken($condition['value']))) {
          $to_evaluate[] = &$condition['value'];
        }
      }
    }
  }

}

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

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