Created
August 13, 2019 17:10
-
-
Save mglaman/2925bf398a35cc9c7fc1008ee65a7280 to your computer and use it in GitHub Desktop.
Destructable performance wins
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
services: | |
commerce_stripe.order_events_subscriber: | |
class: Drupal\commerce_stripe\EventSubscriber\OrderEventsSubscriber | |
arguments: ['@entity_type.manager'] | |
tags: | |
- { name: needs_destruction } | |
- { name: event_subscriber } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\commerce_stripe\EventSubscriber; | |
use Drupal\commerce_order\Event\OrderEvent; | |
use Drupal\commerce_order\Event\OrderEvents; | |
use Drupal\commerce_price\Calculator; | |
use Drupal\commerce_price\Price; | |
use Drupal\commerce_stripe\Plugin\Commerce\PaymentGateway\StripeInterface; | |
use Drupal\Core\DestructableInterface; | |
use Drupal\Core\Entity\EntityTypeManagerInterface; | |
use Stripe\Error\Base as StripeError; | |
use Stripe\PaymentIntent; | |
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
/** | |
* Subscribers to order events for the Stripe integration. | |
*/ | |
class OrderEventsSubscriber implements EventSubscriberInterface, DestructableInterface { | |
/** | |
* The entity type manager. | |
* | |
* @var \Drupal\Core\Entity\EntityTypeManagerInterface | |
*/ | |
protected $entityTypeManager; | |
/** | |
* The intent IDs that need updating. | |
* | |
* @var int[] | |
*/ | |
protected $updateList = []; | |
/** | |
* Constructs a new OrderEventsSubscriber object. | |
* | |
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager | |
* The entity type manager. | |
*/ | |
public function __construct(EntityTypeManagerInterface $entity_type_manager) { | |
$this->entityTypeManager = $entity_type_manager; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public static function getSubscribedEvents() { | |
return [ | |
OrderEvents::ORDER_UPDATE => 'onOrderUpdate', | |
]; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function destruct() { | |
foreach ($this->updateList as $intent_id => $amount) { | |
try { | |
PaymentIntent::update($intent_id, ['amount' => $amount]); | |
} | |
catch (StripeError $e) { | |
// Allow sync errors to silently fail. | |
} | |
} | |
} | |
/** | |
* Ensures the Stripe payment intent is up to date. | |
* | |
* @param \Drupal\commerce_order\Event\OrderEvent $event | |
* The event. | |
*/ | |
public function onOrderUpdate(OrderEvent $event) { | |
$order = $event->getOrder(); | |
$gateway = $order->get('payment_gateway'); | |
if ($gateway->isEmpty()) { | |
return; | |
} | |
$plugin = $gateway->entity->getPlugin(); | |
if (!$plugin instanceof StripeInterface) { | |
return; | |
} | |
$intent_id = $order->getData('stripe_intent'); | |
if ($intent_id !== NULL) { | |
$amount = $this->toMinorUnits($order->getTotalPrice()); | |
$this->updateList[$intent_id] = $amount; | |
} | |
} | |
/** | |
* Converts the given amount to its minor units. | |
* | |
* For example, 9.99 USD becomes 999. | |
* | |
* @todo Remove after https://www.drupal.org/node/2944281 is fixed. | |
* | |
* @param \Drupal\commerce_price\Price $amount | |
* The amount. | |
* | |
* @return int | |
* The amount in minor units, as an integer. | |
*/ | |
private function toMinorUnits(Price $amount) { | |
$currency_storage = $this->entityTypeManager->getStorage('commerce_currency'); | |
/** @var \Drupal\commerce_price\Entity\CurrencyInterface $currency */ | |
$currency = $currency_storage->load($amount->getCurrencyCode()); | |
$fraction_digits = $currency->getFractionDigits(); | |
$number = $amount->getNumber(); | |
if ($fraction_digits > 0) { | |
$number = Calculator::multiply($number, pow(10, $fraction_digits)); | |
} | |
return round($number, 0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment