Problem/Motivation

I'm in the process of porting the Search API module to D8 and just tried to create a new config entity type, for search indexes (see here).
As you can see, I renamed all entity keys, since they were already named like this in D7 (where I built on the Entity API contrib module). I'd expect the corresponding functions, like id() and status(), to respect these settings. However, this doesn't seem to be the case.

I had to override id() manually to provide the right field, otherwise the storage controller (which also doesn't seem to use the entity_keys setting, at least there) threw an exception. The entity's status() method also uses the status field instead of enabled, and ConfigEntityBase even adds the property public $status = TRUE;, no matter whether you want that field, or are even using it for something completely different, etc.
I couldn't really test uuid(), as the field is called uuid on my entity, but it seems to have the same problem. Only label() seems to work fine, for whatever reason.

Proposed resolution

Rewrite the id(), uuid() and status() methods on Entity and ConfigEntityBase to use the specified entity keys. Also remove ConfigEntityBase::status as long as the object properties are directly used as the entity fields (compared to, e.g., the approach of EntityNG – which seems to have the same problem, though).

Remaining tasks

Problem to be confirmed.
Patch to be written and tested.
Tests to be written.

User interface changes

None.

API changes

I think this would only fix the current API as it is expected to work.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tim.plunkett’s picture

balagan’s picture

The mentioned issue in #1 is fixed and committed. Did that solve it?

tim.plunkett’s picture

Status: Active » Closed (duplicate)
Related issues: +#2429169: ConfigEntityBase::sort() ignores the entity_keys configuration

Even though this issue is way older, #2429169: ConfigEntityBase::sort() ignores the entity_keys configuration is tackling the same problem. Closing as a duplicate.

MattA’s picture

Status: Closed (duplicate) » Postponed

Hmm,

#2182239 only fixed this issue for content entities, not config.
#2004336 seems to be a completely different problem.
#2429169 isn't named very well, and only fixes the problem for 'weight' keys. It does not contain an overall solution for other keys like 'id' or 'status'.

Going to set this as postponed until #2429169: ConfigEntityBase::sort() ignores the entity_keys configuration is either committed or the patch is expanded in scope to actually solve this problem.

tim.plunkett’s picture

Status: Needs review » Needs work

The last submitted patch, 5: 2052083-entity_keys-5.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
479 bytes
2.74 KB

Heh, turns out we use blocks A LOT in tests.

tim.plunkett’s picture

The last submitted patch, 7: 2052083-entity_keys-7.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 8: 2052083-entity_keys-8.patch, failed testing.

tim.plunkett’s picture

Assigned: Unassigned » tim.plunkett

Working more on this.

tim.plunkett’s picture

Title: entity_keys seem to be largely ignored » EntityType::getKey() should be used instead of hardcoding id, status, weight, etc.
Status: Needs work » Needs review
FileSize
41.1 KB
46.53 KB

Fixing all the unit tests that bypass getKey.

Status: Needs review » Needs work

The last submitted patch, 12: 2052083-entity_keys-12.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
46.98 KB
458 bytes
dawehner’s picture

Interesting #1826602-50: Allow all configuration entities to be enabled/disabled argued against using keys for everything.

+++ b/core/modules/editor/src/Entity/Editor.php
@@ -17,7 +17,8 @@
  *   label = @Translation("Text Editor"),
  *   entity_keys = {
- *     "id" = "format"
+ *     "id" = "format",
+ *     "status" = "status",
  *   },
  *   config_export = {

If we need that this is an API change, so if we want to do that, we need to adapt \Drupal\Core\Config\Entity\ConfigEntityType::__construct to deal with it.

tim.plunkett’s picture

It's interesting, because some entity types already had status in their annotation.

I too would just prefer people override the methods if they're going to change the property they use. That would make more sense for status, unfortunately we didn't standardized on id/label for every one earlier.

Agreed on fixing the constructor for status.

tim.plunkett’s picture

dawehner’s picture

So for test coverage purposes at least one entity type should not specify it.
While I see usecases for id(), its hard to see usecases for status(), given that its a concept in the Drupal domain, unlike id() which is a very generic concept.

tim.plunkett’s picture

Thanks for asking for tests, if you look at my last interdiff you'll see I added it to ContentEntityType not ConfigEntityType, whoops!

tim.plunkett’s picture

Issue tags: +rc target triage

PIFT is having issues today, it can't get results from Drupal CI. but if you click all the way through, you'll see that the FAIL failed and the PASS passed :)

Status: Needs review » Needs work

The last submitted patch, 19: 2052083-entity_keys-19-FAIL.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 19: 2052083-entity_keys-19-FAIL.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review

Get it together DrupalCI. And I uploaded the pass/fail in the other order, why did you switch them...

dawehner’s picture

+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -253,13 +256,20 @@ public function createDuplicate() {
+    $entity_type = $a->getEntityType();
+    if ($entity_type->hasKey('weight')) {
+      $weight_key = $entity_type->getKey('weight');
...
+
+    if ($a_weight == $b_weight) {
+      return strnatcasecmp($a->label(), $b->label());
+    }

Is there any way to optimize this maybe? Sorting could potentially call that method really often.

In general it feels quite harsh to rewrite all that tests to use prophecy. it makes the patch much bigger than it has to be.

tim.plunkett’s picture

Assigned: tim.plunkett » Unassigned

1) I'm not sure how to optimize this.
We need the getEntityType() call to find the keys...

2) In order to fix this issue, we have to switch from this:

$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
$entity_type->expects($this->any())
  ->method('getKey')
  ->with('label')
  ->will($this->returnValue('label'));

to either this

$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
$entity_type->expects($this->any())
  ->method('getKey')
  ->willReturnMap([
    ['id', 'id'],
    ['label', 'label'],
  ]);

or

$entity_type = $this->prophesize(EntityTypeInterface::class);
$entity_type->getKey('id')->willReturn('id');
$entity_type->getKey('label')->willReturn('label');

I consider the latter more readable and maintainable. I only switched the mocks when they had to be rewritten anyway.

dawehner’s picture

The other scary bit about this, is that the container is accessed in the constructor, according to tim.

tim.plunkett’s picture

Issue tags: -rc target triage

\Drupal\Core\Entity\Entity::id() with this patch:

  public function id() {
    $id_key = $this->getEntityType()->getKey('id');
    return $id_key && isset($this->{$id_key}) ? $this->{$id_key} : NULL;
  }

Entity::getEntityType() in HEAD and unchanged here:

  public function getEntityType() {
    return $this->entityManager()->getDefinition($this->getEntityTypeId());
  }

And of course, entityManager():

  protected function entityManager() {
    return \Drupal::entityManager();
  }

So yeah, this change results in the container being consulted in entity constructors.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work

After 6 years wonder if this is still valid.

Imagine it could use a issue summary update.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.