consent-8.x-1.0-alpha5/modules/consent_iframe/src/Controller/ConsentIframeControllerBase.php

modules/consent_iframe/src/Controller/ConsentIframeControllerBase.php
<?php

namespace Drupal\consent_iframe\Controller;

use Drupal\Component\Utility\Unicode;
use Drupal\consent_iframe\Response\ConsentIframeResponse;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Abstract class ConsentIframeControllerBase.
 */
abstract class ConsentIframeControllerBase implements ContainerInjectionInterface {

  /**
   * The iFrame settings.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $iframeSettings;

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

  /**
   * The block storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $blockStorage;

  /**
   * The system performance configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $systemPerformanceConfig;

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

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('config.factory')->get('consent_iframe.settings'),
      $container->get('renderer'),
      $container->get('entity_type.manager')->getStorage('block'),
      $container->get('current_user'),
      $container->get('config.factory')->get('system.performance')
    );
  }

  /**
   * ConsentIframeControllerBase constructor.
   */
  public function __construct(ImmutableConfig $iframe_settings, RendererInterface $renderer, EntityStorageInterface $block_storage, AccountProxyInterface $current_user, ImmutableConfig $system_performance_config) {
    $this->iframeSettings = $iframe_settings;
    $this->renderer = $renderer;
    $this->blockStorage = $block_storage;
    $this->currentUser = $current_user;
    $this->systemPerformanceConfig = $system_performance_config;
  }

  /**
   * Build the page content as render array.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return array
   *   The page content as render array.
   */
  abstract protected function pageContent(Request $request);

  /**
   * The iFrame page controller method.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   The Http response.
   */
  public function page(Request $request) {
    $cache_max_age = (int) $this->systemPerformanceConfig->get('cache.page.max_age');
    $not_cacheable = !($cache_max_age > 0) || $this->currentUser->isAuthenticated() || !$this->currentUser->isAnonymous();
    $cache_header = $not_cacheable ? 'must-revalidate, no-cache, private' : 'public, max-age=' . $cache_max_age . ' s-maxage=' . $cache_max_age;
    $build = $this->pageContent($request) + $this->pageAttachments();
    $this->renderer->renderRoot($build);
    $response = new ConsentIframeResponse($build, 200, [
      'Content-Type' => 'text/html; charset=UTF-8',
      'Cache-Control' => $cache_header,
    ]);
    $this->setCORSHeaders($request, $response);
    if (!$not_cacheable) {
      $response->headers->remove('Pragma');
    }
    return $response;
  }

  /**
   * Get the required attachments as render array.
   *
   * @return array
   *   The attachments as render array.
   */
  protected function pageAttachments() {
    return ['#attached' => ['library' => $this->getEnabledLibraries()]];
  }

  /**
   * Get the enabled libraries.
   *
   * @return array
   *   The enabled libraries.
   */
  protected function getEnabledLibraries() {
    $libraries = ['consent/layer'];
    $trigger_libraries = [
      'storage' => 'consent/trigger.storage',
      'parent_response' => 'consent_iframe/trigger.parent_response',
    ];
    $triggers = NULL;
    if ($block_id = $this->iframeSettings->get('block')) {
      /** @var \Drupal\block\BlockInterface $block */
      if ($block = $this->blockStorage->load($block_id)) {
        $plugin_settings = $block->getPlugin()->getConfiguration();
        $triggers = isset($plugin_settings['trigger']) ? $plugin_settings['trigger'] : [];
        // Block config does not include option to enable
        // parent response trigger. Assuming to be used.
        $triggers['parent_response'] = TRUE;
      }
    }
    else {
      $triggers = $this->iframeSettings->get('trigger');
    }
    if ($triggers && is_array($triggers)) {
      foreach ($triggers as $trigger => $enabled) {
        if ($enabled && isset($trigger_libraries[$trigger])) {
          $libraries[] = $trigger_libraries[$trigger];
        }
      }
    }
    return $libraries;
  }

  /**
   * Sets proper CORS headers based on the given request.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The current request.
   * @param \Symfony\Component\HttpFoundation\Response $response
   *   The corresponding response.
   */
  protected function setCORSHeaders(Request $request, Response $response) {
    $response->setVary('Origin', FALSE);
    $host = $request->getSchemeAndHttpHost();
    $origin = $request->headers->has('Referer') && !$request->headers->has('Origin') ?
      Request::create($request->headers->get('Referer'))->getSchemeAndHttpHost() : $request->headers->get('Origin');

    // Support CORS for cached Accelerated Mobile Pages (AMP).
    if ($request->query->has('__amp_source_origin')) {
      $response->setVary('AMP-Same-Origin', FALSE);
      $source_origin = $request->query->get('__amp_source_origin');
      if (($source_origin !== $host) || !Unicode::validateUtf8($source_origin)) {
        return;
      }
      if ('true' === $request->headers->get('AMP-Same-Origin')) {
        $origin = $source_origin;
      }
    }

    if (empty($origin) || !Unicode::validateUtf8($origin)) {
      return;
    }

    $is_allowed = FALSE;
    $cors_allowed = $this->iframeSettings->get('cors_allowed');
    $cors_allowed[] = $host;
    $domain = parse_url($origin, PHP_URL_HOST);
    foreach ($cors_allowed as $whitelisted) {
      if ($origin === $whitelisted) {
        $is_allowed = TRUE;
        break;
      }
      elseif (strpos($whitelisted, '*') === 0) {
        $wildcard = str_replace('*', '', $whitelisted);
        if ('' === $wildcard) {
          $is_allowed = TRUE;
          $origin = '*';
          break;
        }
      }
      elseif (preg_match('/^(.*\.)*'.$domain.'+$/', $whitelisted)) {
        $is_allowed = TRUE;
        break;
      }
    }
    if (!$is_allowed) {
      return;
    }

    // Set headers to allow cross-origin resource sharing.
    $response->headers->set('Access-Control-Allow-Origin', $origin);
    $response->headers->set('Access-Control-Allow-Credentials', 'true');
    if (!empty($source_origin)) {
      $response->headers->set('Access-Control-Expose-Headers', 'AMP-Access-Control-Allow-Source-Origin');
      $response->headers->set('AMP-Access-Control-Allow-Source-Origin', $source_origin);
    }
  }

}

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

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