1. Go to this page and download the library: Download bear/event-sourcing 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/ */
bear / event-sourcing example snippets
use BEAR\EventSourcing\SemanticLogExtractor;
$log = $semanticLogger->flush(); // Koriym\SemanticLogger\LogJson
$events = (new SemanticLogExtractor())->extract($log);
foreach ($events as $event) {
// $event->id, $event->uri, $event->method, $event->params, $event->result, $event->timestamp
echo $event->method, ' ', $event->uri, "\n";
}
use BEAR\EventSourcing\Module\EventSourcingModule;
use BEAR\EventSourcing\RecordedMethods;
use Override;
use Ray\Di\AbstractModule;
final class AppModule extends AbstractModule
{
#[Override]
protected function configure(): void
{
$this->install(new EventSourcingModule(
methods: new RecordedMethods(RecordedMethods::WITH_READS),
));
}
}
use BEAR\EventSourcing\Filtered;
use BEAR\EventSourcing\Resource\FilteredParams;
use BEAR\EventSourcing\Resource\ParamsFilterInterface;
use BEAR\EventSourcing\Resource\SensitiveParamsFilter;
use Override;
final class AppParamsFilter implements ParamsFilterInterface
{
private SensitiveParamsFilter $default;
public function __construct()
{
// Composed, never replaced, and `otp` goes through the constructor rather than a
// hand-rolled check: the default matches it the way it matches its own set — at every
// depth, case and `_`/`-` ignored — where an isset() on the top level would sail past
// ['user' => ['otp' => '123456']].
$this->default = new SensitiveParamsFilter(['otp']);
}
#[Override]
public function __invoke(array $params): FilteredParams
{
$filtered = ($this->default)($params);
// What the constructor cannot express: a verdict this application reaches for the
// request as a whole, whatever its params turned out to hold.
$replayable = $filtered->replayable && ($params['mode'] ?? null) !== 'sandbox';
return new FilteredParams($filtered->params, $replayable);
}
}
$this->bind(ParamsFilterInterface::class)->annotatedWith(Filtered::class)->to(AppParamsFilter::class);
use BEAR\EventSourcing\Event;
$userEvents = new CallbackFilterIterator(
$events->getIterator(),
static fn (Event $event): bool => ($event->params['id'] ?? null) === 'koriym',
);
$userWrites = new CallbackFilterIterator(
$userEvents,
static fn (Event $event): bool => $event->method !== 'GET',
);
foreach ($userWrites as $event) {
// replay, project, or inspect events for id=koriym
}
use BEAR\EventSourcing\Resource\ResourceObservationModule;
use BEAR\Resource\Module\ResourceClientModule;
use Ray\Di\Injector;
$injector = new Injector(new ResourceObservationModule(
module: new ResourceClientModule(),
));
use BEAR\EventSourcing\EventCollector;
$collect = new EventCollector($logger, $extractor, $store); // store is optional
$events = $collect(); // once per request, at the boundary
$log = $logger->flush(); // the tree, for inspection
file_put_contents($logFile, json_encode($log));
$events = $extractor->extract($log); // the facts
use BEAR\EventSourcing\Resource\DevLogModule;
use BEAR\Resource\Module\ResourceClientModule;
use Ray\Di\Injector;
$injector = new Injector(new DevLogModule(
bodyDir: __DIR__ . '/var/es/bodies',
module: new ResourceClientModule(),
));
use BEAR\EventSourcing\Module\MediaQueryObservationModule;
$this->install(new MediaQueryObservationModule()); // before the MediaQuery modules
use Koriym\SemanticLogger\SemanticLogValidator;
(new SemanticLogValidator())->validate($logFile, $projectDir . '/docs/schemas');
use BEAR\RepositoryModule\Annotation\CacheLog;
use Koriym\SemanticLogger\SemanticLogger;
use Koriym\SemanticLogger\SemanticLoggerInterface;
$logger = new SemanticLogger();
$this->install(new DevLogModule($bodyDir, logger: $logger, module: $appModule));
$this->bind(SemanticLoggerInterface::class)->annotatedWith(CacheLog::class)->toInstance($logger);
final class CacheLogProvider implements ProviderInterface
{
public function __construct(private readonly SemanticLoggerInterface $logger)
{
}
public function get(): SemanticLoggerInterface
{
return $this->logger;
}
}
$this->bind(SemanticLoggerInterface::class)->annotatedWith(CacheLog::class)
->toProvider(CacheLogProvider::class)->in(Scope::SINGLETON);