Verified Commit 7bbe0f1a authored by Sascha Grossenbacher's avatar Sascha Grossenbacher Committed by Lee Rowlands
Browse files

Issue #3266176 by Berdir: Add normalizer for entity_reference_revisions module

parent bf69e482
Loading
Loading
Loading
Loading

composer.json

0 → 100644
+13 −0
Original line number Diff line number Diff line
{
  "name": "drupal/hal",
  "description": "Hypermedia Application Language (HAL)",
  "type": "drupal-module",
  "license": "GPL-2.0-or-later",
  "require": {
    "drupal/core": "^10"
  },
  "require-dev": {
    "drupal/entity_reference_revisions": "1.x-dev",
    "drupal/aggregator": "2.x-dev"
  }
}
+0 −20
Original line number Diff line number Diff line
langcode: en
status: true
dependencies:
  module:
    - basic_auth
    - hal
    - node
id: entity.node
plugin_id: 'entity:node'
granularity: resource
configuration:
  methods:
    - GET
    - POST
    - PATCH
    - DELETE
  formats:
    - hal_json
  authentication:
    - basic_auth
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,12 @@ services:
   tags:
     # Priority must be higher than serializer.normalizer.field_item.hal.
     - { name: normalizer, priority: 20 }
  serializer.normalizer.entity_reference_revisions_item.hal:
    class: Drupal\hal\Normalizer\EntityReferenceRevisionItemNormalizer
    arguments: [ '@hal.link_manager', '@serializer.entity_resolver', '@entity_type.manager' ]
    # Priority must be higher than serializer.normalizer.entity_reference_item.hal.
    tags:
      - { name: normalizer, priority: 20 }
  serializer.normalizer.entity.hal:
    class: Drupal\hal\Normalizer\ContentEntityNormalizer
    arguments: ['@hal.link_manager', '@entity_type.manager', '@module_handler', '@entity_type.repository', '@entity_field.manager']
+40 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\hal\Normalizer;

/**
 * Defines a class for normalizing EntityReferenceRevisionItems.
 */
class EntityReferenceRevisionItemNormalizer extends EntityReferenceItemNormalizer {

  /**
   * The interface or class that this Normalizer supports.
   *
   * @var string
   */
  protected $supportedInterfaceOrClass = '\Drupal\entity_reference_revisions\Plugin\Field\FieldType\EntityReferenceRevisionsItem';

  /**
   * {@inheritdoc}
   */
  protected function constructValue($data, $context) {
    $value = parent::constructValue($data, $context);
    if ($value) {
      $value['target_revision_id'] = $data['target_revision_id'];
    }
    return $value;
  }

  /**
   * {@inheritdoc}
   */
  public function normalize($field_item, $format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|NULL {
    $data = parent::normalize($field_item, $format, $context);
    $field_name = $field_item->getParent()->getName();
    $entity = $field_item->getEntity();
    $field_uri = $this->linkManager->getRelationUri($entity->getEntityTypeId(), $entity->bundle(), $field_name, $context);
    $data['_embedded'][$field_uri][0]['target_revision_id'] = $field_item->target_revision_id;
    return $data;
  }

}
+115 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\hal\Functional\entity_reference_revisions;

use Drupal\node\Entity\Node;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;

/**
 * Tests the entity_reference_revisions configuration.
 *
 * @group hal
 * @requires module entity_reference_revisions
 */
class EntityReferenceRevisionsNormalizerTest extends BrowserTestBase {

  use FieldUiTestTrait;

  /**
   * Modules to enable.
   *
   * @var array
   */
  protected static $modules = array(
    'node',
    'field',
    'entity_reference_revisions',
    'field_ui',
    'block',
    'hal',
    'serialization',
    'rest',
  );

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    // Create paragraphs and article content types.
    $this->drupalCreateContentType(array('type' => 'entity_revisions', 'name' => 'Entity revisions'));
    $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
    // Place the breadcrumb, tested in fieldUIAddNewField().
    $this->drupalPlaceBlock('system_breadcrumb_block');
  }

  /**
   * Tests the entity reference revisions configuration.
   */
  public function testEntityReferenceRevisions() {
    $admin_user = $this->drupalCreateUser(array(
      'administer site configuration',
      'administer nodes',
      'create article content',
      'create entity_revisions content',
      'administer content types',
      'administer node fields',
      'administer node display',
      'administer node form display',
      'edit any article content',
    ));
    $this->drupalLogin($admin_user);
    // Create entity reference revisions field.
    static::fieldUIAddNewField('admin/structure/types/manage/entity_revisions', 'entity_reference_revisions', 'Entity reference revisions', 'entity_reference_revisions', array('settings[target_type]' => 'node', 'cardinality' => '-1'), array('settings[handler_settings][target_bundles][article]' => TRUE));
    $this->assertSession()->pageTextContains('Saved Entity reference revisions configuration.');

    // Create an article.
    $title = $this->randomMachineName();
    $edit = array(
      'title[0][value]' => $title,
      'body[0][value]' => 'Revision 1',
    );
    $this->drupalGet('node/add/article');
    $this->submitForm($edit, 'Save');
    $this->assertSession()->pageTextContains($title);
    $this->assertSession()->pageTextContains('Revision 1');
    $node = $this->drupalGetNodeByTitle($title);

    // Create entity revisions content that includes the above article.
    $err_title = 'Entity reference revision content';
    $edit = array(
      'title[0][value]' => $err_title,
      'field_entity_reference_revisions[0][target_id]' => $node->label() . ' (' . $node->id() . ')',
    );
    $this->drupalGet('node/add/entity_revisions');
    $this->submitForm($edit, 'Save');
    $this->assertSession()->pageTextContains('Entity revisions Entity reference revision content has been created.');
    $err_node = $this->drupalGetNodeByTitle($err_title);

    $this->assertSession()->pageTextContains($err_title);
    $this->assertSession()->pageTextContains($title);
    $this->assertSession()->pageTextContains('Revision 1');

    // Create 2nd revision of the article.
    $edit = array(
      'body[0][value]' => 'Revision 2',
      'revision' => TRUE,
    );
    $this->drupalGet('node/' . $node->id() . '/edit');
    $this->submitForm($edit, 'Save');
    $serializer = $this->container->get('serializer');
    $normalized = $serializer->normalize($err_node, 'hal_json');
    $request = \Drupal::request();
    $link_domain = $request->getSchemeAndHttpHost() . $request->getBasePath();
    $this->assertEquals($err_node->field_entity_reference_revisions->target_revision_id, $normalized['_embedded'][$link_domain . '/rest/relation/node/entity_revisions/field_entity_reference_revisions'][0]['target_revision_id']);
    $new_err_node = $serializer->denormalize($normalized, Node::class, 'hal_json');
    $this->assertEquals($err_node->field_entity_reference_revisions->target_revision_id, $new_err_node->field_entity_reference_revisions->target_revision_id);
  }

}
Loading