Skip to content

Commit

Permalink
Merge pull request #7 from barryosull/feature/method_deserialization
Browse files Browse the repository at this point in the history
Can deserialize a payload into a callable method.
  • Loading branch information
Barry O Sullivan authored Jun 9, 2017
2 parents 69e17a8 + b0ce952 commit 9f30188
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 81 deletions.
65 changes: 33 additions & 32 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/Contracts/MethodDeserializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php namespace EventSourced\ValueObject\Contracts;

interface MethodDeserializer
{
public function deserializeMethod($object, $method, $parameters);
}
12 changes: 11 additions & 1 deletion src/Deserializer/Deserializer.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<?php namespace EventSourced\ValueObject\Deserializer;

use EventSourced\ValueObject\Contracts;
use EventSourced\ValueObject\Deserializer\Deserializer\MethodArguments;
use EventSourced\ValueObject\Extensions\ExtensionRepository;
use EventSourced\ValueObject\ValueObject\Type;

class Deserializer implements Contracts\Deserializer
class Deserializer implements Contracts\Deserializer, Contracts\MethodDeserializer
{
private $single_value;
private $composite;
private $set;
private $type_entity;
private $method_arguments;
private $extensionRepository;

public function __construct(
Expand All @@ -20,6 +22,7 @@ public function __construct(
$this->composite = new Deserializer\Composite($this, $reflector);
$this->set = new Deserializer\Set($this);
$this->type_entity = new Deserializer\TypeEntity($this, $reflector);
$this->method_arguments = new MethodArguments($this, $reflector);
$this->extensionRepository = $repository;
}

Expand Down Expand Up @@ -57,4 +60,11 @@ private function is_instance_of($class, $parent_class)
return is_subclass_of($class, $parent_class)
|| ($class == $parent_class);
}

public function deserializeMethod($object, $method, $serialized_parameters)
{
$arguments = $this->method_arguments->deserialize(get_class($object), $method, $serialized_parameters);

return new Method($object, $method, $arguments);
}
}
52 changes: 4 additions & 48 deletions src/Deserializer/Deserializer/Composite.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

use EventSourced\ValueObject\Deserializer\Deserializer;
use EventSourced\ValueObject\Deserializer\Reflector;
use EventSourced\ValueObject\Deserializer\Exception;
use EventSourced\ValueObject\Assert\Exception as AssertException;
use ReflectionParameter;

class Composite
{
Expand All @@ -19,53 +16,12 @@ public function __construct(Deserializer $deserializer, Reflector $reflector)

public function deserialize($class, $serialized)
{
if (is_array($serialized)) {
$serialized = (object)$serialized;
}
$parameters_deserializer = new Parameters($this->deserializer);

$errors = [];
$deserialized_parameters = [];
$reflection_parameters = $this->reflector->get_constructor_parameters($class);

$parameters = $this->reflector->get_constructor_parameters($class);
foreach ($parameters as $parameter) {
$name = $parameter->getName();
$parameters = $parameters_deserializer->deserialize($reflection_parameters, $serialized);

try {
$deserialized_parameters[$name] = $this->make_parameter($parameter, $serialized);
} catch (AssertException $e) {
$errors[$name] = $e->error_messages();
} catch (Exception $e) {
$errors[$name] = $e->error_messages();
}
}

if (count($errors) != 0) {
throw new Exception($errors);
}

return $this->reflector->call_constructor($class, $deserialized_parameters);
}

private function make_parameter($parameter, $serialized)
{
$name = $parameter->getName();
$parameter_class = $parameter->getClass()->getName();

if ($this->is_nullable_parameter($parameter) && is_null($serialized)) {
return null;
}

if (!property_exists($serialized, $name)) {
throw new Exception(["Property '$name' is missing"]);
}

return $this->deserializer->deserialize(
$parameter_class, $serialized->$name
);
}

private function is_nullable_parameter(ReflectionParameter $parameter)
{
return ($parameter->isOptional() && $parameter->getDefaultValue() === null);
return $this->reflector->call_constructor($class, $parameters);
}
}
25 changes: 25 additions & 0 deletions src/Deserializer/Deserializer/MethodArguments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php namespace EventSourced\ValueObject\Deserializer\Deserializer;

use EventSourced\ValueObject\Deserializer\Deserializer;
use EventSourced\ValueObject\Deserializer\Reflector;

class MethodArguments
{
private $deserializer;
private $reflector;

public function __construct(Deserializer $deserializer, Reflector $reflector)
{
$this->deserializer = $deserializer;
$this->reflector = $reflector;
}

public function deserialize($class, $method, $serialized)
{
$reflection_parameters = new Parameters($this->deserializer);

$parameters = $this->reflector->get_method_parameters($class, $method);

return $reflection_parameters->deserialize($parameters, $serialized);
}
}
Loading

0 comments on commit 9f30188

Please sign in to comment.