-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds traits with a generalized json serializer and hydration solution…
…s. (#13)
- Loading branch information
Showing
13 changed files
with
236 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,71 @@ | ||
<?php | ||
|
||
|
||
namespace Procrastinator; | ||
|
||
/** | ||
* @todo Change name to HydratableTrait. | ||
*/ | ||
trait HydratableTrait | ||
{ | ||
public static function hydrate(string $json, $instance = null) | ||
{ | ||
$data = json_decode($json); | ||
$data = (array) json_decode($json); | ||
|
||
$class = new \ReflectionClass(static::class); | ||
|
||
if (!$instance) { | ||
$instance = $class->newInstanceWithoutConstructor(); | ||
} | ||
|
||
$reflector = new \ReflectionClass(self::class); | ||
$object = $reflector->newInstanceWithoutConstructor(); | ||
$properties = []; | ||
$parent = $class; | ||
while ($parent) { | ||
$properties = array_merge($properties, $parent->getProperties()); | ||
$parent = $parent->getParentClass(); | ||
} | ||
|
||
$reflector = new \ReflectionClass($object); | ||
foreach ($data as $property => $value) { | ||
$p = $reflector->getProperty($property); | ||
$p->setAccessible(true); | ||
$p->setValue($object, $value); | ||
/* @var $property \ReflectionProperty */ | ||
foreach ($properties as $property) { | ||
$name = $property->getName(); | ||
if (isset($data[$name])) { | ||
$property->setAccessible(true); | ||
$property->setValue($instance, static::hydrateProcessValue($data[$name])); | ||
} | ||
} | ||
return $object; | ||
return $instance; | ||
} | ||
|
||
private static function hydrateProcessValue($value) | ||
{ | ||
if (is_object($value)) { | ||
$value = (array) $value; | ||
if (isset($value["@type"])) { | ||
$type = $value["@type"]; | ||
$value = (object) $value; | ||
switch ($type) { | ||
case "object": | ||
return static::hydrateProcessValueObject($value); | ||
case "array": | ||
return static::hydrateProcessValueArray($value); | ||
} | ||
throw new \Exception("Unrecognized type: {$type}."); | ||
} else { | ||
return (object) $value; | ||
} | ||
} | ||
return $value; | ||
} | ||
|
||
private static function hydrateProcessValueObject($value) | ||
{ | ||
$value = (array) $value; | ||
$class = $value['@class']; | ||
return $class::hydrate(json_encode($value['data'])); | ||
} | ||
|
||
private static function hydrateProcessValueArray($value) | ||
{ | ||
$value = (array) $value; | ||
$array = (array) $value['data']; | ||
return array_map(function ($item) { | ||
return static::hydrateProcessValue($item); | ||
}, $array); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,6 @@ | |
|
||
namespace Procrastinator\Job; | ||
|
||
use Procrastinator\Result; | ||
|
||
class Method extends Job | ||
{ | ||
private $object; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
namespace Procrastinator; | ||
|
||
trait JsonSerializeTrait | ||
{ | ||
private function serialize() | ||
{ | ||
$serialized = []; | ||
|
||
$properties = []; | ||
$class = new \ReflectionClass(static::class); | ||
$parent = $class; | ||
while ($parent) { | ||
$properties = array_merge($properties, $parent->getProperties()); | ||
$parent = $parent->getParentClass(); | ||
} | ||
|
||
/* @var $property \ReflectionProperty */ | ||
foreach ($properties as $property) { | ||
$name = $property->getName(); | ||
if (!in_array($name, $this->serializeIgnoreProperties())) { | ||
$property->setAccessible(true); | ||
$serialized[$property->getName()] = $this->serializeProcessValue($property->getValue($this)); | ||
} | ||
} | ||
|
||
return $serialized; | ||
} | ||
|
||
private function serializeProcessValue($value) | ||
{ | ||
if (is_object($value)) { | ||
return $this->serializeProcessValueObject($value); | ||
} elseif (is_array($value)) { | ||
return $this->serializeProcessValueArray($value); | ||
} | ||
return $value; | ||
} | ||
|
||
private function serializeProcessValueObject($object) | ||
{ | ||
if ($object instanceof \stdClass) { | ||
return $object; | ||
} elseif ($object instanceof \JsonSerializable) { | ||
return ['@type' => 'object', '@class' => get_class($object), 'data' => $object->jsonSerialize()]; | ||
} else { | ||
$class = get_class($object); | ||
$interface = \JsonSerializable::class; | ||
$message = "Failed to serialize {$class} object as it does not implement {$interface}"; | ||
throw new \Exception($message); | ||
} | ||
} | ||
|
||
private function serializeProcessValueArray($array) | ||
{ | ||
$serialized = []; | ||
|
||
foreach ($array as $key => $value) { | ||
$serialized[$key] = $this->serializeProcessValue($value); | ||
} | ||
|
||
return ['@type' => 'array', 'data' => $serialized]; | ||
} | ||
|
||
protected function serializeIgnoreProperties(): array | ||
{ | ||
return []; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace ProcrastinatorTest\Mock; | ||
|
||
use Contracts\HydratableInterface; | ||
use Procrastinator\HydratableTrait; | ||
use Procrastinator\JsonSerializeTrait; | ||
|
||
class Complex implements \JsonSerializable, HydratableInterface | ||
{ | ||
use JsonSerializeTrait; | ||
use HydratableTrait; | ||
|
||
private $stuff; | ||
|
||
public function __construct() | ||
{ | ||
$this->stuff["hello"] = (object) [ | ||
"first_name" => "Gerardo", | ||
"last_name" => "Gonzalez" | ||
]; | ||
$this->stuff['goodbye'] = 2; | ||
} | ||
|
||
public function getItem($key) | ||
{ | ||
return $this->stuff[$key]; | ||
} | ||
|
||
public function jsonSerialize() | ||
{ | ||
return $this->serialize(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
|
||
namespace ProcrastinatorTest\Mock; | ||
|
||
use Procrastinator\Job\AbstractPersistentJob; | ||
|
||
class Persistor extends AbstractPersistentJob | ||
{ | ||
private $errorOut = false; | ||
|
||
public function errorOut() | ||
{ | ||
$this->errorOut = true; | ||
} | ||
|
||
protected function runIt() | ||
{ | ||
if ($this->errorOut) { | ||
throw new \Exception("ERROR"); | ||
} | ||
$this->setStateProperty("ran", true); | ||
return; | ||
} | ||
|
||
protected function serializeIgnoreProperties(): array | ||
{ | ||
$properties = parent::serializeIgnoreProperties(); | ||
$properties[] = 'errorOut'; | ||
return $properties; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.