Created
September 14, 2015 08:30
-
-
Save boekkooi/d3b4bda2160f74657c56 to your computer and use it in GitHub Desktop.
ValueObject + Broadway
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
<?php | |
namespace Xoip\Component\ValueObject; | |
interface Collection extends \IteratorAggregate, \Countable | |
{ | |
/** | |
* Adds an element at the end of the collection. | |
* | |
* @param ValueObject $object The object to add. | |
* | |
* @return boolean Always TRUE. | |
*/ | |
public function add(ValueObject $object); | |
/** | |
* Removes the specified object from the collection, if it is found. | |
* | |
* @param mixed $object The object to remove. | |
* @return boolean TRUE if this collection contained the specified object, FALSE otherwise. | |
*/ | |
public function remove(ValueObject $object); | |
/** | |
* Checks whether an object is contained in the collection. | |
* | |
* @param ValueObject $object The object to search for. | |
* @return boolean TRUE if the collection contains the object, FALSE otherwise. | |
*/ | |
public function contains(ValueObject $object); | |
/** | |
* Gets a native PHP array representation of the collection. | |
* | |
* @return array | |
*/ | |
public function toArray(); | |
/** | |
* @inheritdoc | |
*/ | |
public function getIterator(); | |
} |
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
<?php | |
namespace Xoip\Component\ValueObject; | |
final class CollectionHelper | |
{ | |
/** | |
* @codeCoverageIgnore | |
*/ | |
private function __construct() | |
{ | |
} | |
/** | |
* Resolve the changes that are need to the original to be the same as the target. | |
* | |
* @param ValueObject[]|\Traversable $original | |
* @param ValueObject[]|\Traversable $target | |
* @return array list($removed, $added) | |
*/ | |
public static function resolveChanges($original, $target) | |
{ | |
/** @var ValueObject[] $original */ | |
if (!is_array($original) && !$original instanceof \Traversable) { | |
throw new \InvalidArgumentException('Expected $original to be a array or implement Traversable.'); | |
} | |
/** @var ValueObject[] $target */ | |
if (!is_array($target) && !$target instanceof \Traversable) { | |
throw new \InvalidArgumentException('Expected $target to be a array or implement Traversable.'); | |
} | |
// Discover removed items | |
$removed = []; | |
foreach ($original as $originalObject) { | |
foreach ($target as $targetObject) { | |
if ($originalObject->equals($targetObject)) { | |
// Nothing changed | |
continue 2; | |
} | |
} | |
$removed[] = $originalObject; | |
} | |
// Add new items | |
$added = []; | |
foreach ($target as $targetObject) { | |
foreach ($original as $originalObject) { | |
if ($targetObject->equals($originalObject)) { | |
// Nothing changed | |
continue 2; | |
} | |
} | |
$added[] = $targetObject; | |
} | |
return [ $removed, $added ]; | |
} | |
} |
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
<?php | |
namespace Xoip\Component\ValueObject\EventSourced; | |
use Broadway\EventSourcing\AggregateRootAlreadyRegisteredException; | |
use Broadway\EventSourcing\EventSourcedAggregateRoot; | |
use Broadway\EventSourcing\EventSourcedEntityInterface; | |
use Xoip\Component\ValueObject\Collection; | |
use Xoip\Component\ValueObject\ValueObject; | |
use Xoip\Component\ValueObject\ValueObjectCollection as InternalValueObjectCollection; | |
abstract class ValueObjectCollection implements EventSourcedEntityInterface, Collection | |
{ | |
/** | |
* @var object|null | |
*/ | |
private $aggregateRoot; | |
/** | |
* @var InternalValueObjectCollection | |
*/ | |
protected $collection; | |
/** | |
* Initializes a new ValueObjectCollection. | |
*/ | |
public function __construct() | |
{ | |
$this->collection = new InternalValueObjectCollection($objects = []); | |
} | |
/** | |
* Handles event if capable. | |
* | |
* @param $event | |
*/ | |
public function handleRecursively($event) | |
{ | |
$method = $this->getApplyMethod($event); | |
if (!method_exists($this, $method)) { | |
return; | |
} | |
$this->$method($event); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function registerAggregateRoot(EventSourcedAggregateRoot $aggregateRoot) | |
{ | |
if (null !== $this->aggregateRoot && $this->aggregateRoot !== $aggregateRoot) { | |
throw new AggregateRootAlreadyRegisteredException(); | |
} | |
$this->aggregateRoot = $aggregateRoot; | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function contains(ValueObject $object) | |
{ | |
return $this->collection->contains($object); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function toArray() | |
{ | |
return $this->collection->toArray(); | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function getIterator() | |
{ | |
return $this->collection->getIterator(); | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function count() | |
{ | |
return $this->collection->count(); | |
} | |
/** | |
* Applies an event. The event is added to the (parent) AggregateRoot's list of uncommitted events. | |
* | |
* @param $event | |
*/ | |
protected function apply($event) | |
{ | |
$this->aggregateRoot->apply($event); | |
} | |
/** | |
* Resolve the apply method name for a event | |
* | |
* @param string $event | |
* @return string | |
*/ | |
private function getApplyMethod($event) | |
{ | |
$classParts = explode('\\', get_class($event)); | |
return 'apply' . end($classParts); | |
} | |
} |
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
<?php | |
namespace Xoip\Component\ValueObject; | |
interface ValueObject | |
{ | |
/** | |
* Returns TRUE if this value object is equal to another. | |
* | |
* @param mixed $other | |
* @return boolean | |
*/ | |
public function equals($other); | |
} |
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
<?php | |
namespace Xoip\Component\ValueObject; | |
class ValueObjectCollection implements Collection | |
{ | |
/** | |
* @var ValueObject[] | |
*/ | |
private $objects; | |
/** | |
* Initializes a new ValueObjectCollection. | |
* | |
* @param ValueObject[]|\Traversable $objects | |
*/ | |
public function __construct($objects = []) | |
{ | |
if (!is_array($objects) && !$objects instanceof \Traversable) { | |
throw new \InvalidArgumentException('Expected $objects to be a array or implement Traversable.'); | |
} | |
$this->objects = is_array($objects) ? $objects : iterator_to_array($objects); | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function add(ValueObject $object) | |
{ | |
$this->objects[] = $object; | |
return true; | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function remove(ValueObject $object) | |
{ | |
$index = $this->indexOf($object); | |
if ($index === false) { | |
return false; | |
} | |
unset($this->objects[$index]); | |
return true; | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function contains(ValueObject $object) | |
{ | |
return $this->indexOf($object) !== false; | |
} | |
/** | |
* @inheritdoc | |
*/ | |
protected function indexOf(ValueObject $object) | |
{ | |
foreach ($this->objects as $i => $item) { | |
if ($item->equals($object)) { | |
return $i; | |
} | |
} | |
return false; | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function toArray() | |
{ | |
return $this->objects; | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function getIterator() | |
{ | |
return new \ArrayIterator($this->objects); | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function count() | |
{ | |
return count($this->objects); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment