commerce_license-8.x-2.x-dev/src/Plugin/Commerce/SubscriptionType/LicenseSubscription.php
src/Plugin/Commerce/SubscriptionType/LicenseSubscription.php
<?php namespace Drupal\commerce_license\Plugin\Commerce\SubscriptionType; use Drupal\commerce_order\Entity\OrderInterface; use Drupal\commerce_order\Entity\OrderItemInterface; use Drupal\commerce_recurring\Entity\SubscriptionInterface; use Drupal\commerce_recurring\Plugin\Commerce\SubscriptionType\SubscriptionTypeBase; use Drupal\entity\BundleFieldDefinition; /** * Provides a Commerce Recurring subscription type for use with licenses. * * @CommerceSubscriptionType( * id = "license", * label = @Translation("License"), * purchasable_entity_type = "commerce_product_variation", * ) */ class LicenseSubscription extends SubscriptionTypeBase { /** * {@inheritdoc} */ public function onSubscriptionCreate(SubscriptionInterface $subscription, OrderItemInterface $order_item) { $purchased_entity = $subscription->getPurchasedEntity(); // Ensure that the order item being used has the license trait, otherwise // the license won't get handled properly. if (!$order_item->hasField('license')) { throw new \RuntimeException(sprintf('Order item type %s used for product variation %s is missing the license field.', $order_item->bundle(), $purchased_entity->id() )); } // The order item should already have a license set, as our // \Drupal\commerce_license\EventSubscriber\OrderSubscriber's // commerce_order.place.pre_transition listener // should run before Commerce Recurring's // \Drupal\commerce_recurring\EventSubscriber\EventSubscriber listener, // which is what then creates the subscription. if (empty($order_item->license->entity)) { // Something's gone wrong: either other code has changed priorities, or // the modules' relative priorities have become out of sync due to changes // in code. throw new \RuntimeException(sprintf("Attempt to create a license subscription with order item ID %s that doesn't have a license.", $order_item->id() )); } // Get the license the order item refers to. $license = $order_item->license->entity; // Ensure that the license expiry is unlimited. if ($license->expiration_type->target_plugin_id !== 'unlimited') { throw new \RuntimeException(sprintf('Invalid expiry type %s on product variation %s', $license->expiration_type->target_plugin_id, $purchased_entity->id() )); } // Set the license on the subscription, but don't save the subscription, as // it's currently only being created by the storage handler. $subscription->license = $license; } /** * {@inheritdoc} */ public function onSubscriptionActivate(SubscriptionInterface $subscription, OrderInterface $order) { // We don't need to do anything here, as LicenseOrderSyncSubscriber takes // care of activating the license in an initial order with a subscription. } /** * {@inheritdoc} */ public function onSubscriptionRenew(SubscriptionInterface $subscription, OrderInterface $order, OrderInterface $next_order) { $license = $subscription->license->entity; if (!$license) { return; } // Change the license's renewed time and save it. // Use the subscription's renewed time rather than the current time to // ensure the timestamps are in sync. $license->setRenewedTime($subscription->getRenewedTime()); $license->save(); } /** * {@inheritdoc} */ public function onSubscriptionExpire(SubscriptionInterface $subscription) { /** @var \Drupal\commerce_license\Entity\LicenseInterface $license */ $license = $subscription->license->entity; if (!$license) { return; } // Change the license's state to expired. // The License entity will handle deactivating the license type plugin. if ($license->getState()->isTransitionAllowed('expire')) { $license->getState()->applyTransitionById('expire'); $license->save(); } } /** * {@inheritdoc} */ public function onSubscriptionCancel(SubscriptionInterface $subscription) { /** @var \Drupal\commerce_license\Entity\LicenseInterface $license */ $license = $subscription->license->entity; if (!$license) { return; } // Change the license's state to canceled. if ($license->getState()->isTransitionAllowed('cancel')) { $license->getState()->applyTransitionById('cancel'); $license->save(); } } /** * {@inheritdoc} */ public function buildFieldDefinitions() { $fields = parent::buildFieldDefinitions(); $fields['license'] = BundleFieldDefinition::create('entity_reference') ->setLabel($this->t('License')) ->setDescription($this->t('The license this subscription controls.')) ->setCardinality(1) ->setRequired(TRUE) ->setSetting('target_type', 'commerce_license') ->setDisplayConfigurable('view', TRUE) ->setDisplayConfigurable('form', TRUE) ->setDisplayOptions('view', [ 'label' => 'above', 'type' => 'entity_reference_label', 'weight' => 1, 'settings' => [ 'link' => TRUE, ], ]); return $fields; } }