Version 1.0.0

This commit is contained in:
diffhead
2025-11-16 01:51:25 +04:00
committed by Viktor Smagin
commit 8cb7f400fd
43 changed files with 4462 additions and 0 deletions

153
src/Service/Enrichment.php Normal file
View File

@@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Service;
use ArrayAccess;
use Diffhead\PHP\DataEnrichmentKit\Interface\Enrichment as EnrichmentInterface;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Storage\Repositories;
use Diffhead\PHP\DataEnrichmentKit\Storage\Requests;
use Diffhead\PHP\DataEnrichmentKit\Utility\Arr;
class Enrichment implements EnrichmentInterface
{
public function __construct(
private Repositories $repositories,
) {}
/**
* @param array $payload
* @param \Diffhead\PHP\DataEnrichmentKit\Storage\Requests $requests
*
* @return array
*/
public function enrich(array $data, Requests $requests): array
{
foreach ($requests as $request) {
$data = $this->enrichSingle($data, $request);
}
return $data;
}
private function enrichSingle(array $data, Request $request): array
{
$targetFieldValues = [];
$target = $request->target();
$items = $request->items();
$targetFieldValues = $this->getFieldValuesByItems($data, $items);
$targets = $this->getTargetsByFieldValue(
$target->entity(),
$target->field(),
$targetFieldValues
);
return $this->enrichUsingTargets($data, $items, $targets);
}
private function getFieldValuesByItems(array $data, ItemsBag $items): array
{
$targetFieldValues = [];
/**
* @var \Diffhead\PHP\DataEnrichmentKit\Object\Item $item
*/
foreach ($items as $item) {
$valueOrValues = Arr::get($item->key(), $data);
if (is_array($valueOrValues)) {
$targetFieldValues = array_merge($targetFieldValues, $valueOrValues);
} else {
$targetFieldValues[] = $valueOrValues;
}
}
return array_unique($targetFieldValues);
}
private function getTargetsByFieldValue(string $entity, string $field, array $values): array
{
$targets = $this->repositories->get($entity)
->getByFieldValues($field, $values);
$targetsHaveArrayAccess = is_array($targets) || $targets instanceof ArrayAccess;
$targetsByFieldValue = [];
foreach ($targets as $index => $target) {
$fieldValue = $target[$field];
$targetsByFieldValue[$fieldValue] = $target;
if ($targetsHaveArrayAccess) {
unset($targets[$index]);
}
}
return $targetsByFieldValue;
}
private function enrichUsingTargets(array $data, ItemsBag $items, array $targets): array
{
foreach ($items as $item) {
$data = $this->enrichByItem($data, $item, $targets);
}
return $data;
}
private function enrichByItem(array $data, Item $item, array &$targets): array
{
$keyFirstItemIsWildcard = strpos($item->key(), '*.') === 0;
if (array_is_list($data) && $keyFirstItemIsWildcard) {
/**
* If passed *.user_id key as example then
* we need to remove first wildcard part
*/
$parts = explode('.', $item->key());
$nextKey = implode('.', array_slice($parts, 1));
$item = new Item($nextKey, $item->alias());
foreach ($data as $index => $entry) {
$data[$index] = $this->enrichByItem($entry, $item, $targets);
}
return $data;
}
$keyIsWildcard = is_numeric(strpos($item->key(), '*.'));
if ($keyIsWildcard) {
$parts = explode('.', $item->key());
$first = $parts[0];
$temporary = Arr::get($first, $data, []);
$nextKey = implode('.', array_slice($parts, 1));
$nextItem = new Item($nextKey, $item->alias());
$data[$first] = $this->enrichByItem($temporary, $nextItem, $targets);
} else {
$value = Arr::get($item->key(), $data);
$parts = explode('.', $item->key());
$alias = $item->alias()
? $item->alias()
: $parts[count($parts) - 1];
$parts[count($parts) - 1] = $alias;
$nextKey = implode('.', $parts);
$data = Arr::set($nextKey, $data, $targets[$value] ?? null);
}
return $data;
}
}

57
src/Service/Parser.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Service;
use Diffhead\PHP\DataEnrichmentKit\Exception\InvalidRequest;
use Diffhead\PHP\DataEnrichmentKit\Interface\Parser as ParserInterface;
use Diffhead\PHP\DataEnrichmentKit\Object\Item;
use Diffhead\PHP\DataEnrichmentKit\Object\ItemsBag;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
use Diffhead\PHP\DataEnrichmentKit\Object\Target;
class Parser implements ParserInterface
{
/**
* @param string $value
*
* @return \Diffhead\PHP\DataEnrichmentKit\Object\Request
*
* @throws \Diffhead\PHP\DataEnrichmentKit\Exception\InvalidRequest
*/
public function parse(string $value): Request
{
$referenceWithTarget = explode('@', $value);
if (! isset($referenceWithTarget[1])) {
throw new InvalidRequest($value);
}
$entityWithField = explode(',', $referenceWithTarget[1]);
if (! isset($entityWithField[0]) || ! isset($entityWithField[1])) {
throw new InvalidRequest($value);
}
$entity = $entityWithField[0];
$field = $entityWithField[1];
$target = new Target($entity, $field);
$references = $referenceWithTarget[0];
$references = explode(',', $references);
$items = new ItemsBag();
foreach ($references as $reference) {
$referenceWithAlias = explode('+', $reference);
$items->push(
new Item($referenceWithAlias[0], $referenceWithAlias[1] ?? '')
);
}
return new Request($items, $target);
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace Diffhead\PHP\DataEnrichmentKit\Service;
use Diffhead\PHP\DataEnrichmentKit\Interface\Serializer as SerializerInterface;
use Diffhead\PHP\DataEnrichmentKit\Object\Request;
class Serializer implements SerializerInterface
{
public function toString(Request $request): string
{
$targetParts = [
$request->target()->entity(),
$request->target()->field(),
];
$target = implode(',', $targetParts);
$itemsParts = [];
/**
* @var \Diffhead\PHP\DataEnrichmentKit\Object\Item $item
*/
foreach ($request->items() as $item) {
$itemParts = [$item->key()];
if ($alias = $item->alias()) {
$itemParts[] = $alias;
}
$itemsParts[] = implode('+', $itemParts);
}
$items = implode(',', $itemsParts);
return sprintf('%s@%s', $items, $target);
}
}