Skip to content

Commit

Permalink
Merge pull request #13 from sunrise-php/release/v2.2.0
Browse files Browse the repository at this point in the history
v2.2.0
  • Loading branch information
fenric authored Jan 10, 2022
2 parents a361c49 + 468710e commit 973bee7
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ final class Foo
private Bar $bar; // see bellow...
private BarCollection $barCollection; // see bellow...

private DateInterval $duration; // see ISO 8601, e.g. "P3Y6M4DT12H30M5S"

/**
* @Alias("non-normalized")
*/
Expand Down
45 changes: 45 additions & 0 deletions src/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class Hydrator implements HydratorInterface
'object' => 'hydratePropertyWithObject',
'DateTime' => 'hydratePropertyWithTimestamp',
'DateTimeImmutable' => 'hydratePropertyWithTimestamp',
'DateInterval' => 'hydratePropertyWithInterval',
];

/**
Expand Down Expand Up @@ -585,6 +586,50 @@ private function hydratePropertyWithTimestamp(
));
}

/**
* Hydrates the given property with the given interval
*
* @param object $object
* @param ReflectionClass $class
* @param ReflectionProperty $property
* @param ReflectionNamedType $type
* @param mixed $value
*
* @return void
*
* @throws Exception\InvalidValueException
* If the given value isn't valid.
*/
private function hydratePropertyWithInterval(
object $object,
ReflectionClass $class,
ReflectionProperty $property,
ReflectionNamedType $type,
$value
) : void {
if (!is_string($value)) {
throw new Exception\InvalidValueException($property, sprintf(
'The %s.%s property accepts a string only.',
$class->getShortName(),
$property->getName()
));
}

$prototype = $type->getName();

try {
$interval = new $prototype($value);
} catch (\Exception $e) {
throw new Exception\InvalidValueException($property, sprintf(
'The %s.%s property accepts a valid interval based on ISO 8601.',
$class->getShortName(),
$property->getName()
));
}

$property->setValue($object, $interval);
}

/**
* Hydrates the given property with the given many associations
*
Expand Down
29 changes: 29 additions & 0 deletions tests/HydratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -318,4 +318,33 @@ public function testHydratePropertyWithInvalidOneOfAssociations() : void
'value' => [0],
]);
}

public function testHydratePropertyWithInterval() : void
{
$object = (new Hydrator)->hydrate(Fixtures\Baz::class, [
'duration' => 'P1W2D',
]);

$this->assertInstanceOf(\DateInterval::class, $object->duration);
}

public function testHydratePropertyWithInvalidIntervalType() : void
{
$this->expectException(Exception\InvalidValueException::class);
$this->expectExceptionMessage('The Baz.duration property accepts a string only.');

(new Hydrator)->hydrate(Fixtures\Baz::class, [
'duration' => 0,
]);
}

public function testHydratePropertyWithInvalidInterval() : void
{
$this->expectException(Exception\InvalidValueException::class);
$this->expectExceptionMessage('The Baz.duration property accepts a valid interval based on ISO 8601.');

(new Hydrator)->hydrate(Fixtures\Baz::class, [
'duration' => 'fuuu',
]);
}
}
12 changes: 12 additions & 0 deletions tests/fixtures/Baz.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Sunrise\Hydrator\Tests\Fixtures;

use DateInterval;

final class Baz
{
public DateInterval $duration;
}

0 comments on commit 973bee7

Please sign in to comment.