Commit 1b75d423 authored by catch's avatar catch

Issue #1988426 by damiankloip, linclark: Support deserialization of file entities in HAL.

parent 0a1e9aa0
......@@ -12,6 +12,11 @@ services:
class: Drupal\hal\Normalizer\FieldNormalizer
tags:
- { name: normalizer, priority: 10 }
serializer.normalizer.file_entity.hal:
class: Drupal\hal\Normalizer\FileEntityNormalizer
tags:
- { name: normalizer, priority: 20 }
arguments: ['@entity.manager', '@http_default_client', '@rest.link_manager']
serializer.normalizer.entity.hal:
class: Drupal\hal\Normalizer\EntityNormalizer
arguments: ['@rest.link_manager']
......
<?php
/**
* @file
* Contains \Drupal\hal\Normalizer\FileEntityNormalizer.
*/
namespace Drupal\hal\Normalizer;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\file\Plugin\Core\Entity\File;
use Drupal\rest\LinkManager\LinkManagerInterface;
use Guzzle\Http\ClientInterface;
/**
* Converts the Drupal entity object structure to a HAL array structure.
*/
class FileEntityNormalizer extends EntityNormalizer {
/**
* The interface or class that this Normalizer supports.
*
* @var string
*/
protected $supportedInterfaceOrClass = 'Drupal\file\FileInterface';
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityManagerInterface
*/
protected $entityManager;
/**
* The HTTP client.
*
* @var \Guzzle\Http\ClientInterface
*/
protected $httpClient;
/**
* Constructs a FileEntityNormalizer object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Guzzle\Http\ClientInterface $http_client
* The HTTP Client.
* @param \Drupal\rest\LinkManager\LinkManagerInterface $link_manager
* The hypermedia link manager.
*/
public function __construct(EntityManagerInterface $entity_manager, ClientInterface $http_client, LinkManagerInterface $link_manager) {
parent::__construct($link_manager);
$this->entityManager = $entity_manager;
$this->httpClient = $http_client;
}
/**
* {@inheritdoc}
*/
public function normalize($entity, $format = NULL, array $context = array()) {
$data = parent::normalize($entity, $format, $context);
// Replace the file url with a full url for the file.
$data['uri'][0]['value'] = file_create_url($data['uri'][0]['value']);
return $data;
}
/**
* {@inheritdoc}
*/
public function denormalize($data, $class, $format = NULL, array $context = array()) {
$file_data = $this->httpClient->get($data['uri'][0]['value'])
->send()
->getBody(TRUE);
$path = 'temporary://' . drupal_basename($data['uri'][0]['value']);
$data['uri'] = file_unmanaged_save_data($file_data, $path);
return $this->entityManager->getStorageController('file')->create($data);
}
}
......@@ -34,7 +34,7 @@ public function supportsNormalization($data, $format = NULL) {
* Implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface::supportsDenormalization()
*/
public function supportsDenormalization($data, $type, $format = NULL) {
if (in_array($format, $this->formats)) {
if (in_array($format, $this->formats) && (class_exists($this->supportedInterfaceOrClass) || interface_exists($this->supportedInterfaceOrClass))) {
$target = new \ReflectionClass($type);
$supported = new \ReflectionClass($this->supportedInterfaceOrClass);
if ($supported->isInterface()) {
......@@ -44,6 +44,8 @@ public function supportsDenormalization($data, $type, $format = NULL) {
return ($target->getName() == $this->supportedInterfaceOrClass || $target->isSubclassOf($this->supportedInterfaceOrClass));
}
}
return FALSE;
}
}
<?php
/**
* @file
* Contains \Drupal\hal\Tests\FileDenormalizeTest.
*/
namespace Drupal\hal\Tests;
use Drupal\file\Entity\File;
use Drupal\simpletest\WebTestBase;
/**
* Tests denormalization of the FileEntityNormalizer class.
*
* @see \Drupal\hal\Normalizer\FileEntityNormalizer
*/
class FileDenormalizeTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('hal', 'file');
public static function getInfo() {
return array(
'name' => 'File denormalize Test',
'description' => 'Test that file entities can be denormalized in HAL.',
'group' => 'HAL',
);
}
/**
* Tests file entity denormalization.
*/
public function testFileDenormalize() {
$file_params = array(
'filename' => 'test_1.txt',
'uri' => 'public://test_1.txt',
'filemime' => 'text/plain',
'status' => FILE_STATUS_PERMANENT,
);
// Create a new file entity.
$file = entity_create('file', $file_params);
file_put_contents($file->getFileUri(), 'hello world');
$file->save();
$serializer = \Drupal::service('serializer');
$normalized_data = $serializer->normalize($file, 'hal_json');
$denormalized = $serializer->denormalize($normalized_data, 'Drupal\file\Entity\File', 'hal_json');
$this->assertTrue($denormalized instanceof File, 'A File instance was created.');
$this->assertIdentical('temporary://' . $file->getFilename(), $denormalized->getFileUri(), 'The expected file URI was found.');
$this->assertTrue(file_exists($denormalized->getFileUri()), 'The temporary file was found.');
$this->assertIdentical($file->uuid(), $denormalized->uuid(), 'The expected UUID was found');
$this->assertIdentical($file->getMimeType(), $denormalized->getMimeType(), 'The expected mime type was found.');
$this->assertIdentical($file->getFilename(), $denormalized->getFilename(), 'The expected filename was found.');
$this->assertTrue($denormalized->isPermanent(), 'The file has a permanent status.');
// Try to denormalize with the file uri only.
$file_name = 'test_2.txt';
$file_path = 'public://' . $file_name;
file_put_contents($file_path, 'hello world');
$file_uri = file_create_url($file_path);
$data = array(
'uri' => array(
array('value' => $file_uri),
),
);
$denormalized = $serializer->denormalize($data, 'Drupal\file\Entity\File', 'hal_json');
$this->assertIdentical('temporary://' . $file_name, $denormalized->getFileUri(), 'The expected file URI was found.');
$this->assertTrue(file_exists($denormalized->getFileUri()), 'The temporary file was found.');
$this->assertIdentical('text/plain', $denormalized->getMimeType(), 'The expected mime type was found.');
$this->assertIdentical($file_name, $denormalized->getFilename(), 'The expected filename was found.');
$this->assertFalse($denormalized->isPermanent(), 'The file has a permanent status.');
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment