contacts_subscriptions-1.x-dev/src/Plugin/QueueWorker/GenerateRenewals.php
src/Plugin/QueueWorker/GenerateRenewals.php
<?php
namespace Drupal\contacts_subscriptions\Plugin\QueueWorker;
use Drupal\Component\Datetime\Time;
use Drupal\contacts_subscriptions\Entity\SubscriptionInterface;
use Drupal\contacts_subscriptions\InvoiceManager;
use Drupal\Core\Entity\ContentEntityStorageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueWorkerBase;
use Drupal\Core\Session\AccountProxy;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Queue worker to generate renewals.
*
* @QueueWorker(
* id = "contacts_subscription_generate_renewals",
* title = @Translation("Generate subscription renewals"),
* cron = {"time" = 30}
* )
*/
class GenerateRenewals extends QueueWorkerBase implements ContainerFactoryPluginInterface {
/**
* The user entity storage handler.
*
* @var \Drupal\Core\Entity\ContentEntityStorageInterface
*/
protected ContentEntityStorageInterface $subscriptionStorage;
/**
* The subscription invoice manager.
*
* @var \Drupal\contacts_subscriptions\InvoiceManager
*/
protected InvoiceManager $invoiceManager;
/**
* A time service.
*
* @var \Drupal\Component\Datetime\Time
*/
protected Time $time;
/**
* Current user.
*
* @var \Drupal\Core\Session\AccountProxy
*/
protected AccountProxy $currentUser;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$plugin = new static($configuration, $plugin_id, $plugin_definition);
$plugin->subscriptionStorage = $container->get('entity_type.manager')->getStorage('contacts_subscription');
$plugin->invoiceManager = $container->get('contacts_subscriptions.invoice_manager');
$plugin->time = $container->get('datetime.time');
$plugin->currentUser = $container->get('current_user');
return $plugin;
}
/**
* {@inheritdoc}
*/
public function processItem($data) {
/** @var \Drupal\contacts_subscriptions\Entity\SubscriptionInterface $subscription */
if ($subscription = $this->subscriptionStorage->load($data)) {
try {
// We can only auto renew subscriptions that are currently active, as
// other statuses require intervention from the subscription holder.
if ($subscription->willAutoRenew()) {
$failed = !$this->invoiceManager->generateInvoice($subscription);
$transition = NULL;
}
else {
// Won't renew so we will transition to prevent further attempts.
$failed = TRUE;
$transition = 'cancel_renewal';
}
}
catch (\Exception $e) {
$failed = TRUE;
$transition = 'payment_failed';
}
if ($failed && $transition) {
// Transition may hae already been applied by order subscribers, so
// we'll use a function to check if the transition is allowed.
$this->applyTransitionIfAllowed($subscription, $transition);
}
}
}
/**
* Apply a subscription transition, if allowed.
*
* @param \Drupal\contacts_subscriptions\Entity\SubscriptionInterface $subscription
* The subscription.
* @param string $transition_id
* The transition ID to apply.
* @param bool $save
* Whether to save if the transition is applied.
*
* @return bool
* Whether the transition was applied.
*/
protected function applyTransitionIfAllowed(SubscriptionInterface $subscription, string $transition_id, bool $save = TRUE): bool {
/** @var \Drupal\state_machine\Plugin\Field\FieldType\StateItemInterface $state */
$state = $subscription->get('status')->first();
$workflow = $state->getWorkflow();
$transitions = $workflow->getAllowedTransitions($state->value, $subscription);
if (!isset($transitions[$transition_id])) {
return FALSE;
}
$subscription->setNewRevision();
$subscription->setRevisionCreationTime($this->time->getCurrentTime());
$subscription->setRevisionUserId($this->currentUser->id());
$state->applyTransition($transitions[$transition_id]);
if ($save) {
$subscription->save();
}
return TRUE;
}
}
