Skip to content

Commit

Permalink
feature: add a json provider to handle object serialization and move …
Browse files Browse the repository at this point in the history
…processors and providers into their own namespace
  • Loading branch information
johnkrovitch committed Oct 28, 2023
1 parent ce7a4c1 commit 3a09748
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 72 deletions.
26 changes: 15 additions & 11 deletions config/services/state.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
services:
lag_admin.state.data_provider: '@LAG\AdminBundle\State\DataProviderInterface'
LAG\AdminBundle\State\DataProviderInterface:
class: LAG\AdminBundle\State\CompositeDataProvider
lag_admin.state.data_provider: '@LAG\AdminBundle\State\Provider\DataProviderInterface'
lag_admin.state.data_processor: '@LAG\AdminBundle\State\Processor\DataProcessorInterface'

# Data providers
LAG\AdminBundle\State\Provider\DataProviderInterface:
class: LAG\AdminBundle\State\Provider\CompositeDataProvider
arguments:
$providers: !tagged_iterator lag_admin.data_provider

lag_admin.state.data_processor: '@LAG\AdminBundle\State\DataProcessorInterface'
LAG\AdminBundle\State\DataProcessorInterface:
class: LAG\AdminBundle\State\CompositeDataProcessor
LAG\AdminBundle\State\Provider\JsonDataProviderDecorator:
decorates: lag_admin.state.data_provider
arguments:
$processors: !tagged_iterator lag_admin.data_processor
$decorated: '@.inner'
$serializer: '@serializer'

LAG\AdminBundle\State\EventDataProcessor:
decorates: 'lag_admin.state.data_processor'
# Data processors
LAG\AdminBundle\State\Processor\DataProcessorInterface:
class: LAG\AdminBundle\State\Processor\CompositeDataProcessor
arguments:
$decorated: '@.inner'
$eventDispatcher: '@event_dispatcher'
$processors: !tagged_iterator lag_admin.data_processor
$eventDispatcher: '@lag_admin.resource.dispatcher'
31 changes: 0 additions & 31 deletions src/State/CompositeDataProcessor.php

This file was deleted.

26 changes: 0 additions & 26 deletions src/State/EventDataProcessor.php

This file was deleted.

65 changes: 65 additions & 0 deletions src/State/Processor/CompositeDataProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace LAG\AdminBundle\State\Processor;

use LAG\AdminBundle\Event\DataEvents;
use LAG\AdminBundle\Event\Dispatcher\ResourceEventDispatcherInterface;
use LAG\AdminBundle\Event\Events\DataEvent;
use LAG\AdminBundle\Exception\Exception;
use LAG\AdminBundle\Metadata\OperationInterface;

class CompositeDataProcessor implements DataProcessorInterface
{
public function __construct(
private ResourceEventDispatcherInterface $eventDispatcher,
/** @var DataProcessorInterface[] $processors */
private iterable $processors = [],
) {
}

public function process(mixed $data, OperationInterface $operation, array $uriVariables = [], array $context = []): void
{
/** @var DataProcessorInterface $processor */
foreach ($this->processors as $processor) {
if ($processor::class === $operation->getProcessor()) {
$this->dispatchPreEvent($data, $operation);
$processor->process($data, $operation, $uriVariables, $context);
$this->dispatchPostEvent($data, $operation);

return;
}
}

throw new Exception(sprintf(
'The resource "%s" and operation "%s" is not supported by any processor',
$operation->getResource()->getName(),
$operation->getName()
));
}

private function dispatchPreEvent(mixed $data, OperationInterface $operation): void
{
$this->eventDispatcher->dispatch(
new DataEvent($data),
DataEvents::DATA_PROCESS,
DataEvents::DATA_RESOURCE_PROCESS,
DataEvents::DATA_OPERATION_PROCESS,
$operation->getResource()->getName(),
$operation->getName(),
);
}

private function dispatchPostEvent(mixed $data, OperationInterface $operation): void
{
$this->eventDispatcher->dispatch(
new DataEvent($data),
DataEvents::DATA_PROCESSED,
DataEvents::DATA_RESOURCE_PROCESSED,
DataEvents::DATA_OPERATION_PROCESSED,
$operation->getResource()->getName(),
$operation->getName(),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace LAG\AdminBundle\State;
namespace LAG\AdminBundle\State\Processor;

use LAG\AdminBundle\Metadata\OperationInterface;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace LAG\AdminBundle\State;
namespace LAG\AdminBundle\State\Provider;

use LAG\AdminBundle\Exception\Exception;
use LAG\AdminBundle\Metadata\OperationInterface;
Expand All @@ -24,6 +24,10 @@ public function provide(OperationInterface $operation, array $uriVariables = [],
}
}

throw new Exception(sprintf('The admin resource "%s" and operation "%s" is not supported by any provider', $operation->getResource()->getName(), $operation->getName()));
throw new Exception(sprintf(
'The admin resource "%s" and operation "%s" is not supported by any provider',
$operation->getResource()->getName(),
$operation->getName())
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace LAG\AdminBundle\State;
namespace LAG\AdminBundle\State\Provider;

use LAG\AdminBundle\Metadata\OperationInterface;

Expand Down
38 changes: 38 additions & 0 deletions src/State/Provider/JsonDataProviderDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace LAG\AdminBundle\State\Provider;

use LAG\AdminBundle\Metadata\CollectionOperationInterface;
use LAG\AdminBundle\Metadata\OperationInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\SerializerInterface;

class JsonDataProviderDecorator implements DataProviderInterface
{
public function __construct(
private DataProviderInterface $decorated,
private SerializerInterface $serializer,
) {
}

public function provide(OperationInterface $operation, array $uriVariables = [], array $context = []): mixed
{
$data = $this->decorated->provide($operation, $uriVariables, $context);

if (($context['json'] ?? false) && $operation->useAjax()) {
$type = $operation->getResource()->getDataClass();

if ($operation instanceof CollectionOperationInterface) {
$type .= '[]';
}
$data = $this->serializer->deserialize(
$data,
$type,
'json',
$operation->getNormalizationContext() + [AbstractNormalizer::OBJECT_TO_POPULATE => $data],
);
}

return $data;
}
}

0 comments on commit 3a09748

Please sign in to comment.