Completed
Push — master ( 02cef1...375238 )
by ARCANEDEV
12s
created

DistanceMatrixService::setMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php namespace Arcanedev\GeoLocation\Google\DistanceMatrix;
2
3
use Arcanedev\GeoLocation\Contracts\Entities\Position;
4
use GuzzleHttp\ClientInterface;
5
use InvalidArgumentException;
6
7
/**
8
 * Class     DistanceMatrixService
9
 *
10
 * @package  Arcanedev\GeoLocation\Google\DistanceMatrix
11
 * @author   ARCANEDEV <[email protected]>
12
 *
13
 * @link     https://developers.google.com/maps/documentation/distance-matrix/intro
14
 */
15
class DistanceMatrixService
16
{
17
    /* -----------------------------------------------------------------
18
     |  Constants
19
     | -----------------------------------------------------------------
20
     */
21
22
    const BASE_URL = 'https://maps.googleapis.com/maps/api/distancematrix/json';
23
24
    /* -----------------------------------------------------------------
25
     |  Properties
26
     | -----------------------------------------------------------------
27
     */
28
29
    /** @var  \GuzzleHttp\ClientInterface */
30
    protected $client;
31
32
    /** @var string|null */
33
    protected $key = null;
34
35
    /** @var string */
36
    protected $language = 'en';
37
38
    /** @var string */
39
    protected $mode = 'driving';
40
41
    /** @var string */
42
    protected $units = 'metric';
43
44
    /* -----------------------------------------------------------------
45
     |  Constructor
46
     | -----------------------------------------------------------------
47
     */
48
49
    /**
50
     * GoogleDistanceMatrix constructor.
51
     *
52
     * @param  \GuzzleHttp\ClientInterface  $client
53
     */
54 21
    public function __construct(ClientInterface $client)
55
    {
56 21
        $this->setHttpClient($client);
57 21
        $this->setKey(getenv('GOOGLE_MAPS_DISTANCE_MATRIX_KEY'));
58 21
    }
59
60
    /* -----------------------------------------------------------------
61
     |  Getters & Setters
62
     | -----------------------------------------------------------------
63
     */
64
65
    /**
66
     * Set the HTTP Client.
67
     *
68
     * @param  \GuzzleHttp\ClientInterface  $client
69
     *
70
     * @return self
71
     */
72 21
    public function setHttpClient(ClientInterface $client)
73
    {
74 21
        $this->client = $client;
75
76 21
        return $this;
77
    }
78
79
    /**
80
     * Set the API Key.
81
     *
82
     * @param  string  $key
83
     *
84
     * @return self
85
     */
86 21
    public function setKey($key)
87
    {
88 21
        $this->key = $key;
89
90 21
        return $this;
91
    }
92
93
    /**
94
     * Set the language.
95
     *
96
     * @param  string  $language
97
     *
98
     * @return self
99
     */
100 3
    public function setLanguage($language)
101
    {
102 3
        $this->language = $language;
103
104 3
        return $this;
105
    }
106
107
    /**
108
     * Set the mode of transport.
109
     *
110
     * @param  string  $mode
111
     *
112
     * @return self
113
     */
114 6
    public function setMode($mode)
115
    {
116 6
        $this->mode = $this->checkMode($mode);
117
118 3
        return $this;
119
    }
120
121
    /**
122
     * Set the unit system.
123
     *
124
     * @param  string  $units
125
     *
126
     * @return self
127
     */
128 6
    public function setUnits($units)
129
    {
130 6
        $this->units = $this->checkUnits($units);
131
132 3
        return $this;
133
    }
134
135
    /* -----------------------------------------------------------------
136
     |  Main Methods
137
     | -----------------------------------------------------------------
138
     */
139
140
    /**
141
     * Calculate the distance.
142
     *
143
     * @param  \Arcanedev\GeoLocation\Contracts\Entities\Position  $start
144
     * @param  \Arcanedev\GeoLocation\Contracts\Entities\Position  $end
145
     * @param  array                                               $options
146
     *
147
     * @return \Arcanedev\GeoLocation\Google\DistanceMatrix\DistanceMatrixResponse
148
     */
149 12
    public function calculate(Position $start, Position $end, array $options = [])
150
    {
151
        // https://developers.google.com/maps/documentation/distance-matrix/intro
152
153 12
        $url = static::BASE_URL.'?'.$this->prepareQuery($start, $end);
154
155 12
        $result = $this->client->request('GET', $url, $options);
156
157 12
        return new DistanceMatrixResponse(
158 12
            json_decode($result->getBody(), true)
159 4
        );
160
    }
161
162
    /**
163
     * Prepare the URL query.
164
     *
165
     * @param  \Arcanedev\GeoLocation\Contracts\Entities\Position  $start
166
     * @param  \Arcanedev\GeoLocation\Contracts\Entities\Position  $end
167
     *
168
     * @return string
169
     */
170 12
    private function prepareQuery(Position $start, Position $end)
171
    {
172 12
        $queryData = array_filter([
173 12
            'origins'      => $this->parsePosition($start),
174 12
            'destinations' => $this->parsePosition($end),
175 12
            'mode'         => $this->mode,
176 12
            'language'     => $this->language,
177 12
            'units'        => $this->units,
178 12
            'key'          => $this->key,
179 4
        ]);
180
181 12
        return urldecode(http_build_query($queryData));
182
    }
183
184
    /**
185
     * Parse the position object.
186
     *
187
     * @param  \Arcanedev\GeoLocation\Contracts\Entities\Position  $position
188
     *
189
     * @return string
190
     */
191 12
    private function parsePosition(Position $position)
192
    {
193 12
        return $position->lat()->value().','.$position->long()->value();
194
    }
195
196
    /* -----------------------------------------------------------------
197
     |  Other Methods
198
     | -----------------------------------------------------------------
199
     */
200
201
    /**
202
     * Check the mode of transport.
203
     *
204
     * @param  string  $mode
205
     *
206
     * @return string
207
     */
208 6
    private function checkMode($mode)
209
    {
210 6
        $mode = strtolower($mode);
211
212 6
        if ( ! in_array($mode, ['driving', 'walking', 'bicycling', 'transit'])) {
213 3
            throw new InvalidArgumentException(
214 3
                "The given mode of transport [{$mode}] is invalid. Please check the supported travel modes: ".
215 2
                "https://developers.google.com/maps/documentation/distance-matrix/intro#travel_modes"
216 1
            );
217
        }
218
219 3
        return $mode;
220
    }
221
222
    /**
223
     * Check the unit system.
224
     *
225
     * @param  string  $units
226
     *
227
     * @return string
228
     */
229 6
    private function checkUnits($units)
230
    {
231 6
        $units = strtolower($units);
232
233 6
        if ( ! in_array($units, ['metric', 'imperial'])) {
234 3
            throw new InvalidArgumentException(
235 3
                "The given unit system [{$units}] is invalid. Please check the supported units: ".
236 2
                "https://developers.google.com/maps/documentation/distance-matrix/intro#unit_systems"
237 1
            );
238
        }
239
240 3
        return $units;
241
    }
242
}
243