contacts_subscriptions-1.x-dev/src/Event/SubscriptionProductVariationsEvent.php

src/Event/SubscriptionProductVariationsEvent.php
<?php

namespace Drupal\contacts_subscriptions\Event;

use Drupal\commerce_product\Entity\ProductVariationInterface;
use Drupal\Component\EventDispatcher\Event;
use Drupal\contacts_subscriptions\Entity\SubscriptionType;
use Drupal\Core\Entity\ContentEntityStorageInterface;
use Drupal\user\UserInterface;

/**
 * Event class for determining the product variations to use for subscriptions.
 */
class SubscriptionProductVariationsEvent extends Event {

  /**
   * The event name.
   */
  const NAME = 'contacts_subscription_get_product_variation';

  /**
   * Indicates that the specified variation suffix is preferred.
   */
  const VARIATION_PREFERRED = 'preferred';

  /**
   * Indicates the specified variation suffix is required.
   */
  const VARIATION_REQUIRED = 'required';

  /**
   * The product entity storage.
   *
   * @var \Drupal\Core\Entity\ContentEntityStorageInterface
   */
  protected ContentEntityStorageInterface $storage;

  /**
   * The variation SKU suffix.
   *
   * @var string|null
   */
  protected ?string $variationSuffix = NULL;

  /**
   * The strength of the variation suffix requirement.
   *
   * @var string
   */
  protected string $variationStrength = self::VARIATION_PREFERRED;

  /**
   * Products that are allowed.
   *
   * @var int[]
   */
  protected array $allowedProductIds = [];

  /**
   * Products that are dis-allowed.
   *
   * @var int[]
   */
  protected array $disallowedProductIds = [];

  /**
   * The user entity.
   *
   * @var \Drupal\user\UserInterface|null
   */
  protected ?UserInterface $user;

  /**
   * SubscriptionProductVariationEvent constructor.
   *
   * @param \Drupal\user\UserInterface|null $user
   *   The user entity, if any.
   * @param \Drupal\Core\Entity\ContentEntityStorageInterface $storage
   *   The product entity storage handler.
   * @param string|null $variation_suffix
   *   The variation suffix, if any, that we want. By default this will be a
   *   preference. To require a variation suffix, use `::setVariationStrength`.
   * @param string|null $subscription_type
   *   (Optional) The type of subscription.
   */
  public function __construct(
    ?UserInterface $user,
    ContentEntityStorageInterface $storage,
    ?string $variation_suffix = NULL,
    ?SubscriptionType $subscription_type = NULL
  ) {
    $this->storage = $storage;
    if ($variation_suffix) {
      $this->variationSuffix = "-{$variation_suffix}";
    }
    $this->user = $user;
  }

  /**
   * Get the organisation, if any.
   *
   * @return \Drupal\user\UserInterface|null
   *   The organisation or NULL.
   */
  public function getUser(): ?UserInterface {
    return $this->user;
  }

  /**
   * Get the variation suffix.
   *
   * @return string
   *   The variation suffix.
   */
  public function getVariationSuffix(): string {
    return $this->variationSuffix;
  }

  /**
   * Set the variation suffix.
   *
   * @param string|null $variationSuffix
   *   The variation suffix or NULL for none.
   *
   * @return $this
   */
  public function setVariationSuffix(?string $variationSuffix) {
    $this->variationSuffix = $variationSuffix;
    return $this;
  }

  /**
   * Get the strength of the variation suffix.
   *
   * @return string
   *   One of the self::VARIATION_* constants.
   */
  public function getVariationStrength(): string {
    return $this->variationStrength;
  }

  /**
   * Set the strength of the variation suffix.
   *
   * @param string $variationStrength
   *   One of the self::VARIATION_* constants.
   *
   * @return $this
   */
  public function setVariationStrength(string $variationStrength) {
    $this->variationStrength = $variationStrength;
    return $this;
  }

  /**
   * Allowed products.
   *
   * @param int[] $product_ids
   *   The product IDs to allow.
   * @param bool $override_disallowed
   *   Whether to override a previous dis-allowance. Defaults to FALSE.
   *
   * @return $this
   */
  public function allowProducts(array $product_ids, bool $override_disallowed = FALSE) {
    // Clear from dis-allowed if overriding.
    if ($override_disallowed) {
      $this->disallowedProductIds = array_diff($this->disallowedProductIds, $product_ids);
    }
    // Otherwise, remove disallowed items.
    else {
      $product_ids = array_diff($product_ids, $this->disallowedProductIds);
    }

    if (!empty($product_ids)) {
      // Remove anything that would cause a duplicate.
      $product_ids = array_diff($product_ids, $this->allowedProductIds);

      // Add in the remaining product IDs.
      if (!empty($product_ids)) {
        $this->allowedProductIds = array_merge($this->allowedProductIds, $product_ids);
      }
    }

    return $this;
  }

  /**
   * Dis-allow products types.
   *
   * @param int[] $product_ids
   *   The product IDs to dis-allow.
   *
   * @return $this
   */
  public function disallowProducts(array $product_ids) {
    // Remove anything that would cause a duplicate.
    $product_ids = array_diff($product_ids, $this->disallowedProductIds);

    if (!empty($product_ids)) {
      // Add in the remaining product IDs.
      $this->disallowedProductIds = array_merge($this->disallowedProductIds, $product_ids);

      // Clean up the allowed list.
      $this->allowedProductIds = array_diff($this->allowedProductIds, $this->disallowedProductIds);
    }

    return $this;
  }

  /**
   * Get the available product variations.
   *
   * @return \Drupal\commerce_product\Entity\ProductVariationInterface[]
   *   The product variations, keyed by product ID.
   */
  public function getProductVariations(): array {
    /** @var \Drupal\commerce_product\Entity\ProductInterface[] $products */
    $products = $this->storage->loadMultiple($this->allowedProductIds);
    $variations = [];

    // Loop over the allowed products.
    foreach ($products as $product_id => $product) {
      // Get all the variations for this product and filter them. We will also
      // explicitly track a matching suffix.
      $variation_with_suffix = NULL;

      // We use an anonymous function as we need to use $variation_with_suffix,
      // which can't be done via a method as the callback. However, we do want
      // to use a callback so extending classes can override the filter.
      $product_variations = array_filter($product->getVariations(), function (ProductVariationInterface $variation) use (&$variation_with_suffix) {
        return $this->filterVariation($variation, $variation_with_suffix);
      });

      // If we have a suffix match, use it.
      if ($variation_with_suffix) {
        $variations[$product_id] = $variation_with_suffix;
      }
      // Otherwise, if we have any matches and only prefer the suffix, we use
      // the first of our matches.
      elseif ($this->variationStrength === self::VARIATION_PREFERRED && $product_variations) {
        $variations[$product_id] = reset($product_variations);
      }
    }

    return $variations;
  }

  /**
   * Check whether a variation is suitable.
   *
   * @param \Drupal\commerce_product\Entity\ProductVariationInterface $variation
   *   The variation we are checking.
   * @param \Drupal\commerce_product\Entity\ProductVariationInterface|null $variation_with_suffix
   *   Variable by reference to store the first variation that matches the
   *   specified suffix.
   *
   * @return bool
   *   Whether the variation should be included in the possible matches.
   */
  protected function filterVariation(ProductVariationInterface $variation, ?ProductVariationInterface &$variation_with_suffix): bool {
    if ($variation->getProduct()->bundle() !== 'subscription') {
      return FALSE;
    }

    // Only include published products.
    if (!$variation->isPublished()) {
      return FALSE;
    }

    // Ensure we have access.
    if (!$variation->access('view')) {
      return FALSE;
    }

    // If we have an exact match on suffix, track it.
    if ($this->variationSuffix && substr($variation->getSku(), -strlen($this->variationSuffix)) === $this->variationSuffix) {
      $variation_with_suffix = $variation;
    }

    return TRUE;
  }

}

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

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