Skip to content

Commit db900e9

Browse files
authored
Added a callable to decide what provider that should be used. (#731)
* Added a callable to decide what provider that should be used. * Applied changes from StyleCI
1 parent ed3af33 commit db900e9

File tree

3 files changed

+90
-39
lines changed

3 files changed

+90
-39
lines changed

src/Common/CHANGELOG.md

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

33
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
44

5+
## Unreleased
6+
7+
### Added
8+
9+
- The constructor of `ProvierAggregator` will accept a callable that can decide what providers should be used for a specific query.
10+
11+
### Changed
12+
13+
- `ProvierAggregator::getProvider` is now private
14+
515
## 4.0.0 - Beta 2
616

717
### Added

src/Common/ProviderAggregator.php

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,44 @@ class ProviderAggregator implements Geocoder
3838
*/
3939
private $limit;
4040

41+
/**
42+
* A callable that decided what provider to use.
43+
*
44+
* @var callable
45+
*/
46+
private $decider;
47+
4148
/**
4249
* @param int $limit
4350
*/
44-
public function __construct(int $limit = Geocoder::DEFAULT_RESULT_LIMIT)
51+
public function __construct(int $limit = Geocoder::DEFAULT_RESULT_LIMIT, callable $decider = null)
4552
{
4653
$this->limit($limit);
54+
$this->decider = $decider ?? __CLASS__.'::getProvider';
4755
}
4856

4957
/**
5058
* {@inheritdoc}
5159
*/
5260
public function geocodeQuery(GeocodeQuery $query): Collection
5361
{
54-
return $this->getProvider()->geocodeQuery($query);
62+
if (null === $query->getLimit()) {
63+
$query = $query->withLimit($this->limit);
64+
}
65+
66+
return call_user_func($this->decider, $query, $this->providers, $this->provider)->geocodeQuery($query);
5567
}
5668

5769
/**
5870
* {@inheritdoc}
5971
*/
6072
public function reverseQuery(ReverseQuery $query): Collection
6173
{
62-
return $this->getProvider()->reverseQuery($query);
74+
if (null === $query->getLimit()) {
75+
$query = $query->withLimit($this->limit);
76+
}
77+
78+
return call_user_func($this->decider, $query, $this->providers, $this->provider)->reverseQuery($query);
6379
}
6480

6581
/**
@@ -167,22 +183,29 @@ public function getProviders(): array
167183
}
168184

169185
/**
170-
* Returns the current provider in use.
186+
* Get a provider to use for this query.
187+
*
188+
* @param GeocodeQuery|ReverseQuery $query
189+
* @param Provider[] $providers
190+
* @param Provider $currentProvider
171191
*
172192
* @return Provider
173193
*
174-
* @throws \RuntimeException
194+
* @throws ProviderNotRegistered
175195
*/
176-
protected function getProvider(): Provider
196+
private static function getProvider($query, array $providers, Provider $currentProvider = null): Provider
177197
{
178-
if (null === $this->provider) {
179-
if (0 === count($this->providers)) {
180-
throw ProviderNotRegistered::noProviderRegistered();
181-
}
198+
if (null !== $currentProvider) {
199+
return $currentProvider;
200+
}
182201

183-
$this->using(key($this->providers));
202+
if (0 === count($providers)) {
203+
throw ProviderNotRegistered::noProviderRegistered();
184204
}
185205

186-
return $this->provider;
206+
// Take first
207+
$key = key($providers);
208+
209+
return $providers[$key];
187210
}
188211
}

src/Common/Tests/ProviderAggregatorTest.php

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
use Geocoder\Collection;
1616
use Geocoder\Geocoder;
17+
use Geocoder\Model\Address;
18+
use Geocoder\Model\AddressCollection;
1719
use Geocoder\Query\GeocodeQuery;
1820
use Geocoder\Query\ReverseQuery;
1921
use Geocoder\ProviderAggregator;
@@ -36,38 +38,49 @@ protected function setUp()
3638
$this->geocoder = new ProviderAggregator();
3739
}
3840

39-
public function testRegisterProvider()
41+
public function testGeocode()
4042
{
41-
$provider = new MockProvider('test');
42-
$this->geocoder->registerProvider($provider);
43-
44-
$this->assertSame($provider, NSA::invokeMethod($this->geocoder, 'getProvider'));
45-
}
43+
$provider1 = new MockProvider('test1');
44+
$provider1->result = [Address::createFromArray(['providedBy' => 'p1'])];
45+
$provider2 = new MockProvider('test2');
46+
$provider2->result = [Address::createFromArray(['providedBy' => 'p2'])];
4647

47-
public function testRegisterProviders()
48-
{
49-
$provider = new MockProvider('test');
50-
$this->geocoder->registerProviders([$provider]);
48+
$this->geocoder->registerProvider($provider1);
49+
$this->geocoder->registerProvider($provider2);
5150

52-
$this->assertSame($provider, NSA::invokeMethod($this->geocoder, 'getProvider'));
51+
$result = $this->geocoder->geocode('foo');
52+
$this->assertEquals('p1', $result->first()->getProvidedBy());
5353
}
5454

55-
public function testUsing()
55+
public function testReverse()
5656
{
5757
$provider1 = new MockProvider('test1');
58+
$provider1->result = [Address::createFromArray(['providedBy' => 'p1'])];
5859
$provider2 = new MockProvider('test2');
59-
$this->geocoder->registerProviders([$provider1, $provider2]);
60+
$provider2->result = [Address::createFromArray(['providedBy' => 'p2'])];
61+
62+
$this->geocoder->registerProvider($provider1);
63+
$this->geocoder->registerProvider($provider2);
64+
$this->geocoder->using('test2');
6065

61-
$this->assertSame($provider1, NSA::invokeMethod($this->geocoder, 'getProvider'));
66+
$result = $this->geocoder->reverse(0.1, 0.2);
67+
$this->assertEquals('p2', $result->first()->getProvidedBy());
68+
}
6269

63-
$this->geocoder->using('test1');
64-
$this->assertSame($provider1, NSA::invokeMethod($this->geocoder, 'getProvider'));
70+
public function testRegisterProvider()
71+
{
72+
$provider = new MockProvider('test');
73+
$this->geocoder->registerProvider($provider);
6574

66-
$this->geocoder->using('test2');
67-
$this->assertSame($provider2, NSA::invokeMethod($this->geocoder, 'getProvider'));
75+
$this->assertSame(['test' => $provider], NSA::getProperty($this->geocoder, 'providers'));
76+
}
6877

69-
$this->geocoder->using('test1');
70-
$this->assertSame($provider1, NSA::invokeMethod($this->geocoder, 'getProvider'));
78+
public function testRegisterProviders()
79+
{
80+
$provider = new MockProvider('test');
81+
$this->geocoder->registerProviders([$provider]);
82+
83+
$this->assertSame(['test' => $provider], NSA::getProperty($this->geocoder, 'providers'));
7184
}
7285

7386
/**
@@ -109,19 +122,21 @@ public function testGetProviders()
109122
*/
110123
public function testGetProvider()
111124
{
112-
NSA::invokeMethod($this->geocoder, 'getProvider');
125+
NSA::invokeMethod($this->geocoder, 'getProvider', GeocodeQuery::create('foo'), [], null);
113126
$this->fail('getProvider() should throw an exception');
114127
}
115128

116129
public function testGetProviderWithMultipleProvidersReturnsTheFirstOne()
117130
{
118-
$this->geocoder->registerProviders([
131+
$providers = [
119132
$provider1 = new MockProvider('test1'),
120133
$provider2 = new MockProvider('test2'),
121134
$provider3 = new MockProvider('test3'),
122-
]);
135+
];
123136

124-
$this->assertSame($provider1, NSA::invokeMethod($this->geocoder, 'getProvider'));
137+
$query = GeocodeQuery::create('foo');
138+
$this->assertSame($provider1, NSA::invokeMethod($this->geocoder, 'getProvider', $query, $providers, null));
139+
$this->assertSame($provider2, NSA::invokeMethod($this->geocoder, 'getProvider', $query, $providers, $provider2));
125140
}
126141

127142
public function testDefaultMaxResults()
@@ -134,19 +149,21 @@ class MockProvider implements Provider
134149
{
135150
protected $name;
136151

152+
public $result = [];
153+
137154
public function __construct($name)
138155
{
139156
$this->name = $name;
140157
}
141158

142159
public function geocodeQuery(GeocodeQuery $query): Collection
143160
{
144-
return $this->returnResult([]);
161+
return $this->returnResult();
145162
}
146163

147164
public function reverseQuery(ReverseQuery $query): Collection
148165
{
149-
return $this->returnResult([]);
166+
return $this->returnResult();
150167
}
151168

152169
public function getName(): string
@@ -163,7 +180,8 @@ public function limit($limit)
163180
return $this;
164181
}
165182

166-
public function returnResult(array $data = [])
183+
private function returnResult()
167184
{
185+
return new AddressCollection($this->result);
168186
}
169187
}

0 commit comments

Comments
 (0)