Skip to content

Instantly share code, notes, and snippets.

@nikathone
Last active November 21, 2019 22:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nikathone/9f0f71f345bc20a8371eb58a5700d146 to your computer and use it in GitHub Desktop.
Save nikathone/9f0f71f345bc20a8371eb58a5700d146 to your computer and use it in GitHub Desktop.
Customization for revoking a subscription/Commerce recurring
<?php
/**
* @file
* Contains custom_commerce_recurring.module.
*/
use Drupal\commerce_recurring\Entity\SubscriptionInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_entity_base_field_info_alter().
*/
function custom_commerce_recurring_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
if ($entity_type->id() == 'commerce_subscription' && !empty($fields['state'])) {
$fields['state']->setSetting('workflow', 'subscription_default_revoke');
}
}
/**
* Implements hook_form_FORM_ID_alter() for commerce_subscription_license_edit_form.
*/
function custom_commerce_recurring_form_commerce_subscription_license_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Attaching core form library which help to prevent double submit.
$form['#attached']['library'][] = 'core/drupal.form';
$actions = &$form['actions'];
$subscription = $form_state->getFormObject()->getEntity();
$state = $subscription->getState()->value;
$actions['revoke'] = [
'#type' => 'submit',
'#value' => t('Revoke subscription'),
'#submit' => ['custom_commerce_recurring_revoke_submit'],
'#access' => $state != 'revoked' && $state != 'pending' && $state != 'canceled',
];
}
/**
* Revoke submit callback.
*/
function custom_commerce_recurring_revoke_submit(array &$form, FormStateInterface $form_state) {
/** @var \Drupal\commerce_recurring\Entity\SubscriptionInterface $subscription */
$subscription = $form_state->getFormObject()->getEntity();
if ($subscription instanceof SubscriptionInterface) {
$transition = $subscription->getState()->getWorkflow()->getTransition('revoke');
$subscription->getState()->applyTransition($transition);
$subscription->save();
\Drupal::messenger()->addMessage(t('A subscription has been successfully revoked and it will not be renewed.'));
$form_state->setRedirect('entity.commerce_subscription.collection');
}
}
services:
custom_commerce_recurring.order_manager:
class: \Drupal\custom_commerce_recurring\RecurringOrderManager
decorates: commerce_recurring.order_manager
decoration_priority: -99
arguments: ['@custom_commerce_recurring.order_manager.inner', '@entity_type.manager', '@datetime.time']
subscription_default_revoke:
id: subscription_default_revoke
group: commerce_subscription
label: 'Default, with revoke'
states:
pending:
label: Pending
active:
label: Active
revoked:
label: Revoked
expired:
label: Expired
canceled:
label: Canceled
transitions:
activate:
label: Activate
from: [pending]
to: active
revoke:
label: Revoke
from: [active]
to: revoked
expire:
label: Expire
from: [active]
to: expired
cancel:
label: Cancel
from: [active]
to: canceled
reactivate:
label: Reactivate
from: [revoked]
to: active
<?php
namespace Drupal\custom_commerce_recurring;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_recurring\RecurringOrderManager as BaseRecurringOrderManager;
use Drupal\commerce_recurring\RecurringOrderManagerInterface;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Overrides the default recurring order manager.
*/
class RecurringOrderManager extends BaseRecurringOrderManager {
/**
* The recurring order manager.
*
* @var \Drupal\commerce_recurring\RecurringOrderManagerInterface
*/
protected $recurringOrderManager;
/**
* Constructs a new RecurringOrderManager object.
*
* @param \Drupal\commerce_recurring\RecurringOrderManagerInterface $recurring_order_manager
* The recurring order manager.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time.
*/
public function __construct(RecurringOrderManagerInterface $recurring_order_manager, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
$this->recurringOrderManager = $recurring_order_manager;
parent::__construct($entity_type_manager, $time);
}
/**
* {@inheritdoc}
*/
public function closeOrder(OrderInterface $order) {
$subscriptions = $this->recurringOrderManager->collectSubscriptions($order);
/** @var \Drupal\commerce_recurring\Entity\SubscriptionInterface $subscription */
$subscription = reset($subscriptions);
/** @var \Drupal\state_machine\Plugin\Field\FieldType\StateItemInterface $subscription_state */
$subscription_state = $subscription ? $subscription->getState() : NULL;
// When a subscription is revoked then on close we cancel it.
if ($subscription_state->value == 'revoked') {
// Cancelling the order.
$transition = $order->getState()->getWorkflow()->getTransition('cancel');
$order->getState()->applyTransition($transition);
$order->save();
// Cancelling the subscription.
$transition = $subscription_state->getWorkflow()->getTransition('cancel');
$subscription->getState()->applyTransition($transition);
$subscription->save();
return;
}
$this->recurringOrderManager->closeOrder($order);
}
}
@nikathone
Copy link
Author

nikathone commented Sep 12, 2018

This part can be skipped if someone doesn't want to provide a revoke submission button on subscription edit form.

/**
 * Implements hook_form_FORM_ID_alter() for commerce_subscription_license_edit_form.
 */
function custom_commerce_recurring_form_commerce_subscription_license_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Attaching core form library which help to prevent double submit.
  $form['#attached']['library'][] = 'core/drupal.form';
  $actions = &$form['actions'];
  $subscription = $form_state->getFormObject()->getEntity();
  $state = $subscription->getState()->value;
  $actions['revoke'] = [
    '#type' => 'submit',
    '#value' => t('Revoke subscription'),
    '#submit' => ['custom_commerce_recurring_revoke_submit'],
    '#access' => $state != 'revoked' && $state != 'pending' && $state != 'canceled',
  ];
}

/**
 * Revoke submit callback.
 */
function custom_commerce_recurring_revoke_submit(array &$form, FormStateInterface $form_state) {
  /** @var \Drupal\commerce_recurring\Entity\SubscriptionInterface $subscription */
  $subscription = $form_state->getFormObject()->getEntity();
  if ($subscription instanceof SubscriptionInterface) {
    $transition = $subscription->getState()->getWorkflow()->getTransition('revoke');
    $subscription->getState()->applyTransition($transition);
    $subscription->save();
    \Drupal::messenger()->addMessage(t('A subscription has been successfully revoked and it will not be renewed.'));
    $form_state->setRedirect('entity.commerce_subscription.collection');
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment