View source
<?php
namespace Drupal\Core\Entity;
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\TypedData\TranslatableInterface as TranslatableDataInterface;
class EntityRepository implements EntityRepositoryInterface {
protected $entityTypeManager;
protected $languageManager;
protected $contextRepository;
public function __construct(EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager, ContextRepositoryInterface $context_repository = NULL) {
$this->entityTypeManager = $entity_type_manager;
$this->languageManager = $language_manager;
if (isset($context_repository)) {
$this->contextRepository = $context_repository;
}
else {
@trigger_error('The context.repository service must be passed to EntityRepository::__construct(), it is required before Drupal 9.0.0. See https://www.drupal.org/node/2938929.', E_USER_DEPRECATED);
$this->contextRepository = \Drupal::service('context.repository');
}
}
public function loadEntityByUuid($entity_type_id, $uuid) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
if (!($uuid_key = $entity_type
->getKey('uuid'))) {
throw new EntityStorageException("Entity type {$entity_type_id} does not support UUIDs.");
}
$entities = $this->entityTypeManager
->getStorage($entity_type_id)
->loadByProperties([
$uuid_key => $uuid,
]);
return $entities ? reset($entities) : NULL;
}
public function loadEntityByConfigTarget($entity_type_id, $target) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
if ($entity_type instanceof ConfigEntityTypeInterface) {
$entity = $this->entityTypeManager
->getStorage($entity_type_id)
->load($target);
}
else {
$entity = $this
->loadEntityByUuid($entity_type_id, $target);
}
return $entity;
}
public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = []) {
$translation = $entity;
if ($entity instanceof TranslatableDataInterface && count($entity
->getTranslationLanguages()) > 1) {
if (empty($langcode)) {
$langcode = $this->languageManager
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId();
$entity
->addCacheContexts([
'languages:' . LanguageInterface::TYPE_CONTENT,
]);
}
if ($entity
->language()
->getId() != $langcode) {
$context['data'] = $entity;
$context += [
'operation' => 'entity_view',
'langcode' => $langcode,
];
$candidates = $this->languageManager
->getFallbackCandidates($context);
$default_language = $entity
->getUntranslated()
->language();
$candidates[$default_language
->getId()] = LanguageInterface::LANGCODE_DEFAULT;
foreach ($candidates as $candidate) {
if ($entity
->hasTranslation($candidate)) {
$translation = $entity
->getTranslation($candidate);
break;
}
}
}
}
return $translation;
}
public function getActive($entity_type_id, $entity_id, array $contexts = NULL) {
return current($this
->getActiveMultiple($entity_type_id, [
$entity_id,
], $contexts)) ?: NULL;
}
public function getActiveMultiple($entity_type_id, array $entity_ids, array $contexts = NULL) {
$active = [];
if (!isset($contexts)) {
$contexts = $this->contextRepository
->getAvailableContexts();
}
$langcode = $this->languageManager
->isMultilingual() ? $this
->getContentLanguageFromContexts($contexts) : $this->languageManager
->getDefaultLanguage()
->getId();
$entities = $this->entityTypeManager
->getStorage($entity_type_id)
->loadMultiple($entity_ids);
foreach ($entities as $id => $entity) {
if ($entity instanceof RevisionableInterface && $entity
->getEntityType()
->isRevisionable()) {
$entity = $this
->getLatestTranslationAffectedRevision($entity, $langcode);
}
if ($entity instanceof TranslatableInterface) {
$entity = $this
->getTranslationFromContext($entity, $langcode);
}
$active[$id] = $entity;
}
return $active;
}
public function getCanonical($entity_type_id, $entity_id, array $contexts = NULL) {
return current($this
->getCanonicalMultiple($entity_type_id, [
$entity_id,
], $contexts)) ?: NULL;
}
public function getCanonicalMultiple($entity_type_id, array $entity_ids, array $contexts = NULL) {
$entities = $this->entityTypeManager
->getStorage($entity_type_id)
->loadMultiple($entity_ids);
if (!$entities || !$this->languageManager
->isMultilingual()) {
return $entities;
}
if (!isset($contexts)) {
$contexts = $this->contextRepository
->getAvailableContexts();
}
$legacy_context = [];
$key = static::CONTEXT_ID_LEGACY_CONTEXT_OPERATION;
if (isset($contexts[$key])) {
$legacy_context['operation'] = $contexts[$key]
->getContextValue();
}
$canonical = [];
$langcode = $this
->getContentLanguageFromContexts($contexts);
foreach ($entities as $id => $entity) {
$canonical[$id] = $this
->getTranslationFromContext($entity, $langcode, $legacy_context);
}
return $canonical;
}
protected function getContentLanguageFromContexts(array $contexts) {
foreach ([
LanguageInterface::TYPE_CONTENT,
LanguageInterface::TYPE_INTERFACE,
] as $language_type) {
$context_id = '@language.current_language_context:' . $language_type;
if (isset($contexts[$context_id])) {
return $contexts[$context_id]
->getContextValue()
->getId();
}
}
return $this->languageManager
->getDefaultLanguage()
->getId();
}
protected function getLatestTranslationAffectedRevision(RevisionableInterface $entity, $langcode) {
$revision = NULL;
$storage = $this->entityTypeManager
->getStorage($entity
->getEntityTypeId());
if ($entity instanceof TranslatableRevisionableInterface && $entity
->isTranslatable()) {
$revision_id = $storage
->getLatestTranslationAffectedRevisionId($entity
->id(), $langcode);
$revision = $revision_id ? $this
->loadRevision($entity, $revision_id) : NULL;
if (!$revision || $revision
->wasDefaultRevision() && !$revision
->isDefaultRevision()) {
$revision = NULL;
}
}
if (!isset($revision)) {
$revision_id = $storage
->getLatestRevisionId($entity
->id());
$revision = $this
->loadRevision($entity, $revision_id);
}
return $revision;
}
protected function loadRevision(RevisionableInterface $entity, $revision_id) {
if ($entity
->getLoadedRevisionId() != $revision_id) {
$storage = $this->entityTypeManager
->getStorage($entity
->getEntityTypeId());
return $storage
->loadRevision($revision_id);
}
return $entity;
}
}