Skip to content

Commit 24a72f2

Browse files
committed
Some improvements and V2 support.
- Add cache implementation. - Can sort providers. - Usage of ChainProvider. - Adding NationalBankOfRomania provider. - http_provider is configurable.
1 parent 8cf2961 commit 24a72f2

File tree

9 files changed

+367
-79
lines changed

9 files changed

+367
-79
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
language: php
22

33
php:
4-
- 5.3
54
- 5.4
65
- 5.5
76
- 5.6

DependencyInjection/Compiler/ProviderPass.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Florianv\SwapBundle\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\Definition;
1415
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\DependencyInjection\Reference;
@@ -27,14 +28,44 @@ class ProviderPass implements CompilerPassInterface
2728
*/
2829
public function process(ContainerBuilder $container)
2930
{
30-
if (!$container->hasDefinition('florianv_swap.swap')) {
31-
return;
31+
$providers = array();
32+
33+
foreach ($container->findTaggedServiceIds('florianv_swap.provider') as $id => $attributes) {
34+
$providers[$id] = isset($attributes[0]) ? $attributes[0] : 0;
35+
}
36+
37+
$providers = $this->normalizeProviders($providers);
38+
39+
if (1 === count($providers)) {
40+
$provider = current($providers);
41+
} else {
42+
$provider = new Definition('%florianv_swap.provider.chain.class%', array($providers));
3243
}
3344

3445
$definition = $container->getDefinition('florianv_swap.swap');
46+
$definition->replaceArgument(0, $provider);
47+
}
3548

36-
foreach ($container->findTaggedServiceIds('florianv_swap.provider') as $id => $attributes) {
37-
$definition->addMethodCall('addProvider', array(new Reference($id)));
49+
private function normalizeProviders(array $providers)
50+
{
51+
$providersByPriority = array();
52+
53+
foreach ($providers as $id => $provider) {
54+
$priority = isset($provider['priority']) ? $provider['priority'] : 0;
55+
$providersByPriority[$priority][] = new Reference($id);
3856
}
57+
58+
// cannot use uasort because of https://github.com/florianv/FlorianvSwapBundle/pull/2#issuecomment-105971854
59+
krsort($providersByPriority);
60+
61+
$result = array();
62+
63+
foreach ($providersByPriority as $priority => $providers) {
64+
foreach ($providers as $provider) {
65+
$result[] = $provider;
66+
}
67+
}
68+
69+
return $result;
3970
}
4071
}

DependencyInjection/Configuration.php

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,89 @@ public function getConfigTreeBuilder()
3030
$rootNode = $treeBuilder->root('florianv_swap');
3131

3232
$rootNode
33+
->validate()
34+
->ifTrue(function($providers) {
35+
return !isset($providers['providers']) || count($providers['providers']) === 0;
36+
})
37+
->thenInvalid('You must define at least one provider.')
38+
->end()
3339
->children()
40+
->scalarNode('http_adapter')->defaultValue('florianv_swap.http_adapter.file_get_contents')->end()
41+
->arrayNode('cache')
42+
->children()
43+
->integerNode('ttl')->isRequired()->end()
44+
->append($this->getCacheDriverNode('doctrine'))
45+
->end()
46+
->end()
3447
->arrayNode('providers')
3548
->children()
36-
->scalarNode('yahoo_finance')->end()
37-
->scalarNode('google_finance')->end()
38-
->scalarNode('european_central_bank')->end()
49+
->append($this->createSimpleProviderNode('yahoo_finance'))
50+
->append($this->createSimpleProviderNode('google_finance'))
51+
->append($this->createSimpleProviderNode('european_central_bank'))
52+
->append($this->createSimpleProviderNode('national_bank_of_romania'))
3953
->arrayNode('open_exchange_rates')
4054
->children()
55+
->integerNode('priority')->defaultValue(0)->end()
4156
->scalarNode('app_id')->isRequired()->cannotBeEmpty()->end()
4257
->booleanNode('enterprise')->defaultFalse()->end()
4358
->end()
4459
->end()
4560
->arrayNode('xignite')
4661
->children()
62+
->integerNode('priority')->defaultValue(0)->end()
4763
->scalarNode('token')->isRequired()->cannotBeEmpty()->end()
4864
->end()
4965
->end()
50-
->scalarNode('webservicex')->end()
66+
->append($this->createSimpleProviderNode('webservicex'))
5167
->end()
5268
->end()
5369
->end()
5470
;
5571

5672
return $treeBuilder;
5773
}
74+
75+
private function createSimpleProviderNode($name)
76+
{
77+
$treeBuilder = new TreeBuilder();
78+
$node = $treeBuilder->root($name);
79+
80+
$node
81+
->children()
82+
->integerNode('priority')->defaultValue(0)->end()
83+
->end()
84+
;
85+
86+
return $node;
87+
}
88+
89+
/**
90+
* Return a cache driver node
91+
*
92+
* @param string $name
93+
*
94+
* @return ArrayNodeDefinition
95+
*/
96+
private function getCacheDriverNode($name)
97+
{
98+
$treeBuilder = new TreeBuilder();
99+
$node = $treeBuilder->root($name);
100+
101+
$node
102+
->addDefaultsIfNotSet()
103+
->beforeNormalization()
104+
->ifString()
105+
->then(function($v) { return array('type' => $v); })
106+
->end()
107+
->isRequired()
108+
->children()
109+
->enumNode('type')
110+
->values(array('apc', 'array', 'xcache', 'wincache', 'zenddata'))
111+
->defaultValue('array')
112+
->end()
113+
->end()
114+
;
115+
116+
return $node;
117+
}
58118
}

DependencyInjection/FlorianvSwapExtension.php

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\DependencyInjection\Extension\Extension;
1818
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
1919
use Symfony\Component\DependencyInjection\Reference;
20+
use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension;
2021

2122
/**
2223
* The container extension.
@@ -35,49 +36,73 @@ public function load(array $config, ContainerBuilder $container)
3536

3637
$config = $this->processConfiguration(new Configuration(), $config);
3738

38-
if (isset($config['providers'])) {
39-
foreach ($config['providers'] as $providerName => $providerConfig) {
40-
switch ($providerName) {
41-
case 'yahoo_finance':
42-
case 'google_finance':
43-
case 'european_central_bank':
44-
case 'webservicex':
45-
$this->addProvider($container, $providerName, array(
46-
new Reference('florianv_swap.client')
47-
));
48-
break;
49-
50-
case 'open_exchange_rates':
51-
$this->addProvider($container, $providerName, array(
52-
new Reference('florianv_swap.client'),
53-
$providerConfig['app_id'],
54-
$providerConfig['enterprise']
55-
));
56-
break;
57-
58-
case 'xignite':
59-
$this->addProvider($container, $providerName, array(
60-
new Reference('florianv_swap.client'),
61-
$providerConfig['token'],
62-
));
63-
break;
64-
}
39+
$container->setAlias('florianv_swap.http_adapter', $config['http_adapter']);
40+
41+
$this->loadProviders($config['providers'], $container);
42+
43+
if (isset($config['cache'])) {
44+
$this->loadCache($config['cache'], $container);
45+
}
46+
}
47+
48+
private function loadProviders(array $config, ContainerBuilder $container)
49+
{
50+
foreach ($config as $providerName => $providerConfig) {
51+
switch ($providerName) {
52+
case 'yahoo_finance':
53+
case 'google_finance':
54+
case 'european_central_bank':
55+
case 'national_bank_of_romania':
56+
case 'webservicex':
57+
$this->addProvider($container, $providerName, array(
58+
new Reference('florianv_swap.http_adapter'),
59+
), $providerConfig['priority']);
60+
break;
61+
62+
case 'open_exchange_rates':
63+
$this->addProvider($container, $providerName, array(
64+
new Reference('florianv_swap.http_adapter'),
65+
$providerConfig['app_id'],
66+
$providerConfig['enterprise']
67+
), $providerConfig['priority']);
68+
break;
69+
70+
case 'xignite':
71+
$this->addProvider($container, $providerName, array(
72+
new Reference('florianv_swap.http_adapter'),
73+
$providerConfig['token'],
74+
), $providerConfig['priority']);
75+
break;
6576
}
6677
}
6778
}
6879

80+
private function loadCache(array $config, ContainerBuilder $container)
81+
{
82+
$cacheProvider = new Definition('%florianv_swap.cache.doctrine.'.$config['doctrine']['type'].'.class%');
83+
$cacheProvider->setPublic(false);
84+
85+
$cacheDefinition = new Definition('%florianv_swap.cache.doctrine.class%', array(
86+
$cacheProvider,
87+
$config['ttl']
88+
));
89+
$cacheDefinition->setPublic(false);
90+
91+
$container->getDefinition('florianv_swap.swap')->replaceArgument(1, $cacheDefinition);
92+
}
93+
6994
/**
7095
* Creates the provider definition and add it to the container.
7196
*
7297
* @param ContainerBuilder $container
7398
* @param string $name
7499
* @param array $arguments
75100
*/
76-
private function addProvider(ContainerBuilder $container, $name, array $arguments = array())
101+
private function addProvider(ContainerBuilder $container, $name, array $arguments = array(), $priority = null)
77102
{
78103
$definition = new Definition('%florianv_swap.provider.'.$name.'.class%', $arguments);
79104
$definition->setPublic(false);
80-
$definition->addTag('florianv_swap.provider');
105+
$definition->addTag('florianv_swap.provider', array('priority' => $priority));
81106

82107
$container->setDefinition(sprintf('florianv_swap.provider.%s', $name), $definition);
83108
}

Resources/config/services.xml

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,32 @@
66

77
<parameters>
88
<parameter key="florianv_swap.swap.class">Swap\Swap</parameter>
9-
<parameter key="florianv_swap.client.class">Guzzle\Http\Client</parameter>
10-
<parameter key="florianv_swap.provider.yahoo_finance.class">Swap\Provider\YahooFinance</parameter>
11-
<parameter key="florianv_swap.provider.google_finance.class">Swap\Provider\GoogleFinance</parameter>
12-
<parameter key="florianv_swap.provider.european_central_bank.class">Swap\Provider\EuropeanCentralBank</parameter>
13-
<parameter key="florianv_swap.provider.open_exchange_rates.class">Swap\Provider\OpenExchangeRates</parameter>
14-
<parameter key="florianv_swap.provider.xignite.class">Swap\Provider\Xignite</parameter>
15-
<parameter key="florianv_swap.provider.webservicex.class">Swap\Provider\WebserviceX</parameter>
9+
<parameter key="florianv_swap.http_adapter.file_get_contents.class">Ivory\HttpAdapter\FileGetContentsHttpAdapter</parameter>
10+
<parameter key="florianv_swap.provider.chain.class">Swap\Provider\ChainProvider</parameter>
11+
<parameter key="florianv_swap.provider.yahoo_finance.class">Swap\Provider\YahooFinanceProvider</parameter>
12+
<parameter key="florianv_swap.provider.google_finance.class">Swap\Provider\GoogleFinanceProvider</parameter>
13+
<parameter key="florianv_swap.provider.european_central_bank.class">Swap\Provider\EuropeanCentralBankProvider</parameter>
14+
<parameter key="florianv_swap.provider.national_bank_of_romania.class">Swap\Provider\NationalBankOfRomaniaProvider</parameter>
15+
<parameter key="florianv_swap.provider.open_exchange_rates.class">Swap\Provider\OpenExchangeRatesProvider</parameter>
16+
<parameter key="florianv_swap.provider.xignite.class">Swap\Provider\XigniteProvider</parameter>
17+
<parameter key="florianv_swap.provider.webservicex.class">Swap\Provider\WebserviceXProvider</parameter>
18+
19+
<!-- cache -->
20+
<parameter key="florianv_swap.cache.doctrine.class">Swap\Cache\DoctrineCache</parameter>
21+
<parameter key="florianv_swap.cache.doctrine.array.class">Doctrine\Common\Cache\ArrayCache</parameter>
22+
<parameter key="florianv_swap.cache.doctrine.apc.class">Doctrine\Common\Cache\ApcCache</parameter>
23+
<parameter key="florianv_swap.cache.doctrine.xcache.class">Doctrine\Common\Cache\XcacheCache</parameter>
24+
<parameter key="florianv_swap.cache.doctrine.wincache.class">Doctrine\Common\Cache\WinCacheCache</parameter>
25+
<parameter key="florianv_swap.cache.doctrine.array.zenddata">Doctrine\Common\Cache\ZendDataCache</parameter>
1626
</parameters>
1727

1828
<services>
19-
<service id="florianv_swap.swap" class="%florianv_swap.swap.class%"/>
20-
<service id="florianv_swap.client" class="%florianv_swap.client.class%" public="false"/>
29+
<service id="florianv_swap.swap" class="%florianv_swap.swap.class%">
30+
<argument /> <!-- required provider(s) -->
31+
<argument>null</argument> <!-- cache -->
32+
</service>
33+
34+
<service id="florianv_swap.http_adapter.file_get_contents" class="%florianv_swap.http_adapter.file_get_contents.class%" public="false"/>
2135
</services>
2236

2337
</container>

0 commit comments

Comments
 (0)