FieldMapperBase not supporting programatically declared properties

Created on 14 February 2025, about 2 months ago

Problem/Motivation

It is possible to declare mappable fields via the Event ExternalEntitiesEvents::GET_MAPPABLE_FIELDS.
These fields then show up in the field mapping config but no mapping can be configured.

Btw. my use case is somewhat convoluted in that I want to use a "deep filter" via json:api.
This means I'll filter by a value of an include field, a value I otherwise don't want directly to be imported nor would I be able to filter by the mapping I actually "import" it needs a complex JsonPath which certainly won't work as json:api filter.
So instead I want to declare a custom "filter" field mapping - which can use a simple mapping name which then can be used as deep filter.
Another way more complex approach would be extend the mappers to allow a filter mapping in the field mapping config. If set this would overwrite the data mapping when filtering.

Steps to reproduce

Proposed resolution

FieldMapper\FieldMapperBase::getFieldDefinition() currently uses a piece of "custom code" to fetch the fields. I think it should instead use \Drupal\external_entities\Entity\ConfigurableExternalEntityTypeInterface::getMappableFields()

However, I'm not entirely sure if that method doesn't filter out some things that normally would be considered mappable with the current implementation.

Remaining tasks

  1. Write Code
  2. Review
  3. Merge

User interface changes

None

API changes

None

Data model changes

None

Feature request
Status

Active

Version

3.0

Component

Code

Created by

🇨🇭Switzerland das-peter

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

Merge Requests

Comments & Activities

  • Issue created by @das-peter
  • 🇫🇷France guignonv Montpellier

    Hi!
    I reviewed the changes. Looks quite good so far and I agree on the change to get mappable fields from the xntt. It makes sens.
    However, I less confident in this part you removed:

          $derived_entity_type = $this
            ->getExternalEntityType()
            ->getDerivedEntityType();
          if (empty($derived_entity_type)) {
            $this->logger->warning('FieldMapperBase::getFieldDefinition(): Cannot get external entity derived type.');
            return NULL;
          }
    

    This is used by annotation entities. I did not make automated tests on these so I'm not sure it will work properly. I believe you removed that part also because it was not working with your use case right?
    What about keeping that part but commented then?

          /*
          @todo The following code as been disabled and impacts on annotation nodes should be checked before removing it permanently.
          @code
          $derived_entity_type = $this
            ->getExternalEntityType()
            ->getDerivedEntityType();
          if (empty($derived_entity_type)) {
            $this->logger->warning('FieldMapperBase::getFieldDefinition(): Cannot get external entity derived type.');
            return NULL;
          }
          @endcode
          */
    

    ...or something similar.

  • 🇨🇭Switzerland das-peter

    @guignonv Thanks for the feedback, much appreciated!

    I removed it because with the new code $derived_entity_type isn't used anymore and pretty much the same code is used in the concrete implementation of ConfigurableExternalEntityTypeInterface::getMappableFields() -
    ExternalEntityType::getMappableFields:getMappableFields():

          $derived_entity_type = $this->getDerivedEntityType();
    
          $fields = [];
          if (!empty($derived_entity_type)) {
            $fields = $this
              ->entityFieldManager()
              ->getFieldDefinitions(
                $derived_entity_type->id(),
                $derived_entity_type->id()
              );
          }
    

    It just also fires the event.

    If we want the error logging we might want to move it to ExternalEntityType::getMappableFields:getMappableFields()?
    But annotation entities support should be the same, at least in this concrete implementation.
    If we do not want to rely on the concrete implementation we might need to add another interface so that concrete implementations signal that they support annotation.

  • 🇫🇷France guignonv Montpellier

    Fair enough! :) Merged! (I got time to update the repo now)

  • 🇨🇭Switzerland das-peter

    @guignonv Awesome! Have a fantastic weekend!

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

Production build 0.71.5 2024