Add ComponentSourceInterface::getReferencedEntities

Created on 7 July 2025, about 1 month ago

Overview

Default content exports needs to know if a field item references another entity so it can resolve a dependency graph.
Prop sources can reference entities but there is no way to retrieve that information when you have a ComponentTreeItem

Proposed resolution

Add ComponentSourceInterface::getReferenceEntities and have each source plugin implement it. Most likely only JS and SDC will return something, based on the use of an entity-reference field in the prop sources

User interface changes

โœจ Feature request
Status

Active

Version

0.0

Component

Component sources

Created by

๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

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

Merge Requests

Comments & Activities

  • Issue created by @larowlan
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    have each source plugin implement it

    I'm confused by this. Block components never reference other entities? An SDC can never reference content entities?

    It's not the component itself that can reference other (content) entities, but only the inputs for the component.

    So then what you need is to call \Drupal\experience_builder\Plugin\DataType\ComponentInputs::getPropSources() and add some logic around that to filter down to only content dependencies?

    IOW: a sibling to \Drupal\experience_builder\Plugin\DataType\ComponentInputs::getPropSourcesWithDependency() (which was added in ๐Ÿ› Component trees with dynamic prop sources that introspect field values don't add the relevant fields to their dependencies Active ), to get just the content dependencies?

    IOW โ€ฆ \Drupal\experience_builder\Plugin\DataType\ComponentInputs::calculateDependencies(), but filtered down to content dependencies? Which is already tested by \Drupal\Tests\experience_builder\Kernel\DataType\ComponentInputsDependenciesTest::testCalculateDependencies():

        // Verify content dependencies if we have a valid entity.
        $file_entity = $hero_reference->get('field_media_image')->entity;
        assert($file_entity instanceof File);
        $file_uuid = $file_entity->get('uuid')->value;
        self::assertSame([
          'module' => [
    โœ‚โœ‚โœ‚
          ],
          'config' => [
    โœ‚โœ‚โœ‚
          ],
          'content' => [
            'file:file:' . $file_uuid,
          ],
        ], $item_list->get(3)->get('inputs')->calculateDependencies($node));
    
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    I know @phenaproxima asked about this in chat, that's why @larowlan opened this.

    So let's get him unblocked by providing a test, should be simple :)

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Test coverage pushed.

    I used \Drupal\experience_builder\Plugin\Field\FieldType\ComponentTreeItem::calculateFieldItemValueDependencies() to also allow for the case of anything else besides the explicit inputs of a component instance (the inputs property) to declare content dependencies.

    (I could have used $item->get('inputs')->calculateDependencies($node)['content']) instead of $item->calculateFieldItemValueDependencies($node)['content'], but this just seemed more prudent because truly all-encompassing all dependencies of the component instance/ComponentTreeItem.)

    And in doing so โ€ฆ this revealed a bug in \Drupal\experience_builder\Plugin\DataType\ComponentInputs: it should've been implementing ContentAwareDependentInterface, not DependentPluginInterface, because that is the difference between calculateFieldItemValueDependencies() executing either of these 2 branches:

          if ($property instanceof DependentPluginInterface) {
            $dependencies = NestedArray::mergeDeep($dependencies, $property->calculateDependencies());
          }
          elseif ($property instanceof ContentAwareDependentInterface) {
            $dependencies = NestedArray::mergeDeep($dependencies, $property->calculateDependencies($host_entity));
          }
    

    ๐Ÿ˜…

    Yay for tests exercising what we say/think should work. Here's hoping there's no additional bug discoveriesโ€ฆ

  • Pipeline finished with Failed
    about 1 month ago
    Total: 780s
    #541738
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • Pipeline finished with Success
    about 1 month ago
    Total: 6152s
    #541761
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    For the record, this blocks site templates. Or at least, site templates that ship XB-ified content (which is likely to be all site templates).

    The reason this blocks site templates is because default content (including xb_page entities) needs to be able to calculate its dependencies. Without a method to get the referenced entities in an XB component tree, the default content exporter will have no way to do that.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
    1. [โ€ฆ] would indeed be most helpful.

      I'm sure that would be for that particular use case. But it's a single use case. And this works, doesn't it? So are you really not unblocked?

    2. I bet that ideally, you'd actually be able to just call \Drupal\Core\Entity\ContentEntityBase::referencedEntities() and that'd automatically take care of XB fields' reliance on other entities?

      And that's actually totally doable too, we'd just add a new references computed property to \Drupal\experience_builder\Plugin\Field\FieldType\ComponentTreeItem::propertyDefinitions(). But that's not something we should A) rush, B) delay beta for.

    So can you please confirm that this MR (point 1) would unblock you for now? Then I'd be happy to merge it right away, and we can keep this issue open (to implement point 2). ๐Ÿ˜Š๐Ÿ™

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    I have not tested this (I need that damn default content exporter in core first!) but here's my inference from reading the code in HEAD and the MR...

    If this results in content dependencies being added to the field item like node:page:SOME_UUID, that will be enough data to give the exporter what it needs. This appears to be confirmed by the test coverage.

    So in the interest of acceleration, I'm calling this one ready.

  • Pipeline finished with Skipped
    about 1 month ago
    #542005
  • Pipeline finished with Skipped
    about 1 month ago
    #542006
  • Pipeline finished with Skipped
    about 1 month ago
    #542007
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Merged & rescoped for #9.2 ๐Ÿ‘

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Still needs clarifications on what exactly is needed though โ€” probably best after is done? ๐Ÿ˜Š

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    I don't think the component tree field type should need to provide another property at all.

    The content exporter is currently leaning towards allowing modules to supply callback functions that know how to handle specific field/data types. So in fact, XB would have an event subscriber like this pseudocode:

    $event->setCallback('component_tree', function (ComponentTreeItem $item, ExportMetadata $metadata): array {
      foreach ($item->referencedEntities() as $referenced) {
        $metadata->addDependency($referenced);
      }
    });
    
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    The content exporter is currently leaning towards

    ๐Ÿ‘

    Looked through your post history and found โœจ Add a command-line utility to export content in YAML format Active , which seems to be what this is for?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    That's the one!

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    ...dude, where's my patch?

    This MR had originally had an event subscriber that hooked into the default content export event so that component tree items would be exported properly. That's just...gone?

    Do I have to rewrite it? Am I the victim of a drive-by force push?

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    @phenaproxima this was merged?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    Test coverage was. My event subscriber, not that I can seeโ€ฆ?

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    I don't see any comments for gitlab commits from you in this issue - perhaps it was a different issue?

    If you can remember what the filename was you could possibly `git log --all -S` to find it?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    It's entirely possible I never actually posted the event subscriber patch (this would seem to be the case), but the issue got repurposed before I could intervene. In any event, I'll open a new MR here to add the event subscriber, since the exporter was committed to core today.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • Merge request !1300Resolve #3534561 "Add export callback" โ†’ (Open) created by phenaproxima
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    Opened the initial MR for your perusal, but still needs tests.

  • Pipeline finished with Failed
    about 1 month ago
    #549006
  • Pipeline finished with Running
    about 1 month ago
    #549060
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Per @phenaproxima at #3526814-12: Default content exports of component trees are invalid and hence are not correct after importing โ†’ , closed that as a duplicate of this one. Hence also moved over the most crucial issue metadata.

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland
Production build 0.71.5 2024