<commit_before><?php

namespace EventSourced;

use Rhumsaa\Uuid\Uuid;
use LiteCQRS\DefaultDomainEvent;
use LiteCQRS\AggregateRoot;

require_once __DIR__ . "/../vendor/autoload.php";

class InventoryItem extends AggregateRoot
{
    private $name;
    private $activated = true;

    public function __construct($id)
    {
        $this->apply(new InventoryItemCreated($id));
    }

    public function changeName($name)
    {
        if (!$name) {
            throw new \RuntimeException("Setting empty name is not allowed.");
        }

        $this->apply(new InventoryItemRenamed($this->getId(), $name));
    }

    public function deactivate()
    {
        if (!$this->activated) {
            throw new \RuntimeException("Cannot deactivate item again.");
        }

        $this->apply(new InventoryItemDeactivated($this->getId()));
    }

    protected function applyInventoryItemCreated($event)
    {
        $this->setId($event->id);
    }

    protected function applyInventoryItemRenamed($event)
    {
        $this->name = $event->name;
    }

    protected function applyInventoryItemDeactivated($event)
    {
        $this->activated = false;
    }
}

class InventoryItemCreated extends DefaultDomainEvent
{
    protected $id;

    public function __construct($id)
    {
        $this->id = $id;
    }
}

class InventoryItemRenamed extends DefaultDomainEvent
{
    protected $id;
    protected $name;

    public function __construct($id, $name)
    {
        $this->id = $id;
        $this->name = $name;
    }
}

class InventoryItemDeactivated extends DefaultDomainEvent
{
    protected $id;

    public function __construct($id)
    {
        $this->id = $id;
    }
}

$item = new InventoryItem(Uuid::uuid4());
$item->changeName("Foo");
$item->deactivate();

var_dump($item);<commit_msg>Full example<commit_after><?php

namespace EventSourced;

use Rhumsaa\Uuid\Uuid;

use LiteCQRS\Repository;
use LiteCQRS\DefaultCommand;
use LiteCQRS\Commanding;
use LiteCQRS\DefaultDomainEvent;
use LiteCQRS\AggregateRoot;
use LiteCQRS\EventStore;
use LiteCQRS\Serializer\ReflectionSerializer;
use LiteCQRS\Eventing;

require_once __DIR__ . "/../vendor/autoload.php";

class InventoryItem extends AggregateRoot
{
    private $name;
    private $activated = true;

    public function __construct($id)
    {
        $this->apply(new InventoryItemCreated($id));
    }

    public function changeName($name)
    {
        if (!$name) {
            throw new \RuntimeException("Setting empty name is not allowed.");
        }

        $this->apply(new InventoryItemRenamed($this->getId(), $name));
    }

    public function deactivate()
    {
        if (!$this->activated) {
            throw new \RuntimeException("Cannot deactivate item again.");
        }

        $this->apply(new InventoryItemDeactivated($this->getId()));
    }

    protected function applyInventoryItemCreated($event)
    {
        $this->setId($event->id);
    }

    protected function applyInventoryItemRenamed($event)
    {
        $this->name = $event->name;
    }

    protected function applyInventoryItemDeactivated($event)
    {
        $this->activated = false;
    }
}

class InventoryItemCreated extends DefaultDomainEvent
{
    protected $id;

    public function __construct($id)
    {
        $this->id = $id;
    }
}

class InventoryItemRenamed extends DefaultDomainEvent
{
    protected $id;
    protected $name;

    public function __construct($id, $name)
    {
        $this->id = $id;
        $this->name = $name;
    }
}

class InventoryItemDeactivated extends DefaultDomainEvent
{
    protected $id;

    public function __construct($id)
    {
        $this->id = $id;
    }
}

class CreateInventoryItem extends DefaultCommand
{
    public $id;
}

class ChangeInventoryName extends DefaultCommand
{
    public $id;
    public $newName;
}

class DeactivateInventoryItem extends DefaultCommand
{
    public $id;
}

class InventoryHandler
{
    private $repository;

    public function __construct(Repository $repository)
    {
        $this->repository = $repository;
    }

    public function createInventoryItem(CreateInventoryItem $command)
    {
        $inventoryItem = new InventoryItem($command->id);

        $this->repository->save($inventoryItem);
    }

    public function changeInventoryName(ChangeInventoryName $command)
    {
        $inventoryItem = $this->repository->find('EventSourced\\InventoryItem', $command->id);
        $inventoryItem->changeName($command->newName);

        $this->repository->save($inventoryItem);
    }

    public function deactivateInventoryItem(DeactivateInventoryItem $command)
    {
        $inventoryItem = $this->repository->find('EventSourced\\InventoryItem', $command->id);
        $inventoryItem->deactivate();

        $this->repository->save($inventoryItem);
    }
}

class InventoryConsoleOutputListener
{
    public function onInventoryItemCreated(InventoryItemCreated $event)
    {
        echo $event->id;
    }
}

$listener = new InventoryConsoleOutputListener();
$eventHandlerLocator = new Eventing\MemoryEventHandlerLocator();
$eventHandlerLocator->register($listener);

$eventStore = new EventStore\OptimisticLocking\OptimisticLockingEventStore(
    new EventStore\OptimisticLocking\MemoryStorage(),
    new ReflectionSerializer()
);
$eventBus = new Eventing\SynchronousInProcessEventBus($eventHandlerLocator);

$repository = new EventStore\EventSourceRepository($eventStore, $eventBus);

$inventoryHandler = new InventoryHandler($repository);
$commandHandlerLocator = new Commanding\MemoryCommandHandlerLocator();
$commandHandlerLocator->register('EventSourced\CreateInventoryItem', $inventoryHandler);
$commandHandlerLocator->register('EventSourced\ChangeInventoryName', $inventoryHandler);
$commandHandlerLocator->register('EventSourced\DeactivateInventoryItem', $inventoryHandler);
$commandBus = new Commanding\SequentialCommandBus($commandHandlerLocator);

$id = Uuid::uuid4();

$commandBus->handle(new CreateInventoryItem(array('id' => $id)));
$commandBus->handle(new ChangeInventoryName(array('id' => $id, 'newName' => 'test')));
$commandBus->handle(new DeactivateInventoryItem(arraY('id' => $id)));
{'fraction_non_alphanumeric': 0.12027881342194845, 'fraction_numerical': 0.0003242016534284325, 'mean_word_length': 3.6356123215627347, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7186751', 'n_tokens_mistral': 1853, 'n_tokens_neox': 1788, 'n_words': 345}