Skip to content

Commit 9ee519a

Browse files
committed
Added Yahoo! Finance web service as an adapter
1 parent d2d2682 commit 9ee519a

File tree

8 files changed

+175
-27
lines changed

8 files changed

+175
-27
lines changed

.gitignore

-7
This file was deleted.

.travis.yml

-20
This file was deleted.

Adapter/AdapterFactory.php

+14
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,18 @@ public function createOerAdapter($adapterClass = null)
104104

105105
return $this->create($adapterClass);
106106
}
107+
108+
/**
109+
* Create an YahooCurrencyAdapter.
110+
*
111+
* @return Lexik\Bundle\CurrencyBundle\Adapter\YahooCurrencyAdapter
112+
*/
113+
public function createYahooAdapter($adapterClass = null)
114+
{
115+
if (null == $adapterClass) {
116+
$adapterClass = 'Lexik\Bundle\CurrencyBundle\Adapter\YahooCurrencyAdapter';
117+
}
118+
119+
return $this->create($adapterClass);
120+
}
107121
}

Adapter/YahooCurrencyAdapter.php

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
3+
namespace Lexik\Bundle\CurrencyBundle\Adapter;
4+
5+
use Lexik\Bundle\CurrencyBundle\Exception\CurrencyNotFoundException;
6+
7+
/**
8+
* Yahoo! Adapter
9+
*
10+
* @author Jonas Dambacher <[email protected]>
11+
*/
12+
class YahooCurrencyAdapter extends AbstractCurrencyAdapter
13+
{
14+
/**
15+
* @var string
16+
*/
17+
private $yahooUrl;
18+
19+
/**
20+
* @var array
21+
*/
22+
private $currencyCodes = array();
23+
24+
25+
/**
26+
* Set the Yahoo! url.
27+
*
28+
* @param string $url
29+
*/
30+
public function setYahooUrl($url)
31+
{
32+
$this->yahooUrl = $url;
33+
}
34+
35+
/**
36+
* Init object storage
37+
*/
38+
public function attachAll()
39+
{
40+
foreach ($this->managedCurrencies as $managedCurrency) {
41+
$this->addCurrency($managedCurrency);
42+
}
43+
44+
$defaultRate = 1;
45+
46+
// Add default currency (euro in this example)
47+
$euro = new $this->currencyClass;
48+
$euro->setCode('EUR');
49+
$euro->setRate($defaultRate);
50+
51+
$this[$euro->getCode()] = $euro;
52+
53+
// Build YQL query
54+
$strCodes = '';
55+
foreach ($this->currencyCodes as $index=>$currencyCode) {
56+
$strCodes .= "'EUR".$currencyCode."'";
57+
if ($index != count($this->currencyCodes) - 1) {
58+
$strCodes .= ", ";
59+
}
60+
}
61+
62+
$yqlQuery = "select id,Rate from yahoo.finance.xchange where pair in (".$strCodes.")";
63+
64+
$args = array(
65+
'q' => $yqlQuery,
66+
'format' => "json",
67+
'env' => "store://datatables.org/alltableswithkeys",
68+
);
69+
70+
$yqlQueryURL = $this->yahooUrl
71+
. "?q=" . urlencode($yqlQuery)
72+
. "&format=json"
73+
. "&env=store://datatables.org/alltableswithkeys";
74+
75+
$ch = curl_init();
76+
curl_setopt($ch, CURLOPT_URL, $yqlQueryURL);
77+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
78+
$json = curl_exec($ch);
79+
80+
// Convert JSON response to PHP object
81+
$data = json_decode($json);
82+
$results = $data->query->results->rate;
83+
84+
// Check if query was okay and result is given
85+
if (is_null($results)) {
86+
new \RuntimeException('YQL query failed!');
87+
}
88+
89+
$currencies = array();
90+
91+
foreach ($results as $row) {
92+
$code = substr($row->id, 3);
93+
$rate = $row->Rate;
94+
95+
$currencies[$code] = $rate;
96+
}
97+
98+
foreach ($currencies as $code => $rate) {
99+
if (in_array($code, $this->managedCurrencies)) { // you can check if the currency is in the managed currencies
100+
$currency = new $this->currencyClass;
101+
$currency->setCode($code);
102+
$currency->setRate($rate);
103+
104+
$this[$currency->getCode()] = $currency;
105+
}
106+
}
107+
108+
// get the default rate from the default currency defined in the configuration
109+
if (isset($this[$this->defaultCurrency])) {
110+
$defaultRate = $this[$this->defaultCurrency]->getRate();
111+
}
112+
113+
// convert rates according to the default one.
114+
$this->convertAll($defaultRate);
115+
}
116+
117+
/**
118+
* {@inheritdoc}
119+
*/
120+
public function getIdentifier()
121+
{
122+
return 'yahoo';
123+
}
124+
125+
/**
126+
* Add currency to the query
127+
*
128+
* @param $code
129+
*/
130+
private function addCurrency($code) {
131+
$this->currencyCodes[] = $code;
132+
}
133+
134+
}

DependencyInjection/Configuration.php

+6
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ public function getConfigTreeBuilder()
7373
->scalarNode('oer_app_id')
7474
->defaultValue(null)
7575
->end()
76+
77+
->scalarNode('yahoo_url')
78+
->cannotBeEmpty()
79+
->defaultValue('https://query.yahooapis.com/v1/public/yql')
80+
->end()
81+
7682
->end()
7783
;
7884

DependencyInjection/LexikCurrencyExtension.php

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function load(array $configs, ContainerBuilder $container)
3030
$container->setParameter('lexik_currency.ecb_url', $config['ecb_url']);
3131
$container->setParameter('lexik_currency.oer_url', $config['oer_url']);
3232
$container->setParameter('lexik_currency.oer_app_id', $config['oer_app_id']);
33+
$container->setParameter('lexik_currency.yahoo_url', $config['yahoo_url']);
3334
$container->setParameter('lexik_currency.decimal_part.precision', $config['decimal_part']['precision']);
3435
$container->setParameter('lexik_currency.decimal_part.round_mode', $config['decimal_part']['round_mode']);
3536

Resources/config/adapters.xml

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<parameter key="lexik_currency.abstract_adapter.class">Lexik\Bundle\CurrencyBundle\Adapter\AbstractCurrencyAdapter</parameter>
1111
<parameter key="lexik_currency.ecb_adapter.class">Lexik\Bundle\CurrencyBundle\Adapter\EcbCurrencyAdapter</parameter>
1212
<parameter key="lexik_currency.oer_adapter.class">Lexik\Bundle\CurrencyBundle\Adapter\OerCurrencyAdapter</parameter>
13+
<parameter key="lexik_currency.yahoo_adapter.class">Lexik\Bundle\CurrencyBundle\Adapter\YahooCurrencyAdapter</parameter>
1314
<parameter key="lexik_currency.doctrine_adapter.class">Lexik\Bundle\CurrencyBundle\Adapter\DoctrineCurrencyAdapter</parameter>
1415
<parameter key="lexik_currency.doctrine.orm.entity_manager">default</parameter>
1516
</parameters>
@@ -54,6 +55,14 @@
5455
</call>
5556
<tag name="lexik_currency.adapter" alias="oer_currency_adapter" />
5657
</service>
58+
59+
<service id="lexik_currency.yahoo_adapter" class="%lexik_currency.yahoo_adapter.class%" parent="lexik_currency.abstract_adapter">
60+
<factory service="lexik_currency.adapter_factory" method="createYahooAdapter" />
61+
<call method="setYahooUrl">
62+
<argument>%lexik_currency.yahoo_url%</argument>
63+
</call>
64+
<tag name="lexik_currency.adapter" alias="yahoo_currency_adapter" />
65+
</service>
5766
</services>
5867

5968
</container>

Tests/Unit/Adapter/AdapterFactoryTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ public function testCreateEcbAdapter()
2929
$this->assertEquals(0, count($adapter));
3030
}
3131

32+
public function testCreateYahooAdapter()
33+
{
34+
$factory = new AdapterFactory($this->doctrine, 'EUR', array('EUR', 'USD'), self::CURRENCY_ENTITY);
35+
$adapter = $factory->createYahooAdapter();
36+
37+
$this->assertInstanceOf('Lexik\Bundle\CurrencyBundle\Adapter\YahooCurrencyAdapter', $adapter);
38+
$this->assertEquals('EUR', $adapter->getDefaultCurrency());
39+
$this->assertEquals(array('EUR', 'USD'), $adapter->getManagedCurrencies());
40+
$this->assertEquals(0, count($adapter));
41+
}
42+
3243
public function testCreateDoctrineAdapter()
3344
{
3445
$em = $this->getEntityManager();

0 commit comments

Comments
 (0)