Passed
Push — master ( 196682...b0fa32 )
by Stephen
02:42
created

PostcodeService::getNearestOutwardCode()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

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