Version 1.0.0
This commit is contained in:
22
.editorconfig
Normal file
22
.editorconfig
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.php]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size = 2
|
||||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
vendor/
|
||||||
|
|
||||||
|
.phpunit.cache/
|
||||||
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright 2025 Viktor S. <thinlineseverywhere@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the “Software”),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
220
README.md
Normal file
220
README.md
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
# Laravel Data Enrichment
|
||||||
|
|
||||||
|
Laravel Data Enrichment helps you enrich and augment data across your Laravel applications. It offers a flexible, extensible workflow to collect enrichment requests and resolve them against repositories, whether you work with arrays, HTTP messages, or custom data sources.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Multiple sources:** Enrich array data, HTTP requests, and responses.
|
||||||
|
- **Middleware support:** Pin enrichment requests to controller responses automatically.
|
||||||
|
- **Extensible managers:** Plug in custom logic via interfaces and repositories.
|
||||||
|
- **Simple facades:** Convenient API via `ArrayEnrichment` and `HttpEnrichment`.
|
||||||
|
|
||||||
|
## Additional Info
|
||||||
|
|
||||||
|
- Core library: [diffhead/php-data-enrichment-kit](https://github.com/diffhead/php-data-enrichment-kit)
|
||||||
|
- This package provides Laravel integration (service provider, facades, middleware, and configuration) on top of the core kit.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Install via Composer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require diffhead/laravel-data-enrichment
|
||||||
|
```
|
||||||
|
|
||||||
|
Publish the configuration (if needed):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan vendor:publish --provider="Diffhead\PHP\LaravelDataEnrichment\ServiceProvider"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The configuration file `config/enrichment.php` controls how enrichment works. Customize it for your application.
|
||||||
|
|
||||||
|
- **Repositories:** On the receiver side, create repositories implementing `\Diffhead\PHP\DataEnrichmentKit\Interface\Repository` and list them under `enrichment.repositories`.
|
||||||
|
- **Bindings:** Optionally map repository interfaces to implementations via `enrichment.bindings` for auto-resolution.
|
||||||
|
- **Custom logic:** Override the enrichment workflow by providing your implementations for:
|
||||||
|
- `\Diffhead\PHP\DataEnrichmentKit\Interface\Parser` — parse raw requests
|
||||||
|
- `\Diffhead\PHP\DataEnrichmentKit\Interface\Serializer` — serialize request objects
|
||||||
|
- `\Diffhead\PHP\DataEnrichmentKit\Interface\Enrichment` — core enrichment business logic
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Array Enrichment
|
||||||
|
|
||||||
|
Use the `ArrayEnrichment` facade to enrich plain PHP arrays:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Diffhead\LaravelDataEnrichment\Facade\ArrayEnrichment;
|
||||||
|
|
||||||
|
$books = [
|
||||||
|
[
|
||||||
|
'title' => 'Magic Things: How To',
|
||||||
|
'author_id' => 353,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
ArrayEnrichment::addRequest('user', 'id', [
|
||||||
|
['key' => '*.author_id', 'alias' => 'author'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$enrichedBooks = ArrayEnrichment::enrich($books);
|
||||||
|
/**
|
||||||
|
* Result:
|
||||||
|
* [
|
||||||
|
* [
|
||||||
|
* 'title' => 'Magic Things: How To',
|
||||||
|
* 'author_id' => 353,
|
||||||
|
* 'author' => [
|
||||||
|
* 'id' => 353,
|
||||||
|
* 'name' => 'John Doe',
|
||||||
|
* 'email' => 'john-doe@mysite.com'
|
||||||
|
* ]
|
||||||
|
* ],
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
print_r($enrichedBooks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When done, clear the request storage and add new
|
||||||
|
* requests for the next data object to enrich.
|
||||||
|
*/
|
||||||
|
ArrayEnrichment::clearRequests();
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTTP Enrichment
|
||||||
|
|
||||||
|
Use the `HttpEnrichment` facade to enrich HTTP requests or responses:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Diffhead\LaravelDataEnrichment\Facade\HttpEnrichment;
|
||||||
|
|
||||||
|
enum Header: string
|
||||||
|
{
|
||||||
|
case XEnrich = 'X-Enrich';
|
||||||
|
}
|
||||||
|
|
||||||
|
$psrFactory = new PsrHttpFactory();
|
||||||
|
/**
|
||||||
|
* @var \Symfony\Component\HttpFoundation\Response $response
|
||||||
|
* @var \Psr\Http\Message\MessageInterface $psrMessage
|
||||||
|
*/
|
||||||
|
$psrMessage = $psrFactory->createResponse($response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionally set the header used for enrichment.
|
||||||
|
* Default: \Diffhead\LaravelDataEnrichment\Header::XEnrichRequest
|
||||||
|
* Accepts any BackedEnum.
|
||||||
|
* Note: if you change the default on the client, also change it on the server.
|
||||||
|
*/
|
||||||
|
HttpEnrichment::useHeader(Header::XEnrich);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add enrichment requests to storage.
|
||||||
|
*/
|
||||||
|
HttpEnrichment::addRequest('user', 'id', [
|
||||||
|
['key' => 'data.*.assigned.*.user_id', 'alias' => 'user'],
|
||||||
|
['key' => 'data.*.created_by', 'alias' => 'creator'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client-side step: attach requests before passing the message downstream.
|
||||||
|
*/
|
||||||
|
$psrMessagePrepared = HttpEnrichment::setRequests($psrMessage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example (gateway side): enrich a response.
|
||||||
|
* This method parses and enriches the JSON payload in the PSR message.
|
||||||
|
* Note: call HttpEnrichment::useHeader again if you changed it earlier.
|
||||||
|
*/
|
||||||
|
$psrMessageEnriched = HttpEnrichment::enrichMessage($psrMessagePrepared);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Middleware
|
||||||
|
|
||||||
|
Use the `enrichment.pin-requests` middleware to automatically pin added requests to the controller response:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Diffhead\LaravelDataEnrichment\Facade\HttpEnrichment;
|
||||||
|
|
||||||
|
Route::middleware(['enrichment.pin-requests'])->group(
|
||||||
|
function () {
|
||||||
|
Route::get('/posts', function () {
|
||||||
|
HttpEnrichment::addRequest('user', 'id', [
|
||||||
|
['key' => 'data.*.owner_id', 'alias' => 'owner'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'data' => [
|
||||||
|
['id' => 1, 'title' => 'Cats Dev', 'owner_id' => 1],
|
||||||
|
['id' => 2, 'title' => "Sponge Bob's Bio", 'owner_id' => 2],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Repository Examples
|
||||||
|
|
||||||
|
Below is an example of a repository interface and its Laravel Eloquent implementation used for enrichment. The repository searches users by a field with multiple values and returns an iterable cursor.
|
||||||
|
|
||||||
|
#### Interface
|
||||||
|
|
||||||
|
```php
|
||||||
|
namespace App\Shared\Service\User;
|
||||||
|
|
||||||
|
use Diffhead\PHP\DataEnrichmentKit\Interface\Repository;
|
||||||
|
|
||||||
|
interface SearchByFieldValuesInterface extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $field
|
||||||
|
* @param array $values
|
||||||
|
*
|
||||||
|
* @return iterable<int,\App\Models\User\User>
|
||||||
|
*/
|
||||||
|
public function getByFieldValues(string $field, array $values): iterable;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### Implementation
|
||||||
|
|
||||||
|
```php
|
||||||
|
namespace App\Shared\Service\User;
|
||||||
|
|
||||||
|
use App\Models\User\User;
|
||||||
|
|
||||||
|
class SearchByFieldValues implements SearchByFieldValuesInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $field
|
||||||
|
* @param array<int,mixed> $values
|
||||||
|
*
|
||||||
|
* @return iterable<int,\App\Models\User\User>
|
||||||
|
*/
|
||||||
|
public function getByFieldValues(string $field, array $values): iterable
|
||||||
|
{
|
||||||
|
return User::query()->whereIn($field, $values)->cursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Registration
|
||||||
|
|
||||||
|
`config/enrichment.php`
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
return [
|
||||||
|
/** ... */
|
||||||
|
'bindings' => [
|
||||||
|
\App\Shared\Service\User\SearchByFieldValuesInterface::class =>
|
||||||
|
\App\Shared\Service\User\SearchByFieldValues::class
|
||||||
|
],
|
||||||
|
'repositories' => [
|
||||||
|
'user' => \App\Shared\Service\User\SearchByFieldValuesInterface::class
|
||||||
|
],
|
||||||
|
/** ... */
|
||||||
|
];
|
||||||
|
```
|
||||||
43
composer.json
Normal file
43
composer.json
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "diffhead/laravel-data-enrichment",
|
||||||
|
"description": "Data enrichment library based on DataEnrichmentKit. A suitable components for micro services written using laravel framework.",
|
||||||
|
"type": "library",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"keywords": [
|
||||||
|
"laravel", "data enrichment", "facade", "psr7", "http",
|
||||||
|
"pipeline", "message processing", "middleware", "microservice"
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Diffhead\\PHP\\LaravelDataEnrichment\\": "src/",
|
||||||
|
"Diffhead\\PHP\\LaravelDataEnrichment\\Tests\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Diffhead\\PHP\\LaravelDataEnrichment\\ServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1",
|
||||||
|
"laravel/framework": "^10 || ^11.0 || ^12.0",
|
||||||
|
"diffhead/php-data-enrichment-kit": "^1.0.0",
|
||||||
|
"symfony/psr-http-message-bridge": "^7.3"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "phpunit",
|
||||||
|
"post-install-cmd": [
|
||||||
|
"php artisan vendor:publish --provider=\"Diffhead\\PHP\\LaravelDataEnrichment\\ServiceProvider\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Viktor S.",
|
||||||
|
"email": "thinlineseverywhere@gmail.com"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
6008
composer.lock
generated
Normal file
6008
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
38
config/enrichment.php
Normal file
38
config/enrichment.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* Data enrichment requests parser
|
||||||
|
*/
|
||||||
|
'parser' => \Diffhead\PHP\DataEnrichmentKit\Service\Parser::class,
|
||||||
|
/**
|
||||||
|
* Data enrichment requests serializer
|
||||||
|
*/
|
||||||
|
'serializer' => \Diffhead\PHP\DataEnrichmentKit\Service\Serializer::class,
|
||||||
|
/**
|
||||||
|
* Enrichment business logic
|
||||||
|
*/
|
||||||
|
'enrichment' => \Diffhead\PHP\DataEnrichmentKit\Service\Enrichment::class,
|
||||||
|
/**
|
||||||
|
* DI container bindings if you want to register specific implementations
|
||||||
|
* automatically.
|
||||||
|
*/
|
||||||
|
'bindings' => [
|
||||||
|
/**
|
||||||
|
* \App\Repository\Repository\UserRepositoryInterface::class =>
|
||||||
|
* \App\Repository\Repository\UserRepository::class,
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
/**
|
||||||
|
* Repositories mapping where key is the target name which will be passed
|
||||||
|
* inside the request and value is the repository class name.
|
||||||
|
*
|
||||||
|
* The repository class will be resolved via DI container and it should
|
||||||
|
* implement \Diffhead\PHP\DataEnrichmentKit\Interface\Repository interface.
|
||||||
|
*/
|
||||||
|
'repositories' => [
|
||||||
|
/**
|
||||||
|
* 'user' => \App\Repository\Repository\UserRepository::class,
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
];
|
||||||
20
src/Facade/ArrayEnrichment.php
Normal file
20
src/Facade/ArrayEnrichment.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/Facade/HttpEnrichment.php
Normal file
22
src/Facade/HttpEnrichment.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
99
src/Manager/AbstractManager.php
Normal file
99
src/Manager/AbstractManager.php
Normal 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(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/Manager/ArrayManager.php
Normal file
13
src/Manager/ArrayManager.php
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/Manager/HttpManager.php
Normal file
45
src/Manager/HttpManager.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/Middleware/PinRequestsToResponse.php
Normal file
33
src/Middleware/PinRequestsToResponse.php
Normal 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
137
src/ServiceProvider.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user