3 namespace Drupal\Core\Entity;
5 use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
6 use Drupal\Core\Language\LanguageInterface;
7 use Drupal\Core\Language\LanguageManagerInterface;
8 use Drupal\Core\TypedData\TranslatableInterface;
11 * Provides several mechanisms for retrieving entities.
13 class EntityRepository implements EntityRepositoryInterface {
16 * The entity type manager.
18 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
20 protected $entityTypeManager;
23 * The language manager.
25 * @var \Drupal\Core\Language\LanguageManagerInterface
27 protected $languageManager;
30 * Constructs a new EntityRepository.
32 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
33 * The entity type manager.
34 * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
35 * The language manager.
37 public function __construct(EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager) {
38 $this->entityTypeManager = $entity_type_manager;
39 $this->languageManager = $language_manager;
45 public function loadEntityByUuid($entity_type_id, $uuid) {
46 $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
48 if (!$uuid_key = $entity_type->getKey('uuid')) {
49 throw new EntityStorageException("Entity type $entity_type_id does not support UUIDs.");
52 $entities = $this->entityTypeManager->getStorage($entity_type_id)->loadByProperties([$uuid_key => $uuid]);
54 return ($entities) ? reset($entities) : NULL;
60 public function loadEntityByConfigTarget($entity_type_id, $target) {
61 $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
63 // For configuration entities, the config target is given by the entity ID.
64 // @todo Consider adding a method to allow entity types to indicate the
65 // target identifier key rather than hard-coding this check. Issue:
66 // https://www.drupal.org/node/2412983.
67 if ($entity_type instanceof ConfigEntityTypeInterface) {
68 $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($target);
71 // For content entities, the config target is given by the UUID.
73 $entity = $this->loadEntityByUuid($entity_type_id, $target);
82 public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = []) {
83 $translation = $entity;
85 if ($entity instanceof TranslatableInterface && count($entity->getTranslationLanguages()) > 1) {
86 if (empty($langcode)) {
87 $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
88 $entity->addCacheContexts(['languages:' . LanguageInterface::TYPE_CONTENT]);
91 // Retrieve language fallback candidates to perform the entity language
92 // negotiation, unless the current translation is already the desired one.
93 if ($entity->language()->getId() != $langcode) {
94 $context['data'] = $entity;
95 $context += ['operation' => 'entity_view', 'langcode' => $langcode];
96 $candidates = $this->languageManager->getFallbackCandidates($context);
98 // Ensure the default language has the proper language code.
99 $default_language = $entity->getUntranslated()->language();
100 $candidates[$default_language->getId()] = LanguageInterface::LANGCODE_DEFAULT;
102 // Return the most fitting entity translation.
103 foreach ($candidates as $candidate) {
104 if ($entity->hasTranslation($candidate)) {
105 $translation = $entity->getTranslation($candidate);