PostcodeService::validate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

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