Consider making the createCopy config action optionally fail if the entity display already exists

Created on 25 October 2024, 5 months ago

Problem/Motivation

As a follow up for the issue "Entity displays cloning requires special config action" โ†’ and inspired by "Consider making the cloneAs config action optionally fail if the clone already exists" โœจ Consider making the cloneAs config action optionally fail if the clone already exists Active I think it makes sense to ignore the existing entity display if someone tries to copy another entity display into it. This is needed to allow to run recipe multiple time if it has createCopy config action. This will ensure the idempotence of the recipe.

Steps to reproduce

Create a recipe with config action createCopy for some entity display.
Run the recipe.
Try to run the recipe one more time.
Observe the error similar to this:

'entity_view_display' entity with ID 'node.page.search_index' already exists.

Proposed resolution

In method createCopy of EntityDisplayBase first try to load the entity display with new view mode and only if it doesn't exist do the duplicate. Field UI module does the check earlier in the form class core/modules/field_ui/src/Form/EntityDisplayFormBase.php:

          if (!$this->entityTypeManager->getStorage($this->entity->getEntityTypeId())->load($this->entity->getTargetEntityTypeId() . '.' . $this->entity->getTargetBundle() . '.' . $mode)) {
            $display = $this->getEntityDisplay($this->entity->getTargetEntityTypeId(), $this->entity->getTargetBundle(), 'default')->createCopy($mode);
            $display->save();
          }

This makes sure that the copy doesn't exist. But in config action this is not done.

Remaining tasks

Add check in createCopy method

User interface changes

None

Introduced terminology

None

API changes

None

Data model changes

None

Release notes snippet

createCopy config action will be ignored if the target entity display already exists.

โœจ Feature request
Status

Active

Version

10.4 โœจ

Component

recipe system

Created by

๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

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

Merge Requests

Comments & Activities

  • Issue created by @a.dmitriiev
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    Uploading patch for composer

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    I have checked the change with Drupal CMS search track recipes and it works as expected.

  • Pipeline finished with Failed
    5 months ago
    Total: 545s
    #320359
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    This is a flaw(?) in the actual method itself, not the recipe system, so a little housekeeping here...

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

    One possible fix here is to add an optional boolean flag to createCopy() that loads an existing one if possible:

    createCopy($new_mode, bool $use_existing = FALSE)
    

    Not sure what the default behavior should be, though. Probably to keep the current behavior but allow it to be overridden.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    I think optional parameter bool $use_existing = FALSE would be a nice solution here, so that the method doesn't try to load the copy always, but only when use_existing is TRUE. Nice approach.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    Updated patch

  • Pipeline finished with Canceled
    5 months ago
    Total: 434s
    #320746
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    Forgot about the interface core/lib/Drupal/Core/Entity/Display/EntityDisplayInterface.php

  • Pipeline finished with Failed
    5 months ago
    #320758
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    Two things:

    1. Can you post to the MR instead? Patches are hard to review.
    2. We cannot update the interface as that would constitute a backwards compatibility break. That's why $use_existing has a default value -- because as long as it has a default value, it won't break the interface.
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    The change is in MR https://git.drupalcode.org/project/drupal/-/merge_requests/9944/diffs . I posted a patch just to use it in composer. Ok, I will remove the change from the interface, but the LayoutBuilder complains that its declaration is different, so this has to stay.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    Uploading the new patch for using in composer. The change was pushed to MR.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev
  • Pipeline finished with Failed
    5 months ago
    Total: 882s
    #321338
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    Looks sensible to me, but needs test coverage :) Once that's done I'd be fine RTBCing this.

    Also, we need to target 11.x here - this changes public API to an extent and therefore I don't know if committers will be comfortable backporting it to 10.4.x. That will be a decision for them to make.

  • Pipeline finished with Failed
    5 months ago
    Total: 470s
    #325821
  • Pipeline finished with Failed
    5 months ago
    Total: 895s
    #325842
  • Pipeline finished with Failed
    5 months ago
    Total: 465s
    #325857
  • Pipeline finished with Success
    5 months ago
    Total: 759s
    #325883
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    Just a couple of suggested clarifications that might benefit the test, but overall I don't have anything to complain about here.

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

    Just a couple of suggested clarifications that might benefit the test, but overall I don't have anything to complain about here.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands roderik Amsterdam,NL / Budapest,HU

    I did a hit-and-run review comment because I was curious after seeing the review request in Drupal Slack.

    I don't know the full history, but could you have a look? (Not changing status myself.)

  • Pipeline finished with Canceled
    5 months ago
    Total: 70s
    #325948
  • Pipeline finished with Failed
    5 months ago
    Total: 541s
    #325949
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    Appears to have test failures.

  • Pipeline finished with Failed
    5 months ago
    Total: 584s
    #339479
  • Pipeline finished with Success
    5 months ago
    Total: 1968s
    #339492
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    The tests were fixed.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia atul_ghate

    I followed the steps to reproduce the issue as outlined below:

    1Installed Drupal with the standard profile.
    2.Switched to the 3483353-entity-copy-use-existing branch from 11.x.
    3.Created a recipe with the createCopy configuration action.
    4.Ran the recipe twice and verified the result on the site.

    Test result: After running the recipe twice, I am still encountering the same error as mentioned (please refer to the attached video for reference).

    Please let me know if there are any steps I might be missing in order to properly reproduce this issue? Thank you.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    For action method `createCopy` the new optional parameter was added `use_existing`, that allows avoiding the error. The recipe should have this config action:

        core.entity_view_display.node.*.default:
          # Clone the "Default" view display by default.
          createCopy:
            mode: search_index
            use_existing: true
    
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia atul_ghate

    Hi @a.dmitriiev, thank you for correcting me during the testing.

    I went through the verification process again, following the steps outlined in comment #28. (You can check the attached video for reference.)
    Test Results:
    1.No errors occurred when I ran the same recipe twice.
    2.Everything is functioning correctly, and all tests have passed.
    Since everything is working as expected, I'm changing the issue status to RTBC.

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

    Drupal CMS's search functionality depends on this patch, and it is therefore a Drupal CMS stable release blocker.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom alexpott ๐Ÿ‡ช๐Ÿ‡บ๐ŸŒ

    I'm not sure about this. I think with the clone and createCopy config actions we've kind of built new create and createIfNotExists actions and this specific issue has made me ponder if we should have extend those actions to support getting default values from existing entities. That way we'd get both functionalities in a consistent way and we would have the problem we have here where every recipe is going to want to have $use_existing set to TRUEโ€ฆ but obvs we donโ€™t want to change the behaviour of the existing method

  • Pipeline finished with Failed
    5 months ago
    Total: 138s
    #347378
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    That's a good point.

    I have opened a new merge request that implements two new config actions:

    core.entity_view_display.node.test.new_mode:
      # Wraps `create`, and will err if `core.entity_view_display.node.test.new_mode` already exists.
      createFrom: core.entity_view_display.node.test.existing_mode
    
    image.style.new_style:
      # Wraps `createIfNotExists`, and will not err if `image.style.new_style` already exists.
      createFromIfNotExists: image.style.existing_style
    

    The cloneAs and createCopy actions have not yet made it into a stable release, so let's just remove them now and replace them with these more generalized and versatile actions. It turns out this is quite a bit simpler to implement, and the existing test coverage pretty much handles it (you just gotta switch the order of the "arguments", as it were).

  • Pipeline finished with Failed
    5 months ago
    Total: 198s
    #347383
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts

    As I play with this more, I kind of wonder...do we even need to expose createCopy() as an action?

    We already changed EntityDisplayBase::set() so that, if you update the ID, the associated properties are updated as well.

    And we already have a fail_if_exists flag in cloneAs -- it's a wrapper around both create and createIfNotExists.

    So maybe there is actually no bug here at all, and we just should rip out createCopy, because it's not necessary. You could clone entity displays politely like this:

    core.entity_view_display.node.foo.teaser:
      cloneAs:
        id: node.foo.search_result
        fail_if_exists: false # This is the default, by the way
    

    The problem here, again, is wildcards. It's hard to do cloning with wildcards. I think that is why we exposed createCopy() as an action in the first place. But that obviously has its own problems. So I am now +1 on removing createCopy().

    But we still need to figure out how to support wildcards. One possibility is to change cloneAs so that it supports positional wildcard arguments, something like this:

    core.entity_view_display.node.*.teaser:
      cloneAs:
        id: node.${1}.search_result
        fail_if_exists: false
    

    In this example, the ${1} is replaced by the second period-separated component of the original entity's ID. This would be giving cloneAs a superpower, but it would be similar in syntax to inputs and would handle the problem of cloning when wildcards are there.

  • Pipeline finished with Canceled
    5 months ago
    Total: 274s
    #347405
  • Pipeline finished with Success
    5 months ago
    Total: 4219s
    #347410
  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    I can confirm that new approach works for Search recipe from Drupal CMS

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany a.dmitriiev

    Checked the changes, they are working properly in the recipe for entities with complex ids.

  • Pipeline finished with Success
    4 months ago
    Total: 1545s
    #349416
  • Pipeline finished with Success
    4 months ago
    Total: 1112s
    #349588
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom alexpott ๐Ÿ‡ช๐Ÿ‡บ๐ŸŒ

    alexpott โ†’ changed the visibility of the branch 3483353-entity-copy-use-existing to hidden.

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

    Adjusting credit.

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

    Tagging for change record update on commit.

  • Pipeline finished with Canceled
    4 months ago
    Total: 840s
    #349631
  • Pipeline finished with Success
    4 months ago
    Total: 2218s
    #349640
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom alexpott ๐Ÿ‡ช๐Ÿ‡บ๐ŸŒ

    Committed and pushed 3de28c0f679 to 11.x and fef85c9a8d8 to 11.1.x and d7ddf065f91 to 10.5.x and 21d16eedcce to 10.4.x. Thanks!

    Which CRs need updating?

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

    Updated [#3481718].

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024