Completed
Pull Request — master (#33)
by
unknown
03:07 queued 46s
created

PostcodeService   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 259
Duplicated Lines 0 %

Test Coverage

Coverage 93.1%

Importance

Changes 8
Bugs 0 Features 1
Metric Value
eloc 44
c 8
b 0
f 1
dl 0
loc 259
ccs 54
cts 58
cp 0.931
rs 10
wmc 20

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A validate() 0 3 1
A validateOutcode() 0 6 2
A getNearestOutwardCode() 0 10 3
A getPostcodes() 0 12 2
A nearest() 0 3 1
A getResponse() 0 19 2
A query() 0 5 1
A autocomplete() 0 3 1
A getOutwardCode() 0 3 1
A nearestPostcodesForGivenLngAndLat() 0 6 1
A nearestOutwardCodesForGivenLngAndLat() 0 6 1
A getPostcode() 0 3 1
A getRandomPostcode() 0 3 1
A getTerminatedPostcode() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JustSteveKing\LaravelPostcodes\Service;
6
7
use GuzzleHttp\Client;
8
use Illuminate\Support\Collection;
9
use function GuzzleHttp\Psr7\build_query;
10
11
class PostcodeService
12
{
13
    /**
14
     * @var string
15
     */
16
    protected $url;
17
18
    /**
19
     * @var Client
20
     */
21
    protected $http;
22
23
    /**
24
     * Postcode Service constructor.
25
     *
26
     * @param Client $client
27
     *
28
     * @return void
29
     */
30 60
    public function __construct(Client $client)
31
    {
32 60
        $this->url = config('services.postcodes.url');
33
34 60
        $this->http = $client;
35 60
    }
36
37
    /**
38
     * Validate a postcode against the API
39
     *
40
     * @param string $postcode
41
     *
42
     * @return bool
43
     */
44 9
    public function validate(string $postcode): bool
45
    {
46 9
        return $this->getResponse("postcodes/$postcode/validate");
47
    }
48
    
49
    /**
50
     * Validate a Outcode against the RegEx
51
     *
52
     * @param string $postcode
53
     *
54
     * @return bool
55
     */
56
    public function validateOutcode(string $postcode): bool
57
    {
58
      if (preg_match('#^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]))#', $postcode)) {
59
        return TRUE;
60
      }
61
      return FALSE;
62
    }
63
64
    /**
65
     * Get the address details from a postcode
66
     *
67
     * @param string $postcode
68
     *
69
     * @return object
70
     */
71 3
    public function getPostcode(string $postcode): object
72
    {
73 3
        return $this->getResponse("postcodes/$postcode");
74
    }
75
76
    /**
77
     * Get the address details from a multiple postcodes at once
78
     *
79
     * @param array $postcodes
80
     *
81
     * @param array $filter - optional array of fields to return
82
     * @return Collection
83
     *
84
     * @throws \GuzzleHttp\Exception\GuzzleException
85
     */
86 3
    public function getPostcodes(array $postcodes, array $filter = []): Collection
87
    {
88 3
        if (!empty($filter)) {
89 3
            $filter = build_query(['filter' => implode(',', $filter)]);
90
        }
91
92 3
        return collect($this->getResponse(
93 3
            'postcodes?' . $filter,
94 3
            'POST',
95 3
            ['postcodes' => array_values($postcodes)]
96
        ))->map(function ($item) {
97 3
            return $item->result;
98 3
        });
99
    }
100
101
    /**
102
     * Get information based on outward code including geo data
103
     *
104
     * @param string $outwardcode
105
     *
106
     * @return object
107
     */
108 3
    public function getOutwardCode(string $outwardcode): object
109
    {
110 3
        return $this->getResponse("outcodes/$outwardcode");
111
    }
112
113
    /**
114
     * Get the address details from a random postcode
115
     *
116
     * @return object
117
     */
118 3
    public function getRandomPostcode()
119
    {
120 3
        return $this->getResponse("random/postcodes");
121
    }
122
123
    /**
124
     * Query the API for a given string
125
     *
126
     * @param string $query
127
     *
128
     * @return Collection
129
     *
130
     * @throws \GuzzleHttp\Exception\GuzzleException
131
     */
132 3
    public function query(string $query): Collection
133
    {
134 3
        $queryString = http_build_query(['q' => $query]);
135
136 3
        return collect($this->getResponse("postcodes?$queryString"));
137
    }
138
139
    /**
140
     * Get data for the postcodes nearest to the passed postcode
141
     *
142
     * @param string $postcode
143
     *
144
     * @return Collection
145
     *
146
     * @throws \GuzzleHttp\Exception\GuzzleException
147
     */
148 3
    public function nearest(string $postcode): Collection
149
    {
150 3
        return collect($this->getResponse("postcodes/$postcode/nearest"));
151
    }
152
153
    /**
154
     * Lookup a terminated postcode. Returns the postcode, year and month of termination.
155
     *
156
     * @param string $postcode
157
     *
158
     * @return object
159
     */
160 3
    public function getTerminatedPostcode($postcode)
161
    {
162 3
        return $this->getResponse("terminated_postcodes/$postcode");
163
    }
164
165
    /**
166
     * Autocomplete a postcode partial.
167
     *
168
     * @param string $partialPostcode
169
     *
170
     * @return Collection
171
     *
172
     * @throws \GuzzleHttp\Exception\GuzzleException
173
     */
174 6
    public function autocomplete(string $partialPostcode): Collection
175
    {
176 6
        return collect($this->getResponse("postcodes/$partialPostcode/autocomplete"));
177
    }
178
179
    /**
180
     * Get nearest outward codes for a given longitude & latitude
181
     *
182
     * @param float $longitude
183
     *
184
     * @param float $latitude
185
     * @return Collection
186
     *
187
     * @throws \GuzzleHttp\Exception\GuzzleException
188
     */
189 6
    public function nearestOutwardCodesForGivenLngAndLat(float $longitude, float $latitude): Collection
190
    {
191 6
        return collect($this->getResponse(sprintf(
192 6
            'outcodes?lon=%s&lat=%s',
193 4
            $longitude,
194 4
            $latitude
195
        )));
196
    }
197
198
    /**
199
     * Get information about nearest outcodes based on outward code
200
     *
201
     * @param string $outwardcode
202
     *
203
     * @param int $limit Needs to be less than 100
204
     * @param int $radius Needs to be less than 25,000m
205
     * @return Collection
206
     *
207
     * @throws \GuzzleHttp\Exception\GuzzleException
208
     */
209 3
    public function getNearestOutwardCode(
210
        string $outwardcode,
211
        int $limit = 10,
212
        int $radius = 5000
213
    ): Collection {
214 3
        $limit = ($limit > 100) ? 100 : $limit;
215 3
        $radius = ($radius > 100) ? 25000 : $radius;
216
217 3
        return collect($this->getResponse(
218 3
            "outcodes/$outwardcode/nearest?limit=$limit&radius=$radius"
219
        ));
220
    }
221
222
    /**
223
     * Get nearest postcodes for a given longitude & latitude
224
     *
225
     * @param float $longitude
226
     * @param float $latitude
227
     *
228
     * @return Collection
229
     *
230
     * @throws \GuzzleHttp\Exception\GuzzleException
231
     */
232 6
    public function nearestPostcodesForGivenLngAndLat(float $longitude, float $latitude): Collection
233
    {
234 6
        return collect($this->getResponse(sprintf(
235 6
            'postcodes?lon=%s&lat=%s',
236 4
            $longitude,
237 4
            $latitude
238
        )));
239
    }
240
241
    /**
242
     * Get the response and return the result object
243
     *
244
     * @param string|null $uri
245
     * @param string $method
246
     * @param array $data - data to be sent in post/patch/put request
247
     * @param array $options - array of options to be passed to curl, if $data is passed 'json' will be overwritten
248
     * @return mixed
249
     * @throws \GuzzleHttp\Exception\GuzzleException
250
     */
251 51
    protected function getResponse(
252
        string $uri = null,
253
        string $method = 'GET',
254
        array $data = [],
255
        array $options = []
256
    ) {
257 51
        $url = $this->url . $uri;
258
259 51
        if (!empty($data)) {
260 3
            $options['json'] = $data;
261
        }
262
263 51
        $request = $this->http->request(
264 51
            $method,
265 34
            $url,
266 34
            $options
267
        );
268
269 51
        return json_decode($request->getBody()->getContents())->result;
270
    }
271
}
272