Skip to content

Commit

Permalink
add emptyToNull support
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominik Zogg committed Mar 10, 2019
1 parent d2771ac commit 79dc4fc
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -30,7 +30,7 @@ A simple deserialization.
Through [Composer](http://getcomposer.org) as [chubbyphp/chubbyphp-deserialization][1].

```sh
composer require chubbyphp/chubbyphp-deserialization "~2.7"
composer require chubbyphp/chubbyphp-deserialization "~2.8"
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -30,7 +30,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
"dev-master": "2.8-dev"
}
}
}
15 changes: 14 additions & 1 deletion src/Denormalizer/ConvertTypeFieldDenormalizer.php
Expand Up @@ -32,20 +32,27 @@ final class ConvertTypeFieldDenormalizer implements FieldDenormalizerInterface
self::TYPE_STRING,
];

/**
* @var bool
*/
private $emptyToNull;

/**
* @param AccessorInterface $accessor
* @param string $type
* @param bool $emptyToNull
*
* @throws DeserializerLogicException
*/
public function __construct(AccessorInterface $accessor, string $type)
public function __construct(AccessorInterface $accessor, string $type, bool $emptyToNull = false)
{
if (!in_array($type, self::TYPES, true)) {
throw DeserializerLogicException::createConvertTypeDoesNotExists($type);
}

$this->accessor = $accessor;
$this->type = $type;
$this->emptyToNull = $emptyToNull;
}

/**
Expand All @@ -64,6 +71,12 @@ public function denormalizeField(
DenormalizerContextInterface $context,
DenormalizerInterface $denormalizer = null
) {
if ($this->emptyToNull && '' === $value) {
$this->accessor->setValue($object, null);

return;
}

$this->accessor->setValue($object, $this->convertType($value));
}

Expand Down
15 changes: 14 additions & 1 deletion src/Denormalizer/DateTimeFieldDenormalizer.php
Expand Up @@ -21,11 +21,18 @@ final class DateTimeFieldDenormalizer implements FieldDenormalizerInterface
*/
private $accessor;

/**
* @var bool
*/
private $emptyToNull;

/**
* @param AccessorInterface|FieldDenormalizerInterface $accessor
*/
public function __construct($accessor)
public function __construct($accessor, bool $emptyToNull = false)
{
$this->emptyToNull = $emptyToNull;

if ($accessor instanceof AccessorInterface) {
$this->accessor = $accessor;

Expand Down Expand Up @@ -74,6 +81,12 @@ public function denormalizeField(
DenormalizerContextInterface $context,
DenormalizerInterface $denormalizer = null
) {
if ($this->emptyToNull && '' === $value) {
$this->setValue($path, $object, null, $context, $denormalizer);

return;
}

if (!is_string($value) || '' === $trimmedValue = trim($value)) {
$this->setValue($path, $object, $value, $context, $denormalizer);

Expand Down
15 changes: 14 additions & 1 deletion src/Denormalizer/FieldDenormalizer.php
Expand Up @@ -14,12 +14,19 @@ final class FieldDenormalizer implements FieldDenormalizerInterface
*/
private $accessor;

/**
* @var bool
*/
private $emptyToNull;

/**
* @param AccessorInterface $accessor
* @param bool $emptyToNull
*/
public function __construct(AccessorInterface $accessor)
public function __construct(AccessorInterface $accessor, bool $emptyToNull = false)
{
$this->accessor = $accessor;
$this->emptyToNull = $emptyToNull;
}

/**
Expand All @@ -38,6 +45,12 @@ public function denormalizeField(
DenormalizerContextInterface $context,
DenormalizerInterface $denormalizer = null
) {
if ($this->emptyToNull && '' === $value) {
$this->accessor->setValue($object, null);

return;
}

$this->accessor->setValue($object, $value);
}
}
18 changes: 11 additions & 7 deletions src/Mapping/DenormalizationFieldMappingBuilder.php
Expand Up @@ -42,9 +42,12 @@ private function __construct(string $name)
*
* @return DenormalizationFieldMappingBuilderInterface
*/
public static function create(string $name): DenormalizationFieldMappingBuilderInterface
public static function create(string $name, bool $emptyToNull = false): DenormalizationFieldMappingBuilderInterface
{
return new self($name);
$self = new self($name);
$self->fieldDenormalizer = new FieldDenormalizer(new PropertyAccessor($name), $emptyToNull);

return $self;
}

/**
Expand All @@ -64,13 +67,14 @@ public static function createCallback(string $name, callable $callback): Denorma
/**
* @param string $name
* @param string $type
* @param bool $emptyToNull
*
* @return DenormalizationFieldMappingBuilderInterface
*/
public static function createConvertType(string $name, string $type): DenormalizationFieldMappingBuilderInterface
public static function createConvertType(string $name, string $type, bool $emptyToNull = false): DenormalizationFieldMappingBuilderInterface
{
$self = new self($name);
$self->fieldDenormalizer = new ConvertTypeFieldDenormalizer(new PropertyAccessor($name), $type);
$self->fieldDenormalizer = new ConvertTypeFieldDenormalizer(new PropertyAccessor($name), $type, $emptyToNull);

return $self;
}
Expand All @@ -80,10 +84,10 @@ public static function createConvertType(string $name, string $type): Denormaliz
*
* @return DenormalizationFieldMappingBuilderInterface
*/
public static function createDateTime(string $name): DenormalizationFieldMappingBuilderInterface
public static function createDateTime(string $name, bool $emptyToNull = false): DenormalizationFieldMappingBuilderInterface
{
$self = new self($name);
$self->fieldDenormalizer = new DateTimeFieldDenormalizer(new PropertyAccessor($name));
$self->fieldDenormalizer = new DateTimeFieldDenormalizer(new PropertyAccessor($name), $emptyToNull);

return $self;
}
Expand Down Expand Up @@ -181,7 +185,7 @@ public function getMapping(): DenormalizationFieldMappingInterface
return new DenormalizationFieldMapping(
$this->name,
$this->groups,
$this->fieldDenormalizer ?? new FieldDenormalizer(new PropertyAccessor($this->name))
$this->fieldDenormalizer
);
}
}
32 changes: 32 additions & 0 deletions tests/Denormalizer/ConvertTypeFieldDenormalizerTest.php
Expand Up @@ -380,4 +380,36 @@ public function testDenormalizeFieldWithSpecialIntegerConvertedToString()
$fieldDenormalizer->denormalizeField('value', $object, 02471, $context);
$fieldDenormalizer->denormalizeField('value', $object, 1337e0, $context);
}

public function testDenormalizeFieldWithEmptyToNullDisabled()
{
$object = new \stdClass();

/** @var AccessorInterface|MockObject $accessor */
$accessor = $this->getMockByCalls(AccessorInterface::class, [
Call::create('setValue')->with($object, ''),
]);

/** @var DenormalizerContextInterface|MockObject $context */
$context = $this->getMockByCalls(DenormalizerContextInterface::class);

$fieldDenormalizer = new ConvertTypeFieldDenormalizer($accessor, ConvertTypeFieldDenormalizer::TYPE_FLOAT);
$fieldDenormalizer->denormalizeField('value', $object, '', $context);
}

public function testDenormalizeFieldWithEmptyToNullEnabled()
{
$object = new \stdClass();

/** @var AccessorInterface|MockObject $accessor */
$accessor = $this->getMockByCalls(AccessorInterface::class, [
Call::create('setValue')->with($object, null),
]);

/** @var DenormalizerContextInterface|MockObject $context */
$context = $this->getMockByCalls(DenormalizerContextInterface::class);

$fieldDenormalizer = new ConvertTypeFieldDenormalizer($accessor, ConvertTypeFieldDenormalizer::TYPE_FLOAT, true);
$fieldDenormalizer->denormalizeField('value', $object, '', $context);
}
}
36 changes: 36 additions & 0 deletions tests/Denormalizer/DateTimeFieldDenormalizerTest.php
Expand Up @@ -288,4 +288,40 @@ public function testDenormalizeObjectField()

self::assertNull(error_get_last());
}

public function testDenormalizeFieldWithEmptyToNullDisabled()
{
$object = new \stdClass();

/** @var AccessorInterface|MockObject $accessor */
$accessor = $this->getMockByCalls(AccessorInterface::class, [
Call::create('setValue')->with($object, ''),
]);

/** @var DenormalizerContextInterface|MockObject $context */
$context = $this->getMockByCalls(DenormalizerContextInterface::class);

$fieldDenormalizer = new DateTimeFieldDenormalizer($accessor);
$fieldDenormalizer->denormalizeField('date', $object, '', $context);

self::assertNull(error_get_last());
}

public function testDenormalizeFieldWithEmptyToNullEnabled()
{
$object = new \stdClass();

/** @var AccessorInterface|MockObject $accessor */
$accessor = $this->getMockByCalls(AccessorInterface::class, [
Call::create('setValue')->with($object, null),
]);

/** @var DenormalizerContextInterface|MockObject $context */
$context = $this->getMockByCalls(DenormalizerContextInterface::class);

$fieldDenormalizer = new DateTimeFieldDenormalizer($accessor, true);
$fieldDenormalizer->denormalizeField('date', $object, '', $context);

self::assertNull(error_get_last());
}
}
32 changes: 32 additions & 0 deletions tests/Denormalizer/FieldDenormalizerTest.php
Expand Up @@ -34,4 +34,36 @@ public function testDenormalizeField()
$fieldDenormalizer = new FieldDenormalizer($accessor);
$fieldDenormalizer->denormalizeField('name', $object, 'name', $context);
}

public function testDenormalizeFieldWithEmptyToNullDisabled()
{
$object = new \stdClass();

/** @var AccessorInterface|MockObject $accessor */
$accessor = $this->getMockByCalls(AccessorInterface::class, [
Call::create('setValue')->with($object, ''),
]);

/** @var DenormalizerContextInterface|MockObject $context */
$context = $this->getMockByCalls(DenormalizerContextInterface::class);

$fieldDenormalizer = new FieldDenormalizer($accessor);
$fieldDenormalizer->denormalizeField('name', $object, '', $context);
}

public function testDenormalizeFieldWithEmptyToNullEnabled()
{
$object = new \stdClass();

/** @var AccessorInterface|MockObject $accessor */
$accessor = $this->getMockByCalls(AccessorInterface::class, [
Call::create('setValue')->with($object, null),
]);

/** @var DenormalizerContextInterface|MockObject $context */
$context = $this->getMockByCalls(DenormalizerContextInterface::class);

$fieldDenormalizer = new FieldDenormalizer($accessor, true);
$fieldDenormalizer->denormalizeField('name', $object, '', $context);
}
}

0 comments on commit 79dc4fc

Please sign in to comment.