Skip to content
Snippets Groups Projects
Commit adedbb17 authored by catch's avatar catch
Browse files

Issue #3158130 by longwave, Berdir, voleger, mayurjadhav, ranjith_kumar_k_u,...

Issue #3158130 by longwave, Berdir, voleger, mayurjadhav, ranjith_kumar_k_u, _pratik_, smustgrave, acbramley: Many calls to ContextRepository::getAvailableContexts() due to entity upcasting
parent ff0bc592
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface; use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\Context\ContextInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface; use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\TypedData\TranslatableInterface as TranslatableDataInterface; use Drupal\Core\TypedData\TranslatableInterface as TranslatableDataInterface;
...@@ -137,7 +138,7 @@ public function getActiveMultiple($entity_type_id, array $entity_ids, array $con ...@@ -137,7 +138,7 @@ public function getActiveMultiple($entity_type_id, array $entity_ids, array $con
$active = []; $active = [];
if (!isset($contexts)) { if (!isset($contexts)) {
$contexts = $this->contextRepository->getAvailableContexts(); $contexts = [];
} }
// @todo Consider implementing a more performant version of this logic fully // @todo Consider implementing a more performant version of this logic fully
...@@ -186,21 +187,19 @@ public function getCanonicalMultiple($entity_type_id, array $entity_ids, array $ ...@@ -186,21 +187,19 @@ public function getCanonicalMultiple($entity_type_id, array $entity_ids, array $
} }
if (!isset($contexts)) { if (!isset($contexts)) {
$contexts = $this->contextRepository->getAvailableContexts(); $contexts = [];
} }
// @todo Consider deprecating the legacy context operation altogether in $key = '@entity.repository:legacy_context_operation';
// https://www.drupal.org/node/3031124.
$legacy_context = [];
$key = static::CONTEXT_ID_LEGACY_CONTEXT_OPERATION;
if (isset($contexts[$key])) { if (isset($contexts[$key])) {
$legacy_context['operation'] = $contexts[$key]->getContextValue(); @trigger_error('Providing an \Drupal\Core\Entity\EntityRepositoryInterface::CONTEXT_ID_LEGACY_CONTEXT_OPERATION context to EntityRepository::getCanonicalMultiple() is deprecated in drupal:10.3.0 and is removed from drupal:12.0.0. There is no replacement. See https://www.drupal.org/node/3437685', E_USER_DEPRECATED);
$contexts['operation'] = $contexts[$key]->getContextValue();
} }
$canonical = []; $canonical = [];
$langcode = $this->getContentLanguageFromContexts($contexts); $langcode = $this->getContentLanguageFromContexts($contexts);
foreach ($entities as $id => $entity) { foreach ($entities as $id => $entity) {
$canonical[$id] = $this->getTranslationFromContext($entity, $langcode, $legacy_context); $canonical[$id] = $this->getTranslationFromContext($entity, $langcode, $contexts);
} }
return $canonical; return $canonical;
...@@ -209,22 +208,33 @@ public function getCanonicalMultiple($entity_type_id, array $entity_ids, array $ ...@@ -209,22 +208,33 @@ public function getCanonicalMultiple($entity_type_id, array $entity_ids, array $
/** /**
* Retrieves the current content language from the specified contexts. * Retrieves the current content language from the specified contexts.
* *
* @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts * This is a BC layer to support plugin context system identifiers, the
* langcode key should be used instead and is preferred when given.
*
* @param string[] $contexts
* An array of context items. * An array of context items.
* *
* @return string|null * @return string|null
* A language code or NULL if no language context was provided. * A language code or NULL if no language context was provided.
*
* @internal
*/ */
protected function getContentLanguageFromContexts(array $contexts) { protected function getContentLanguageFromContexts(array $contexts) {
if (isset($contexts['langcode'])) {
return $contexts['langcode'];
}
// Content language might not be configurable, in which case we need to fall // Content language might not be configurable, in which case we need to fall
// back to a configurable language type. // back to a configurable language type.
foreach ([LanguageInterface::TYPE_CONTENT, LanguageInterface::TYPE_INTERFACE] as $language_type) { foreach ([LanguageInterface::TYPE_CONTENT, LanguageInterface::TYPE_INTERFACE] as $language_type) {
$context_id = '@language.current_language_context:' . $language_type; $context_id = '@language.current_language_context:' . $language_type;
if (isset($contexts[$context_id])) { if (isset($contexts[$context_id]) && $contexts[$context_id] instanceof ContextInterface) {
@trigger_error('Providing the language as ' . $context_id . ' context to EntityRepository is deprecated in drupal:10.3.0 and is removed from drupal:12.0.0. Use the langcode key instead. See https://www.drupal.org/node/3437685', E_USER_DEPRECATED);
return $contexts[$context_id]->getContextValue()->getId(); return $contexts[$context_id]->getContextValue()->getId();
} }
} }
return $this->languageManager->getDefaultLanguage()->getId(); return $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
} }
/** /**
......
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
*/ */
interface EntityRepositoryInterface { interface EntityRepositoryInterface {
/**
* @deprecated in drupal:10.3.0 and is removed from drupal:12.0.0. There is no
* replacement.
*
* @see https://www.drupal.org/node/3437685
*/
const CONTEXT_ID_LEGACY_CONTEXT_OPERATION = '@entity.repository:legacy_context_operation'; const CONTEXT_ID_LEGACY_CONTEXT_OPERATION = '@entity.repository:legacy_context_operation';
/** /**
...@@ -62,7 +68,8 @@ public function loadEntityByConfigTarget($entity_type_id, $target); ...@@ -62,7 +68,8 @@ public function loadEntityByConfigTarget($entity_type_id, $target);
* content language. * content language.
* @param array $context * @param array $context
* (optional) An associative array of arbitrary data that can be useful to * (optional) An associative array of arbitrary data that can be useful to
* determine the proper fallback sequence. * determine the proper fallback sequence. See
* \Drupal\Core\Language\LanguageManagerInterface::getFallbackCandidates().
* *
* @return \Drupal\Core\Entity\EntityInterface|null * @return \Drupal\Core\Entity\EntityInterface|null
* An entity object for the translated data, or NULL if the requested * An entity object for the translated data, or NULL if the requested
...@@ -93,10 +100,11 @@ public function getTranslationFromContext(EntityInterface $entity, $langcode = N ...@@ -93,10 +100,11 @@ public function getTranslationFromContext(EntityInterface $entity, $langcode = N
* The entity type identifier. * The entity type identifier.
* @param int|string $entity_id * @param int|string $entity_id
* An entity identifier. * An entity identifier.
* @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts * @param array|null $contexts
* (optional) An associative array of objects representing the contexts the * (optional) An associative array of arbitrary data that can be useful to
* entity will be edited in keyed by fully qualified context ID. Defaults to * determine the proper fallback sequence. See
* the currently available contexts. * \Drupal\Core\Language\LanguageManagerInterface::getFallbackCandidates().
* Using context ids from the plugin context system is deprecated.
* *
* @return \Drupal\Core\Entity\EntityInterface|null * @return \Drupal\Core\Entity\EntityInterface|null
* An entity object variant or NULL if the entity does not exist. * An entity object variant or NULL if the entity does not exist.
...@@ -110,10 +118,11 @@ public function getActive($entity_type_id, $entity_id, array $contexts = NULL); ...@@ -110,10 +118,11 @@ public function getActive($entity_type_id, $entity_id, array $contexts = NULL);
* The entity type identifier. * The entity type identifier.
* @param int[]|string[] $entity_ids * @param int[]|string[] $entity_ids
* An array of entity identifiers. * An array of entity identifiers.
* @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts * @param array|null $contexts
* (optional) An associative array of objects representing the contexts the * (optional) An associative array of arbitrary data that can be useful to
* entity will be edited in keyed by fully qualified context ID. Defaults to * determine the proper fallback sequence. See
* the currently available contexts. * \Drupal\Core\Language\LanguageManagerInterface::getFallbackCandidates().
* Using context ids from the plugin context system is deprecated.
* *
* @return \Drupal\Core\Entity\EntityInterface[] * @return \Drupal\Core\Entity\EntityInterface[]
* An array of entity object variants keyed by entity ID. * An array of entity object variants keyed by entity ID.
...@@ -139,10 +148,11 @@ public function getActiveMultiple($entity_type_id, array $entity_ids, array $con ...@@ -139,10 +148,11 @@ public function getActiveMultiple($entity_type_id, array $entity_ids, array $con
* The entity type identifier. * The entity type identifier.
* @param int|string $entity_id * @param int|string $entity_id
* An entity identifier. * An entity identifier.
* @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts * @param array|null $contexts
* (optional) An associative array of objects representing the contexts the * (optional) An associative array of arbitrary data that can be useful to
* entity will be edited in keyed by fully qualified context ID. Defaults to * determine the proper fallback sequence. See
* the currently available contexts. * \Drupal\Core\Language\LanguageManagerInterface::getFallbackCandidates().
* Using context ids from the plugin context system is deprecated.
* *
* @return \Drupal\Core\Entity\EntityInterface|null * @return \Drupal\Core\Entity\EntityInterface|null
* An entity object variant or NULL if the entity does not exist. * An entity object variant or NULL if the entity does not exist.
...@@ -156,10 +166,11 @@ public function getCanonical($entity_type_id, $entity_id, array $contexts = NULL ...@@ -156,10 +166,11 @@ public function getCanonical($entity_type_id, $entity_id, array $contexts = NULL
* The entity type identifier. * The entity type identifier.
* @param int[]|string[] $entity_ids * @param int[]|string[] $entity_ids
* An array of entity identifiers. * An array of entity identifiers.
* @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts * @param array|null $contexts
* (optional) An associative array of objects representing the contexts the * (optional) An associative array of arbitrary data that can be useful to
* entity will be edited in keyed by fully qualified context ID. Defaults to * determine the proper fallback sequence. See
* the currently available contexts. * \Drupal\Core\Language\LanguageManagerInterface::getFallbackCandidates().
* Using context ids from the plugin context system is deprecated.
* *
* @return \Drupal\Core\Entity\EntityInterface[] * @return \Drupal\Core\Entity\EntityInterface[]
* An array of entity object variants keyed by entity ID. * An array of entity object variants keyed by entity ID.
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
/** /**
...@@ -132,24 +130,7 @@ public function convert($value, $definition, $name, array $defaults) { ...@@ -132,24 +130,7 @@ public function convert($value, $definition, $name, array $defaults) {
return $entity; return $entity;
} }
// Do not inject the context repository as it is not an actual dependency: $contexts = ['operation' => 'entity_upcast'];
// it will be removed once both the todo items below are fixed.
/** @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface $contexts_repository */
$contexts_repository = \Drupal::service('context.repository');
// @todo Consider deprecating the legacy context operation altogether in
// https://www.drupal.org/node/3031124.
$contexts = $contexts_repository->getAvailableContexts();
$contexts[EntityRepositoryInterface::CONTEXT_ID_LEGACY_CONTEXT_OPERATION] =
new Context(new ContextDefinition('string'), 'entity_upcast');
// @todo At the moment we do not need the current user context, which is
// triggering some test failures. We can remove these lines once
// https://www.drupal.org/node/2934192 is fixed.
$context_id = '@user.current_user_context:current_user';
if (isset($contexts[$context_id])) {
$account = $contexts[$context_id]->getContextValue();
unset($account->_skipProtectedUserFieldConstraint);
unset($contexts[$context_id]);
}
$entity = $this->entityRepository->getCanonical($entity_type_id, $value, $contexts); $entity = $this->entityRepository->getCanonical($entity_type_id, $value, $contexts);
if ( if (
......
...@@ -154,11 +154,11 @@ public function testAnonymous() { ...@@ -154,11 +154,11 @@ public function testAnonymous() {
$recorded_queries = $performance_data->getQueries(); $recorded_queries = $performance_data->getQueries();
$this->assertSame($expected_queries, $recorded_queries); $this->assertSame($expected_queries, $recorded_queries);
$this->assertSame(12, $performance_data->getQueryCount()); $this->assertSame(12, $performance_data->getQueryCount());
$this->assertSame(80, $performance_data->getCacheGetCount()); $this->assertSame(79, $performance_data->getCacheGetCount());
$this->assertSame(16, $performance_data->getCacheSetCount()); $this->assertSame(16, $performance_data->getCacheSetCount());
$this->assertSame(0, $performance_data->getCacheDeleteCount()); $this->assertSame(0, $performance_data->getCacheDeleteCount());
$this->assertCountBetween(22, 23, $performance_data->getCacheTagChecksumCount()); $this->assertCountBetween(22, 23, $performance_data->getCacheTagChecksumCount());
$this->assertCountBetween(33, 34, $performance_data->getCacheTagIsValidCount()); $this->assertCountBetween(32, 33, $performance_data->getCacheTagIsValidCount());
$this->assertSame(0, $performance_data->getCacheTagInvalidationCount()); $this->assertSame(0, $performance_data->getCacheTagInvalidationCount());
} }
...@@ -204,7 +204,7 @@ public function testLogin(): void { ...@@ -204,7 +204,7 @@ public function testLogin(): void {
$recorded_queries = $performance_data->getQueries(); $recorded_queries = $performance_data->getQueries();
$this->assertSame($expected_queries, $recorded_queries); $this->assertSame($expected_queries, $recorded_queries);
$this->assertSame(15, $performance_data->getQueryCount()); $this->assertSame(15, $performance_data->getQueryCount());
$this->assertSame(64, $performance_data->getCacheGetCount()); $this->assertSame(63, $performance_data->getCacheGetCount());
$this->assertSame(1, $performance_data->getCacheSetCount()); $this->assertSame(1, $performance_data->getCacheSetCount());
$this->assertSame(1, $performance_data->getCacheDeleteCount()); $this->assertSame(1, $performance_data->getCacheDeleteCount());
$this->assertSame(1, $performance_data->getCacheTagChecksumCount()); $this->assertSame(1, $performance_data->getCacheTagChecksumCount());
......
...@@ -4,9 +4,6 @@ ...@@ -4,9 +4,6 @@
namespace Drupal\KernelTests\Core\Entity; namespace Drupal\KernelTests\Core\Entity;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\entity_test\Entity\EntityTest; use Drupal\entity_test\Entity\EntityTest;
use Drupal\KernelTests\KernelTestBase; use Drupal\KernelTests\KernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage; use Drupal\language\Entity\ConfigurableLanguage;
...@@ -320,11 +317,7 @@ protected function assertEntityType(?object $entity, string $expected_entity_typ ...@@ -320,11 +317,7 @@ protected function assertEntityType(?object $entity, string $expected_entity_typ
* An array of contexts. * An array of contexts.
*/ */
protected function getLanguageContexts($langcode) { protected function getLanguageContexts($langcode) {
$prefix = '@language.current_language_context:'; return ['langcode' => $langcode];
return [
$prefix . LanguageInterface::TYPE_INTERFACE => new Context(new ContextDefinition('language'), $langcode),
$prefix . LanguageInterface::TYPE_CONTENT => new Context(new ContextDefinition('language'), $langcode),
];
} }
} }
...@@ -12,9 +12,6 @@ ...@@ -12,9 +12,6 @@
use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\ParamConverter\EntityConverter; use Drupal\Core\ParamConverter\EntityConverter;
use Drupal\Core\ParamConverter\ParamNotConvertedException; use Drupal\Core\ParamConverter\ParamNotConvertedException;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\TypedData\DataDefinition; use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\Core\TypedData\TypedDataManagerInterface; use Drupal\Core\TypedData\TypedDataManagerInterface;
...@@ -108,11 +105,6 @@ protected function setUpMocks($service_map = []) { ...@@ -108,11 +105,6 @@ protected function setUpMocks($service_map = []) {
->with('entity_test') ->with('entity_test')
->willReturn($entity_type); ->willReturn($entity_type);
$context_repository = $this->createMock(ContextRepositoryInterface::class);
$context_repository->expects($this->any())
->method('getAvailableContexts')
->willReturn([]);
$context_definition = $this->createMock(DataDefinition::class); $context_definition = $this->createMock(DataDefinition::class);
foreach (['setLabel', 'setDescription', 'setRequired', 'setConstraints'] as $method) { foreach (['setLabel', 'setDescription', 'setRequired', 'setConstraints'] as $method) {
$context_definition->expects($this->any()) $context_definition->expects($this->any())
...@@ -132,7 +124,6 @@ protected function setUpMocks($service_map = []) { ...@@ -132,7 +124,6 @@ protected function setUpMocks($service_map = []) {
->willReturn($context_definition); ->willReturn($context_definition);
$service_map += [ $service_map += [
'context.repository' => $context_repository,
'typed_data_manager' => $typed_data_manager, 'typed_data_manager' => $typed_data_manager,
]; ];
...@@ -221,11 +212,8 @@ public static function providerTestConvert() { ...@@ -221,11 +212,8 @@ public static function providerTestConvert() {
public function testConvertWithInvalidEntityType() { public function testConvertWithInvalidEntityType() {
$this->setUpMocks(); $this->setUpMocks();
$contexts = [
EntityRepositoryInterface::CONTEXT_ID_LEGACY_CONTEXT_OPERATION => new Context(new ContextDefinition('string'), 'entity_upcast'),
];
$plugin_id = 'invalid_id'; $plugin_id = 'invalid_id';
$contexts = ['operation' => 'entity_upcast'];
$this->entityRepository->expects($this->once()) $this->entityRepository->expects($this->once())
->method('getCanonical') ->method('getCanonical')
->with($plugin_id, 'id', $contexts) ->with($plugin_id, 'id', $contexts)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment