Token Exists condition no longer accepts tokens

Created on 28 September 2023, over 1 year ago
Updated 22 February 2024, 11 months ago

Problem/Motivation

To prevent other errors, I'm trying to detect whether a particular field has a value set -- however, I need to traverse an entity reference to get to the appropriate field.

Using "Compare two Scalar Values" fails, because if the field is not set, the token is not replaced, so we can't branch on whether or not the field value is greater than zero.

Using "Entity field is empty" fails because we can't walk the entity reference.

Using "Token is empty" fails because the validation on this condition rejects using a token.

Steps to reproduce

Add a "Token exists" condition with a token name like "[order_item:purchased_entity:entity:weight:number]".

Save.

Get a validation warning, and the model won't save.

Proposed resolution

Remove the "#eca_token_reference" from the token_name form field definition, on \Drupal\eca_base\Plugin\ECA\Condition\TokenExists.

The evaluate function already properly evaluates a token, if it receives a full token instead of just a name. However, the ECA model validation prevents you from saving it.

User interface changes

Possibly clarify the help text, to say this can be either a token name (with no brackets) or a token (with brackets).

API changes

None.

Data model changes

None.

πŸ’¬ Support request
Status

Closed: works as designed

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States freelock Seattle

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

Merge Requests

Comments & Activities

  • Issue created by @freelock
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    The purpose of Token: exists is to test a token by name. And order_item:purchased_entity:entity:weight:number is not a token name nor would be [order_item:purchased_entity:entity:weight:number]. The former is a token named order_item with a chained list of properties. The latter would resolve to the value of that token. In this example, the token name would just be order_item, and this condition can only test exactly that.

    The condition Entity: field value is empty should work though when you load the entity [order_item:purchased_entity] into a token (e.g. orderedentity) and then use that as the entity in that condition and check for its field value.

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    296 pass, 1 fail
  • Status changed to Needs review over 1 year ago
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    Proposing a change in the MR !392 to keep the token reference validation in place, but allow the configuration to refer to order_item:purchased_entity:entity:weight:number (without brackets) such that the evaluate function now tries to replace token data by adding the brackets if not otherwise found already. This should give us both, the config validation as well as the deep resolution of token names.

    More details about this in this Slack thread.

  • πŸ‡ΊπŸ‡ΈUnited States freelock Seattle

    Hi,

    This looks like a good fix for the issue, allows you to support this need.

    I'm wondering about consistency and user expectations, though, particularly around how these are chained together.

    We know that if we're inside a token, you walk these relationships with : (colon) characters. However, if you're not inside a token -- if you're in a Twig context, or Javascript, or other places in ECA that refer to sub-fields, the separator is a . (period).

    order_item:purchased_entity:entity:weight:number

    vs

    order_item.purchased_entity.entity.weight.number

    And of course PHP is entirely different, depending on whether you're looking at an array or object, and declaring or assigning...

    How is a non-developer supposed to know what to use?

    I'm not sure I can justify this, but at least the way I think about it currently, I think we should use : as the separator ONLY INSIDE tokens with square brackets, and if there's no brackets, use dots.

    That would just mean adding a string replacement inside your MR to replace colons with dots... This wouldn't actually break the colon syntax, but I think it's a pattern that might be more familiar?

  • Status changed to Needs work over 1 year ago
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    I'm wondering about consistency and user expectations, though, particularly around how these are chained together.

    This is a good point. However, the different syntax for e.g. tokens, twig, javascript and others is not originated by ECA, it comes from the various technologies or APIs that are behind those.

    However, we could easily replace periods by colons in the context of this plugin. That wouldn't make any difference. So, users could use either order_item:purchased_entity:entity:weight:number or order_item.purchased_entity.entity.weight.number and both would respond with the same result.

    However, we've broken tests now and need to clean them all up in \Drupal\Tests\eca_base\Kernel\TokenExistsTest::testTokenExists where the tests are falsely test for token names with brackets, expecting the same result as without, which is no longer correct and shouldn't have been before, but this went through unnoticed, since the validation happens when saving the model and that is not part of the tests.

    I think all the tests with brackets should now respond with FALSE. But we should maybe also add new tests?

  • Assigned to jurgenhaas
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen
  • Pipeline finished with Failed
    11 months ago
    Total: 400s
    #101244
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    I wanted to address the latest bits and realized that the solution was already in place: we can already use order_item:purchased_entity:entity:weight:number as the token name, and both form validation and later the condition evaluation do work as expected. So, there is nothing to do in the code.

  • Issue was unassigned.
  • Status changed to Closed: works as designed 11 months ago
  • Pipeline finished with Failed
    10 months ago
    Total: 2608s
    #126263
  • Pipeline finished with Skipped
    10 months ago
    #137485
  • Pipeline finished with Failed
    2 months ago
    Total: 724s
    #330506
  • Pipeline finished with Failed
    2 months ago
    Total: 558s
    #340085
  • Pipeline finished with Failed
    about 2 months ago
    Total: 767s
    #347425
  • Pipeline finished with Failed
    about 2 months ago
    Total: 592s
    #353055
  • Pipeline finished with Failed
    about 1 month ago
    Total: 589s
    #357973
  • Pipeline finished with Failed
    about 1 month ago
    Total: 606s
    #357976
  • Pipeline finished with Failed
    about 1 month ago
    Total: 357s
    #359150
  • Pipeline finished with Failed
    about 1 month ago
    Total: 711s
    #359159
  • Pipeline finished with Failed
    about 1 month ago
    Total: 596s
    #359180
  • Pipeline finished with Success
    about 1 month ago
    Total: 246117s
    #361539
  • Pipeline finished with Success
    about 1 month ago
    Total: 737s
    #367548
  • Pipeline finished with Success
    about 1 month ago
    Total: 2268s
    #367879
  • Pipeline finished with Canceled
    about 1 month ago
    Total: 382s
    #367907
  • Pipeline finished with Success
    about 1 month ago
    Total: 661s
    #367914
  • Pipeline finished with Success
    about 1 month ago
    Total: 667s
    #367995
  • Pipeline finished with Failed
    29 days ago
    Total: 669s
    #371081
  • Pipeline finished with Success
    28 days ago
    Total: 873s
    #371715
  • Pipeline finished with Skipped
    8 days ago
    #388528
  • Pipeline finished with Success
    6 days ago
    Total: 274s
    #390906
  • Pipeline finished with Success
    6 days ago
    Total: 164s
    #390946
  • Pipeline finished with Success
    6 days ago
    Total: 176s
    #390948
Production build 0.71.5 2024