Completed
Branch master (57012f)
by Mike
04:00
created

ProviderAndDumperAggregator   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 212
Duplicated Lines 12.26 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 97.14%

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 3
dl 26
loc 212
ccs 102
cts 105
cp 0.9714
rs 10
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A all() 0 4 1
A get() 0 4 1
A getName() 0 4 1
A limit() 0 8 1
A getLimit() 0 4 1
A registerProvider() 0 6 1
A registerProviders() 0 6 1
A using() 0 6 1
A getProviders() 0 4 1
A getProvider() 0 4 1
A registerProvidersFromConfig() 0 6 1
A getProvidersFromConfiguration() 0 15 2
A getArguments() 0 16 3
A getAdapterClass() 0 13 2
B dump() 0 26 2
A geocodeQuery() 0 13 1
A reverseQuery() 0 13 1
A geocode() 13 13 1
A reverse() 13 13 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php namespace Geocoder\Laravel;
2
3
/**
4
 * This file is part of the Geocoder Laravel package.
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author Mike Bronner <[email protected]>
9
 * @license    MIT License
10
 */
11
12
use Geocoder\Dumper\GeoJson;
13
use Geocoder\Dumper\Gpx;
14
use Geocoder\Dumper\Kml;
15
use Geocoder\Dumper\Wkb;
16
use Geocoder\Dumper\Wkt;
17
use Geocoder\Geocoder;
18
use Geocoder\Query\GeocodeQuery;
19
use Geocoder\Query\ReverseQuery;
20
use Geocoder\Laravel\Exceptions\InvalidDumperException;
21
use Geocoder\ProviderAggregator;
22
use Illuminate\Support\Collection;
23
use ReflectionClass;
24
25
/**
26
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
27
 */
28
class ProviderAndDumperAggregator
29
{
30
    protected $aggregator;
31
    protected $limit;
32
    protected $results;
33
34 19
    public function __construct()
35
    {
36 19
        $this->aggregator = new ProviderAggregator();
37 19
        $this->results = collect();
38 19
    }
39
40
    /**
41
     * @deprecated Use `get()` instead.
42
     */
43 1
    public function all() : array
44
    {
45 1
        return $this->results->all();
46
    }
47
48 13
    public function get() : Collection
49
    {
50 13
        return $this->results;
51
    }
52
53 2
    public function dump(string $dumper) : Collection
54
    {
55 2
        $dumperClasses = collect([
56 2
            'geojson' => GeoJson::class,
57
            'gpx' => Gpx::class,
58
            'kml' => Kml::class,
59
            'wkb' => Wkb::class,
60
            'wkt' => Wkt::class,
61
        ]);
62
63 2
        if (!$dumperClasses->has($dumper)) {
64 1
            $errorMessage = implode('', [
65 1
                "The dumper specified ('{$dumper}') is invalid. Valid dumpers ",
66 1
                "are: geojson, gpx, kml, wkb, wkt.",
67
            ]);
68 1
            throw new InvalidDumperException($errorMessage);
69
        }
70
71 1
        $dumperClass = $dumperClasses->get($dumper);
72 1
        $dumper = new $dumperClass;
73 1
        $results = collect($this->results->all());
74
75 1
        return $results->map(function ($result) use ($dumper) {
76 1
            return $dumper->dump($result);
77 1
        });
78
    }
79
80 1
    public function geocodeQuery(GeocodeQuery $query) : self
81
    {
82 1
        $cacheKey = serialize($query);
83 1
        $this->results = app('cache')->remember(
84 1
            "geocoder-{$cacheKey}",
85 1
            config('geocoder.cache-duration', 0),
86 1
            function () use ($query) {
87 1
                return collect($this->aggregator->geocodeQuery($query));
88 1
            }
89
        );
90
91 1
        return $this;
92
    }
93
94 1
    public function reverseQuery(ReverseQuery $query) : self
95
    {
96 1
        $cacheKey = serialize($query);
97 1
        $this->results = app('cache')->remember(
98 1
            "geocoder-{$cacheKey}",
99 1
            config('geocoder.cache-duration', 0),
100 1
            function () use ($query) {
101 1
                return collect($this->aggregator->reverseQuery($query));
102 1
            }
103
        );
104
105 1
        return $this;
106
    }
107
108 1
    public function getName() : string
109
    {
110 1
        return $this->aggregator->getName();
111
    }
112
113 12 View Code Duplication
    public function geocode(string $value) : self
114
    {
115 12
        $cacheKey = str_slug(strtolower(urlencode($value)));
116 12
        $this->results = app('cache')->remember(
117 12
            "geocoder-{$cacheKey}",
118 12
            config('geocoder.cache-duration', 0),
119 12
            function () use ($value) {
120 12
                return collect($this->aggregator->geocode($value));
121 12
            }
122
        );
123
124 12
        return $this;
125
    }
126
127 1 View Code Duplication
    public function reverse(float $latitude, float $longitude) : self
128
    {
129 1
        $cacheKey = str_slug(strtolower(urlencode("{$latitude}-{$longitude}")));
130 1
        $this->results = app('cache')->remember(
131 1
            "geocoder-{$cacheKey}",
132 1
            config('geocoder.cache-duration', 0),
133 1
            function () use ($latitude, $longitude) {
134 1
                return collect($this->aggregator->reverse($latitude, $longitude));
135 1
            }
136
        );
137
138 1
        return $this;
139
    }
140
141 1
    public function limit(int $limit) : self
142
    {
143 1
        $this->aggregator = new ProviderAggregator(null, $limit);
144 1
        $this->registerProvidersFromConfig(collect(config('geocoder.providers')));
145 1
        $this->limit = $limit;
146
147 1
        return $this;
148
    }
149
150 1
    public function getLimit() : int
151
    {
152 1
        return $this->limit;
153
    }
154
155 1
    public function registerProvider($provider) : self
156
    {
157 1
        $this->aggregator->registerProvider($provider);
158
159 1
        return $this;
160
    }
161
162 19
    public function registerProviders(array $providers = []) : self
163
    {
164 19
        $this->aggregator->registerProviders($providers);
165
166 19
        return $this;
167
    }
168
169 5
    public function using(string $name) : self
170
    {
171 5
        $this->aggregator = $this->aggregator->using($name);
172
173 5
        return $this;
174
    }
175
176 1
    public function getProviders() : Collection
177
    {
178 1
        return collect($this->aggregator->getProviders());
179
    }
180
181
    protected function getProvider()
182
    {
183
        return $this->aggregator->getProvider();
184
    }
185
186 19
    public function registerProvidersFromConfig(Collection $providers) : self
187
    {
188 19
        $this->registerProviders($this->getProvidersFromConfiguration($providers));
189
190 19
        return $this;
191
    }
192
193
    protected function getProvidersFromConfiguration(Collection $providers) : array
194
    {
195 19
        $providers = $providers->map(function ($arguments, $provider) {
196 19
            $arguments = $this->getArguments($arguments, $provider);
197 19
            $reflection = new ReflectionClass($provider);
198
199 19
            if ($provider === 'Geocoder\Provider\Chain\Chain') {
200 19
                return $reflection->newInstance($arguments);
201
            }
202
203 19
            return $reflection->newInstanceArgs($arguments);
204 19
        });
205
206 19
        return $providers->toArray();
207
    }
208
209 19
    protected function getArguments(array $arguments, string $provider) : array
210
    {
211 19
        if ($provider === 'Geocoder\Provider\Chain\Chain') {
212 19
            return $this->getProvidersFromConfiguration(
213 19
                collect(config('geocoder.providers.Geocoder\Provider\Chain\Chain'))
214
            );
215
        }
216
217 19
        $adapter = $this->getAdapterClass($provider);
218
219 19
        if ($adapter) {
220 19
            array_unshift($arguments, (new $adapter));
221
        }
222
223 19
        return $arguments;
224
    }
225
226 19
    protected function getAdapterClass(string $provider) : string
227
    {
228 19
        $specificAdapters = collect([
229 19
            'Geocoder\Provider\GeoIP2' => 'Geocoder\Adapter\GeoIP2Adapter',
230
            'Geocoder\Provider\MaxMindBinary' => null,
231
        ]);
232
233 19
        if ($specificAdapters->has($provider)) {
234
            return $specificAdapters->get($provider);
235
        }
236
237 19
        return config('geocoder.adapter');
238
    }
239
}
240