Updated to Drupal 8.6.4, which is PHP 7.3 friendly. Also updated HTMLaw library....
[yaffs-website] / web / core / modules / serialization / src / Normalizer / FieldableEntityNormalizerTrait.php
1 <?php
2
3 namespace Drupal\serialization\Normalizer;
4
5 use Drupal\Core\Entity\EntityTypeInterface;
6 use Drupal\Core\Entity\FieldableEntityInterface;
7 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
8
9 /**
10  * A trait for providing fieldable entity normalization/denormalization methods.
11  *
12  * @todo Move this into a FieldableEntityNormalizer in Drupal 9. This is a trait
13  *   used in \Drupal\serialization\Normalizer\EntityNormalizer to maintain BC.
14  *   @see https://www.drupal.org/node/2834734
15  */
16 trait FieldableEntityNormalizerTrait {
17
18   /**
19    * The entity manager.
20    *
21    * @var \Drupal\Core\Entity\EntityManagerInterface
22    */
23   protected $entityManager;
24
25   /**
26    * Determines the entity type ID to denormalize as.
27    *
28    * @param string $class
29    *   The entity type class to be denormalized to.
30    * @param array $context
31    *   The serialization context data.
32    *
33    * @return string
34    *   The entity type ID.
35    */
36   protected function determineEntityTypeId($class, $context) {
37     // Get the entity type ID while letting context override the $class param.
38     return !empty($context['entity_type']) ? $context['entity_type'] : $this->entityManager->getEntityTypeFromClass($class);
39   }
40
41   /**
42    * Gets the entity type definition.
43    *
44    * @param string $entity_type_id
45    *   The entity type ID to load the definition for.
46    *
47    * @return \Drupal\Core\Entity\EntityTypeInterface
48    *   The loaded entity type definition.
49    *
50    * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
51    */
52   protected function getEntityTypeDefinition($entity_type_id) {
53     /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type_definition */
54     // Get the entity type definition.
55     $entity_type_definition = $this->entityManager->getDefinition($entity_type_id, FALSE);
56
57     // Don't try to create an entity without an entity type id.
58     if (!$entity_type_definition) {
59       throw new UnexpectedValueException(sprintf('The specified entity type "%s" does not exist. A valid entity type is required for denormalization', $entity_type_id));
60     }
61
62     return $entity_type_definition;
63   }
64
65   /**
66    * Denormalizes the bundle property so entity creation can use it.
67    *
68    * @param array $data
69    *   The data being denormalized.
70    * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type_definition
71    *   The entity type definition.
72    *
73    * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
74    *
75    * @return string
76    *   The valid bundle name.
77    */
78   protected function extractBundleData(array &$data, EntityTypeInterface $entity_type_definition) {
79     $bundle_key = $entity_type_definition->getKey('bundle');
80     // Get the base field definitions for this entity type.
81     $base_field_definitions = $this->entityManager->getBaseFieldDefinitions($entity_type_definition->id());
82
83     // Get the ID key from the base field definition for the bundle key or
84     // default to 'value'.
85     $key_id = isset($base_field_definitions[$bundle_key]) ? $base_field_definitions[$bundle_key]->getFieldStorageDefinition()->getMainPropertyName() : 'value';
86
87     // Normalize the bundle if it is not explicitly set.
88     $bundle_value = isset($data[$bundle_key][0][$key_id]) ? $data[$bundle_key][0][$key_id] : (isset($data[$bundle_key]) ? $data[$bundle_key] : NULL);
89     // Unset the bundle from the data.
90     unset($data[$bundle_key]);
91
92     // Get the bundle entity type from the entity type definition.
93     $bundle_type_id = $entity_type_definition->getBundleEntityType();
94     $bundle_types = $bundle_type_id ? $this->entityManager->getStorage($bundle_type_id)->getQuery()->execute() : [];
95
96     // Make sure a bundle has been provided.
97     if (!is_string($bundle_value)) {
98       throw new UnexpectedValueException(sprintf('Could not determine entity type bundle: "%s" field is missing.', $bundle_key));
99     }
100
101     // Make sure the submitted bundle is a valid bundle for the entity type.
102     if ($bundle_types && !in_array($bundle_value, $bundle_types)) {
103       throw new UnexpectedValueException(sprintf('"%s" is not a valid bundle type for denormalization.', $bundle_value));
104     }
105
106     return [$bundle_key => $bundle_value];
107   }
108
109   /**
110    * Denormalizes entity data by denormalizing each field individually.
111    *
112    * @param array $data
113    *   The data to denormalize.
114    * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
115    *   The fieldable entity to set field values for.
116    * @param string $format
117    *   The serialization format.
118    * @param array $context
119    *   The context data.
120    */
121   protected function denormalizeFieldData(array $data, FieldableEntityInterface $entity, $format, array $context) {
122     foreach ($data as $field_name => $field_data) {
123       $field_item_list = $entity->get($field_name);
124
125       // Remove any values that were set as a part of entity creation (e.g
126       // uuid). If the incoming field data is set to an empty array, this will
127       // also have the effect of emptying the field in REST module.
128       $field_item_list->setValue([]);
129       $field_item_list_class = get_class($field_item_list);
130
131       if ($field_data) {
132         // The field instance must be passed in the context so that the field
133         // denormalizer can update field values for the parent entity.
134         $context['target_instance'] = $field_item_list;
135         $this->serializer->denormalize($field_data, $field_item_list_class, $format, $context);
136       }
137     }
138   }
139
140 }