acquia_vwo-1.0.x-dev/src/Service/Context/PageContext.php

src/Service/Context/PageContext.php
<?php

namespace Drupal\acquia_vwo\Service\Context;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Render\Markup;
use Drupal\node\NodeInterface;
use Symfony\Component\HttpFoundation\RequestStack;

// cspell:ignore data-cfasync
/**
 * Page Context class.
 */
class PageContext implements CacheableDependencyInterface {

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageInterface
   */
  protected $languageManager;

  /**
   * The entity repository service.
   *
   * @var \Drupal\Core\Entity\EntityRepositoryInterface
   */
  protected $entityRepository;

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  private $configFactory;

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

  /**
   * Field mapping.
   *
   * @var array
   */
  private $fieldMapping;

  /**
   * The current node.
   *
   * @var \Drupal\node\NodeInterface
   */
  private $node;

  /**
   * The Visibility Context.
   *
   * @var \Drupal\acquia_vwo\Service\Context\VisibilityContext
   */
  private $visibilityContext;

  /**
   * The Request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  private $requestStack;

  /**
   * Constructor for Acquia VWO class.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager.
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
   *   The entity repository service.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param \Drupal\acquia_vwo\Service\Context\VisibilityContext $visibility_context
   *   The visibility context service.
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   *   The language manager service.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module Handler Service.
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    EntityTypeManagerInterface $entity_type_manager,
    EntityRepositoryInterface $entity_repository,
    RequestStack $request_stack,
    VisibilityContext $visibility_context,
    LanguageManagerInterface $language_manager,
    ModuleHandlerInterface $module_handler,
  ) {
    $this->configFactory = $config_factory;
    $this->entityRepository = $entity_repository;
    $this->visibilityContext = $visibility_context;
    $this->languageManager = $language_manager;
    $this->moduleHandler = $module_handler;
    $this->entityTypeManager = $entity_type_manager;
    $this->requestStack = $request_stack;
  }

  /**
   * Populates the script on the page.
   *
   * @param array $page
   *   The current page array.
   */
  public function populate(&$page) {
    $this->populateCacheContexts($page);
    $this->populateCacheTags($page);
    if (!$this->visibilityContext->shouldAttach()) {
      return;
    }
    $this->populateHtmlHead($page['#attached']['html_head']);
  }

  /**
   * Populate page's cache context.
   *
   * @param array $page
   *   The page that is to be populated.
   */
  protected function populateCacheContexts(array &$page) {
    $page['#cache']['contexts'] = Cache::mergeContexts($page['#cache']['contexts'], $this->getCacheContexts());
  }

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

  /**
   * Populate page's cache tags.
   *
   * @param array $page
   *   The page that is to be populated.
   */
  protected function populateCacheTags(array &$page) {
    $page['#cache']['tags'] = Cache::mergeTags($page['#cache']['tags'] ?? [], $this->getCacheTags());
  }

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

  /**
   * Populates the script on the page.
   *
   * @param array $htmlHead
   *   The head elements.
   */
  protected function populateHtmlHead(&$htmlHead) {
    $htmlHead[] = $this->getJavaScriptTagRenderArray();
  }

  /**
   * Get the render array for a JavaScript tag.
   *
   * @return array
   *   The render array
   */
  private function getJavaScriptTagRenderArray() {
    // Load the VWO script.
    $module_path = $this->moduleHandler->getModule('acquia_vwo')->getPath();
    $vwo_script = file_get_contents("$module_path/js/vwo.min.js");

    // Add VWO script.
    $account_id = $this->getVwoConfigSettings()->get('id');
    $timeout = $this->getVwoConfigSettings()->get('loading.timeout');
    $script = "!acquiaVwoUserOptOut() && (window._vwo_code || (function () {
      var account_id=$account_id,
      version=2.1,
      settings_tolerance=$timeout,
      hide_element='body',
      hide_element_style='opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important',
      $vwo_script)" . PHP_EOL;

    // Add Acquia VWO script with field mapping.
    $node_data = json_encode($this->getNodeData());
    $script .= "window.VWO = window.VWO || [];
      window.VWO.data = window.VWO.data || {};
      window.VWO.data.acquia=$node_data" . PHP_EOL;

    return [
      [
        '#tag' => 'script',
        '#attributes' => [
          'data-cfasync' => 'false',
          'type' => 'text/javascript',
        ],
        '#value' => Markup::create($script),
      ],
      'acquia_vwo',
    ];
  }

  /**
   * Helper to extract the node data for each of the field mappings.
   *
   * @return array
   *   The node data.
   */
  private function getNodeData() {
    $node_data = [];
    $node = $this->getNode();
    if (empty($node)) {
      return $node_data;
    }

    // Get values for each item from the field mapping configuration.
    foreach ($this->getFieldMapping() as $key => $field_name) {
      if (empty($field_name) ||
        !$node->hasField($field_name) ||
        $node->get($field_name)->isEmpty()
      ) {
        continue;
      }
      $term_ids = $node->get($field_name)->getValue();
      $term_data = $this->getTermData($term_ids);
      foreach ($term_data as $term_name) {
        $node_data[$key][] = $term_name;
      }
    }

    return [
      'drupal' => [
        'title' => $node->getTitle(),
        'content_type' => $node->bundle(),
        'taxonomy' => $node_data,
      ],
    ];
  }

  /**
   * Getter for node.
   *
   * @return \Drupal\node\NodeInterface|null
   *   Returns the node or null.
   */
  private function getNode() {
    /** @var \Symfony\Component\HttpFoundation\Request $request */
    $request = $this->requestStack->getCurrentRequest();
    $node = $request->attributes->get('node');
    if (!empty($node) && $node instanceof NodeInterface) {
      $this->node = $node;
    }
    return $this->node ?? NULL;
  }

  /**
   * Getter for field mapping.
   *
   * @return array
   *   The field mapping.
   */
  private function getFieldMapping() {
    return $this->getVwoConfigSettings()->get('field_mapping') ?? [];
  }

  /**
   * Helper to get the term names from term ids.
   *
   * @param array $term_ids
   *   The term ids.
   *
   * @return array
   *   The term data.
   */
  private function getTermData(array $term_ids) {
    $term_data = [];
    /** @var \Drupal\taxonomy\TermStorageInterface $taxonomy_storage */
    $taxonomy_storage = $this->entityTypeManager->getStorage('taxonomy_term');
    $terms = $taxonomy_storage->loadMultiple(array_column($term_ids, 'target_id'));

    foreach ($terms as $term) {
      $taxonomy_term_trans = $this->getTranslatedContent($term);
      $term_data[] = $taxonomy_term_trans->getName();
    }

    return $term_data;
  }

  /**
   * Helper to get translated version of the entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity.
   *
   * @return \Drupal\Core\Entity\EntityInterface|null
   *   The translated entity.
   */
  private function getTranslatedContent(EntityInterface $entity) {
    $lang_code = $this->getCurrentLangCode();
    return $this->entityRepository->getTranslationFromContext($entity, $lang_code);
  }

  /**
   * Helper to get the current lang code.
   *
   * @return string
   *   The lang code.
   */
  private function getCurrentLangCode() {
    return $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
      ->getId();
  }

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

  /**
   * Get Acquia VWO config settings.
   * 
   * @return \Drupal\Core\Config\Config
   *   The VWO Config Object.
   */
  protected function getVwoConfigSettings() {
    return $this->configFactory->get('acquia_vwo.settings');
  }

}

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

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