Skip to content

Commit ba9eafb

Browse files
committed
Switch to monorepo
0 parents  commit ba9eafb

File tree

22 files changed

+619
-0
lines changed

22 files changed

+619
-0
lines changed

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2019 Yann Eugoné
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Yokai Batch
2+
3+
[![Latest Stable Version](https://img.shields.io/packagist/v/yokai/batch-symfony-framework?style=flat-square)](https://packagist.org/packages/yokai/batch-symfony-framework)
4+
[![Downloads Monthly](https://img.shields.io/packagist/dm/yokai/batch-symfony-framework?style=flat-square)](https://packagist.org/packages/yokai/batch-symfony-framework)
5+
6+
Bridge of [`symfony/framework-bundle`](https://github.com/symfony/framework-bundle) for [Batch](https://github.com/yokai-php/batch-src).
7+
8+
9+
## Documentation
10+
11+
Please refer to [main repository](https://github.com/yokai-php/batch-src) documentation.
12+
13+
14+
## Contribution
15+
16+
Please feel free to open an [issue](https://github.com/yokai-php/batch-src/issues)
17+
or a [pull request](https://github.com/yokai-php/batch-src/pulls)
18+
in the [main repository](https://github.com/yokai-php/batch-src).
19+
20+
21+
## MIT License
22+
23+
License can be found [here](LICENSE).

composer.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "yokai/batch-symfony-framework",
3+
"description": "Bridge of symfony/framework-bundle for yokai/batch",
4+
"type": "symfony-bundle",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Yann Eugoné",
9+
"email": "eugone.yann@gmail.com"
10+
}
11+
],
12+
"require": {
13+
"php": "^7.2",
14+
"symfony/framework-bundle": "^4.4"
15+
},
16+
"autoload": {
17+
"psr-4": {
18+
"Yokai\\Batch\\Bridge\\Symfony\\Framework\\": "src/"
19+
}
20+
}
21+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yokai\Batch\Bridge\Symfony\Framework\DependencyInjection\CompilerPass;
6+
7+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
8+
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
9+
use Symfony\Component\DependencyInjection\ContainerBuilder;
10+
use Symfony\Component\DependencyInjection\Reference;
11+
12+
final class RegisterJobsCompilerPass implements CompilerPassInterface
13+
{
14+
/**
15+
* @inheritdoc
16+
*/
17+
public function process(ContainerBuilder $container): void
18+
{
19+
$jobs = [];
20+
foreach ($container->findTaggedServiceIds('yokai_batch.job') as $serviceId => $tags) {
21+
foreach ($tags as $attributes) {
22+
$jobs[$attributes['job'] ?? $serviceId] = new Reference($serviceId);
23+
}
24+
}
25+
26+
$container->getDefinition('yokai_batch.job_registry')
27+
->setArgument('$jobs', ServiceLocatorTagPass::register($container, $jobs));
28+
}
29+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yokai\Batch\Bridge\Symfony\Framework\DependencyInjection;
6+
7+
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
8+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
9+
use Symfony\Component\Config\Definition\ConfigurationInterface;
10+
11+
final class Configuration implements ConfigurationInterface
12+
{
13+
/**
14+
* @inheritdoc
15+
*/
16+
public function getConfigTreeBuilder(): TreeBuilder
17+
{
18+
/** @var ArrayNodeDefinition $root */
19+
$root = ($treeBuilder = new TreeBuilder('yokai_batch'))->getRootNode();
20+
21+
$root
22+
->children()
23+
->append($this->storage())
24+
->end()
25+
;
26+
27+
return $treeBuilder;
28+
}
29+
30+
private function storage(): ArrayNodeDefinition
31+
{
32+
/** @var ArrayNodeDefinition $node */
33+
$node = (new TreeBuilder('storage'))->getRootNode();
34+
35+
$node
36+
->children()
37+
->arrayNode('filesystem')
38+
->children()
39+
->scalarNode('dir')
40+
->defaultValue('%kernel.project_dir%/var/batch')
41+
->end()
42+
->append($this->serializer())
43+
->end()
44+
->end()
45+
->arrayNode('dbal')
46+
->children()
47+
->scalarNode('connection')
48+
->defaultValue('default')
49+
->end()
50+
->arrayNode('options')
51+
->useAttributeAsKey('name')
52+
->scalarPrototype()->end()
53+
->end()
54+
->end()
55+
->end()
56+
->scalarNode('service')
57+
->end()
58+
->end()
59+
;
60+
61+
return $node;
62+
}
63+
64+
private function serializer(): ArrayNodeDefinition
65+
{
66+
/** @var ArrayNodeDefinition $node */
67+
$node = (new TreeBuilder('serializer'))->getRootNode();
68+
69+
$node
70+
->addDefaultsIfNotSet()
71+
->children()
72+
->scalarNode('format')
73+
->defaultValue('json')
74+
->end()
75+
->scalarNode('service')
76+
->defaultNull()
77+
->end()
78+
->arrayNode('symfony')
79+
->addDefaultsIfNotSet()
80+
->children()
81+
->arrayNode('context')
82+
->addDefaultsIfNotSet()
83+
->children()
84+
->arrayNode('common')
85+
->useAttributeAsKey('name')
86+
->variablePrototype()->end()
87+
->end()
88+
->arrayNode('serialize')
89+
->useAttributeAsKey('name')
90+
->variablePrototype()->end()
91+
->end()
92+
->arrayNode('deserialize')
93+
->useAttributeAsKey('name')
94+
->variablePrototype()->end()
95+
->end()
96+
->end()
97+
->end()
98+
->end()
99+
->end()
100+
->end()
101+
;
102+
103+
return $node;
104+
}
105+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yokai\Batch\Bridge\Symfony\Framework\DependencyInjection;
6+
7+
use Symfony\Component\Config\FileLocator;
8+
use Symfony\Component\Config\Loader as ConfigLoader;
9+
use Symfony\Component\Console\Application;
10+
use Symfony\Component\DependencyInjection\ContainerBuilder;
11+
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
12+
use Symfony\Component\DependencyInjection\Loader as DependencyInjectionLoader;
13+
use Symfony\Component\DependencyInjection\Reference;
14+
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
15+
use Symfony\Component\Messenger\MessageBusInterface;
16+
use Symfony\Component\Serializer\SerializerInterface;
17+
use Symfony\Component\Validator\Validator\ValidatorInterface;
18+
use Yokai\Batch\Bridge\Doctrine\DBAL\DoctrineDBALJobExecutionStorage;
19+
use Yokai\Batch\Bridge\Symfony\Serializer\SerializerJobExecutionSerializer;
20+
use Yokai\Batch\Launcher\JobLauncherInterface;
21+
use Yokai\Batch\Storage\FilesystemJobExecutionStorage;
22+
use Yokai\Batch\Storage\JobExecutionStorageInterface;
23+
use Yokai\Batch\Storage\ListableJobExecutionStorageInterface;
24+
use Yokai\Batch\Storage\QueryableJobExecutionStorageInterface;
25+
26+
final class YokaiBatchExtension extends Extension
27+
{
28+
/**
29+
* @inheritDoc
30+
*/
31+
public function load(array $configs, ContainerBuilder $container): void
32+
{
33+
$configuration = new Configuration();
34+
$config = $this->processConfiguration($configuration, $configs);
35+
36+
$loader = $this->getLoader($container);
37+
$loader->load('global/');
38+
$bundles = $container->getParameter('kernel.bundles');
39+
40+
$bridges = [
41+
'doctrine/orm/' => isset($bundles['DoctrineBundle']),
42+
'doctrine/mongodb/' => isset($bundles['DoctrineMongoDBBundle']),
43+
'symfony/console/' => class_exists(Application::class),
44+
'symfony/messenger/' => class_exists(MessageBusInterface::class),
45+
'symfony/serializer/' => interface_exists(SerializerInterface::class),
46+
'symfony/validator/' => interface_exists(ValidatorInterface::class),
47+
];
48+
49+
foreach (array_keys(array_filter($bridges)) as $resource) {
50+
$loader->load($resource);
51+
}
52+
53+
$this->configureStorage($container, $config['storage']);
54+
55+
$launcher = 'yokai_batch.job_launcher.simple';
56+
if (class_exists(MessageBusInterface::class)) {
57+
$launcher = 'yokai_batch.job_launcher.dispatch_message';
58+
} elseif (class_exists(Application::class)) {
59+
$launcher = 'yokai_batch.job_launcher.run_command';
60+
}
61+
$container->setAlias(JobLauncherInterface::class, $launcher);
62+
}
63+
64+
private function getLoader(ContainerBuilder $container): ConfigLoader\LoaderInterface
65+
{
66+
$locator = new FileLocator(__DIR__ . '/../Resources/services');
67+
$resolver = new ConfigLoader\LoaderResolver(
68+
[
69+
new DependencyInjectionLoader\XmlFileLoader($container, $locator),
70+
new DependencyInjectionLoader\DirectoryLoader($container, $locator),
71+
]
72+
);
73+
74+
return new ConfigLoader\DelegatingLoader($resolver);
75+
}
76+
77+
private function configureStorage(ContainerBuilder $container, array $config): void
78+
{
79+
if (isset($config['service'])) {
80+
$defaultStorage = $config['service'];
81+
} elseif (isset($config['dbal'])) {
82+
$container
83+
->register('yokai_batch.storage.dbal', DoctrineDBALJobExecutionStorage::class)
84+
->setArguments(
85+
[
86+
new Reference("doctrine.dbal.{$config['dbal']['connection']}_connection"),
87+
$config['dbal']['options'],
88+
]
89+
)
90+
;
91+
92+
$defaultStorage = 'yokai_batch.storage.dbal';
93+
} elseif (isset($config['filesystem'])) {
94+
$serializer = $config['filesystem']['serializer'];
95+
$format = $serializer['format'];
96+
97+
if (isset($serializer['service'])) {
98+
$serializerId = $serializer['service'];
99+
} elseif (isset($serializer['symfony'])) {
100+
if (!interface_exists(SerializerInterface::class)) {
101+
throw new \LogicException(); //todo
102+
}
103+
104+
$serializerId = 'yokai_batch.job_execution_serializer.filesystem_storage';
105+
$container
106+
->register($serializerId, SerializerJobExecutionSerializer::class)
107+
->setArguments(
108+
[
109+
new Reference(SerializerInterface::class),
110+
$format,
111+
$serializer['symfony']['context']['common'],
112+
$serializer['symfony']['context']['serialize'],
113+
$serializer['symfony']['context']['deserialize'],
114+
]
115+
)
116+
;
117+
} else {
118+
throw new \LogicException(); //todo
119+
}
120+
121+
$container
122+
->register('yokai_batch.storage.filesystem', FilesystemJobExecutionStorage::class)
123+
->setArguments(
124+
[
125+
new Reference($serializerId),
126+
$config['filesystem']['dir'],
127+
$format,
128+
]
129+
)
130+
;
131+
132+
$defaultStorage = 'yokai_batch.storage.filesystem';
133+
} else {
134+
throw new \LogicException();//todo
135+
}
136+
137+
try {
138+
$defaultStorageDefinition = $container->getDefinition($defaultStorage);
139+
} catch (ServiceNotFoundException $exception) {
140+
throw new \LogicException(
141+
sprintf('Configured default job execution storage service "%s" does not exists.', $defaultStorage),
142+
0,
143+
$exception
144+
);
145+
}
146+
147+
$interfaces = [
148+
JobExecutionStorageInterface::class => true,
149+
ListableJobExecutionStorageInterface::class => false,
150+
QueryableJobExecutionStorageInterface::class => false,
151+
];
152+
$defaultStorageClass = $defaultStorageDefinition->getClass();
153+
foreach ($interfaces as $interface => $required) {
154+
if (!is_a($defaultStorageClass, $interface, true)) {
155+
if ($required) {
156+
throw new \LogicException();//todo
157+
}
158+
continue;
159+
}
160+
$container
161+
->setAlias($interface, $defaultStorage)
162+
->setPublic(true)
163+
;
164+
}
165+
}
166+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<defaults public="false"/>
9+
10+
<service id="yokai_batch.item_writer.doctrine_mongodb_object_writer"
11+
class="Yokai\Batch\Bridge\Doctrine\Common\ObjectWriter">
12+
<argument type="service" id="doctrine_mongodb"/>
13+
</service>
14+
</services>
15+
</container>

0 commit comments

Comments
 (0)