diff --git a/modules/payment/src/Entity/Payment.php b/modules/payment/src/Entity/Payment.php index 01fbe95556..0fbf220bb2 100644 --- a/modules/payment/src/Entity/Payment.php +++ b/modules/payment/src/Entity/Payment.php @@ -25,6 +25,7 @@ * bundle_label = @Translation("Payment type"), * bundle_plugin_type = "commerce_payment_type", * handlers = { + * "event" = "Drupal\commerce_payment\Event\PaymentEvent", * "access" = "Drupal\commerce_payment\PaymentAccessControlHandler", * "list_builder" = "Drupal\commerce_payment\PaymentListBuilder", * "storage" = "Drupal\commerce_payment\PaymentStorage", diff --git a/modules/payment/src/Event/PaymentEvent.php b/modules/payment/src/Event/PaymentEvent.php new file mode 100644 index 0000000000..fec57891ec --- /dev/null +++ b/modules/payment/src/Event/PaymentEvent.php @@ -0,0 +1,42 @@ +payment = $payment; + } + + /** + * Gets the payment. + * + * @return \Drupal\commerce_payment\Entity\PaymentInterface + * Gets the payment. + */ + public function getEntity() { + return $this->payment; + } + +} diff --git a/modules/payment/src/Event/PaymentEvents.php b/modules/payment/src/Event/PaymentEvents.php index 9a4abfeab3..10f263946b 100644 --- a/modules/payment/src/Event/PaymentEvents.php +++ b/modules/payment/src/Event/PaymentEvents.php @@ -4,6 +4,71 @@ final class PaymentEvents { + /** + * Name of the event fired after loading an payment. + * + * @Event + * + * @see \Drupal\commerce_payment\Event\PaymentEvent + */ + const PAYMENT_LOAD = 'commerce_payment.commerce_payment.load'; + + /** + * Name of the event fired after creating a new payment. + * + * Fired before the payment is saved. + * + * @Event + * + * @see \Drupal\commerce_payment\Event\PaymentEvent + */ + const PAYMENT_CREATE = 'commerce_payment.commerce_payment.create'; + + /** + * Name of the event fired before saving an payment. + * + * @Event + * + * @see \Drupal\commerce_payment\Event\PaymentEvent + */ + const PAYMENT_PRESAVE = 'commerce_payment.commerce_payment.presave'; + + /** + * Name of the event fired after saving a new payment. + * + * @Event + * + * @see \Drupal\commerce_payment\Event\PaymentEvent + */ + const PAYMENT_INSERT = 'commerce_payment.commerce_payment.insert'; + + /** + * Name of the event fired after saving an existing payment. + * + * @Event + * + * @see \Drupal\commerce_payment\Event\PaymentEvent + */ + const PAYMENT_UPDATE = 'commerce_payment.commerce_payment.update'; + + /** + * Name of the event fired before deleting an payment. + * + * @Event + * + * @see \Drupal\commerce_payment\Event\PaymentEvent + */ + const PAYMENT_PREDELETE = 'commerce_payment.commerce_payment.predelete'; + + /** + * Name of the event fired after deleting an payment. + * + * @Event + * + * @see \Drupal\commerce_payment\Event\PaymentEvent + */ + const PAYMENT_DELETE = 'commerce_payment.commerce_payment.delete'; + /** * Name of the event fired when payment gateways are loaded for an order. * diff --git a/modules/payment/src/PaymentStorage.php b/modules/payment/src/PaymentStorage.php index f59d567fed..3af30cedf6 100644 --- a/modules/payment/src/PaymentStorage.php +++ b/modules/payment/src/PaymentStorage.php @@ -4,6 +4,9 @@ use Drupal\commerce\CommerceContentEntityStorage; use Drupal\commerce_order\Entity\OrderInterface; +use Drupal\commerce_payment\Entity\PaymentInterface; +use Drupal\commerce_payment\Event\PaymentEvent; +use Drupal\commerce_payment\Event\PaymentEvents; use Drupal\Core\Entity\EntityStorageException; /** @@ -53,7 +56,25 @@ protected function doCreate(array $values) { $values['type'] = $payment_type->getPluginId(); } - return parent::doCreate($values); + $payment = parent::doCreate($values); + + $this->dispatchPaymentEvent($payment, PaymentEvents::PAYMENT_CREATE); + + return $payment; + } + + /** + * Notifies other modules about payment events. + * + * @param \Drupal\commerce_payment\Entity\PaymentInterface $payment + * The payment. + * @param string $event_id + * The event identifier defined in + * \Drupal\commerce_payment\Event\PaymentEvents. + */ + public function dispatchPaymentEvent(PaymentInterface $payment, $event_id) { + $event = new PaymentEvent($payment); + $this->eventDispatcher->dispatch($event_id, $event); } } diff --git a/modules/payment/tests/modules/payment_events_test/payment_events_test.info.yml b/modules/payment/tests/modules/payment_events_test/payment_events_test.info.yml new file mode 100644 index 0000000000..604ef369cc --- /dev/null +++ b/modules/payment/tests/modules/payment_events_test/payment_events_test.info.yml @@ -0,0 +1,4 @@ +name: 'Configuration events test' +type: module +package: Testing +core: 8.x diff --git a/modules/payment/tests/modules/payment_events_test/payment_events_test.services.yml b/modules/payment/tests/modules/payment_events_test/payment_events_test.services.yml new file mode 100644 index 0000000000..a7df3aa96c --- /dev/null +++ b/modules/payment/tests/modules/payment_events_test/payment_events_test.services.yml @@ -0,0 +1,6 @@ +services: + payment_events_test.event_subscriber: + class: Drupal\payment_events_test\EventSubscriber + arguments: ['@state'] + tags: + - { name: event_subscriber } diff --git a/modules/payment/tests/modules/payment_events_test/src/EventSubscriber.php b/modules/payment/tests/modules/payment_events_test/src/EventSubscriber.php new file mode 100644 index 0000000000..916bee9cef --- /dev/null +++ b/modules/payment/tests/modules/payment_events_test/src/EventSubscriber.php @@ -0,0 +1,53 @@ +state = $state; + } + + /** + * Reacts to payment event. + * + * @param \Drupal\commerce_payment\Event\PaymentEvent $event + * The payment event. + * @param string $name + * The name of the event. + */ + public function paymentEvent(PaymentEvent $event, $name) { + $this->state->set('payment_events_test.event', [ + 'event_name' => $name, + 'event_entity' => $event->getEntity(), + ]); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[PaymentEvents::PAYMENT_LOAD][] = ['paymentEvent']; + $events[PaymentEvents::PAYMENT_CREATE][] = ['paymentEvent']; + return $events; + } + +} diff --git a/modules/payment/tests/src/Kernel/PaymentEventsTest.php b/modules/payment/tests/src/Kernel/PaymentEventsTest.php new file mode 100644 index 0000000000..7f584004bd --- /dev/null +++ b/modules/payment/tests/src/Kernel/PaymentEventsTest.php @@ -0,0 +1,107 @@ +installEntitySchema('profile'); + $this->installEntitySchema('commerce_order'); + $this->installEntitySchema('commerce_order_item'); + $this->installEntitySchema('commerce_payment'); + $this->installEntitySchema('commerce_payment_method'); + $this->installConfig('commerce_order'); + $this->installConfig('commerce_payment'); + + // An order item type that doesn't need a purchasable entity, for simplicity. + OrderItemType::create([ + 'id' => 'test', + 'label' => 'Test', + 'orderType' => 'default', + ])->save(); + + $payment_gateway = PaymentGateway::create([ + 'id' => 'example', + 'label' => 'Example', + 'plugin' => 'example_onsite', + ]); + $payment_gateway->save(); + + $user = $this->createUser(); + + /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */ + $payment_method_active = PaymentMethod::create([ + 'type' => 'credit_card', + 'payment_gateway' => 'example', + // Thu, 16 Jan 2020. + 'expires' => '1579132800', + 'uid' => $user->id(), + ]); + $payment_method_active->save(); + } + + /** + * Tests the basic payment events. + */ + public function testPaymentEvents() { + // Create a dummy payment. + $payment = Payment::create([ + 'payment_gateway' => 'example', + 'payment_method' => 'credit_card', + 'remote_id' => '123456', + 'amount' => [ + 'number' => '39.99', + 'currency_code' => 'USD', + ], + 'state' => 'capture_completed', + 'test' => TRUE, + ]); + $payment->save(); + + // Check the create event. + $event_recorder = \Drupal::state()->get('payment_events_test.event', FALSE); + $this->assertEquals('commerce_payment.commerce_payment.create', $event_recorder['event_name']); + $this->assertEquals($payment->id(), $event_recorder['event_entity']->id()); + + // Reload the payment. + $this->reloadEntity($payment); + + // Check the load event. + $event_recorder = \Drupal::state()->get('payment_events_test.event', FALSE); + $this->assertEquals('commerce_payment.commerce_payment.load', $event_recorder['event_name']); + } + +}