Version 1.0.0
This commit is contained in:
153
src/Service/Enrichment.php
Normal file
153
src/Service/Enrichment.php
Normal 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
57
src/Service/Parser.php
Normal 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);
|
||||
}
|
||||
}
|
||||
40
src/Service/Serializer.php
Normal file
40
src/Service/Serializer.php
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user