PHP code example of php-architecture-kit / domain-core

1. Go to this page and download the library: Download php-architecture-kit/domain-core library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

php-architecture-kit / domain-core example snippets


use PhpArchitecture\DomainCore\AggregateRoot;
use PhpArchitecture\DomainCore\DomainEvent;

class OrderCreated implements DomainEvent
{
    public function __construct(
        public readonly string $orderId,
        public readonly array $items,
    ) {}
}

class Order extends AggregateRoot
{
    private string $id;
    private array $items;
    private string $status = 'draft';

    public static function create(string $id, array $items): self
    {
        $order = new self();
        $order->id = $id;
        $order->items = $items;
        $order->recordEvent(new OrderCreated($id, $items));

        return $order;
    }

    public function confirm(): void
    {
        if ($this->status !== 'draft') {
            throw new InvalidStateToPerformActionException('Order already confirmed');
        }
        
        $this->status = 'confirmed';
        $this->recordEvent(new OrderConfirmed($this->id));
    }
}

// Create aggregate and perform actions
$order = Order::create('order-123', ['item1', 'item2']);
$order->confirm();

// Get recorded events (without clearing)
$events = $order->getEvents(); // [OrderCreated, OrderConfirmed]

// Release events (get and clear)
$events = $order->releaseEvents(); // [OrderCreated, OrderConfirmed]
$events = $order->getEvents();     // []

use PhpArchitecture\DomainCore\Exception\InvalidInputException;
use PhpArchitecture\DomainCore\Exception\InsufficientPrivilegeException;
use PhpArchitecture\DomainCore\Exception\InvalidStateToPerformActionException;

class Order extends AggregateRoot
{
    public function addItem(string $sku, int $quantity, string $actorId): void
    {
        // 400 - Invalid input
        if ($quantity <= 0) {
            throw new InvalidInputException('Quantity must be positive');
        }

        // 403 - Insufficient privilege
        if ($this->ownerId !== $actorId) {
            throw new InsufficientPrivilegeException('Only owner can modify order');
        }

        // 409 - Invalid state to perform action
        if ($this->status === 'shipped') {
            throw new InvalidStateToPerformActionException('Cannot modify shipped order');
        }

        $this->items[] = new OrderItem($sku, $quantity);
    }
}

// Symfony Exception Listener
use PhpArchitecture\DomainCore\Exception\InvalidInputException;
use PhpArchitecture\DomainCore\Exception\PaymentStatusException;
use PhpArchitecture\DomainCore\Exception\InsufficientPrivilegeException;
use PhpArchitecture\DomainCore\Exception\InvalidStateToPerformActionException;
use PhpArchitecture\DomainCore\Exception\InvalidStateCausedException;
use PhpArchitecture\DomainCore\Exception\DependencyStateException;
use PhpArchitecture\DomainCore\Exception\LegalRestrictionException;

class DomainExceptionListener
{
    private const HTTP_MAP = [
        InvalidInputException::class => 400,
        PaymentStatusException::class => 402,
        InsufficientPrivilegeException::class => 403,
        InvalidStateToPerformActionException::class => 409,
        InvalidStateCausedException::class => 422,
        DependencyStateException::class => 424,
        LegalRestrictionException::class => 451,
    ];

    public function onKernelException(ExceptionEvent $event): void
    {
        $exception = $event->getThrowable();
        
        foreach (self::HTTP_MAP as $class => $code) {
            if ($exception instanceof $class) {
                $event->setResponse(new JsonResponse(
                    ['error' => $exception->getMessage()],
                    $code
                ));
                return;
            }
        }
    }
}

interface DomainEvent {}

__construct(string $message = '', int $code = 0, ?Throwable $previous = null)