PHP code example of gilsegura / shared-bundle

1. Go to this page and download the library: Download gilsegura/shared-bundle 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/ */

    

gilsegura / shared-bundle example snippets


// config/bundles.php
return [
    Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
    SharedBundle\SharedBundle::class => ['all' => true],
];

SharedBundle\SharedBundle::COMMAND_BUS;  // messenger.bus.command
SharedBundle\SharedBundle::QUERY_BUS;    // messenger.bus.query
SharedBundle\SharedBundle::EVENT_BUS;    // messenger.bus.event.async

use Shared\CommandHandling\CommandHandlerInterface;

/** @implements CommandHandlerInterface<RegisterUser> */
final readonly class RegisterUserHandler implements CommandHandlerInterface
{
    public function __invoke(RegisterUser $command): void { ... }
}

use Shared\Projection\AbstractProjector;

final readonly class UserProjector extends AbstractProjector
{
    public function __construct(
        private UserReadModelRepositoryInterface $users,
    ) {
    }

    protected function applyUserWasCreated(UserWasCreated $event): void
    {
        $this->users->save(User::deserialize($event->serialize()));
    }

    protected function applyUserEmailWasChanged(UserEmailWasChanged $event): void
    {
        $user = $this->users->oneOrException($event->id);
        $user->changeEmail($event->email);
        $this->users->save($user);
    }
}

use SharedBundle\Persistence\Doctrine\AbstractObjectManager;
use SharedBundle\Persistence\Doctrine\Attribute\ObjectManager;

/** @template-extends AbstractObjectManager<int, User> */
#[ObjectManager(User::class)]
final readonly class UserReadModelRepository extends AbstractObjectManager
    implements UserReadModelRepositoryInterface { ... }

use Shared\EventSourcing\AbstractEventSourcingRepository;
use SharedBundle\EventSourcing\Attribute\AggregateRoot;

/** @template-extends AbstractEventSourcingRepository<User> */
#[AggregateRoot(User::class)]
final readonly class UserRepository extends AbstractEventSourcingRepository
    implements UserRepositoryInterface
{
    public function get(Uuid $id): User { return $this->load($id); }
    public function store(User $user): void { $this->save($user); }
}

#[AggregateRoot(User::class, upcasters: [UserV1ToV2Upcaster::class, UserV2ToV3Upcaster::class])]
final readonly class UserRepository extends AbstractEventSourcingRepository
    implements UserRepositoryInterface { ... }

use SharedBundle\EventSourcing\Attribute\AggregateRoot;
use SharedBundle\EventSourcing\Attribute\SnapshotConfig;

/** @template-extends AbstractEventSourcingRepository<User> */
#[AggregateRoot(User::class, snapshot: new SnapshotConfig(every: 100))]
final readonly class UserRepository extends AbstractEventSourcingRepository
    implements UserRepositoryInterface { ... }

use Shared\Domain\Metadata;
use Shared\EventSourcing\MetadataEnricher\MetadataEnricherInterface;

final readonly class CorrelationIdEnricher implements MetadataEnricherInterface
{
    public function __construct(
        private RequestContext $context,
    ) {
    }

    public function enrich(Metadata $metadata): Metadata
    {
        return $metadata->merge(Metadata::kv('correlation_id', $this->context->correlationId()));
    }
}

use Shared\Criteria;
use Shared\Domain\DomainMessage;
use Shared\EventStore\CallableEventVisitor;
use Shared\EventStore\EventStoreManagerInterface;
use Shared\Replaying\Replayer;

$replayer = new Replayer(
    $eventStore,                                  // EventStoreManagerInterface
    new CallableEventVisitor(
        fn (DomainMessage $message) => ($projector)($message),
    ),
);

$replayer(new Criteria\AndX());                        // all events
$replayer(new Criteria\AndX(new Criteria\EqId($id)));  // one aggregate