Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 291721

TypedData 'Any' can't be normalized to array if it stores an object

$
0
0

Problem/Motivation

Like commerce's order,It use 'any' type data to store object:Adjustment, But the TypedDataNormalizer just return the Adjustment object, It cause it can't be encode, So it can't be serializad

First(laravel): Let's look at laravel's serialization
laravel's serialization has two steps:

  1. toArray() ====> corresponds to druapl's normalize
  2. toJson() ====> corresponds to drupal's encode

laravel's toArray() is recursive,it will recurs to check whether the child value is Arrayable
https://github.com/illuminate/database/blob/5.5/Eloquent/Model.php#L918
https://github.com/illuminate/database/blob/5.5/Eloquent/Concerns/HasAtt...

Second(symfony):
https://github.com/symfony/serializer/blob/3.2/Serializer.php#L138

    public function normalize($data, $format = null, array $context = array())
    {
        // If a normalizer supports the given data, use it
        if ($normalizer = $this->getNormalizer($data, $format)) {
            return $normalizer->normalize($data, $format, $context);
        }
        if (null === $data || is_scalar($data)) {
            return $data;
        }
        if (is_array($data) || $data instanceof \Traversable) {
            $normalized = array();
            foreach ($data as $key => $val) {
                $normalized[$key] = $this->normalize($val, $format, $context);
            }
            return $normalized;
        }
        if (is_object($data)) {
            if (!$this->normalizers) {
                throw new LogicException('You must register at least one normalizer to be able to normalize objects.');
            }
            throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', get_class($data)));
        }
        throw new UnexpectedValueException(sprintf('An unexpected value could not be normalized: %s', var_export($data, true)));
    }

symfony's Serializer->normalize() has the ability to recursive normalize object and array too

Both laravel and symfony has the ability to recursive normalize object or array

Then(Drupal):
Let's see TypedDataNormalizer used by normalizing 'any' type data
core/modules/serialization/src/Normalizer/TypedDataNormalizer.php#n21

  public function normalize($object, $format = NULL, array $context = []) {
    return $object->getValue();
  }

We can see TypedDataNormalizer Just return the value
Drupal use symfony's serializer, But it dosn't follow or take full advantage of the symfony's serializer's design

Proposed resolution

  1. make TypedDataNormalizer flow and use symfony's serialize->normalize()'s design. (solve here)
  2. Map type data has similar trouble too: But Map have other more base problem, It can't be normalized when it has no propertydefinition , But if TypedDataNormalizer's problem is solved, Two kind of https://www.drupal.org/node/2895532's the patch(two kind of controversial solution) will work good with no change needed

Remaining tasks

User interface changes

API changes

Data model changes


Viewing all articles
Browse latest Browse all 291721

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>