Version 1.0.0

This commit is contained in:
diffhead
2025-11-22 12:10:44 +04:00
committed by Viktor Smagin
commit 3f19a38412
14 changed files with 6722 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\LaravelDataEnrichment\Facade;
use Illuminate\Support\Facades\Facade;
/**
* @method static \Diffhead\PHP\LaravelDataEnrichment\Manager\ArrayManager cleanRequests()
* @method static \Diffhead\PHP\DataEnrichmentKit\Builder addRequest(string $target, string $field, array<int,array{key:string,alias:string}|\Diffhead\PHP\DataEnrichmentKit\Object\Item> $items)
* @method static array enrichData(array $data)
*/
class ArrayEnrichment extends Facade
{
public static function getFacadeAccessor(): string
{
return \Diffhead\PHP\LaravelDataEnrichment\Manager\ArrayManager::class;
}
}

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\LaravelDataEnrichment\Facade;
use Illuminate\Support\Facades\Facade;
/**
* @method static \Diffhead\PHP\LaravelDataEnrichment\Manager\HttpManager useHeader(\BackedEnum $header)
* @method static \Diffhead\PHP\LaravelDataEnrichment\Manager\HttpManager cleanRequests()
* @method static \Diffhead\PHP\DataEnrichmentKit\Builder addRequest(string $target, string $field, array<int,array{key:string,alias:string}|\Diffhead\PHP\DataEnrichmentKit\Object\Item> $items)
* @method static \Psr\Http\Message\MessageInterface setRequests(\Psr\Http\Message\MessageInterface $message)
* @method static \Psr\Http\Message\MessageInterface enrichMessage(\Psr\Http\Message\MessageInterface $message)
*/
class HttpEnrichment extends Facade
{
public static function getFacadeAccessor(): string
{
return \Diffhead\PHP\LaravelDataEnrichment\Manager\HttpManager::class;
}
}

View File

@@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\LaravelDataEnrichment\Manager;
use Diffhead\PHP\DataEnrichmentKit\Builder;
use Diffhead\PHP\DataEnrichmentKit\Enricher;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Storage\Requests;
use InvalidArgumentException;
abstract class AbstractManager
{
/**
* @var array<int,\Diffhead\PHP\DataEnrichmentKit\Builder>
*/
protected array $builders = [];
public function __construct(
protected Enricher $enricher,
) {}
/**
* @param string $target
* @param string $field
* @param array<int,array{key:string,alias:string}|\Diffhead\PHP\DataEnrichmentKit\Object\Item> $items
*
* @return \Diffhead\PHP\DataEnrichmentKit\Builder
*/
public function addRequest(string $target, string $field = 'id', array $items = []): Builder
{
$builder = Builder::withTarget($target, $field);
foreach ($items as $item) {
if (is_array($item)) {
$this->validateRequestItemAsArray($item);
} else {
$item = $this->objectRequestItemToArray($item);
}
$builder->item($item['key'], $item['alias']);
}
$this->builders[] = $builder;
return $builder;
}
public function cleanRequests(): static
{
$this->builders = [];
return $this;
}
protected function getRequests(): Requests
{
$requests = new Requests();
foreach ($this->builders as $builder) {
$requests->append($builder->build());
}
return $requests;
}
/**
* @param array $item
*
* @return void
*
* @throws \InvalidArgumentException
*/
private function validateRequestItemAsArray(array $item): void
{
$notExistingKey = ! array_key_exists('key', $item);
$notExistingAlias = ! array_key_exists('alias', $item);
if ($notExistingKey || $notExistingAlias) {
throw new InvalidArgumentException(
'Item as array should contain "key" and "alias" values.'
);
}
}
/**
* @param \Diffhead\PHP\DataEnrichmentKit\Object\Item $item
*
* @return array{key:string,alias:string}
*/
private function objectRequestItemToArray(Item $item): array
{
return [
'key' => $item->key(),
'alias' => $item->alias(),
];
}
}

View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\LaravelDataEnrichment\Manager;
class ArrayManager extends AbstractManager
{
public function enrichData(array $data): array
{
return $this->enricher->enrich($data, $this->getRequests());
}
}

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\LaravelDataEnrichment\Manager;
use BackedEnum;
use Diffhead\PHP\DataEnrichmentKit\Enricher;
use Diffhead\PHP\DataEnrichmentKit\Header;
use Diffhead\PHP\DataEnrichmentKit\Message;
use Psr\Http\Message\MessageInterface;
class HttpManager extends AbstractManager
{
private BackedEnum $requestsHeader = Header::XEnrichmentRequest;
public function __construct(
protected Enricher $enricher,
private Message $message,
) {}
public function useHeader(BackedEnum $header): static
{
$this->requestsHeader = $header;
return $this;
}
public function setRequests(MessageInterface $message): MessageInterface
{
$header = $this->requestsHeader;
$requests = $this->getRequests();
return $this->message->setRequests($message, $header, $requests);
}
public function enrichMessage(MessageInterface $message): MessageInterface
{
$requests = $this->message->getRequests($message, $this->requestsHeader);
$payload = $this->message->getPayload($message);
$enriched = $this->enricher->enrich($payload, $requests);
return $this->message->setPayload($message, $enriched);
}
}

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\LaravelDataEnrichment\Middleware;
use Closure;
use Diffhead\PHP\LaravelDataEnrichment\Facade\HttpEnrichment;
use Illuminate\Http\Request;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Component\HttpFoundation\Response;
class PinRequestsToResponse
{
public function __construct(
private PsrHttpFactory $psrFactory,
private HttpFoundationFactory $httpFactory,
) {}
public function handle(Request $request, Closure $next): Response
{
/**
* @var \Symfony\Component\HttpFoundation\Response $response
*/
$response = $next($request);
$message = $this->psrFactory->createResponse($response);
return $this->httpFactory->createResponse(
HttpEnrichment::setRequests($message)
);
}
}

137
src/ServiceProvider.php Normal file
View File

@@ -0,0 +1,137 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\LaravelDataEnrichment;
use Diffhead\PHP\DataEnrichmentKit\Enricher;
use Diffhead\PHP\DataEnrichmentKit\Interface\Enrichment as EnrichmentInterface;
use Diffhead\PHP\DataEnrichmentKit\Interface\Parser as ParserInterface;
use Diffhead\PHP\DataEnrichmentKit\Interface\Serializer as SerializerInterface;
use Diffhead\PHP\DataEnrichmentKit\Message;
use Diffhead\PHP\DataEnrichmentKit\Service\Enrichment;
use Diffhead\PHP\DataEnrichmentKit\Service\Parser;
use Diffhead\PHP\DataEnrichmentKit\Service\Serializer;
use Diffhead\PHP\DataEnrichmentKit\Storage\Repositories;
use Diffhead\PHP\LaravelDataEnrichment\Manager\ArrayManager;
use Diffhead\PHP\LaravelDataEnrichment\Manager\HttpManager;
use Diffhead\PHP\LaravelDataEnrichment\Middleware\PinRequestsToResponse;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
class ServiceProvider extends LaravelServiceProvider
{
private array $middlewares = [
'enrichment.pin-requests' => PinRequestsToResponse::class,
];
public function register(): void
{
$this->registerBindings();
$this->registerServices();
$this->registerRepositories();
$this->registerFacadeManagers();
}
public function boot(Router $router): void
{
$this->registerConfigsPublishment();
foreach ($this->middlewares as $alias => $class) {
$router->aliasMiddleware($alias, $class);
}
}
private function registerBindings(): void
{
/**
* @var array<class-string,class-string> $bindings
*/
$bindings = config('enrichment.bindings', []);
foreach ($bindings as $abstract => $concrete) {
$this->app->bind($abstract, $concrete);
}
}
private function registerServices(): void
{
$this->app->bind(
EnrichmentInterface::class,
config('enrichment.enrichment', Enrichment::class)
);
$this->app->bind(
SerializerInterface::class,
config('enrichment.serializer', Serializer::class)
);
$this->app->bind(
ParserInterface::class,
config('enrichment.parser', Parser::class)
);
}
private function registerRepositories(): void
{
$this->app->singleton(
Repositories::class,
function (Application $application): Repositories {
$repositories = new Repositories();
/**
* @var array<string,string> $mapping
*/
$mapping = config('enrichment.repositories', []);
foreach ($mapping as $target => $class) {
/**
* @var \Diffhead\PHP\DataEnrichmentKit\Interface\Repository $repository
*/
$repository = $application->make($class);
$repositories->set($target, $repository);
}
return $repositories;
}
);
}
private function registerFacadeManagers(): void
{
$this->app->singleton(
HttpManager::class,
function (Application $application): HttpManager {
return new HttpManager(
$application->make(Enricher::class),
$application->make(Message::class)
);
}
);
$this->app->singleton(
ArrayManager::class,
function (Application $application): ArrayManager {
return new ArrayManager(
$application->make(Enricher::class)
);
}
);
}
private function registerConfigsPublishment(): void
{
$this->publishes(
[
$this->configPath('config/enrichment.php') => config_path('enrichment.php'),
],
'config'
);
}
private function configPath(string $path): string
{
return sprintf('%s/../%s', __DIR__, $path);
}
}