"entity" token is not set

Created on 28 January 2024, 11 months ago
Updated 27 February 2024, 10 months ago

Problem/Motivation

Hi everyone, I found a bug with the latest eca_commerce module.

The documentation states that:

When an entity-related event gets triggered, e.g. Presave content entity, then ECA automatically puts the related entity onto the token stack with the name entity and also under the name of the entity type, e.g. node, user, etc.

...but it seems like there is currently a bug preventing this from happening. Tokens like "[entity:order_id]" will return an empty value whereas "[commerce_order:order_id]" will return the order ID properly.

Steps to reproduce

* Install Drupal 10.2
* Install ECA commerce and dependencies
* Install commerce_order
* Create a model that reaction to an order event (such as order update, order create, etc.)
* Create a log action with "debug" priority and the following message:

The entity token holds: [entity]<br>
The content token holds: [commerce_order].

*Now trigger the action, and the ECA log will show something like:

The entity token holds: [entity]
The content token holds: 1.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Thanks!

📌 Task
Status

Fixed

Version

1.0

Component

Documentation

Created by

🇹🇭Thailand AlfTheCat

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @AlfTheCat
  • 🇩🇪Germany jurgenhaas Gottmadingen

    Thanks @AlfTheCat for reporting this. At first, I was surprised that we really missed the entity tokens here. But now, I looked into the code and found the list of tokens that are automatically provided by each of the available events:

        if ($event instanceof CartEmptyEvent) {
          $this->tokenService->addTokenData('cart', $event->getCart());
          $this->tokenService->addTokenData('commerce_order_items', $event->getOrderItems());
        }
        if ($event instanceof CartEntityAddEvent) {
          $this->tokenService->addTokenData('entity', $event->getEntity());
          $this->tokenService->addTokenData('cart', $event->getCart());
          $this->tokenService->addTokenData('quantity', $event->getQuantity());
          $this->tokenService->addTokenData('commerce_order_item', $event->getOrderItem());
        }
        if ($event instanceof CartOrderItemAddEvent) {
          $this->tokenService->addTokenData('cart', $event->getCart());
          $this->tokenService->addTokenData('quantity', $event->getQuantity());
          $this->tokenService->addTokenData('commerce_order_item', $event->getOrderItem());
        }
        if ($event instanceof CartOrderItemRemoveEvent) {
          $this->tokenService->addTokenData('cart', $event->getCart());
          $this->tokenService->addTokenData('commerce_order_item', $event->getOrderItem());
        }
        if ($event instanceof CartOrderItemUpdateEvent) {
          $this->tokenService->addTokenData('cart', $event->getCart());
          $this->tokenService->addTokenData('commerce_order_item', $event->getOrderItem());
          $this->tokenService->addTokenData('commerce_order_item_original', $event->getOriginalOrderItem());
        }
        if ($event instanceof OrderItemComparisonFieldsEvent) {
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('commerce_order_item_comparison_fields', $event->getComparisonFields());
          $this->tokenService->addTokenData('commerce_order_item', $event->getOrderItem());
        }
        if ($event instanceof CheckoutCompletionRegisterEvent) {
          $this->tokenService->addTokenData('user', $event->getAccount());
          $this->tokenService->addTokenData('commerce_order', $event->getOrder());
        }
        if ($event instanceof OrderAssignEvent) {
          $this->tokenService->addTokenData('commerce_customer', $event->getCustomer());
          $this->tokenService->addTokenData('commerce_order', $event->getOrder());
        }
        if ($event instanceof OrderEvent) {
          $this->tokenService->addTokenData('commerce_order', $event->getOrder());
        }
        if ($event instanceof OrderItemEvent) {
          $this->tokenService->addTokenData('commerce_order_item', $event->getOrderItem());
        }
        if ($event instanceof OrderLabelEvent) {
          $this->tokenService->addTokenData('commerce_order', $event->getOrder());
          $this->tokenService->addTokenData('commerce_order_label', $event->getLabel());
        }
        if ($event instanceof OrderProfilesEvent) {
          $this->tokenService->addTokenData('commerce_order', $event->getOrder());
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('profile', $event->getProfiles());
        }
        if ($event instanceof FilterPaymentGatewaysEvent) {
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('commerce_order_payment_gateways', $event->getPaymentGateways());
          $this->tokenService->addTokenData('commerce_order', $event->getOrder());
        }
        if ($event instanceof PaymentEvent) {
          $this->tokenService->addTokenData('commerce_payment', $event->getPayment());
        }
        if ($event instanceof NumberFormatDefinitionEvent) {
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('commerce_definition', $event->getDefinition());
        }
        if ($event instanceof FilterVariationsEvent) {
          $this->tokenService->addTokenData('commerce_product', $event->getProduct());
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('commerce_product_variation', $event->getVariations());
        }
        if ($event instanceof ProductAttributeValueEvent) {
          $this->tokenService->addTokenData('commerce_product_attribute_value', $event->getAttributeValue());
        }
        if ($event instanceof ProductDefaultVariationEvent) {
          $this->tokenService->addTokenData('commerce_product', $event->getProduct());
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('commerce_product_variation_default', $event->getDefaultVariation());
        }
        if ($event instanceof ProductEvent) {
          $this->tokenService->addTokenData('commerce_product', $event->getProduct());
        }
        if ($event instanceof ProductVariationAjaxChangeEvent) {
          $this->tokenService->addTokenData('commerce_product_variation', $event->getProductVariation());
          $this->tokenService->addTokenData('commerce_product_variation_response', $event->getResponse());
          $this->tokenService->addTokenData('commerce_product_variation_view_mode', $event->getViewMode());
        }
        if ($event instanceof ProductVariationEvent) {
          $this->tokenService->addTokenData('commerce_product_variation', $event->getProductVariation());
        }
        if ($event instanceof CouponEvent) {
          $this->tokenService->addTokenData('commerce_coupon', $event->getCoupon());
        }
        if ($event instanceof FilterPromotionsEvent) {
          $this->tokenService->addTokenData('commerce_order', $event->getOrder());
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('commerce_promotions', $event->getPromotions());
        }
        if ($event instanceof PromotionEvent) {
          $this->tokenService->addTokenData('commerce_promotion', $event->getPromotion());
        }
        if ($event instanceof StoreEvent) {
          $this->tokenService->addTokenData('commerce_store', $event->getStore());
        }
        if ($event instanceof BuildZonesEvent) {
          $this->tokenService->addTokenData('commerce_store_plugin', $event->getPlugin());
          $this->tokenService->addTokenData('commerce_store_zones', $event->getZones());
        }
        if ($event instanceof CustomerProfileEvent) {
          $this->tokenService->addTokenData('commerce_order_item', $event->getOrderItem());
          // This likely needs some additional work to handle additional methods.
          $this->tokenService->addTokenData('profile', $event->getCustomerProfile());
        }
    

    As you can see, some of the events provide more than 1 entity, e.g. the event CartEntityAddEvent provides the cart, the entity and a line item. Each of which is an entity. So, in that case, it is impossible to follow the rule that entity related events would provide the token called entity.

    For commerce, it seems that it makes more sense to only really provide the tokens under the names above. Everything else might be more confusing than helpful.

    What's missing though is proper documentation, I guess. The good news for ECA 2.0, we're working on automatically discovered token names from the code, so that this can be displayed in the UI and the ECA Guide. I'm not sure what we should be doing for ECA 1 in the meantime. Maybe referring to this issue is enough for now?

  • Status changed to Fixed 11 months ago
  • 🇹🇭Thailand AlfTheCat

    Hi Jurgen,

    This is very interesting. I'm finding some useful tokens (product_variation_default) in that list. And thanks very much for explaining why indeed "entity" would not work in this case. Makes perfect sense.

    Very excited to learn that in 2.0 tokens will be discovered and especially the display in the UI. That will be a time saver.

    I think referring to this issue as documentation will be good, it might be likely for someone in the future to come across the same issue. As such I changed the version to 1.0.x-dev and "fixed", as this is effectively solved in 2.0 via the new token discovery mechanism.

  • 🇩🇪Germany jurgenhaas Gottmadingen
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024