apigee_m10n-8.x-1.7/src/Entity/PurchasedProduct.php

src/Entity/PurchasedProduct.php
<?php

/*
 * Copyright 2021 Google Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
 * License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

namespace Drupal\apigee_m10n\Entity;

use Apigee\Edge\Api\ApigeeX\Entity\AcceptedRatePlan;
use Apigee\Edge\Api\ApigeeX\Entity\DeveloperAcceptedRatePlan;
use Apigee\Edge\Api\Monetization\Entity\DeveloperInterface;
use Apigee\Edge\Entity\EntityInterface as EdgeEntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\apigee_edge\Entity\FieldableEdgeEntityBase;
use Drupal\apigee_m10n\Entity\Property\ApiProductPropertyAwareDecoratorTrait;
use Drupal\apigee_m10n\Entity\Property\EndTimePropertyAwareDecoratorTrait;
use Drupal\apigee_m10n\Entity\Property\NamePropertyAwareDecoratorTrait;
use Drupal\apigee_m10n\Entity\Property\StartTimePropertyAwareDecoratorTrait;
use Drupal\apigee_m10n\Entity\XRatePlanInterface as DrupalRatePlanInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\user\UserInterface;

/**
 * Defines the `purchased_product` entity class.
 *
 * @\Drupal\apigee_edge\Annotation\EdgeEntityType(
 *   id             = "purchased_product",
 *   label          = @Translation("Purchased Product"),
 *   label_singular = @Translation("Subscription"),
 *   label_plural   = @Translation("Subscriptions"),
 *   label_count = @PluralTranslation(
 *     singular = "@count Subscription",
 *     plural   = "@count Subscriptions",
 *   ),
 *   handlers = {
 *     "storage"             = "Drupal\apigee_m10n\Entity\Storage\PurchasedProductStorage",
 *     "access"              = "Drupal\apigee_m10n\Entity\Access\PurchasedProductUpdateAccessControlHandler",
 *     "permission_provider" = "Drupal\apigee_m10n\Entity\Permissions\PurchasedProductPermissionProvider",
 *     "list_builder"        = "Drupal\apigee_m10n\Entity\ListBuilder\PurchasedProductListBuilder",
 *     "form" = {
 *       "default" = "Drupal\apigee_m10n\Entity\Form\PurchasedProductForm",
 *       "cancel"  = "Drupal\apigee_m10n\Entity\Form\CancelPurchasedProductConfirmForm",
 *     },
 *   },
 *   links = {
 *     "developer_product_collection" = "/user/{user}/monetization/purchased-product",
 *   },
 *   entity_keys = {
 *     "id" = "id",
 *   },
 *   admin_permission       = "administer apigee monetization",
 *   field_ui_base_route    = "apigee_m10n.settings.purchased_product",
 * )
 */
#[\AllowDynamicProperties]
class PurchasedProduct extends FieldableEdgeEntityBase implements PurchasedProductInterface, EntityOwnerInterface {

  use EndTimePropertyAwareDecoratorTrait;
  use StartTimePropertyAwareDecoratorTrait;
  use ApiProductPropertyAwareDecoratorTrait;
  use NamePropertyAwareDecoratorTrait;

  public const ENTITY_TYPE_ID = 'purchased_product';

  /**
   * The owner's user entity.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $owner;

  /**
   * Suppress errors if rate plan that overlaps another accepted rate plan.
   *
   * @var bool
   */
  protected $suppressWarning;

  /**
   * The currently logged-in user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  private $currentUser;

  /**
   * The rate plan this purchased_product belongs to.
   *
   * @var \Drupal\apigee_m10n\Entity\XRatePlanInterface
   */
  protected $rate_plan;

  /**
   * Constructs a `purchased_product` entity.
   *
   * @param array $values
   *   An array of values to set, keyed by property name.
   * @param null|string $entity_type
   *   Type of the entity. It is optional because constructor sets its default
   *   value.
   * @param \Apigee\Edge\Entity\EntityInterface|null $decorated
   *   The SDK entity that this Drupal entity decorates.
   *
   * @throws \ReflectionException
   */
  public function __construct(array $values, ?string $entity_type = NULL, ?EdgeEntityInterface $decorated = NULL) {
    /** @var \Apigee\Edge\Api\Management\Entity\DeveloperAppInterface $decorated */
    $entity_type = $entity_type ?? static::ENTITY_TYPE_ID;
    parent::__construct($values, $entity_type, $decorated);

    if (!empty($values['xratePlan']) && $values['xratePlan'] instanceof DrupalRatePlanInterface) {
      // @todo Since `RatePlan::createFrom($sdk_rate_plan)` is available do we
      // need to store an extra reference here. Is the slight performance
      // benefit worth it?
      $this->setRatePlan($values['xratePlan']);
    }

    // Do not suppress warnings by default.
    $this->suppressWarning = FALSE;
    $this->currentUser = \Drupal::currentUser();
  }

  /**
   * {@inheritdoc}
   */
  protected static function decoratedClass(): string {
    return DeveloperAcceptedRatePlan::class;
  }

  /**
   * {@inheritdoc}
   */
  public static function idProperty(): string {
    return AcceptedRatePlan::idProperty();
  }

  /**
   * {@inheritdoc}
   */
  protected static function propertyToBaseFieldTypeMap(): array {
    return [
      'developer'            => 'apigee_monetization_developer',
      'ratePlan'             => 'entity_reference',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    /** @var \Drupal\Core\Field\BaseFieldDefinition[] $definitions */
    $definitions = parent::baseFieldDefinitions($entity_type);

    // The following fields should not be configurable through the UI.
    $read_only_fields = [
      'id',
      'developer',
      'name',
      'apiProduct',
      'ratePlan',
    ];
    // Disable the form display entry for all read only fields.
    foreach ($read_only_fields as $field_name) {
      $definitions[$field_name]->setDisplayConfigurable('form', FALSE);
    }

    // Set the target_type for ratePlan base field.
    $definitions['ratePlan']->setSetting('target_type', 'rate_plan');

    return $definitions;
  }

  /**
   * {@inheritdoc}
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public static function loadByDeveloperId(string $developer_id): array {

    return \Drupal::entityTypeManager()
      ->getStorage(static::ENTITY_TYPE_ID)
      ->loadByDeveloperId($developer_id);
  }

  /**
   * {@inheritdoc}
   */
  public function toUrl($rel = 'canonical', array $options = []) {
    // The string formatter assumes entities are revisionable.
    $rel = ($rel === 'revision') ? 'canonical' : $rel;
    // Use the developer collection as the default collection.
    $rel = ($rel === 'collection') ? 'developer_product_collection' : $rel;
    // Build the URL.
    $url = parent::toUrl($rel, $options);
    // Add the user parameter to any routes that require it.
    if ($rel == 'developer_product_collection') {
      // Strip the `purchased_product` parameter from the collection.
      $url->setRouteParameters(array_diff_key($url->getRouteParameters(), ['purchased_product' => NULL]));
      // Set the developer's user ID.
      $url->setRouteParameter('user', $this->getOwnerId());
    }

    return $url;
  }

  /**
   * {@inheritdoc}
   */
  protected function drupalEntityId(): ?string {
    return $this->getId();
  }

  /**
   * {@inheritdoc}
   */
  public function getId(): ?string {
    return $this->decorated->getId();
  }

  /**
   * {@inheritdoc}
   */
  public function isActive(): bool {
    return ($this->getStatus() === PurchasedProductInterface::STATUS_ACTIVE
      || $this->getStatus() === PurchasedProductInterface::STATUS_FUTURE);
  }

  /**
   * {@inheritdoc}
   */
  public function getStatus(): string {
    // Get Current UTC timestamp & Transform timeRange to the required format and time zone.
    $utc = new \DateTimeZone('UTC');
    $currentTimestamp = (new \DateTimeImmutable())->setTimezone($utc);
    $currentTimestamp = (int) ($currentTimestamp->getTimestamp() . $currentTimestamp->format('v'));
    // If subscription ended before today, the status is ended.
    $subscription_end_time = $this->getEndTime();
    if (!empty($subscription_end_time) && $subscription_end_time < $currentTimestamp) {
      return PurchasedProductInterface::STATUS_ENDED;
    }

    return PurchasedProductInterface::STATUS_ACTIVE;
  }

  /**
   * {@inheritdoc}
   */
  public function getLastModifiedAt(): ?string {
    return $this->decorated->getLastModifiedAt();
  }

  /**
   * {@inheritdoc}
   */
  public function getCreatedAt(): ?string {
    return $this->decorated->getCreatedAt();
  }

  /**
   * {@inheritdoc}
   */
  public function getDeveloper(): ?DeveloperInterface {
    $currentUserId = $this->currentUser;
    // @todo Return the `apigee_edge` developer entity reference.
    return $this->decorated->getDeveloper($currentUserId);
  }

  /**
   * {@inheritdoc}
   */
  public function getDeveloperEmail(): ?string {
    $currentUserEmailId = $this->currentUser->getEmail();
    return $currentUserEmailId;
  }

  /**
   * {@inheritdoc}
   */
  public function getRatePlan(): ?XRatePlanInterface {
    // Return the drupal entity for entity references.
    if (empty($this->rate_plan) && !empty($this->decorated()) && $sdk_rate_plan = $this->decorated()->getRatePlan()) {
      /** @var \Apigee\Edge\Api\ApigeeX\Entity\RatePlanInterface $sdk_rate_plan */
      $this->rate_plan = XRatePlan::createFrom($sdk_rate_plan);
    }

    return $this->rate_plan;
  }

  /**
   * {@inheritdoc}
   */
  public function setRatePlan(XRatePlanInterface $ratePlan): void {
    $this->rate_plan = $ratePlan;
    $this->decorated->setRatePlan($ratePlan->decorated());
  }

  /**
   * {@inheritdoc}
   */
  public function getActiveRatePlans(): ?array {
    $activeRatePlanId = [];
    // Return all the active rate plan Id.
    $activeRatePlans = XRatePlan::loadRatePlansByProduct('-');
    foreach ($activeRatePlans as $key => $value) {
      $activeRatePlanId[$value->decorated()->getApiProduct()] = $value->decorated()->id();
    }
    return $activeRatePlanId;
  }

  /**
   * Gets the monetization service.
   *
   * This gets the monetization service as needed avoiding loading the SDK
   * connector during bootstrap.
   *
   * @return \Drupal\apigee_m10n\MonetizationInterface
   *   The monetization service.
   */
  protected function monetization() {
    return \Drupal::service('apigee_m10n.monetization');
  }

  /**
   * {@inheritdoc}
   */
  public function getOwner() {
    $currentUserEmailId = $this->currentUser->getEmail();
    if (!isset($this->owner)) {
      $owner = $this->entityTypeManager()->getStorage('user')->loadByProperties([
        'mail' => $currentUserEmailId,
      ]);

      $this->owner = !empty($owner) ? reset($owner) : NULL;
    }
    return $this->owner;
  }

  /**
   * {@inheritdoc}
   */
  public function getCurrentOwnerId() {
    if (!isset($this->owner)) {
      $owner = $this->entityTypeManager()->getStorage('user')->loadByProperties([
        'mail' => $this->getDeveloperEmail(),
      ]);
      $this->owner = !empty($owner) ? reset($owner) : NULL;
    }

    return ($owner = $this->owner) ? $owner->id() : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwnerId() {
    return ($owner = $this->getOwner()) ? $owner->id() : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwnerId($uid) {
    // The owner is not settable after instantiation.
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwner(UserInterface $account) {
    // The owner is not settable after instantiation.
    return $this;
  }

}

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

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