View source
<?php
namespace Drupal\Core\Entity;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Entity\Plugin\DataType\EntityReference;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\TranslationStatusInterface;
use Drupal\Core\TypedData\TypedDataInterface;
abstract class ContentEntityBase extends EntityBase implements \IteratorAggregate, ContentEntityInterface, TranslationStatusInterface {
use EntityChangesDetectionTrait {
getFieldsToSkipFromTranslationChangesCheck as traitGetFieldsToSkipFromTranslationChangesCheck;
}
use SynchronizableEntityTrait;
protected $values = [];
protected $fields = [];
protected $fieldDefinitions;
protected $languages;
protected $langcodeKey;
protected $defaultLangcodeKey;
protected $activeLangcode = LanguageInterface::LANGCODE_DEFAULT;
protected $defaultLangcode;
protected $translations = [];
protected $translationInitialize = FALSE;
protected $newRevision = FALSE;
protected $isDefaultRevision = TRUE;
protected $entityKeys = [];
protected $translatableEntityKeys = [];
protected $validated = FALSE;
protected $validationRequired = FALSE;
protected $loadedRevisionId;
protected $revisionTranslationAffectedKey;
protected $enforceRevisionTranslationAffected = [];
protected static $fieldsToSkipFromTranslationChangesCheck = [];
public function __construct(array $values, $entity_type, $bundle = FALSE, $translations = []) {
$this->entityTypeId = $entity_type;
$this->entityKeys['bundle'] = $bundle ? $bundle : $this->entityTypeId;
$this->langcodeKey = $this
->getEntityType()
->getKey('langcode');
$this->defaultLangcodeKey = $this
->getEntityType()
->getKey('default_langcode');
$this->revisionTranslationAffectedKey = $this
->getEntityType()
->getKey('revision_translation_affected');
foreach ($values as $key => $value) {
if (property_exists($this, $key) && isset($value[LanguageInterface::LANGCODE_DEFAULT])) {
$this->{$key} = $value[LanguageInterface::LANGCODE_DEFAULT];
}
}
$this->values = $values;
foreach ($this
->getEntityType()
->getKeys() as $key => $field_name) {
if (isset($this->values[$field_name])) {
if (is_array($this->values[$field_name])) {
if (!$this
->getFieldDefinition($field_name)
->isTranslatable()) {
if (isset($this->values[$field_name][LanguageInterface::LANGCODE_DEFAULT])) {
if (is_array($this->values[$field_name][LanguageInterface::LANGCODE_DEFAULT])) {
if (isset($this->values[$field_name][LanguageInterface::LANGCODE_DEFAULT][0]['value'])) {
$this->entityKeys[$key] = $this->values[$field_name][LanguageInterface::LANGCODE_DEFAULT][0]['value'];
}
}
else {
$this->entityKeys[$key] = $this->values[$field_name][LanguageInterface::LANGCODE_DEFAULT];
}
}
}
else {
foreach ($this->values[$field_name] as $langcode => $field_value) {
if (is_array($this->values[$field_name][$langcode])) {
if (isset($this->values[$field_name][$langcode][0]['value'])) {
$this->translatableEntityKeys[$key][$langcode] = $this->values[$field_name][$langcode][0]['value'];
}
}
else {
$this->translatableEntityKeys[$key][$langcode] = $this->values[$field_name][$langcode];
}
}
}
}
}
}
$data = isset($values[$this
->getEntityType()
->getKey('id')]) ? [
'status' => static::TRANSLATION_EXISTING,
] : [
'status' => static::TRANSLATION_CREATED,
];
$this->translations[LanguageInterface::LANGCODE_DEFAULT] = $data;
$this
->setDefaultLangcode();
if ($translations) {
foreach ($translations as $langcode) {
if ($langcode != $this->defaultLangcode && $langcode != LanguageInterface::LANGCODE_DEFAULT) {
$this->translations[$langcode] = $data;
}
}
}
if ($this
->getEntityType()
->isRevisionable()) {
$this
->updateLoadedRevisionId();
}
}
protected function getLanguages() {
if (empty($this->languages)) {
$this->languages = $this
->languageManager()
->getLanguages(LanguageInterface::STATE_ALL);
if (!isset($this->languages[$this->defaultLangcode])) {
$this->languages[$this->defaultLangcode] = new Language([
'id' => $this->defaultLangcode,
]);
}
}
return $this->languages;
}
public function postCreate(EntityStorageInterface $storage) {
$this->newRevision = TRUE;
}
public function setNewRevision($value = TRUE) {
if (!$this
->getEntityType()
->hasKey('revision')) {
throw new \LogicException("Entity type {$this->getEntityTypeId()} does not support revisions.");
}
if ($value && !$this->newRevision) {
$this
->set($this
->getEntityType()
->getKey('revision'), NULL);
}
elseif (!$value && $this->newRevision) {
$this
->set($this
->getEntityType()
->getKey('revision'), $this
->getLoadedRevisionId());
}
$this->newRevision = $value;
}
public function getLoadedRevisionId() {
return $this->loadedRevisionId;
}
public function updateLoadedRevisionId() {
$this->loadedRevisionId = $this
->getRevisionId() ?: $this->loadedRevisionId;
return $this;
}
public function isNewRevision() {
return $this->newRevision || $this
->getEntityType()
->hasKey('revision') && !$this
->getRevisionId();
}
public function isDefaultRevision($new_value = NULL) {
$return = $this->isDefaultRevision;
if (isset($new_value)) {
$this->isDefaultRevision = (bool) $new_value;
}
return $this
->isNew() || $return;
}
public function wasDefaultRevision() {
$entity_type = $this
->getEntityType();
if (!$entity_type
->isRevisionable()) {
return TRUE;
}
$revision_default_key = $entity_type
->getRevisionMetadataKey('revision_default');
$value = $this
->isNew() || $this
->get($revision_default_key)->value;
return $value;
}
public function isLatestRevision() {
$storage = $this
->entityTypeManager()
->getStorage($this
->getEntityTypeId());
return $this
->getLoadedRevisionId() == $storage
->getLatestRevisionId($this
->id());
}
public function isLatestTranslationAffectedRevision() {
$storage = $this
->entityTypeManager()
->getStorage($this
->getEntityTypeId());
return $this
->getLoadedRevisionId() == $storage
->getLatestTranslationAffectedRevisionId($this
->id(), $this
->language()
->getId());
}
public function isRevisionTranslationAffected() {
return $this
->hasField($this->revisionTranslationAffectedKey) ? $this
->get($this->revisionTranslationAffectedKey)->value : TRUE;
}
public function setRevisionTranslationAffected($affected) {
if ($this
->hasField($this->revisionTranslationAffectedKey)) {
$this
->set($this->revisionTranslationAffectedKey, $affected);
}
return $this;
}
public function isRevisionTranslationAffectedEnforced() {
return !empty($this->enforceRevisionTranslationAffected[$this->activeLangcode]);
}
public function setRevisionTranslationAffectedEnforced($enforced) {
$this->enforceRevisionTranslationAffected[$this->activeLangcode] = $enforced;
return $this;
}
public function isDefaultTranslation() {
return $this->activeLangcode === LanguageInterface::LANGCODE_DEFAULT;
}
public function getRevisionId() {
return $this
->getEntityKey('revision');
}
public function isTranslatable() {
$bundles = $this
->entityTypeBundleInfo()
->getBundleInfo($this->entityTypeId);
return !empty($bundles[$this
->bundle()]['translatable']) && !$this
->getUntranslated()
->language()
->isLocked() && $this
->languageManager()
->isMultilingual();
}
public function preSave(EntityStorageInterface $storage) {
if ($this->validationRequired && !$this->validated) {
throw new \LogicException('Entity validation was skipped.');
}
else {
$this->validated = FALSE;
}
parent::preSave($storage);
}
public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
}
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
$removed = [];
foreach ($this->translations as $langcode => &$data) {
if ($data['status'] == static::TRANSLATION_REMOVED) {
$removed[$langcode] = TRUE;
}
else {
$data['status'] = static::TRANSLATION_EXISTING;
}
}
$this->translations = array_diff_key($this->translations, $removed);
$this->newRevision = FALSE;
$this->enforceRevisionTranslationAffected = [];
}
public function validate() {
$this->validated = TRUE;
$violations = $this
->getTypedData()
->validate();
return new EntityConstraintViolationList($this, iterator_to_array($violations));
}
public function isValidationRequired() {
return (bool) $this->validationRequired;
}
public function setValidationRequired($required) {
$this->validationRequired = $required;
return $this;
}
protected function clearTranslationCache() {
foreach ($this->translations as &$translation) {
unset($translation['entity']);
}
}
public function __sleep() {
foreach ($this->fields as $name => $fields) {
foreach ($fields as $langcode => $field) {
$this->values[$name][$langcode] = $field
->getValue();
}
}
$this->fields = [];
$this->fieldDefinitions = NULL;
$this->languages = NULL;
$this
->clearTranslationCache();
return parent::__sleep();
}
public function id() {
return $this
->getEntityKey('id');
}
public function bundle() {
return $this
->getEntityKey('bundle');
}
public function uuid() {
return $this
->getEntityKey('uuid');
}
public function hasField($field_name) {
return (bool) $this
->getFieldDefinition($field_name);
}
public function get($field_name) {
if (!isset($this->fields[$field_name][$this->activeLangcode])) {
return $this
->getTranslatedField($field_name, $this->activeLangcode);
}
return $this->fields[$field_name][$this->activeLangcode];
}
protected function getTranslatedField($name, $langcode) {
if ($this->translations[$this->activeLangcode]['status'] == static::TRANSLATION_REMOVED) {
throw new \InvalidArgumentException("The entity object refers to a removed translation ({$this->activeLangcode}) and cannot be manipulated.");
}
if (!isset($this->fields[$name][$langcode])) {
$definition = $this
->getFieldDefinition($name);
if (!$definition) {
throw new \InvalidArgumentException("Field {$name} is unknown.");
}
$default = $langcode == LanguageInterface::LANGCODE_DEFAULT;
if (!$default && !$definition
->isTranslatable()) {
if (!isset($this->fields[$name][LanguageInterface::LANGCODE_DEFAULT])) {
$this->fields[$name][LanguageInterface::LANGCODE_DEFAULT] = $this
->getTranslatedField($name, LanguageInterface::LANGCODE_DEFAULT);
}
$this->fields[$name][$langcode] =& $this->fields[$name][LanguageInterface::LANGCODE_DEFAULT];
}
else {
$value = NULL;
if (isset($this->values[$name][$langcode])) {
$value = $this->values[$name][$langcode];
}
$field = \Drupal::service('plugin.manager.field.field_type')
->createFieldItemList($this
->getTranslation($langcode), $name, $value);
if ($default) {
$field_langcode = isset($this->defaultLangcode) ? $this->defaultLangcode : LanguageInterface::LANGCODE_NOT_SPECIFIED;
}
else {
$field_langcode = $langcode;
}
$field
->setLangcode($field_langcode);
$this->fields[$name][$langcode] = $field;
}
}
return $this->fields[$name][$langcode];
}
public function set($name, $value, $notify = TRUE) {
$this
->get($name)
->setValue($value, TRUE);
return $this;
}
public function getFields($include_computed = TRUE) {
$fields = [];
foreach ($this
->getFieldDefinitions() as $name => $definition) {
if ($include_computed || !$definition
->isComputed()) {
$fields[$name] = $this
->get($name);
}
}
return $fields;
}
public function getTranslatableFields($include_computed = TRUE) {
$fields = [];
foreach ($this
->getFieldDefinitions() as $name => $definition) {
if (($include_computed || !$definition
->isComputed()) && $definition
->isTranslatable()) {
$fields[$name] = $this
->get($name);
}
}
return $fields;
}
public function getIterator() {
return new \ArrayIterator($this
->getFields());
}
public function getFieldDefinition($name) {
if (!isset($this->fieldDefinitions)) {
$this
->getFieldDefinitions();
}
if (isset($this->fieldDefinitions[$name])) {
return $this->fieldDefinitions[$name];
}
}
public function getFieldDefinitions() {
if (!isset($this->fieldDefinitions)) {
$this->fieldDefinitions = \Drupal::service('entity_field.manager')
->getFieldDefinitions($this->entityTypeId, $this
->bundle());
}
return $this->fieldDefinitions;
}
public function toArray() {
$values = [];
foreach ($this
->getFields() as $name => $property) {
$values[$name] = $property
->getValue();
}
return $values;
}
public function access($operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
if ($operation == 'create') {
return $this
->entityTypeManager()
->getAccessControlHandler($this->entityTypeId)
->createAccess($this
->bundle(), $account, [], $return_as_object);
}
return $this
->entityTypeManager()
->getAccessControlHandler($this->entityTypeId)
->access($this, $operation, $account, $return_as_object);
}
public function language() {
$language = NULL;
if ($this->activeLangcode != LanguageInterface::LANGCODE_DEFAULT) {
if (!isset($this->languages[$this->activeLangcode])) {
$this
->getLanguages();
}
$language = $this->languages[$this->activeLangcode];
}
else {
if (!isset($this->languages[$this->defaultLangcode])) {
$this
->getLanguages();
}
$language = $this->languages[$this->defaultLangcode];
}
return $language;
}
protected function setDefaultLangcode() {
if (isset($this->translatableEntityKeys['langcode'][$this->activeLangcode])) {
$this->defaultLangcode = $this->translatableEntityKeys['langcode'][$this->activeLangcode];
}
elseif ($this
->hasField($this->langcodeKey) && ($item = $this
->get($this->langcodeKey)) && isset($item->language)) {
$this->defaultLangcode = $item->language
->getId();
$this->translatableEntityKeys['langcode'][$this->activeLangcode] = $this->defaultLangcode;
}
if (empty($this->defaultLangcode)) {
if ($this
->hasField($this->langcodeKey)) {
$this->defaultLangcode = $this
->languageManager()
->getDefaultLanguage()
->getId();
}
else {
$this->defaultLangcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
}
}
if (!empty($this->fields[$this->langcodeKey])) {
$this->fields[$this->langcodeKey][LanguageInterface::LANGCODE_DEFAULT]
->setLangcode($this->defaultLangcode);
}
}
protected function updateFieldLangcodes($langcode) {
foreach ($this->fields as $name => $items) {
if (!empty($items[LanguageInterface::LANGCODE_DEFAULT])) {
$items[LanguageInterface::LANGCODE_DEFAULT]
->setLangcode($langcode);
}
}
}
public function onChange($name) {
foreach (array_keys($this
->getEntityType()
->getKeys(), $name, TRUE) as $key) {
if ($key != 'bundle') {
if (isset($this->entityKeys[$key])) {
unset($this->entityKeys[$key]);
}
elseif (isset($this->translatableEntityKeys[$key][$this->activeLangcode])) {
unset($this->translatableEntityKeys[$key][$this->activeLangcode]);
}
if ($key === 'revision' && $this
->getRevisionId() == $this
->getLoadedRevisionId() && !$this
->isNew()) {
$this->newRevision = FALSE;
}
}
}
switch ($name) {
case $this->langcodeKey:
if ($this
->isDefaultTranslation()) {
$this
->setDefaultLangcode();
if (isset($this->translations[$this->defaultLangcode])) {
$message = new FormattableMarkup('A translation already exists for the specified language (@langcode).', [
'@langcode' => $this->defaultLangcode,
]);
throw new \InvalidArgumentException($message);
}
$this
->updateFieldLangcodes($this->defaultLangcode);
}
else {
$items = $this
->get($this->langcodeKey);
if ($items->value != $this->activeLangcode) {
$items
->setValue($this->activeLangcode, FALSE);
$message = new FormattableMarkup('The translation language cannot be changed (@langcode).', [
'@langcode' => $this->activeLangcode,
]);
throw new \LogicException($message);
}
}
break;
case $this->defaultLangcodeKey:
if (isset($this->values[$this->defaultLangcodeKey]) && $this
->get($this->defaultLangcodeKey)->value != $this
->isDefaultTranslation()) {
$this
->get($this->defaultLangcodeKey)
->setValue($this
->isDefaultTranslation(), FALSE);
$message = new FormattableMarkup('The default translation flag cannot be changed (@langcode).', [
'@langcode' => $this->activeLangcode,
]);
throw new \LogicException($message);
}
break;
case $this->revisionTranslationAffectedKey:
$this
->setRevisionTranslationAffectedEnforced(TRUE);
break;
}
}
public function getTranslation($langcode) {
if ($langcode != LanguageInterface::LANGCODE_DEFAULT && $langcode == $this->defaultLangcode) {
$langcode = LanguageInterface::LANGCODE_DEFAULT;
}
if (!isset($this->translations[$this->activeLangcode]['entity'])) {
$this->translations[$this->activeLangcode]['entity'] = $this;
}
if (isset($this->translations[$langcode]['entity'])) {
$translation = $this->translations[$langcode]['entity'];
}
elseif (isset($this->translations[$langcode])) {
$translation = $this
->initializeTranslation($langcode);
$this->translations[$langcode]['entity'] = $translation;
}
if (empty($translation)) {
throw new \InvalidArgumentException("Invalid translation language ({$langcode}) specified.");
}
return $translation;
}
public function getUntranslated() {
return $this
->getTranslation(LanguageInterface::LANGCODE_DEFAULT);
}
protected function initializeTranslation($langcode) {
$this->translationInitialize = TRUE;
$translation = clone $this;
$this->translationInitialize = FALSE;
$translation->activeLangcode = $langcode;
$translation->values =& $this->values;
$translation->fields =& $this->fields;
$translation->translations =& $this->translations;
$translation->enforceIsNew =& $this->enforceIsNew;
$translation->newRevision =& $this->newRevision;
$translation->entityKeys =& $this->entityKeys;
$translation->translatableEntityKeys =& $this->translatableEntityKeys;
$translation->translationInitialize = FALSE;
$translation->typedData = NULL;
$translation->loadedRevisionId =& $this->loadedRevisionId;
$translation->isDefaultRevision =& $this->isDefaultRevision;
$translation->enforceRevisionTranslationAffected =& $this->enforceRevisionTranslationAffected;
$translation->isSyncing =& $this->isSyncing;
return $translation;
}
public function hasTranslation($langcode) {
if ($langcode == $this->defaultLangcode) {
$langcode = LanguageInterface::LANGCODE_DEFAULT;
}
return !empty($this->translations[$langcode]['status']);
}
public function isNewTranslation() {
return $this->translations[$this->activeLangcode]['status'] == static::TRANSLATION_CREATED;
}
public function addTranslation($langcode, array $values = []) {
$this
->getLanguages();
if (!isset($this->languages[$langcode]) || $this
->hasTranslation($langcode) || $this->languages[$langcode]
->isLocked()) {
throw new \InvalidArgumentException("Invalid translation language ({$langcode}) specified.");
}
if ($this->languages[$this->defaultLangcode]
->isLocked()) {
throw new \InvalidArgumentException("The entity cannot be translated since it is language neutral ({$this->defaultLangcode}).");
}
$storage = $this
->entityTypeManager()
->getStorage($this
->getEntityTypeId());
$this->translations[$langcode]['status'] = !isset($this->translations[$langcode]['status_existed']) ? static::TRANSLATION_CREATED : static::TRANSLATION_EXISTING;
return $storage
->createTranslation($this, $langcode, $values);
}
public function removeTranslation($langcode) {
if (isset($this->translations[$langcode]) && $langcode != LanguageInterface::LANGCODE_DEFAULT && $langcode != $this->defaultLangcode) {
foreach ($this
->getFieldDefinitions() as $name => $definition) {
if ($definition
->isTranslatable()) {
unset($this->values[$name][$langcode]);
unset($this->fields[$name][$langcode]);
}
}
if ($this->translations[$langcode]['status'] == static::TRANSLATION_CREATED) {
unset($this->translations[$langcode]);
}
else {
if ($this->translations[$langcode]['status'] == static::TRANSLATION_EXISTING) {
$this->translations[$langcode]['status_existed'] = TRUE;
}
$this->translations[$langcode]['status'] = static::TRANSLATION_REMOVED;
}
}
else {
throw new \InvalidArgumentException("The specified translation ({$langcode}) cannot be removed.");
}
}
public function getTranslationStatus($langcode) {
if ($langcode == $this->defaultLangcode) {
$langcode = LanguageInterface::LANGCODE_DEFAULT;
}
return isset($this->translations[$langcode]) ? $this->translations[$langcode]['status'] : NULL;
}
public function getTranslationLanguages($include_default = TRUE) {
$translations = array_filter($this->translations, function ($translation) {
return $translation['status'];
});
unset($translations[LanguageInterface::LANGCODE_DEFAULT]);
if ($include_default) {
$translations[$this->defaultLangcode] = TRUE;
}
return array_intersect_key($this
->getLanguages(), $translations);
}
public function updateOriginalValues() {
if (!$this->fields) {
return;
}
foreach ($this
->getFieldDefinitions() as $name => $definition) {
if (!$definition
->isComputed() && !empty($this->fields[$name])) {
foreach ($this->fields[$name] as $langcode => $item) {
$item
->filterEmptyItems();
$this->values[$name][$langcode] = $item
->getValue();
}
}
}
}
public function &__get($name) {
if (isset($this->fields[$name][$this->activeLangcode])) {
return $this->fields[$name][$this->activeLangcode];
}
if (!isset($this->fieldDefinitions)) {
$this
->getFieldDefinitions();
}
if (isset($this->fieldDefinitions[$name])) {
$return = $this
->getTranslatedField($name, $this->activeLangcode);
return $return;
}
if (!isset($this->values[$name])) {
$this->values[$name] = NULL;
}
return $this->values[$name];
}
public function __set($name, $value) {
if (!isset($this->fieldDefinitions)) {
$this
->getFieldDefinitions();
}
if (isset($this->fieldDefinitions[$name])) {
if ($value instanceof TypedDataInterface) {
$value = $value
->getValue();
}
if (isset($this->fields[$name][$this->activeLangcode])) {
$this->fields[$name][$this->activeLangcode]
->setValue($value);
}
else {
$this
->getTranslatedField($name, $this->activeLangcode)
->setValue($value);
}
}
elseif ($name == 'translations') {
$this->translations = $value;
}
else {
$this->values[$name] = $value;
}
}
public function __isset($name) {
return $this
->hasField($name) ? TRUE : isset($this->values[$name]);
}
public function __unset($name) {
if ($this
->hasField($name)) {
$this
->get($name)
->setValue([]);
}
else {
unset($this->values[$name]);
}
}
public function createDuplicate() {
if ($this->translations[$this->activeLangcode]['status'] == static::TRANSLATION_REMOVED) {
throw new \InvalidArgumentException("The entity object refers to a removed translation ({$this->activeLangcode}) and cannot be manipulated.");
}
$duplicate = clone $this;
$entity_type = $this
->getEntityType();
if ($entity_type
->hasKey('id')) {
$duplicate->{$entity_type
->getKey('id')}->value = NULL;
}
$duplicate
->enforceIsNew();
if ($entity_type
->hasKey('uuid')) {
$duplicate->{$entity_type
->getKey('uuid')}->value = $this
->uuidGenerator()
->generate();
}
if ($entity_type
->isRevisionable()) {
$duplicate->{$entity_type
->getKey('revision')}->value = NULL;
$duplicate->loadedRevisionId = NULL;
}
return $duplicate;
}
public function __clone() {
if ($this->translationInitialize) {
return;
}
$this->typedData = NULL;
$definitions = $this
->getFieldDefinitions();
$this
->clearTranslationCache();
$translations = $this->translations;
$this->translations =& $translations;
$enforce_is_new = $this->enforceIsNew;
$this->enforceIsNew =& $enforce_is_new;
$new_revision = $this->newRevision;
$this->newRevision =& $new_revision;
$original_revision_id = $this->loadedRevisionId;
$this->loadedRevisionId =& $original_revision_id;
$fields = $this->fields;
$this->fields =& $fields;
$entity_keys = $this->entityKeys;
$this->entityKeys =& $entity_keys;
$translatable_entity_keys = $this->translatableEntityKeys;
$this->translatableEntityKeys =& $translatable_entity_keys;
$values = $this->values;
$this->values =& $values;
$default_revision = $this->isDefaultRevision;
$this->isDefaultRevision =& $default_revision;
$is_revision_translation_affected_enforced = $this->enforceRevisionTranslationAffected;
$this->enforceRevisionTranslationAffected =& $is_revision_translation_affected_enforced;
$is_syncing = $this->isSyncing;
$this->isSyncing =& $is_syncing;
foreach ($this->fields as $name => $fields_by_langcode) {
$this->fields[$name] = [];
if (!$definitions[$name]
->isTranslatable() && count($fields_by_langcode) > 1) {
$fields_by_langcode = array_intersect_key($fields_by_langcode, [
LanguageInterface::LANGCODE_DEFAULT => TRUE,
]);
}
foreach ($fields_by_langcode as $langcode => $items) {
$this->fields[$name][$langcode] = clone $items;
$this->fields[$name][$langcode]
->setContext($name, $this
->getTranslation($langcode)
->getTypedData());
}
}
}
public function label() {
if ($this
->getEntityType()
->getKey('label')) {
return $this
->getEntityKey('label');
}
}
public function referencedEntities() {
$referenced_entities = [];
foreach ($this
->getFields() as $field_items) {
foreach ($field_items as $field_item) {
foreach ($field_item
->getProperties(TRUE) as $property) {
if ($property instanceof EntityReference && ($entity = $property
->getValue())) {
$referenced_entities[] = $entity;
}
}
}
}
return $referenced_entities;
}
protected function getEntityKey($key) {
if (isset($this->entityKeys[$key])) {
return $this->entityKeys[$key];
}
if (isset($this->translatableEntityKeys[$key][$this->activeLangcode])) {
return $this->translatableEntityKeys[$key][$this->activeLangcode];
}
$value = NULL;
if ($this
->getEntityType()
->hasKey($key)) {
$field_name = $this
->getEntityType()
->getKey($key);
$definition = $this
->getFieldDefinition($field_name);
$property = $definition
->getFieldStorageDefinition()
->getMainPropertyName();
$value = $this
->get($field_name)->{$property};
if ($definition
->isTranslatable()) {
$this->translatableEntityKeys[$key][$this->activeLangcode] = $value;
}
else {
$this->entityKeys[$key] = $value;
}
}
else {
$this->entityKeys[$key] = $value;
}
return $value;
}
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = [];
if ($entity_type
->hasKey('id')) {
$fields[$entity_type
->getKey('id')] = BaseFieldDefinition::create('integer')
->setLabel(new TranslatableMarkup('ID'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
}
if ($entity_type
->hasKey('uuid')) {
$fields[$entity_type
->getKey('uuid')] = BaseFieldDefinition::create('uuid')
->setLabel(new TranslatableMarkup('UUID'))
->setReadOnly(TRUE);
}
if ($entity_type
->hasKey('revision')) {
$fields[$entity_type
->getKey('revision')] = BaseFieldDefinition::create('integer')
->setLabel(new TranslatableMarkup('Revision ID'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
}
if ($entity_type
->hasKey('langcode')) {
$fields[$entity_type
->getKey('langcode')] = BaseFieldDefinition::create('language')
->setLabel(new TranslatableMarkup('Language'))
->setDisplayOptions('view', [
'region' => 'hidden',
])
->setDisplayOptions('form', [
'type' => 'language_select',
'weight' => 2,
]);
if ($entity_type
->isRevisionable()) {
$fields[$entity_type
->getKey('langcode')]
->setRevisionable(TRUE);
}
if ($entity_type
->isTranslatable()) {
$fields[$entity_type
->getKey('langcode')]
->setTranslatable(TRUE);
}
}
if ($entity_type
->hasKey('bundle')) {
if ($bundle_entity_type_id = $entity_type
->getBundleEntityType()) {
$fields[$entity_type
->getKey('bundle')] = BaseFieldDefinition::create('entity_reference')
->setLabel($entity_type
->getBundleLabel())
->setSetting('target_type', $bundle_entity_type_id)
->setRequired(TRUE)
->setReadOnly(TRUE);
}
else {
$fields[$entity_type
->getKey('bundle')] = BaseFieldDefinition::create('string')
->setLabel($entity_type
->getBundleLabel())
->setRequired(TRUE)
->setReadOnly(TRUE);
}
}
return $fields;
}
public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
return [];
}
protected function getFieldsToSkipFromTranslationChangesCheck() {
$bundle = $this
->bundle();
if (!isset(static::$fieldsToSkipFromTranslationChangesCheck[$this->entityTypeId][$bundle])) {
static::$fieldsToSkipFromTranslationChangesCheck[$this->entityTypeId][$bundle] = $this
->traitGetFieldsToSkipFromTranslationChangesCheck($this);
}
return static::$fieldsToSkipFromTranslationChangesCheck[$this->entityTypeId][$bundle];
}
public function hasTranslationChanges() {
if ($this
->isNew()) {
return TRUE;
}
$original = $this->original ? $this->original : NULL;
if (!$original) {
$id = $this
->getOriginalId() !== NULL ? $this
->getOriginalId() : $this
->id();
$original = $this
->entityTypeManager()
->getStorage($this
->getEntityTypeId())
->loadUnchanged($id);
}
$translated = count($this->translations) > 1;
if ($translated && !$original
->hasTranslation($this->activeLangcode)) {
return TRUE;
}
$translation = $original
->getTranslation($this->activeLangcode);
$langcode = $this
->language()
->getId();
$skip_fields = $this
->getFieldsToSkipFromTranslationChangesCheck();
$skip_untranslatable_fields = !$this
->isDefaultTranslation() && $this
->isDefaultTranslationAffectedOnly();
foreach ($this
->getFieldDefinitions() as $field_name => $definition) {
if (in_array($field_name, $skip_fields, TRUE) || $skip_untranslatable_fields && !$definition
->isTranslatable()) {
continue;
}
$items = $this
->get($field_name)
->filterEmptyItems();
$original_items = $translation
->get($field_name)
->filterEmptyItems();
if ($items
->hasAffectingChanges($original_items, $langcode)) {
return TRUE;
}
}
return FALSE;
}
public function isDefaultTranslationAffectedOnly() {
$bundle_name = $this
->bundle();
$bundle_info = \Drupal::service('entity_type.bundle.info')
->getBundleInfo($this
->getEntityTypeId());
return !empty($bundle_info[$bundle_name]['untranslatable_fields.default_translation_affected']);
}
}