From ffe69958b02367dcd2c1141163a4aa498c36f5e2 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Wed, 31 Jul 2019 08:52:27 +0100 Subject: [PATCH] Issue #2450793 by Berdir, Mile23, Wim Leers, mikelutz, xjm, TR: Properly deprecate support for entity type label callbacks --- .../Drupal/Core/Entity/ContentEntityBase.php | 3 +- core/lib/Drupal/Core/Entity/EntityBase.php | 3 +- core/lib/Drupal/Core/Entity/EntityType.php | 10 ++--- .../Core/Entity/EntityTypeInterface.php | 15 +++---- .../src/JsonApiResource/ResourceObject.php | 6 +-- core/modules/user/src/Entity/User.php | 8 +++- ...llbackTest.php => UserEntityLabelTest.php} | 2 +- .../user/tests/src/Kernel/UserLegacyTest.php | 10 +++++ core/modules/user/user.module | 7 +-- .../Core/Entity/ContentEntityBaseUnitTest.php | 9 +++- .../Tests/Core/Entity/EntityTypeTest.php | 43 +++++++++++++++++++ .../Tests/Core/Entity/EntityUnitTest.php | 12 ++++-- 12 files changed, 99 insertions(+), 29 deletions(-) rename core/modules/user/tests/src/Kernel/{UserEntityLabelCallbackTest.php => UserEntityLabelTest.php} (96%) diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index 19ad14fca9e3..5ca737ffbf3e 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -1246,7 +1246,8 @@ public function __clone() { public function label() { $label = NULL; $entity_type = $this->getEntityType(); - if (($label_callback = $entity_type->getLabelCallback()) && is_callable($label_callback)) { + if (($label_callback = $entity_type->get('label_callback')) && is_callable($label_callback)) { + @trigger_error('Entity type ' . $this->getEntityTypeId() . ' defines a label callback. Support for that is deprecated in drupal:8.0.0 and will be removed in drupal:9.0.0. Override the EntityInterface::label() method instead. See https://www.drupal.org/node/3050794', E_USER_DEPRECATED); $label = call_user_func($label_callback, $this); } elseif (($label_key = $entity_type->getKey('label'))) { diff --git a/core/lib/Drupal/Core/Entity/EntityBase.php b/core/lib/Drupal/Core/Entity/EntityBase.php index f6d0b358d889..66a3857dc047 100644 --- a/core/lib/Drupal/Core/Entity/EntityBase.php +++ b/core/lib/Drupal/Core/Entity/EntityBase.php @@ -166,7 +166,8 @@ public function bundle() { public function label() { $label = NULL; $entity_type = $this->getEntityType(); - if (($label_callback = $entity_type->getLabelCallback()) && is_callable($label_callback)) { + if (($label_callback = $entity_type->get('label_callback')) && is_callable($label_callback)) { + @trigger_error('Entity type ' . $this->getEntityTypeId() . ' defines a label callback. Support for that is deprecated in drupal:8.0.0 and will be removed in drupal:9.0.0. Override the EntityInterface::label() method instead. See https://www.drupal.org/node/3050794', E_USER_DEPRECATED); $label = call_user_func($label_callback, $this); } elseif (($label_key = $entity_type->getKey('label')) && isset($this->{$label_key})) { diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php index c7d60384c4d8..388ea31a5467 100644 --- a/core/lib/Drupal/Core/Entity/EntityType.php +++ b/core/lib/Drupal/Core/Entity/EntityType.php @@ -96,13 +96,10 @@ class EntityType extends PluginDefinition implements EntityTypeInterface { * * @var callable|null * - * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. - * Use Drupal\Core\Entity\EntityInterface::label() for complex label - * generation as needed. + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the + * EntityInterface::label() method instead for dynamic labels. * * @see \Drupal\Core\Entity\EntityInterface::label() - * - * @todo Remove usages of label_callback https://www.drupal.org/node/2450793. */ protected $label_callback = NULL; @@ -667,6 +664,7 @@ public function setLinkTemplate($key, $path) { * {@inheritdoc} */ public function getLabelCallback() { + @trigger_error('EntityType::getLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794', E_USER_DEPRECATED); return $this->label_callback; } @@ -674,6 +672,7 @@ public function getLabelCallback() { * {@inheritdoc} */ public function setLabelCallback($callback) { + @trigger_error('EntityType::setLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794', E_USER_DEPRECATED); $this->label_callback = $callback; return $this; } @@ -682,6 +681,7 @@ public function setLabelCallback($callback) { * {@inheritdoc} */ public function hasLabelCallback() { + @trigger_error('EntityType::hasabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794', E_USER_DEPRECATED); return isset($this->label_callback); } diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php index 77fa4933adc3..3a6702281da4 100644 --- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php @@ -488,15 +488,12 @@ public function setLinkTemplate($key, $path); * @return callable|null * The callback, or NULL if none exists. * - * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. - * Use Drupal\Core\Entity\EntityInterface::label() for complex label - * generation as needed. + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the + * EntityInterface::label() method instead for dynamic labels. * * @see \Drupal\Core\Entity\EntityInterface::label() * @see \Drupal\Core\Entity\EntityTypeInterface::setLabelCallback() * @see \Drupal\Core\Entity\EntityTypeInterface::hasLabelCallback() - * - * @todo Remove usages of label_callback https://www.drupal.org/node/2450793. */ public function getLabelCallback(); @@ -508,8 +505,8 @@ public function getLabelCallback(); * * @return $this * - * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. - * Use EntityInterface::label() for complex label generation as needed. + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the + * EntityInterface::label() method instead for dynamic labels. * * @see \Drupal\Core\Entity\EntityInterface::label() * @see \Drupal\Core\Entity\EntityTypeInterface::getLabelCallback() @@ -522,8 +519,8 @@ public function setLabelCallback($callback); * * @return bool * - * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. - * Use EntityInterface::label() for complex label generation as needed. + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the + * EntityInterface::label() method instead for dynamic labels. * * @see \Drupal\Core\Entity\EntityInterface::label() * @see \Drupal\Core\Entity\EntityTypeInterface::getLabelCallback() diff --git a/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php b/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php index 8a08cb3d4e2e..0540248c9b9c 100644 --- a/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php +++ b/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php @@ -281,10 +281,10 @@ protected static function extractContentEntityFields(ResourceType $resource_type [$resource_type, 'isFieldEnabled'] ); - // The "label" field needs special treatment: some entity types have a label - // field that is actually backed by a label callback. + // Special handling for user entities. + // @todo Improve in https://www.drupal.org/project/drupal/issues/3057175. $entity_type = $entity->getEntityType(); - if ($entity_type->hasLabelCallback()) { + if ($entity_type->id() == 'user') { $fields[static::getLabelFieldName($entity)]->value = $entity->label(); } diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 8ed8dfdac8c0..f693fe3826bd 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -48,7 +48,6 @@ * admin_permission = "administer users", * base_table = "users", * data_table = "users_field_data", - * label_callback = "user_format_name", * translatable = TRUE, * entity_keys = { * "id" = "uid", @@ -83,6 +82,13 @@ public function isNew() { return !empty($this->enforceIsNew) || $this->id() === NULL; } + /** + * {@inheritdoc} + */ + public function label() { + return $this->getDisplayName(); + } + /** * {@inheritdoc} */ diff --git a/core/modules/user/tests/src/Kernel/UserEntityLabelCallbackTest.php b/core/modules/user/tests/src/Kernel/UserEntityLabelTest.php similarity index 96% rename from core/modules/user/tests/src/Kernel/UserEntityLabelCallbackTest.php rename to core/modules/user/tests/src/Kernel/UserEntityLabelTest.php index e815c4c0af28..625631e0ef54 100644 --- a/core/modules/user/tests/src/Kernel/UserEntityLabelCallbackTest.php +++ b/core/modules/user/tests/src/Kernel/UserEntityLabelTest.php @@ -11,7 +11,7 @@ * * @group user */ -class UserEntityLabelCallbackTest extends KernelTestBase { +class UserEntityLabelTest extends KernelTestBase { use UserCreationTrait; diff --git a/core/modules/user/tests/src/Kernel/UserLegacyTest.php b/core/modules/user/tests/src/Kernel/UserLegacyTest.php index 46abae4aa4c8..fb7fa3096632 100644 --- a/core/modules/user/tests/src/Kernel/UserLegacyTest.php +++ b/core/modules/user/tests/src/Kernel/UserLegacyTest.php @@ -84,4 +84,14 @@ public function testUserDeleteMultiple() { $this->assert(NULL === User::load(11), "User 11 has been deleted"); } + /** + * Tests user_format_name(). + * + * @expectedDeprecation user_format_name() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use $account->label() or $account->getDisplayName() instead. See https://www.drupal.org/node/3050794 + */ + public function testUserFormatName() { + $user = User::create(['name' => 'foo', 'uid' => 10]); + $this->assertSame('foo', user_format_name($user)); + } + } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 6f46ca3b0e74..7c18443ef1aa 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -436,12 +436,13 @@ function user_preprocess_block(&$variables) { * @return string * An unsanitized string with the username to display. * - * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. - * Use \Drupal\Core\Session\AccountInterface::getDisplayName(). + * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. + * Use $account->label() or $account->getDisplayName() instead * - * @todo Remove usage in https://www.drupal.org/node/2311219. + * @see https://www.drupal.org/node/3050794 */ function user_format_name(AccountInterface $account) { + @trigger_error('user_format_name() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use $account->label() or $account->getDisplayName() instead. See https://www.drupal.org/node/3050794', E_USER_DEPRECATED); return $account->getDisplayName(); } diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php index 02c7a371e227..ce2c999698fa 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php @@ -12,6 +12,7 @@ use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\TypedData\TypedDataManagerInterface; +use Drupal\Tests\Traits\ExpectDeprecationTrait; use Drupal\Tests\UnitTestCase; use Drupal\Core\Language\Language; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -23,6 +24,8 @@ */ class ContentEntityBaseUnitTest extends UnitTestCase { + use ExpectDeprecationTrait; + /** * The bundle of the entity under test. * @@ -475,6 +478,9 @@ public function testAccess() { * @group legacy */ public function testLabel() { + + $this->expectDeprecation('Entity type ' . $this->entityTypeId . ' defines a label callback. Support for that is deprecated in drupal:8.0.0 and will be removed in drupal:9.0.0. Override the EntityInterface::label() method instead. See https://www.drupal.org/node/3050794'); + // Make a mock with one method that we use as the entity's label callback. // We check that it is called, and that the entity's label is the callback's // return value. @@ -484,7 +490,8 @@ public function testLabel() { ->method(__FUNCTION__) ->will($this->returnValue($callback_label)); $this->entityType->expects($this->once()) - ->method('getLabelCallback') + ->method('get') + ->with('label_callback') ->will($this->returnValue([$callback_container, __FUNCTION__])); $this->assertSame($callback_label, $this->entity->label()); diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php index f787a720db8b..b9eef7b9cd8f 100644 --- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php @@ -496,4 +496,47 @@ public function testIsSerializable() { $this->assertEquals('example_entity_type', $entity_type->id()); } + /** + * @covers ::getLabelCallback + * + * @group legacy + * + * @deprecatedMessage EntityType::getLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794 + */ + public function testGetLabelCallack() { + $entity_type = $this->setUpEntityType(['label_callback' => 'label_function']); + $this->assertSame('label_function', $entity_type->getLabelCallback()); + + $entity_type = $this->setUpEntityType([]); + $this->assertNull($entity_type->getLabelCallback()); + } + + /** + * @covers ::setLabelCallback + * + * @group legacy + * + * @deprecatedMessage EntityType::setLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794 + */ + public function testSetLabelCallack() { + $entity_type = $this->setUpEntityType([]); + $entity_type->setLabelCallback('label_function'); + $this->assertSame('label_function', $entity_type->get('label_callback')); + } + + /** + * @covers ::hasLabelCallback + * + * @group legacy + * + * @deprecatedMessage EntityType::hasLabelCallback() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Override the EntityInterface::label() method instead for dynamic labels. See https://www.drupal.org/node/3050794 + */ + public function testHasLabelCallack() { + $entity_type = $this->setUpEntityType(['label_callback' => 'label_function']); + $this->assertTrue($entity_type->hasLabelCallback()); + + $entity_type = $this->setUpEntityType([]); + $this->assertFalse($entity_type->hasLabelCallback()); + } + } diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php index 5a7f26814a96..f04df1b535f0 100644 --- a/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php @@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityTypeRepositoryInterface; use Drupal\Core\Language\Language; use Drupal\entity_test\Entity\EntityTestMul; +use Drupal\Tests\Traits\ExpectDeprecationTrait; use Drupal\Tests\UnitTestCase; /** @@ -19,6 +20,8 @@ */ class EntityUnitTest extends UnitTestCase { + use ExpectDeprecationTrait; + /** * The entity under test. * @@ -171,6 +174,9 @@ public function testBundle() { * @group legacy */ public function testLabel() { + + $this->expectDeprecation('Entity type ' . $this->entityTypeId . ' defines a label callback. Support for that is deprecated in drupal:8.0.0 and will be removed in drupal:9.0.0. Override the EntityInterface::label() method instead. See https://www.drupal.org/node/3050794'); + // Make a mock with one method that we use as the entity's uri_callback. We // check that it is called, and that the entity's label is the callback's // return value. @@ -181,11 +187,9 @@ public function testLabel() { ->method(__FUNCTION__) ->will($this->returnValue($callback_label)); $this->entityType->expects($this->at(0)) - ->method('getLabelCallback') + ->method('get') + ->with('label_callback') ->will($this->returnValue([$callback_container, __FUNCTION__])); - $this->entityType->expects($this->at(1)) - ->method('getLabelCallback') - ->will($this->returnValue(NULL)); $this->entityType->expects($this->at(2)) ->method('getKey') ->with('label') -- GitLab