diff -u b/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php --- b/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -160,7 +160,7 @@ * * @var bool */ - public $serializeCompleteEntityStructure = FALSE; + public $deepSerialization = FALSE; /** * {@inheritdoc} @@ -447,7 +447,7 @@ // Get the values of instantiated field objects, only serialize the values. foreach ($this->fields as $name => $fields) { foreach ($fields as $langcode => $field) { - $this->values[$name][$langcode] = $field->getValue(); + $this->values[$name][$langcode] = $field->getSerializationValue($this->deepSerialization); } } $this->fields = array(); @@ -455,35 +455,33 @@ $this->languages = NULL; $this->clearTranslationCache(); + // As during the serialization process referenced entities might also have + // the "deepSerialization" flag set the only place of unsetting it remains + // in the sleep method right after the entity is prepared for the + // serialization and before executing it. + // @see \Drupal\Core\Field\EntityReferenceFieldItemList::getSerializationValue(). + $this->deepSerialization = FALSE; + return parent::__sleep(); } /** * {@inheritdoc} */ - public function __wakeup() { - parent::__wakeup(); - // If the entity has been serialized with the flag - // "serializeCompleteEntityStructure" set to TRUE then the entity has been - // deeply serialized and in order to allow normal serialization on the - // unserialized entity we have to unset the flag. - $this->serializeCompleteEntityStructure = FALSE; + public function deepSerialize() { + // When running a deep serialization the flag "deepSerialization" has to be + // set in order to serialize referenced entities as well, which are + // referenced by field having the setting "serialize_embedded_entities" set + // to TRUE. + $this->deepSerialization = TRUE; + return serialize($this); } /** * {@inheritdoc} */ - public function serializeWithCompleteStructure() { - // When running a deep serialization the flag - // "serializeCompleteEntityStructure" has to be set in order to serialize - // referenced entities as well, which are referenced by field having the - // setting "serialize_embedded_entities" set to TRUE. - $this->serializeCompleteEntityStructure = TRUE; - $serialized = serialize($this); - // After the deep serialization is ready we have to unset the flag in order - // to allow for normal serialization afterwards. - $this->serializeCompleteEntityStructure = FALSE; - return $serialized; + public function setDeepSerialization() { + $this->deepSerialization = TRUE; } /** @@ -858,7 +856,7 @@ $translation->enforceIsNew = &$this->enforceIsNew; $translation->newRevision = &$this->newRevision; $translation->entityKeys = &$this->entityKeys; - $translation->serializeCompleteEntityStructure = &$this->serializeCompleteEntityStructure; + $translation->deepSerialization = &$this->deepSerialization; $translation->translatableEntityKeys = &$this->translatableEntityKeys; $translation->translationInitialize = FALSE; $translation->typedData = NULL; @@ -1137,11 +1135,10 @@ $original_revision_id = $this->loadedRevisionId; $this->loadedRevisionId = &$original_revision_id; - // Ensure the serializeCompleteEntityStructure property is actually - // cloned by overwriting the original reference with one pointing to a - // copy of it. - $serializeCompleteEntityStructure = $this->serializeCompleteEntityStructure; - $this->serializeCompleteEntityStructure = &$serializeCompleteEntityStructure; + // Ensure the deepSerialization property is actually cloned by + // overwriting the original reference with one pointing to a copy of it. + $deepSerialization = $this->deepSerialization; + $this->deepSerialization = &$deepSerialization; } } diff -u b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php --- b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php @@ -81,5 +81,16 @@ * The deeply serialized entity. */ - public function serializeWithCompleteStructure(); + public function deepSerialize(); + + /** + * Flags the entity for deep serialization. + * + * After calling this method and serializing the entity e.g. + * "serialize($entity);" a deep serialization will be performed and the flag + * will be automatically reset. + * + * @return $this + */ + public function setDeepSerialization(); } diff -u b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php --- b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php +++ b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php @@ -13,31 +13,21 @@ /** * {@inheritdoc} */ - public function getValue($include_computed = FALSE) { - $values = array(); - $serialize_embedded_entities = $this->isDeepSerializationActive(); - if (!$include_computed) { - $include_computed = $serialize_embedded_entities; - } - foreach ($this->list as $delta => $item) { - $values[$delta] = $item->getValue($include_computed); - // If deep serialization is active then flag the referenced entities for - // deep serialization as well. - if (isset($values[$delta]['entity']) && $serialize_embedded_entities) { - $values[$delta]['entity']->serializeCompleteEntityStructure = TRUE; + public function getSerializationValue($deep_serialization) { + if ($deep_serialization) { + $serialize_embedded_entities = $this->getFieldDefinition()->getSetting('serialize_embedded_entities'); + $values = $this->getValue($serialize_embedded_entities); + foreach ($values as $delta => $item_values) { + if (isset($values[$delta]['entity'])) { + $values[$delta]['entity']->setDeepSerialization(); + } } } - return $values; - } + else { + $values = parent::getSerializationValue($deep_serialization); + } - /** - * Checks if deep serialization is active. - * - * @return bool - * TRUE if deep serialization is active, FALSE otherwise. - */ - protected function isDeepSerializationActive() { - return $this->getFieldDefinition()->getSetting('serialize_embedded_entities') && $this->getEntity()->serializeCompleteEntityStructure; + return $values; } /** diff -u b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php --- b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -344,8 +344,8 @@ $form['serialize_embedded_entities'] = array( '#type' => 'checkbox', - '#title' => $this->t('Serialize entity references together with the parent entity'), - '#description' => $this->t('If the field widget to be used for this field is an entity reference inline widget then the setting must be set.'), + '#title' => $this->t('Serialize entity references together with the parent entity when performing deep serialization of the parent entity.'), + '#description' => $this->t('If the field widget to be used for this field is an "entity reference inline widget" then the setting must be set.'), '#default_value' => $field->getSetting('serialize_embedded_entities'), ); diff -u b/core/modules/field/field.install b/core/modules/field/field.install --- b/core/modules/field/field.install +++ b/core/modules/field/field.install @@ -6,7 +6,6 @@ */ use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; -use Drupal\file\Plugin\Field\FieldType\FileItem; /** * Removes the stale 'target_bundle' storage setting on entity_reference fields. @@ -130,7 +129,7 @@ $settings = $field->get('settings'); if (!isset($settings['serialize_embedded_entities'])) { - $settings['serialize_embedded_entities'] = is_subclass_of($class, FileItem::class) ? TRUE : FALSE; + $settings['serialize_embedded_entities'] = FALSE; } $field->set('settings', $settings)->save(TRUE); reverted: --- b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php +++ a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php @@ -81,7 +81,6 @@ 'uri_scheme' => 'public', 'handler' => 'default:file', 'handler_settings' => array(), - 'serialize_embedded_entities' => true, ); $field_settings = $field->getSettings(); ksort($expected); reverted: --- b/core/modules/file/config/schema/file.schema.yml +++ a/core/modules/file/config/schema/file.schema.yml @@ -43,9 +43,6 @@ base_file_field_field_settings: type: mapping mapping: - serialize_embedded_entities: - type: boolean - label: 'Serialize entity references together with the parent entity' handler: type: string label: 'Reference method' reverted: --- b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php +++ a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php @@ -49,7 +49,6 @@ 'file_directory' => '[date:custom:Y]-[date:custom:m]', 'max_filesize' => '', 'description_field' => 0, - 'serialize_embedded_entities' => TRUE, ) + parent::defaultFieldSettings(); } reverted: --- b/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php +++ a/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php @@ -3,10 +3,10 @@ namespace Drupal\file\Plugin\Field\FieldWidget; use Drupal\Component\Utility\NestedArray; -use Drupal\Core\Field\EntityReferenceInlineWidgetBase; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Render\Element; @@ -27,7 +27,7 @@ * } * ) */ +class FileWidget extends WidgetBase implements ContainerFactoryPluginInterface { -class FileWidget extends EntityReferenceInlineWidgetBase implements ContainerFactoryPluginInterface { /** * {@inheritdoc} reverted: --- b/core/profiles/standard/config/install/field.field.node.article.field_image.yml +++ a/core/profiles/standard/config/install/field.field.node.article.field_image.yml @@ -32,7 +32,6 @@ title: '' width: null height: null - serialize_embedded_entities: true handler: 'default:file' handler_settings: { } field_type: image reverted: --- b/core/profiles/standard/config/install/field.field.user.user.user_picture.yml +++ a/core/profiles/standard/config/install/field.field.user.user.user_picture.yml @@ -32,7 +32,6 @@ height: null alt_field_required: false title_field_required: false - serialize_embedded_entities: true handler: 'default:file' handler_settings: { } field_type: image diff -u b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php --- b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php @@ -109,7 +109,7 @@ $this->entityTestMulStorage->resetCache(); - $serialized_entity = $entity_level_zero->serializeWithCompleteStructure(); + $serialized_entity = $entity_level_zero->deepSerialize(); $entity_level_zero = unserialize($serialized_entity); $this->assertEquals('entity level zero', $entity_level_zero->label()); $this->assertEquals($deep_serialization ? 'entity level one' : $initial_entity_name, $entity_level_zero->$field_name->entity->label()); only in patch2: unchanged: --- a/core/lib/Drupal/Core/Field/FieldItemList.php +++ b/core/lib/Drupal/Core/Field/FieldItemList.php @@ -121,6 +121,13 @@ public function setValue($values, $notify = TRUE) { /** * {@inheritdoc} */ + public function getSerializationValue($deep_serialization) { + return $this->getValue(); + } + + /** + * {@inheritdoc} + */ public function __get($property_name) { // For empty fields, $entity->field->property is NULL. if ($item = $this->first()) { only in patch2: unchanged: --- a/core/lib/Drupal/Core/Field/FieldItemListInterface.php +++ b/core/lib/Drupal/Core/Field/FieldItemListInterface.php @@ -271,4 +271,14 @@ public static function processDefaultValue($default_value, FieldableEntityInterf */ public function equals(FieldItemListInterface $list_to_compare); + /** + * Gets the data value prepared for serialization. + * + * @param bool $deep_serialization + * Whether a deep serialization is running. + * + * @return mixed + */ + public function getSerializationValue($deep_serialization); + }