Right now most of the components/entities provided by drupal commerce have event dispatcher for their CRUD. It will be nice if we can have the same thing for commerce_payment entity.

Comments

nikathone created an issue. See original summary.

bojanz’s picture

Title: Add events dispatcher for the payment module » No events thrown for Payment CRUD
Category: Feature request » Bug report

Looks like PaymentStorage extends the correct class (CommerceContentEntityStorage), the only thing that we're missing is an "event" in the Payment entity annotation (plus the actual event class and list of events in PaymentEvents, of course).

harings_rob’s picture

Assigned: Unassigned » harings_rob
Issue tags: +DevDaysSeville
nikathone’s picture

@harings_rob any update on this? thanks

nikathone’s picture

@bojanz found this https://github.com/drupalcommerce/commerce/pull/684 pull request from @harings_rob and was wondering if there is anything I can do to move this forward as I have some custom code which I would like them to subscribe to payment creation event. Thanks

kiwad’s picture

I've tried the commits mentionned in #5.

Works quite well. I would make few changes :

in PaymentStorage, all the events should be declared

In PaymentEvent, I would change the name of the function getOrder() to getEntity() which is more inline with other events and also because the function does not get the order entity but the payment entity

kiwad’s picture

Finally, the events where not triggered when I wanted them and instead of hacking commerce for my project, I ended up using core hooks. Since payments are entities, using function

hook_commerce_payment_update(Drupal\Core\Entity\EntityInterface $entity)

and

hook_commerce_payment_insert(Drupal\Core\Entity\EntityInterface $entity)
jackbravo’s picture

Status: Active » Needs review
StatusFileSize
new10.29 KB
new19.73 KB

Ok, I just re-rolled this patch, and also added the 'event' annotation to the Payment entity, so now all the events should work. There are tests right now for the create and load event. I also changed the getOrder method to getEntity, and added a test for that (as mentioned in comment 6). This issue is related to https://www.drupal.org/node/2856586 so I'm planning on adding that event too but maybe in another patch that depends on this one.

The PR is here: https://github.com/drupalcommerce/commerce/pull/791

harings_rob’s picture

Assigned: harings_rob » Unassigned

Status: Needs review » Needs work

The last submitted patch, 8: 2862339-payment-crud-events.patch, failed testing. View results

sophie.sk’s picture

Status: Needs work » Needs review
StatusFileSize
new10.17 KB

Whew, two years later and this finally needed a re-roll. Updated patch attached for the latest version of Commerce.

I don't know if any other work needs to be done to this - I have just straight up rerolled the latest patch. I haven't attached a diff, since the last patch was a seven-part patch.

Status: Needs review » Needs work

The last submitted patch, 11: payment_crud_events-2862339-11.patch, failed testing. View results

tonifisler’s picture

You could listen for state transitions in an EventListener to achieve something very similar. You won't get any event when there is no change in the state of the payment though. This is what I implemented:

/**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // Logs for payment_default.
    $events['commerce_payment.authorize.pre_transition'] = ['logPayment', -100];
    $events['commerce_payment.void.pre_transition'] = ['onVoid', -100];
    $events['commerce_payment.expire.pre_transition'] = ['logPayment', -100];
    $events['commerce_payment.authorize_capture.pre_transition'] = ['logPayment', -100];
    $events['commerce_payment.capture.pre_transition'] = ['logPayment', -100];
    $events['commerce_payment.partially_refund.pre_transition'] = ['logPayment', -100];
    $events['commerce_payment.refund.pre_transition'] = ['logPayment', -100];

    // Additional logs for payment_manual.
    $events['commerce_payment.create.pre_transition'] = ['logPayment', -100];
    $events['commerce_payment.receive.pre_transition'] = ['logPayment', -100];
    return $events;
  }

  public function logPayment(WorkflowTransitionEvent $event) {...}
lisastreeter’s picture

While working on a payment logging issue: https://www.drupal.org/project/commerce/issues/2845321, @mglaman pointed me towards this issue. I've separated the payment CRUD events from the payment logging and have combined that code with the latest patch here. Changes to the patch include:
* An update hook for the entity event handler. Without the hook, events weren't firing when the patch was applied to an existing site.
* A few minor updates to the test code.

lisastreeter’s picture

Status: Needs work » Needs review
mglaman’s picture

+++ b/modules/payment/commerce_payment.install
@@ -86,3 +86,13 @@ function commerce_payment_update_8203() {
+  $entity_type->setHandlerClass('event', \Drupal\commerce_payment\Event\PaymentEvent::class);

phpcs says we should move this into a `use` statement. nit on commit

+++ b/modules/payment/src/PaymentStorage.php
@@ -49,7 +51,13 @@ class PaymentStorage extends CommerceContentEntityStorage implements PaymentStor
+    $payment = parent::doCreate($values);
+
+    // Notify other modules.
+    $event = new PaymentEvent($payment);
+    $this->eventDispatcher->dispatch(PaymentEvents::PAYMENT_CREATE, $event);
+
+    return $payment;

Shouldn't the parent still invoke hooks here which CommerceContentEntityStorage fires events on?

mglaman’s picture

Assigned: Unassigned » bojanz
Status: Needs review » Reviewed & tested by the community
StatusFileSize
new10.98 KB

Addresses #16. Punting to bojanz for review.

bojanz’s picture

Status: Reviewed & tested by the community » Needs work
+   *
+   * @var string
+   */

Some of the event constants have var string, some don't. So the file itself is inconsistent. Looking at other files, we usually don't declare it, so I'm going to remove it.

--- a/modules/payment/src/PaymentStorage.php
+++ b/modules/payment/src/PaymentStorage.php
@@ -4,6 +4,8 @@ namespace Drupal\commerce_payment;
 
 use Drupal\commerce\CommerceContentEntityStorage;
 use Drupal\commerce_order\Entity\OrderInterface;
+use Drupal\commerce_payment\Event\PaymentEvent;
+use Drupal\commerce_payment\Event\PaymentEvents;

These imports are now unused and trigger phpcs warnings.

+class PaymentEventsTest extends OrderKernelTestBase {

While I like the tests, they are actually out of place here, because commerce_payment doesn't fire any events, the Commerce base class does. So if we want test coverage for entity events, it needs to live in the base module (let's say tests/src/Kernel/EntityEventsTest).

I'm going to remove the test/subscriber and commit, and you can make the coverage generic in a followup issue (post-2.17). I hope that's okay.

  • bojanz committed d52bbf2 on 8.x-2.x
    Issue #2862339 by jackbravo, lisastreeter, mglaman, Sophie.SK, bojanz:...
bojanz’s picture

Status: Needs work » Fixed

Thanks, everyone!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.