Skip to content

Commit 5589b27

Browse files
authored
Allow you to create a custom factory (#184)
This will fix #178
1 parent a7de572 commit 5589b27

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

BazingaGeocoderBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
namespace Bazinga\GeocoderBundle;
1414

1515
use Bazinga\GeocoderBundle\DependencyInjection\Compiler\AddProvidersPass;
16+
use Bazinga\GeocoderBundle\DependencyInjection\Compiler\FactoryValidatorPass;
1617
use Bazinga\GeocoderBundle\DependencyInjection\Compiler\ProfilerPass;
1718
use Symfony\Component\DependencyInjection\ContainerBuilder;
1819
use Symfony\Component\HttpKernel\Bundle\Bundle;
@@ -31,5 +32,6 @@ public function build(ContainerBuilder $container)
3132

3233
$container->addCompilerPass(new ProfilerPass());
3334
$container->addCompilerPass(new AddProvidersPass());
35+
$container->addCompilerPass(new FactoryValidatorPass());
3436
}
3537
}

DependencyInjection/BazingaGeocoderExtension.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
namespace Bazinga\GeocoderBundle\DependencyInjection;
1414

1515
use Bazinga\GeocoderBundle\DataCollector\GeocoderDataCollector;
16+
use Bazinga\GeocoderBundle\DependencyInjection\Compiler\FactoryValidatorPass;
1617
use Bazinga\GeocoderBundle\Plugin\FakeIpPlugin;
1718
use Bazinga\GeocoderBundle\Plugin\ProfilingPlugin;
1819
use Bazinga\GeocoderBundle\ProviderFactory\PluginProviderFactory;
@@ -25,6 +26,7 @@
2526
use Symfony\Component\Config\Definition\Processor;
2627
use Symfony\Component\Config\FileLocator;
2728
use Symfony\Component\DependencyInjection\ContainerBuilder;
29+
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
2830
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
2931
use Symfony\Component\DependencyInjection\Reference;
3032
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@@ -60,14 +62,20 @@ public function load(array $configs, ContainerBuilder $container)
6062
private function loadProviders(ContainerBuilder $container, array $config)
6163
{
6264
foreach ($config['providers'] as $providerName => $providerConfig) {
63-
$factoryService = $container->getDefinition($providerConfig['factory']);
64-
$factoryClass = $factoryService->getClass() ?: $providerConfig['factory'];
65-
if (!$this->implementsPoviderFactory($factoryClass)) {
66-
throw new \LogicException(sprintf('Provider factory "%s" must implement ProviderFactoryInterface', $providerConfig['factory']));
65+
try {
66+
$factoryService = $container->getDefinition($providerConfig['factory']);
67+
$factoryClass = $factoryService->getClass() ?: $providerConfig['factory'];
68+
if (!$this->implementsPoviderFactory($factoryClass)) {
69+
throw new \LogicException(sprintf('Provider factory "%s" must implement ProviderFactoryInterface', $providerConfig['factory']));
70+
}
71+
// See if any option has a service reference
72+
$providerConfig['options'] = $this->findReferences($providerConfig['options']);
73+
$factoryClass::validate($providerConfig['options'], $providerName);
74+
} catch (ServiceNotFoundException $e) {
75+
// Assert: We are using a custom factory. If invalid config, it will be caught in FactoryValidatorPass
76+
$providerConfig['options'] = $this->findReferences($providerConfig['options']);
77+
FactoryValidatorPass::addFactoryServiceId($providerConfig['factory']);
6778
}
68-
// See if any option has a service reference
69-
$providerConfig['options'] = $this->findReferences($providerConfig['options']);
70-
$factoryClass::validate($providerConfig['options'], $providerName);
7179

7280
$serviceId = 'bazinga_geocoder.provider.'.$providerName;
7381
$plugins = $this->configureProviderPlugins($container, $providerConfig, $serviceId);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the BazingaGeocoderBundle package.
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*
10+
* @license MIT License
11+
*/
12+
13+
namespace Bazinga\GeocoderBundle\DependencyInjection\Compiler;
14+
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
18+
19+
/**
20+
* Make sure that the factory actually exists
21+
*
22+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
23+
*/
24+
class FactoryValidatorPass implements CompilerPassInterface
25+
{
26+
private static $factoryServiceIds = [];
27+
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public function process(ContainerBuilder $container)
32+
{
33+
foreach (self::$factoryServiceIds as $id) {
34+
if (!$container->hasAlias($id) && !$container->hasDefinition($id)) {
35+
throw new ServiceNotFoundException(sprintf('Factory with ID "%s" could not be found', $id));
36+
}
37+
}
38+
}
39+
40+
/**
41+
* @param mixed $factoryServiceIds
42+
*/
43+
public static function addFactoryServiceId($factoryServiceIds)
44+
{
45+
self::$factoryServiceIds[] = $factoryServiceIds;
46+
}
47+
}

0 commit comments

Comments
 (0)