the main property name, isn't defined @eca

Created on 25 April 2024, 8 months ago
Updated 29 April 2024, 8 months ago

Problem/Motivation

I started to use this awesome module custom_field β†’ a lot as replacement of paragraph module.
As it has multiple fields - one table and multiple columns it creates following issue when I try to Serialize using JSON Encode (Tamper:Encode/Decode) :

Warning: Undefined array key "value" in Drupal\eca_tamper\Plugin\Action\Tamper::Drupal\eca_tamper\Plugin\{closure}() (line 149 of modules/contrib/eca_tamper/src/Plugin/TamperTrait.php).

Drupal\eca_tamper\Plugin\Action\Tamper::Drupal\eca_tamper\Plugin\{closure}(Array, 0)
array_walk(Array, Object) (Line: 157)
Drupal\eca_tamper\Plugin\Action\Tamper->doTamper('eca_data', 'eca_token_name') (Line: 37)
Drupal\eca_tamper\Plugin\Action\Tamper->execute(NULL) (Line: 102)
Drupal\eca\Entity\Objects\EcaAction->execute(Object, Object, Array) (Line: 210)
Drupal\eca\Processor->executeSuccessors(Object, Object, Object, Array) (Line: 212)
Drupal\eca\Processor->executeSuccessors(Object, Object, Object, Array) (Line: 212)
Drupal\eca\Processor->executeSuccessors(Object, Object, Object, Array) (Line: 168)
Drupal\eca\Processor->execute(Object, 'eca.content_entity.update') (Line: 76)
Drupal\eca\EventSubscriber\EcaBase->onEvent(Object, 'eca.content_entity.update', Object)
call_user_func(Array, Object, 'eca.content_entity.update', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'eca.content_entity.update') (Line: 73)
Drupal\eca\Event\TriggerEvent->dispatchFromPlugin('content_entity:update', Object, Object) (Line: 297)
Drupal\eca_content\HookHandler->update(Object) (Line: 97)
eca_content_entity_update(Object)
call_user_func_array(Object, Array) (Line: 409)
Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}(Object, 'eca_content') (Line: 388)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('entity_update', Object) (Line: 416)
Drupal\Core\Extension\ModuleHandler->invokeAll('entity_update', Array) (Line: 217)
Drupal\Core\Entity\EntityStorageBase->invokeHook('update', Object) (Line: 900)
Drupal\Core\Entity\ContentEntityStorageBase->invokeHook('update', Object) (Line: 564)
Drupal\Core\Entity\EntityStorageBase->doPostSave(Object, 1) (Line: 781)
Drupal\Core\Entity\ContentEntityStorageBase->doPostSave(Object, 1) (Line: 489)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 806)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object) (Line: 354)
Drupal\Core\Entity\EntityBase->save() (Line: 270)
Drupal\node\NodeForm->save(Array, Object)
call_user_func_array(Array, Array) (Line: 129)
Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 67)
Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 597)
Drupal\Core\Form\FormBuilder->processForm('node_project_one_edit_form', Array, Object) (Line: 325)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 627)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 181)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 704)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

It is because in my case I do have 2 fields - Entity reference to user and Role which is text field - hence value as shown here:

Does anyone can help to fix so I can try to serialize users so I can check which one was added/removed.

πŸ’¬ Support request
Status

Fixed

Version

3.0

Component

Code

Created by

πŸ‡ΈπŸ‡°Slovakia coaston

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

Merge Requests

Comments & Activities

  • Issue created by @coaston
  • πŸ‡ΈπŸ‡°Slovakia coaston

    I just found out that there is similar issue for "Entity:GET Value" which triggers :

    event Drupal\eca_content\Event\ContentEntityUpdate: Property value is unknown..
    

    so it seems also standard ECA module needs to handle this first...

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    It looks like neither eca_tamper nor eca can do much about it here, this seems to be an issue with the custom_field module.

    The code, that being executed here is this:

          if ($data instanceof ListInterface) {
            $item_definition = $data->getItemDefinition();
            $main_property = $item_definition instanceof ComplexDataDefinitionInterface ? $item_definition->getMainPropertyName() : NULL;
            $data = $data->getValue() ?? [];
            array_walk($data, static function (&$item) use ($main_property) {
              if (isset($main_property) && is_array($item)) {
                $item = $item[$main_property];
              }
              elseif (is_scalar($item)) {
                // Nothing to do.
              }
              else {
                $item = NULL;
              }
            });
            $data = array_filter($data, static function ($item) {
              return NULL !== $item;
            });
          }
    

    That means, $data is the custom_field object and we use a Drupal core interface to getMainPropertyName(), which gives us back the property name of the main property. I.e. that comes from the custom_field. Then we grab $item[$main_property] and receive the error that this doesn't exist. In other words, the property, that we were told to be the main property name, isn't defined? That must mean, that the field definition has given us the wrong information.

    If I'm not completely wrong, I'd pass that over to the custom_field module.

  • πŸ‡ΈπŸ‡°Slovakia coaston
  • Status changed to Closed: won't fix 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    There is no main property name with custom_field. It's not technically possible as the properties are dynamic so theres no way to know which property would be considered the "main one". If the ECA module is depending on that... I'd have to say its not gonna be compatible with custom_field and nothing I can really do about it from my end. jurgenhaas also uses the custom_field module so I'd suggest bouncing it back to him to see if there is anything differently that can be done for ECA.

  • πŸ‡ΈπŸ‡°Slovakia coaston

    Thank you guys. Maybe one day:)

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    @apmsooner just one little thing to consider, whether you want to re-open the issue for that is totally up to you:

    The field item from custom field is an instance of ComplexDataDefinitionInterface which implements the method getMainPropertyName() that should either return the name of the main property, if one exists, or NULL if it doesn't. As custom_field doesn't have one, it should return NULL, but it returns value. Unfortunately, I don't know what's required to make that change, but I think custom_field would be more compliant with that interface if you got that changed (fixed).

  • Status changed to Active 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Thanks for diligently pointing this out. I could have sworn i already had mainPropertyName() set in the field type but sure enough I'm not seeing it for some reason. Opening this back up and I'll provide a patch that can be tested.

  • Merge request !51Set mainProperty(). β†’ (Merged) created by apmsooner
  • Status changed to Needs review 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Here's a patch that can be tested.

  • πŸ‡ΈπŸ‡°Slovakia coaston

    @apmsooner, thank you so much for your effort. Much appreciated!
    It looks good, I don't see any error in logs, however looks like nothing is passing so it seems @jurgenhaas has to review also.

    @jurgenhaas I have tried simple model with standard entity reference field to User using this manual : Eca manual and i was able to see if user was added + his name or if user was removed so this worked fine.
    However when I changed all parameters to custom field with name "field_resource" (entity reference to user called "name" + one text field called "role" as described on picture above) the first problem is that new_list and origin_list are blank and new_user and original_user is []. When I changed parameter from field_resource to field_resource:name the list value now looks "better" and shows ID of all assigned users, however new_user and original_user are still [].

    Another issue is when it passed through Trigger (custom event entity aware) and loaded - it always loads Node id ,instead of user id.

    So not sure if anything else has to be updated in custom field or I am missing anything.

    @jurgenhaas Can you be so kind and test some simple model to determine the issue ?

    Thank you

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    @jurgenhaas - I suspect there would need to be specific plugin integration to make custom_field work with eca module. The custom_field module field types consist of its own plugin system so ECA wouldn't know (i assume) how to interact with for instance a custom_field entity reference field without accessing the the custom_field plugin for that column type. The column settings "type" value map up to the same named plugin ids: https://git.drupalcode.org/project/custom_field/-/tree/3.0.x/src/Plugin/....

    Theres a helper function here that would return an instance of the custom_field type plugins based on field definition settings passed into it that may be helpful: https://git.drupalcode.org/project/custom_field/-/blob/3.0.x/src/Plugin/...

    I have no knowledge of ECA unfortunately but if theres enough interest in making it work with custom_field, I'm open to helping out where I can. I suspect that further effort would live as a feature request in the ECA module at this point unless you have any insight of additional changes needed in custom_field module. I'll wait on additional feedback before I merge this patch in.

  • Status changed to RTBC 8 months ago
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    This should be fine, thanks a lot @apmsooner for addressing this!

    @coaston when data doesn't have a main property, ECA calls $data->getValue() to receive the data from the object, and that should subsequently being processed without any issue. If you're not receiving data as expected, then it's time for the ECA debugging techniques described at Debugging. That gives you an insight to the available tokens and their data at any single point during ECA processing. If you're still seeing issues with this, that would probably be better addressed in a separate issue in the ECA issue queue, since the original problem for custom_field seems to be resolved and we don't want to create noise in a "foreign" issue queue.

  • Pipeline finished with Skipped
    8 months ago
    #159709
  • Pipeline finished with Skipped
    8 months ago
    #159736
  • Pipeline finished with Skipped
    8 months ago
    #159786
    • apmsooner β†’ committed 08fd8600 on 3.0.x
      Issue #3443547 by apmsooner, jurgenhaas: the main property name, isn't...
  • Status changed to Fixed 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • Status changed to Fixed 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
Production build 0.71.5 2024