Skip to content

Commit

Permalink
👮 Prevent feed providers with duplicate source
Browse files Browse the repository at this point in the history
The feed provider source should be unique for each class that extends
the FeedProvider interface.

In this commit we add a compiler pass who guards against violations of
this rule. The container won't compile if a developer picks a source
name that is already taken by another implementation of the
feed provider interface.
  • Loading branch information
LVoogd committed Jan 7, 2024
1 parent 5bc4643 commit 0291010
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace App\Feed\Infrastructure\Framework\CompilerPass;

use App\Feed\Application\Service\FeedProvider\FeedProvider;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

final class FeedProviderSourceShouldBeUniqueCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
$sources = [];

$services = $container->findTaggedServiceIds(FeedProvider::class);

foreach ($services as $service => $attributes) {
if (class_exists($service) === false) {
throw new \Exception(sprintf('Couldn\'t derive existing FQCN from service %s, the service is probably aliased', $service));
}

if (method_exists($service, 'getSource') === false) {
throw new \Exception('%s must implement static method `getSource`.');
}

$source = call_user_func([$service, 'getSource']);

if (in_array($source, $sources)) {
throw new \Exception(sprintf(
'The \'source\' on a FeedProvider should be unique. Duplicate source found for %s.',
$service,
));
}

$sources[] = $source;
}
}
}
4 changes: 4 additions & 0 deletions src/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Common\Infrastructure\Messenger\CommandBus\AsCommandHandler;
use App\Common\Infrastructure\Messenger\EventBus\AsEventSubscriber;
use App\Feed\Infrastructure\Framework\CompilerPass\FeedProviderSourceShouldBeUniqueCompilerPass;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\DependencyInjection\ChildDefinition;
Expand Down Expand Up @@ -47,5 +48,8 @@ protected function build(ContainerBuilder $container): void

$definition->addTag('messenger.message_handler', $tagAttributes);
});

// @todo move to bundle
$container->addCompilerPass(new FeedProviderSourceShouldBeUniqueCompilerPass());
}
}

0 comments on commit 0291010

Please sign in to comment.