arch-8.x-1.x-dev/modules/product/modules/downloadable/src/ProductFileAccess.php

modules/product/modules/downloadable/src/ProductFileAccess.php
<?php

namespace Drupal\arch_downloadable_product;

use Drupal\arch_product\Entity\ProductInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\file\FileInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Product file access check.
 *
 * @package Drupal\arch_downloadable_product
 */
class ProductFileAccess implements ProductFileAccessInterface, ContainerInjectionInterface {

  /**
   * Database.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $db;

  /**
   * Product storage.
   *
   * @var \Drupal\arch_product\Entity\Storage\ProductStorageInterface
   */
  protected $productStorage;

  /**
   * File storage.
   *
   * @var \Drupal\file\FileStorageInterface
   */
  protected $fileStorage;

  /**
   * User storage.
   *
   * @var \Drupal\user\UserStorageInterface
   */
  protected $userStorage;

  /**
   * Download url builder.
   *
   * @var \Drupal\arch_downloadable_product\DownloadUrlBuilderInterface
   */
  protected $downloadUrlBuilder;

  /**
   * ProductFileAccess constructor.
   *
   * @param \Drupal\Core\Database\Connection $db
   *   Database.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager.
   * @param \Drupal\arch_downloadable_product\DownloadUrlBuilderInterface $download_url_builder
   *   Download url builder.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(
    Connection $db,
    EntityTypeManagerInterface $entity_type_manager,
    DownloadUrlBuilderInterface $download_url_builder,
  ) {
    $this->db = $db;
    $this->productStorage = $entity_type_manager->getStorage('product');
    $this->fileStorage = $entity_type_manager->getStorage('file');
    $this->userStorage = $entity_type_manager->getStorage('user');
    $this->downloadUrlBuilder = $download_url_builder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('database'),
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function check(ProductInterface $product, FileInterface $file, AccountInterface $user) {
    if (!$this->productHasFile($product, $file)) {
      return FALSE;
    }

    if (!$this->customerHasProduct($user, $product)) {
      return FALSE;
    }

    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function checkWithToken(ProductInterface $product, FileInterface $file, AccountInterface $account, $token_to_check) {
    if (!$this->check($product, $file, $account)) {
      return FALSE;
    }

    /** @var \Drupal\user\UserInterface $user */
    $user = $this->userStorage->load($account->id());
    $generated_token = $this->downloadUrlBuilder->getToken($product, $file, $user);
    return $token_to_check === $generated_token;
  }

  /**
   * {@inheritdoc}
   */
  public function checkByIds($product_id, $file_uuid, $user_uuid) {
    /** @var \Drupal\arch_product\Entity\ProductInterface $product */
    $product = $this->productStorage->load($product_id);
    if (!$product) {
      return FALSE;
    }
    /** @var \Drupal\file\FileInterface $file */
    $file = $this->loadFileByUuid($file_uuid);
    if (!$file) {
      return FALSE;
    }

    if (!$this->productHasFile($product, $file)) {
      return FALSE;
    }

    $user = $this->loadUserByUuid($user_uuid);
    if (!$user) {
      return FALSE;
    }

    if (!$this->customerHasProduct($user, $product)) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function checkByIdsWithToken($product_id, $file_uuid, $user_uuid, $token_to_check) {
    /** @var \Drupal\arch_product\Entity\ProductInterface $product */
    $product = $this->productStorage->load($product_id);
    if (!$product) {
      return FALSE;
    }
    /** @var \Drupal\file\FileInterface $file */
    $file = $this->loadFileByUuid($file_uuid);
    if (!$file) {
      return FALSE;
    }

    if (!$this->productHasFile($product, $file)) {
      return FALSE;
    }

    $user = $this->loadUserByUuid($user_uuid);
    if (!$user) {
      return FALSE;
    }

    if (!$this->customerHasProduct($user, $product)) {
      return FALSE;
    }

    $generated_token = $this->downloadUrlBuilder->getToken($product, $file, $user);
    return $token_to_check === $generated_token;
  }

  /**
   * Load product by ID.
   *
   * @param int $pid
   *   Product ID.
   *
   * @return \Drupal\arch_product\Entity\ProductInterface
   *   Product.
   */
  protected function loadProduct($pid) {
    /** @var \Drupal\arch_product\Entity\ProductInterface $product */
    $product = $this->productStorage->load($pid);
    return $product;
  }

  /**
   * Load file by UUID.
   *
   * @param string $file_uuid
   *   File UUID.
   *
   * @return \Drupal\file\FileInterface|null
   *   File instance or NULL on failure.
   */
  protected function loadFileByUuid($file_uuid) {
    $files = $this->fileStorage->loadByProperties([
      'uuid' => $file_uuid,
    ]);
    if (empty($files)) {
      return NULL;
    }

    return current($files);
  }

  /**
   * Load user by UUID.
   *
   * @param string $user_uuid
   *   User UUID.
   *
   * @return \Drupal\user\UserInterface|null
   *   User instance or NULL on failure.
   */
  protected function loadUserByUuid($user_uuid) {
    $users = $this->userStorage->loadByProperties([
      'uuid' => $user_uuid,
    ]);
    if (empty($users)) {
      return NULL;
    }

    return current($users);
  }

  /**
   * Get file of product by File UUID.
   *
   * @param \Drupal\arch_product\Entity\ProductInterface $product
   *   Product.
   * @param string $file_uuid
   *   File UUID.
   *
   * @return \Drupal\file\FileInterface|null
   *   Selected file or NULL on failure.
   */
  protected function getProductFile(ProductInterface $product, $file_uuid) {
    $file = $this->loadFileByUuid($file_uuid);
    if ($this->productHasFile($product, $file)) {
      return $file;
    }

    return NULL;
  }

  /**
   * Check product has given file as "product_file".
   *
   * @param \Drupal\arch_product\Entity\ProductInterface $product
   *   Product instance.
   * @param \Drupal\file\FileInterface $file
   *   File instance.
   *
   * @return bool
   *   Return TRUE if product has file in its "product_file" field.
   */
  protected function productHasFile(ProductInterface $product, FileInterface $file) {
    /** @var \Drupal\file\Plugin\Field\FieldType\FileFieldItemList $files */
    $files = $product->product_file;

    foreach ($files->referencedEntities() as $referenced_file) {
      /** @var \Drupal\file\FileInterface $referenced_file */
      if ($referenced_file->id() == $file->id()) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * Check customer already ordered given product.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Customer.
   * @param \Drupal\arch_product\Entity\ProductInterface $product
   *   Product.
   *
   * @return bool
   *   Returns TRUE if customer purchased product.
   */
  protected function customerHasProduct(AccountInterface $account, ProductInterface $product) {
    if ($account->isAnonymous()) {
      return FALSE;
    }

    $select = $this->db->select('arch_order', 'o');
    $select->distinct(TRUE);
    $select->leftJoin('order__line_items', 'l', 'o.oid = l.entity_id');
    $select->condition('o.uid', $account->id());
    $select->condition('o.status', 'completed');
    $select->condition('l.line_items_product_id', $product->id());
    $select->addField('o', 'oid');
    $order_ids = $select->execute()->fetchCol();
    return !empty($order_ids);
  }

}

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

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