Completed
Push — master ( 43d9ae...dfe893 )
by Stephen
04:40 queued 02:06
created

PostcodeService::autocomplete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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