Initial commit

This commit is contained in:
2019-11-20 07:44:43 +01:00
commit 5bf49c4a81
41188 changed files with 5459177 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
<?php
namespace League\Tactician\Bundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* This compiler pass maps Handler DI tags to specific commands
*/
class CommandHandlerPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* @param ContainerBuilder $container
*
* @throws \Exception
* @api
*/
public function process(ContainerBuilder $container)
{
if (!$container->has('tactician.handler.locator.symfony')) {
throw new \Exception('Missing tactician.handler.locator.symfony definition');
}
$handlerLocator = $container->findDefinition('tactician.handler.locator.symfony');
$mapping = [];
foreach ($container->findTaggedServiceIds('tactician.handler') as $id => $tags) {
foreach ($tags as $attributes) {
if (!isset($attributes['command'])) {
throw new \Exception('The tactician.handler tag must always have a command attribute');
}
$mapping[$attributes['command']] = $id;
}
}
$handlerLocator->addArgument($mapping);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace League\Tactician\Bundle\DependencyInjection\Compiler;
use League\Tactician\Doctrine\ORM\TransactionMiddleware;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
/**
* This compiler pass registers doctrine entity manager middleware
*/
class DoctrineMiddlewarePass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if (!class_exists(TransactionMiddleware::class) || !$container->hasParameter('doctrine.entity_managers')) {
return;
}
$entityManagers = $container->getParameter('doctrine.entity_managers');
if (empty($entityManagers)) {
return;
}
foreach ($entityManagers as $name => $serviceId) {
$container->setDefinition(
sprintf('tactician.middleware.doctrine.%s', $name),
new Definition(TransactionMiddleware::class, [ new Reference($serviceId) ])
);
}
$defaultEntityManager = $container->getParameter('doctrine.default_entity_manager');
$container->setAlias('tactician.middleware.doctrine', sprintf('tactician.middleware.doctrine.%s', $defaultEntityManager));
}
}

View File

@@ -0,0 +1,91 @@
<?php namespace League\Tactician\Bundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
/**
* This is the class that validates and merges configuration from your app/config files
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
*/
class Configuration implements ConfigurationInterface
{
/**
* Create a rootnode tree for configuration that can be injected into the DI container
*
* @return TreeBuilder
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('tactician');
$rootNode
->children()
->arrayNode('commandbus')
->defaultValue(['default' => ['middleware' => ['tactician.middleware.command_handler']]])
->requiresAtLeastOneElement()
->useAttributeAsKey('name')
->prototype('array')
->children()
->arrayNode('middleware')
->requiresAtLeastOneElement()
->useAttributeAsKey('name')
->prototype('scalar')->end()
->validate()
->ifTrue(function ($config) {
$isPresent = in_array('tactician.middleware.command_handler', $config);
$isLast = end($config) == 'tactician.middleware.command_handler';
return ($isPresent && !$isLast);
})
->thenInvalid(
'"tactician.middleware.command_handler" should be last loaded middleware'.
' when it is use.'
)
->end()
->end()
->end()
->end()
->end()
->scalarNode('default_bus')
->defaultValue('default')
->cannotBeEmpty()
->end()
->scalarNode('method_inflector')
->defaultValue('tactician.handler.method_name_inflector.handle')
->cannotBeEmpty()
->end()
->end()
->validate()
->ifTrue(function($config) {
return is_array($config) &&
array_key_exists('default_bus', $config) &&
array_key_exists('commandbus', $config)
;
})
->then(function($config) {
$busNames = [];
foreach ($config['commandbus'] as $busName => $busConfig) {
$busNames[] = $busName;
}
if (!in_array($config['default_bus'], $busNames)) {
throw new InvalidConfigurationException(
sprintf(
'The default_bus "%s" was not defined as command bus. Valid option(s): %s',
$config['default_bus'],
implode(', ', $busNames)
)
);
}
return $config;
})
->end()
;
return $treeBuilder;
}
}

View File

@@ -0,0 +1,74 @@
<?php namespace League\Tactician\Bundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
class TacticianExtension extends ConfigurableExtension
{
/**
* Configures the passed container according to the merged configuration.
*
* @param array $mergedConfig
* @param ContainerBuilder $container
*/
protected function loadInternal(array $mergedConfig, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config/services'));
$loader->load('services.yml');
$this->configureCommandBuses($mergedConfig, $container);
$this->injectMethodNameInflector($mergedConfig, $container);
}
public function getAlias()
{
return 'tactician';
}
/**
* @param array $mergedConfig
* @param ContainerBuilder $container
*/
private function configureCommandBuses(array $mergedConfig, ContainerBuilder $container)
{
foreach ($mergedConfig['commandbus'] as $commandBusName => $commandBusConfig) {
$middlewares = array_map(
function ($middlewareServiceId) {
return new Reference($middlewareServiceId);
},
$commandBusConfig['middleware']
);
$serviceName = 'tactician.commandbus.' . $commandBusName;
$definition = new Definition($container->getParameter('tactician.commandbus.class'), [$middlewares]);
$container->setDefinition($serviceName, $definition);
if ($commandBusName === $mergedConfig['default_bus']) {
$container->setAlias('tactician.commandbus', $serviceName);
}
}
}
/**
* Define the default Method Name Inflector.
* This will fail silently if the command_handler service does not exist
*
* @param array $mergedConfig
* @param ContainerBuilder $container
*/
private function injectMethodNameInflector(array $mergedConfig, ContainerBuilder $container)
{
if (! $container->has('tactician.middleware.command_handler')) {
return;
}
$inflectorReference = new Reference($mergedConfig['method_inflector']);
$handlerLocator = $container->findDefinition('tactician.middleware.command_handler');
$handlerLocator->replaceArgument(2, $inflectorReference);
}
}