Skip to content

Commit

Permalink
fix: Allow UuidInterface array deserialization
Browse files Browse the repository at this point in the history
This commit will allow deserialization of array of UuidInterface using
PhpDocExtractor.

Ref: #12
  • Loading branch information
gbprod committed Jul 22, 2020
1 parent 596a00a commit 5acb53a
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 71 deletions.
20 changes: 14 additions & 6 deletions CHANGELOG.md
@@ -1,25 +1,33 @@
# Change Log

All notable changes to this project will be documented in this file based on the [Keep a Changelog](http://keepachangelog.com/) Standard.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased](https://github.com/gbprod/uuid-normalizer/compare/v1.1.0...HEAD)
## [Unreleased](https://github.com/gbprod/uuid-normalizer/compare/v1.2.0...HEAD)

- Fix array of UuidInterface deserialization (#12)

## [Unreleased](https://github.com/gbprod/uuid-normalizer/compare/v1.1.0...v1.2.0)

- Changing licence
- Update dependencies to php 8, Symfony 5 and Ramsey Uuid 4
- Changing licence

## [v1.1.0](https://github.com/gbprod/uuid-normalizer/compare/v1.0.1...v1.1.0)
- Symfony 4 compatibility
- Add Contributing file
- Drop php 5.5 compatibility

- Symfony 4 compatibility
- Add Contributing file
- Drop php 5.5 compatibility

## [v1.0.0](https://github.com/gbprod/uuid-normalizer/compare/v1.0.0...v1.0.1)

### Added

- Version eye badge
- Changelog
- Compatibility and tests for Symfony Serializer 3.1 and Ramsey/Uuid 3.3 and 3.4
- More examples in documentation

### Changed

- Scrutinizer use PSR2 codesniffer
- Use codecov instead of scrutinizer for coverage
28 changes: 14 additions & 14 deletions README.md
@@ -1,8 +1,8 @@
# Uuid normalizer

[![Build Status](https://travis-ci.org/gbprod/uuid-normalizer.svg?branch=master)](https://travis-ci.org/gbprod/uuid-normalizer)
[![Build Status](https://travis-ci.org/gbprod/uuid-normalizer.svg?branch=master)](https://travis-ci.org/gbprod/uuid-normalizer)
[![codecov](https://codecov.io/gh/gbprod/uuid-normalizer/branch/master/graph/badge.svg)](https://codecov.io/gh/gbprod/uuid-normalizer)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/gbprod/uuid-normalizer/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/gbprod/uuid-normalizer/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/gbprod/uuid-normalizer/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/gbprod/uuid-normalizer/?branch=master)
[![Dependency Status](https://www.versioneye.com/user/projects/574a9caace8d0e004130d3aa/badge.svg)](https://www.versioneye.com/user/projects/574a9caace8d0e004130d3aa)

[![Latest Stable Version](https://poser.pugx.org/gbprod/uuid-normalizer/v/stable)](https://packagist.org/packages/gbprod/uuid-normalizer)
Expand All @@ -23,9 +23,9 @@ composer require gbprod/uuid-normalizer
## Why

By default, [Symfony Serializer](https://github.com/symfony/serializer) can't handle serialization and deserialization of [Ramsey Uuid](https://github.com/ramsey/uuid).
You will have that kind of errors:
You will have that kind of errors:

> Not a time-based UUID
> Not a time-based UUID
> 500 Internal Server Error - UnsupportedOperationException
### Setup
Expand All @@ -34,15 +34,15 @@ In your `app/config/service.yml` file:

```yaml
services:
uuid_normalizer:
class: GBProd\UuidNormalizer\UuidNormalizer
tags:
- { name: serializer.normalizer }

uuid_denormalizer:
class: GBProd\UuidNormalizer\UuidDenormalizer
tags:
- { name: serializer.normalizer }
uuid_normalizer:
class: GBProd\UuidNormalizer\UuidNormalizer
tags:
- { name: serializer.normalizer }

uuid_denormalizer:
class: GBProd\UuidNormalizer\UuidDenormalizer
tags:
- { name: serializer.normalizer }
```

Or using `xml`:
Expand Down Expand Up @@ -87,7 +87,7 @@ $serializer = new Serializer([

## Requirements

* PHP 5.6+
- PHP 5.6+

## Contributing

Expand Down
57 changes: 29 additions & 28 deletions composer.json
@@ -1,30 +1,31 @@
{
"name": "gbprod/uuid-normalizer",
"description": "Normalizer to serialize Ramsey Uuid with Symfony Serializer",
"type": "library",
"autoload": {
"psr-4": {
"GBProd\\UuidNormalizer\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\GBProd\\UuidNormalizer\\": "tests/"
}
},
"require": {
"php": "^5.6|^7.0|^8.0",
"ramsey/uuid": "^3.0|^4.0",
"symfony/serializer": "^2.3|^3.0|^4.0|^5.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7|^6.0"
},
"license": "WTFPL",
"authors": [
{
"name": "GBProd",
"email": "contact@gb-prod.fr"
}
]
"name": "gbprod/uuid-normalizer",
"description": "Normalizer to serialize Ramsey Uuid with Symfony Serializer",
"type": "library",
"autoload": {
"psr-4": {
"GBProd\\UuidNormalizer\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\GBProd\\UuidNormalizer\\": "tests/"
}
},
"require": {
"php": "^5.6|^7.0|^8.0",
"ramsey/uuid": "^3.0|^4.0",
"symfony/serializer": "^2.3|^3.0|^4.0|^5.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7|^6.0",
"symfony/property-access": "^2.3|^3.0|^4.0|^5.0"
},
"license": "WTFPL",
"authors": [
{
"name": "GBProd",
"email": "contact@gb-prod.fr"
}
]
}
14 changes: 8 additions & 6 deletions src/UuidDenormalizer.php
Expand Up @@ -4,6 +4,7 @@

use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

/**
Expand All @@ -18,6 +19,10 @@ class UuidDenormalizer implements DenormalizerInterface
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
if (!$this->isValid($data)) {
throw new UnexpectedValueException('Expected a valid Uuid.');
}

if (null === $data) {
return null;
}
Expand All @@ -30,15 +35,12 @@ public function denormalize($data, $class, $format = null, array $context = arra
*/
public function supportsDenormalization($data, $type, $format = null)
{
return (Uuid::class === $type || UuidInterface::class === $type)
&& $this->isValid($data)
;
return (Uuid::class === $type || UuidInterface::class === $type);
}

private function isValid($data)
{
return $data === null
|| (is_string($data) && Uuid::isValid($data))
;
|| (is_string($data) && Uuid::isValid($data));
}
}
}
2 changes: 1 addition & 1 deletion src/UuidNormalizer.php
Expand Up @@ -27,4 +27,4 @@ public function supportsNormalization($data, $format = null)
{
return $data instanceof UuidInterface;
}
}
}
126 changes: 126 additions & 0 deletions tests/Functionnal/DenormalizeUsingPhpDocTest.php
@@ -0,0 +1,126 @@
<?php

namespace Tests\GBProd\UuidNormalizer;

use GBProd\UuidNormalizer\UuidDenormalizer;
use GBProd\UuidNormalizer\UuidNormalizer;
use PHPUnit\Framework\TestCase;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

class DenormalizeUsingPhpDocTest extends TestCase
{
private $serializer;

public function setUp()
{
$normalizers = [
new UuidNormalizer(),
new UuidDenormalizer(),
new ObjectNormalizer(
null,
null,
null,
class_exists('Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor') ? new PhpDocExtractor() : null
)
];

if (class_exists('Symfony\Component\Serializer\Normalizer\ArrayDenormalizer')) {
$normalizers[] = new ArrayDenormalizer();
}

$this->serializer = new Serializer($normalizers, [
new JsonEncoder(),
]);
}

public function testDenormalizeWithUuid()
{
$uuid = Uuid::uuid4();
$denormalized = $this->serializer->denormalize(
['uuid' => $uuid->toString()],
ClassWithUuidAttribute::class
);

$this->assertEquals($uuid, $denormalized->uuid);
}

public function testDenormalizeWithUuidInterface()
{
$uuid = Uuid::uuid4();
$denormalized = $this->serializer->denormalize(
['uuid' => $uuid->toString()],
ClassWithUuidInterfaceAttribute::class
);

$this->assertEquals($uuid, $denormalized->uuid);
}

public function testDenormalizeWithArrayOfUuid()
{
$uuids = [
Uuid::uuid1(),
Uuid::uuid3(Uuid::NAMESPACE_DNS, 'php.net'),
Uuid::uuid4(),
Uuid::uuid5(Uuid::NAMESPACE_DNS, 'php.net'),
];

$denormalized = $this->serializer->denormalize(
['uuids' => array_map(function ($uuid) {
return $uuid->toString();
}, $uuids)],
ClassWithArrayOfUuidAttribute::class
);

$this->assertEquals($uuids, $denormalized->uuids);
}

public function testDenormalizeWithArrayOfUuidInterface()
{
$uuids = [
Uuid::uuid1(),
Uuid::uuid3(Uuid::NAMESPACE_DNS, 'php.net'),
Uuid::uuid4(),
Uuid::uuid5(Uuid::NAMESPACE_DNS, 'php.net'),
];

$denormalized = $this->serializer->denormalize(
['uuids' => array_map(function ($uuid) {
return $uuid->toString();
}, $uuids)],
ClassWithArrayOfUuidInterfaceAttribute::class
);

$this->assertEquals($uuids, $denormalized->uuids);
}
}

class ClassWithUuidAttribute
{
/** @var Uuid */
public $uuid;
}

class ClassWithUuidInterfaceAttribute
{
/** @var UuidInterface */
public $uuid;
}


class ClassWithArrayOfUuidAttribute
{
/** @var Uuid[] */
public $uuids;
}

class ClassWithArrayOfUuidInterfaceAttribute
{
/** @var UuidInterface[] */
public $uuids;
}

0 comments on commit 5acb53a

Please sign in to comment.