Skip to content

Commit caa509f

Browse files
authored
Merge pull request #33 from leightonthomas/feature/compiler-pass
[#22] Configuring generators via compiler pass
2 parents a382a0e + c3c3926 commit caa509f

8 files changed

Lines changed: 123 additions & 99 deletions

File tree

README.md

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,6 @@ public function registerBundles()
2424
new Vivait\StringGeneratorBundle\VivaitStringGeneratorBundle(),
2525
}
2626
```
27-
## Configure
28-
29-
The default configuration is shown below:
30-
31-
```yaml
32-
vivait_string_generator:
33-
generators:
34-
string: vivait_generator.generator.string
35-
secure_bytes: vivait_generator.generator.secure_bytes
36-
secure_string: vivait_generator.generator.secure_string
37-
```
3827

3928
## Bundled generators
4029

@@ -157,8 +146,14 @@ However, by setting `override` to false, only null properties will have a string
157146

158147

159148
## Custom generators
160-
You can use your own generators by implementing `GeneratorInterface` and defining the generator in the configuration,
161-
using either its service or classname.
149+
You can use your own generators by implementing `GeneratorInterface` and defining the generator in your `services.yml` file with the tag `vivait_generator.generator` and an `alias`, which will be used to identify the Generator in annotations.
150+
151+
```yaml
152+
vivait_generator.generator.secure_bytes:
153+
class: Vivait\StringGeneratorBundle\Generator\SecureBytesGenerator
154+
tags:
155+
- { name: vivait_generator.generator, alias: 'secure_bytes' }
156+
```
162157
163158
To create configurable generators, implement `ConfigurableGeneratorInterface`. This interface uses
164159
[`Symfony\Component\OptionsResolver\OptionsResolver`](http://symfony.com/doc/current/components/options_resolver.html) to set the generator configuration.
@@ -167,30 +162,30 @@ Set default options:
167162

168163
```php
169164
/**
170-
* @param OptionsResolver $resolver
171-
* @return mixed
172-
*/
165+
* @param OptionsResolver $resolver
166+
*/
173167
public function getDefaultOptions(OptionsResolver $resolver)
174168
{
175-
$resolver->setDefaults([
176-
'chars' => $this->chars,
177-
'length' => $this->length,
178-
'prefix' => $this->prefix,
179-
]);
180-
}
169+
$resolver->setDefaults(
170+
[
171+
'chars' => $this->chars,
172+
'length' => $this->length,
173+
'prefix' => $this->prefix,
174+
]
175+
);
176+
}
181177
```
182178

183179
Do something with options:
184180

185-
```php
186-
/**
187-
* @param array $options
188-
* @return mixed|void
189-
*/
190-
public function setOptions(array $options)
191-
{
192-
$this->chars = $options['chars'];
181+
```php
182+
/**
183+
* @param array $options
184+
*/
185+
public function setOptions(array $options)
186+
{
187+
$this->chars = $options['chars'];
193188
$this->length = $options['length'];
194189
$this->prefix = $options['prefix'];
195-
}
196-
```
190+
}
191+
```

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
"symfony/polyfill-php70": "^1.3",
1818
"symfony/security": "^2.8|^3.0",
1919
"symfony/options-resolver": "^2.8|^3.0",
20-
"ircmaxell/random-lib": "~1.0"
20+
"ircmaxell/random-lib": "~1.0",
21+
"symfony/dependency-injection": "^2.7|^3.3",
22+
"symfony/config": "^2.7|^3.3"
2123
},
2224
"require-dev": {
2325
"phpspec/phpspec": "~2.0"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace AppBundle\DependencyInjection\Compiler;
4+
5+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
use Symfony\Component\DependencyInjection\Reference;
8+
9+
class GeneratorPass implements CompilerPassInterface
10+
{
11+
12+
/**
13+
* {@inheritdoc}
14+
*/
15+
public function process(ContainerBuilder $container)
16+
{
17+
if ( ! $container->has('vivait_generator.registry')) {
18+
return;
19+
}
20+
21+
$definition = $container->findDefinition('vivait_generator.registry');
22+
$allGenerators = $container->findTaggedServiceIds('vivait_generator.generator');
23+
24+
// Loop through all service IDs
25+
foreach ($allGenerators as $id => $tags) {
26+
// Loop through all of the individual tags
27+
foreach ($tags as $attributes) {
28+
$definition->addMethodCall(
29+
'addGenerator',
30+
[
31+
new Reference($id),
32+
$attributes['alias']
33+
]
34+
);
35+
}
36+
}
37+
}
38+
}

src/Vivait/StringGeneratorBundle/DependencyInjection/Configuration.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@
55
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
66
use Symfony\Component\Config\Definition\ConfigurationInterface;
77

8-
/**
9-
* This is the class that validates and merges configuration from your app/config files
10-
*
11-
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
12-
*/
138
class Configuration implements ConfigurationInterface
149
{
10+
1511
/**
1612
* {@inheritDoc}
1713
*/
@@ -25,7 +21,8 @@ public function getConfigTreeBuilder()
2521
->children()
2622
->arrayNode('generators')
2723
->useAttributeAsKey('class')
28-
->prototype('scalar')->end()
24+
->prototype('scalar')
25+
->end()
2926
->end()
3027
->end();
3128

src/Vivait/StringGeneratorBundle/DependencyInjection/VivaitStringGeneratorExtension.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,33 @@
77
use Symfony\Component\DependencyInjection\Loader;
88
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
99

10-
/**
11-
* This is the class that loads and manages your bundle configuration
12-
*
13-
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
14-
*/
1510
class VivaitStringGeneratorExtension extends ConfigurableExtension
1611
{
12+
1713
/**
1814
* {@inheritdoc}
1915
*/
2016
public function loadInternal(array $mergedConfig, ContainerBuilder $container)
2117
{
22-
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
18+
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
2319
$loader->load('services.yml');
2420

25-
if($mergedConfig['generators'] && $container->hasDefinition('vivait_generator.registry')){
21+
if ($mergedConfig['generators'] && $container->hasDefinition('vivait_generator.registry')) {
22+
@trigger_error(
23+
'Defining Generators in config is deprecated since version 2.0.1 and will be removed in version 3.0. ' .
24+
'Use services tagged with "vivait_generator.generator" and an "alias" instead.',
25+
E_USER_DEPRECATED
26+
);
27+
2628
$registry = $container->findDefinition('vivait_generator.registry');
2729

28-
$registry->replaceArgument(1, $mergedConfig['generators']);
30+
$legacyGenerators = [];
31+
32+
foreach ($mergedConfig['generators'] as $alias => $generatorService) {
33+
$legacyGenerators[$alias] = $container->get($generatorService);
34+
}
35+
36+
$registry->addArgument($legacyGenerators);
2937
}
3038
}
3139
}

src/Vivait/StringGeneratorBundle/Registry/Registry.php

Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,82 +2,50 @@
22

33
namespace Vivait\StringGeneratorBundle\Registry;
44

5-
use Symfony\Component\DependencyInjection\ContainerInterface;
65
use Vivait\StringGeneratorBundle\Model\GeneratorInterface;
76

87
class Registry
98
{
9+
1010
/**
1111
* @var array
1212
*/
1313
private $generators;
1414

1515
/**
16-
* @var ContainerInterface
17-
*/
18-
private $container;
19-
20-
/**
21-
* @param ContainerInterface $container
22-
* @param array $generators
16+
* @param array $legacyGenerators
2317
*/
24-
function __construct(ContainerInterface $container, array $generators = [])
18+
public function __construct(array $legacyGenerators = [])
2519
{
26-
$this->container = $container;
27-
$this->addAll($generators);
20+
$this->generators = $legacyGenerators;
2821
}
2922

3023
/**
31-
* @param $field
32-
* @return GeneratorInterface
33-
* @throws \OutOfBoundsException
24+
* @param GeneratorInterface $generator
25+
* @param string $alias
3426
*/
35-
public function get($field)
27+
public function addGenerator(GeneratorInterface $generator, $alias)
3628
{
37-
if (isset($this->generators[$field])) {
38-
return $this->generators[$field];
29+
if (array_key_exists($alias, $this->generators)) {
30+
throw new \InvalidArgumentException("The alias {$alias} is already a registered Generator.");
3931
}
4032

41-
throw new \OutOfBoundsException(sprintf('Field "%s" not found in registry', $field));
42-
}
43-
44-
/**
45-
* @param $field
46-
* @param $class
47-
* @return $this
48-
*/
49-
public function add($field, $class)
50-
{
51-
$this->generators[$field] = $this->resolveGeneratorType($class);
52-
return $this;
53-
}
54-
55-
/**
56-
* @param array $generators
57-
* @return $this
58-
*/
59-
public function addAll(array $generators)
60-
{
61-
foreach ($generators as $field => $class) {
62-
$this->add($field, $class);
63-
}
64-
return $this;
33+
$this->generators[$alias] = $generator;
6534
}
6635

6736
/**
68-
* @param $class
37+
* @param string $field
38+
*
39+
* @throws \OutOfBoundsException
40+
*
6941
* @return GeneratorInterface
7042
*/
71-
private function resolveGeneratorType($class)
43+
public function get($field)
7244
{
73-
if ($class instanceof GeneratorInterface) {
74-
return $class;
75-
} elseif (($service = $this->container->get($class, ContainerInterface::NULL_ON_INVALID_REFERENCE))) {
76-
return $service;
77-
} elseif (is_a($class, 'Vivait\StringGeneratorBundle\Generator\GeneratorInterface', true)) {
78-
return new $class;
45+
if (isset($this->generators[$field])) {
46+
return $this->generators[$field];
7947
}
8048

81-
throw new \InvalidArgumentException('Invalid Generator');
49+
throw new \OutOfBoundsException(sprintf('Field "%s" not found in registry', $field));
8250
}
8351
}

src/Vivait/StringGeneratorBundle/Resources/config/services.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,23 @@ services:
1010

1111
vivait_generator.registry:
1212
class: Vivait\StringGeneratorBundle\Registry\Registry
13-
arguments: ["@service_container", []]
1413

1514
vivait_generator.generator.string:
1615
class: Vivait\StringGeneratorBundle\Generator\StringGenerator
16+
tags:
17+
- { name: vivait_generator.generator, alias: 'string' }
1718

1819
vivait_generator.generator.secure_bytes:
1920
class: Vivait\StringGeneratorBundle\Generator\SecureBytesGenerator
21+
tags:
22+
- { name: vivait_generator.generator, alias: 'secure_bytes' }
2023

2124
vivait_generator.generator.secure_string:
2225
class: Vivait\StringGeneratorBundle\Generator\SecureStringGenerator
23-
arguments: ["@vivait_generator.randomlib"]
26+
arguments:
27+
- "@vivait_generator.randomlib"
28+
tags:
29+
- { name: vivait_generator.generator, alias: 'secure_string' }
2430

2531
vivait_generator.randomlib:
2632
class: RandomLib\Factory

src/Vivait/StringGeneratorBundle/VivaitStringGeneratorBundle.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@
22

33
namespace Vivait\StringGeneratorBundle;
44

5+
use AppBundle\DependencyInjection\Compiler\GeneratorPass;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
57
use Symfony\Component\HttpKernel\Bundle\Bundle;
68

79
class VivaitStringGeneratorBundle extends Bundle
810
{
11+
12+
/**
13+
* {@inheritdoc}
14+
*/
15+
public function build(ContainerBuilder $container)
16+
{
17+
$container->addCompilerPass(new GeneratorPass());
18+
}
919
}

0 commit comments

Comments
 (0)