Split services based on autoloading

This commit is contained in:
Tim
2025-10-01 00:25:01 +02:00
parent 47f1a860b1
commit b7cfec0151
10 changed files with 50 additions and 28 deletions

View File

@@ -3,5 +3,5 @@ services:
autowire: true autowire: true
autoconfigure: true autoconfigure: true
Ardent\PipelineBundle\Pipeline\OptionsProcessor\: Ardent\PipelineBundle\Pipeline\Service\:
resource: '../src/Pipeline/OptionsProcessor' resource: '../src/Pipeline/Service'

View File

@@ -17,8 +17,7 @@ class Item
string|int|null $id = null string|int|null $id = null
) )
{ {
$id ??= sha1(microtime()); $this->id = $id ?? sha1(microtime());
$this->id = $id;
} }
public function getId(): string public function getId(): string
@@ -125,4 +124,9 @@ class Item
$this->parent = $parent; $this->parent = $parent;
return $this; return $this;
} }
public function getKeys(): array
{
return array_keys($this->data);
}
} }

View File

@@ -2,6 +2,7 @@
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor;
use Ardent\PipelineBundle\Pipeline\Service\OptionsStageInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
class ItemsOptionsPipeline class ItemsOptionsPipeline
@@ -13,7 +14,8 @@ class ItemsOptionsPipeline
public function __construct( public function __construct(
private readonly OptionsProcessor $processor, private readonly OptionsProcessor $processor,
OptionsStageInterface ...$stages) OptionsStageInterface ...$stages
)
{ {
$this->stages = $stages; $this->stages = $stages;
} }
@@ -28,9 +30,11 @@ class ItemsOptionsPipeline
/** /**
* @param Item[]|ItemCollection $items * @param Item[]|ItemCollection $items
*/ */
public function process(array|ItemCollection $items): ItemCollection public function process(array|ItemCollection|Item $items): ItemCollection
{ {
if (is_array($items)) { if ($items instanceof Item) {
$itemBag = new ItemCollection()->add($items);
} elseif (is_array($items)) {
$itemBag = new ItemCollection(); $itemBag = new ItemCollection();
foreach ($items as $item) { foreach ($items as $item) {
$itemBag->add($item); $itemBag->add($item);

View File

@@ -2,11 +2,9 @@
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor;
class Options readonly class Options
{ {
public function __construct(private readonly array $options) public function __construct(private array $options) {}
{
}
public function get(string $key, $default = null): mixed public function get(string $key, $default = null): mixed
{ {

View File

@@ -2,6 +2,8 @@
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor;
use Ardent\PipelineBundle\Pipeline\Service\OptionsStageInterface;
class OptionsProcessor class OptionsProcessor
{ {
private Options $options; private Options $options;

View File

@@ -2,6 +2,11 @@
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor;
use Ardent\PipelineBundle\Pipeline\Service\OptionsStageBag;
use Ardent\PipelineBundle\Pipeline\Service\OptionsStageInterface;
use Ardent\PipelineBundle\Pipeline\Service\SubItemStage;
use Psr\Log\LoggerInterface;
class OptionsStageBuilder class OptionsStageBuilder
{ {
/** /**
@@ -11,10 +16,7 @@ class OptionsStageBuilder
public function __construct( public function __construct(
private readonly OptionsStageBag $bag, private readonly OptionsStageBag $bag,
private readonly ?Options $options = null, ) {}
)
{
}
/** /**
* @param string|OptionsStageInterface $stageClass Can either be the classFQN of an OptionsStageInterface or one directly * @param string|OptionsStageInterface $stageClass Can either be the classFQN of an OptionsStageInterface or one directly
@@ -26,7 +28,7 @@ class OptionsStageBuilder
$this->stages[] = $this->bag->get($stageClass); $this->stages[] = $this->bag->get($stageClass);
} else { } else {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
sprintf('Stage must be an instance of OptionsStageInterface, %s given', get_debug_type($stage)) sprintf('Stage must be an instance of OptionsStageInterface, %s given', get_debug_type($stageClass))
); );
} }
} else { } else {
@@ -43,8 +45,13 @@ class OptionsStageBuilder
return $this; return $this;
} }
public function build(): ItemsOptionsPipeline public function build(?Options $options = null): ItemsOptionsPipeline
{ {
return new ItemsOptionsPipeline(new OptionsProcessor($this->options), ...$this->stages); $pipeline = new ItemsOptionsPipeline(new OptionsProcessor($options), ...$this->stages);
$logger = $options?->get(LoggerInterface::class);
if ($logger !== null) {
$pipeline->setLogger($logger);
}
return $pipeline;
} }
} }

View File

@@ -1,7 +1,9 @@
<?php <?php
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\Service;
use Ardent\PipelineBundle\Pipeline\OptionsProcessor\ItemCollection;
use Ardent\PipelineBundle\Pipeline\OptionsProcessor\Options;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Contracts\Service\Attribute\Required; use Symfony\Contracts\Service\Attribute\Required;

View File

@@ -1,7 +1,8 @@
<?php <?php
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\Service;
use Ardent\PipelineBundle\Pipeline\Service\OptionsStageInterface as T;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator; use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
@@ -12,7 +13,7 @@ class OptionsStageBag implements ContainerInterface
private readonly ServiceLocator $locator; private readonly ServiceLocator $locator;
public function __construct( public function __construct(
#[AutowireLocator(OptionsStageInterface::class, indexAttribute: 'name')] #[AutowireLocator(T::class, indexAttribute: 'name')]
ServiceLocator $locator ServiceLocator $locator
) )
{ {
@@ -20,14 +21,14 @@ class OptionsStageBag implements ContainerInterface
} }
/** /**
* @template T of OptionsStageInterface * @template T of T
* *
* @param class-string<T> $id * @param class-string<T> $id
* *
* @return T * @return T
* @throws ServiceNotFoundException * @throws ServiceNotFoundException
*/ */
public function get(string $id): OptionsStageInterface public function get(string $id): T
{ {
return $this->locator->get($id); return $this->locator->get($id);
} }

View File

@@ -1,11 +1,13 @@
<?php <?php
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\Service;
use Ardent\PipelineBundle\Pipeline\OptionsProcessor\Item;
use Ardent\PipelineBundle\Pipeline\OptionsProcessor\ItemCollection;
use Ardent\PipelineBundle\Pipeline\OptionsProcessor\Options;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
//#[AutoconfigureTag('ardent.pipeline.optionsProcessor')]
#[AutoconfigureTag] #[AutoconfigureTag]
interface OptionsStageInterface interface OptionsStageInterface
{ {

View File

@@ -1,7 +1,9 @@
<?php <?php
namespace Ardent\PipelineBundle\Pipeline\OptionsProcessor; namespace Ardent\PipelineBundle\Pipeline\Service;
use Ardent\PipelineBundle\Pipeline\OptionsProcessor\Item;
use Ardent\PipelineBundle\Pipeline\OptionsProcessor\ItemsOptionsPipeline;
use Exception; use Exception;
class SubItemStage extends AbstractOptionsStage class SubItemStage extends AbstractOptionsStage