XmlEntityNormalizationQuirksTrait.php

Same filename in other branches
  1. 9 core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php
  2. 8.9.x core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php
  3. 10 core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php

Namespace

Drupal\Tests\rest\Functional\EntityResource

File

core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\rest\Functional\EntityResource;

use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\BooleanItem;
use Drupal\Core\Field\Plugin\Field\FieldType\ChangedItem;
use Drupal\Core\Field\Plugin\Field\FieldType\CreatedItem;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem;
use Drupal\Core\Field\Plugin\Field\FieldType\TimestampItem;
use Drupal\file\Plugin\Field\FieldType\FileItem;
use Drupal\image\Plugin\Field\FieldType\ImageItem;
use Drupal\options\Plugin\Field\FieldType\ListIntegerItem;
use Drupal\path\Plugin\Field\FieldType\PathItem;
use Drupal\Tests\rest\Functional\XmlNormalizationQuirksTrait;
use Drupal\user\StatusItem;
use PHPUnit\Framework\Attributes\Before;

/**
 * Trait for EntityResourceTestBase subclasses testing $format='xml'.
 */
trait XmlEntityNormalizationQuirksTrait {
    use XmlNormalizationQuirksTrait;
    
    /**
     * Marks some tests as skipped because XML cannot be deserialized.
     */
    public function xmlEntityNormalizationQuirksTraitSkipTests() : void {
        if (in_array($this->name(), [
            'testPatch',
            'testPost',
        ], TRUE)) {
            $this->markTestSkipped('Deserialization of the XML format is not supported.');
        }
    }
    
    /**
     * {@inheritdoc}
     */
    protected function getExpectedNormalizedEntity() {
        $default_normalization = parent::getExpectedNormalizedEntity();
        if ($this->entity instanceof FieldableEntityInterface) {
            $normalization = $this->applyXmlFieldDecodingQuirks($default_normalization);
        }
        else {
            $normalization = $this->applyXmlConfigEntityDecodingQuirks($default_normalization);
        }
        $normalization = $this->applyXmlDecodingQuirks($normalization);
        return $normalization;
    }
    
    /**
     * Applies the XML entity field encoding quirks that remain after decoding.
     *
     * The XML encoding:
     * - loses type data (int and bool become string)
     *
     * @param array $normalization
     *   An entity normalization.
     *
     * @return array
     *   The updated fieldable entity normalization.
     *
     * @see \Symfony\Component\Serializer\Encoder\XmlEncoder
     */
    protected function applyXmlFieldDecodingQuirks(array $normalization) : array {
        foreach ($this->entity
            ->getFields(TRUE) as $field_name => $field) {
            // Not every field is accessible.
            if (!isset($normalization[$field_name])) {
                continue;
            }
            for ($i = 0; $i < count($normalization[$field_name]); $i++) {
                switch ($field->getItemDefinition()
                    ->getClass()) {
                    case BooleanItem::class:
                    case StatusItem::class:
                        // @todo Remove the StatusItem case in
                        //   https://www.drupal.org/project/drupal/issues/2936864.
                        $value =& $normalization[$field_name][$i]['value'];
                        $value = $value === TRUE ? '1' : '0';
                        break;
                    case IntegerItem::class:
                    case ListIntegerItem::class:
                        $value =& $normalization[$field_name][$i]['value'];
                        $value = (string) $value;
                        break;
                    case PathItem::class:
                        $pid =& $normalization[$field_name][$i]['pid'];
                        $pid = (string) $pid;
                        break;
                    case EntityReferenceItem::class:
                    case FileItem::class:
                        $target_id =& $normalization[$field_name][$i]['target_id'];
                        $target_id = (string) $target_id;
                        break;
                    case ChangedItem::class:
                    case CreatedItem::class:
                    case TimestampItem::class:
                        $value =& $normalization[$field_name][$i]['value'];
                        if (is_numeric($value)) {
                            $value = (string) $value;
                        }
                        break;
                    case ImageItem::class:
                        $height =& $normalization[$field_name][$i]['height'];
                        $height = (string) $height;
                        $width =& $normalization[$field_name][$i]['width'];
                        $width = (string) $width;
                        $target_id =& $normalization[$field_name][$i]['target_id'];
                        $target_id = (string) $target_id;
                        break;
                }
            }
            if (count($normalization[$field_name]) === 1) {
                $normalization[$field_name] = $normalization[$field_name][0];
            }
        }
        return $normalization;
    }
    
    /**
     * Applies the XML config entity encoding quirks that remain after decoding.
     *
     * The XML encoding:
     * - loses type data (int and bool become string)
     * - converts single-item arrays into single items (non-arrays)
     *
     * @param array $normalization
     *   An entity normalization.
     *
     * @return array
     *   The updated config entity normalization.
     *
     * @see \Symfony\Component\Serializer\Encoder\XmlEncoder
     */
    protected function applyXmlConfigEntityDecodingQuirks(array $normalization) {
        $normalization = static::castToString($normalization);
        // When a single dependency is listed, it's not decoded into an array.
        if (isset($normalization['dependencies'])) {
            foreach ($normalization['dependencies'] as $dependency_type => $dependency_list) {
                if (count($dependency_list) === 1) {
                    $normalization['dependencies'][$dependency_type] = $dependency_list[0];
                }
            }
        }
        return $normalization;
    }

}

Traits

Title Deprecated Summary
XmlEntityNormalizationQuirksTrait Trait for EntityResourceTestBase subclasses testing $format='xml'.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.