Test Failed
Push — fix-22 ( b0221b )
by Davide
04:48
created

Ipinfo::jsonDecodeResponse()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
dl 0
loc 14
c 0
b 0
f 0
ccs 6
cts 7
cp 0.8571
rs 9.7998
cc 3
nc 3
nop 1
crap 3.0261
1
<?php
2
3
namespace DavidePastore\Ipinfo;
4
5
use DavidePastore\Ipinfo\Exception\RateLimitExceedException;
6
7
/**
8
 * ipinfo.io service wrapper.
9
 *
10
 * @author davidepastore
11
 */
12
class Ipinfo
13
{
14
    /**
15
     * The base url of the ipinfo service.
16
     *
17
     * @var string
18
     */
19
    const BASE_URL = 'http://ipinfo.io/';
20
21
    /**
22
     * The ip string.
23
     *
24
     * @var string
25
     */
26
    const IP = 'ip';
27
28
    /**
29
     * The hostname string.
30
     *
31
     * @var string
32
     */
33
    const HOSTNAME = 'hostname';
34
35
    /**
36
     * The loc string.
37
     *
38
     * @var string
39
     */
40
    const LOC = 'loc';
41
42
    /**
43
     * The org string.
44
     *
45
     * @var string
46
     */
47
    const ORG = 'org';
48
49
    /**
50
     * The city string.
51
     *
52
     * @var string
53
     */
54
    const CITY = 'city';
55
56
    /**
57
     * The region string.
58
     *
59
     * @var string
60
     */
61
    const REGION = 'region';
62
63
    /**
64
     * The country string.
65
     *
66
     * @var string
67
     */
68
    const COUNTRY = 'country';
69
70
    /**
71
     * The phone string.
72
     *
73
     * @var string
74
     */
75
    const PHONE = 'phone';
76
77
    /**
78
     * The geo string.
79
     *
80
     * @var string
81
     */
82
    const GEO = 'geo';
83
84
    /**
85
     * The postal string.
86
     *
87
     * @var string
88
     */
89
    const POSTAL = 'postal';
90
91
    /**
92
     * All the settings.
93
     *
94
     * @var array
95
     */
96
    protected $settings;
97
98
    /**
99
     * Create an Ipinfo instance.
100
     *
101
     * @param array $settings An array with all the settings.
102
     *                        Supported keys are:
103
     *                        - token: string the developer token;
104
     *                        - debug: boolean active or not the debug.
105
     */
106 9
    public function __construct($settings = array())
107
    {
108
        //Merge user settings
109 9
        $this->settings = array_merge(array(
110 9
                'token' => '',
111
                'debug' => false,
112 9
        ), $settings);
113 9
    }
114
115
    /**
116
     * Get all the info about your own ip address.
117
     *
118
     * @return \DavidePastore\Ipinfo\Host The Host object with all the info.
119
     */
120 1 View Code Duplication
    public function getYourOwnIpDetails()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121
    {
122 1
        $response = $this->makeCurlRequest($this::BASE_URL.'json');
123 1
        $response = $this->jsonDecodeResponse($response);
124
125 1
        return new Host($response);
126
    }
127
128
    /**
129
     * Get all the info about an ip address.
130
     *
131
     * @param string $ipAddress The ip address.
132
     *
133
     * @return \DavidePastore\Ipinfo\Host The Host object with all the info.
134
     */
135 2 View Code Duplication
    public function getFullIpDetails($ipAddress)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
136
    {
137 2
        $response = $this->makeCurlRequest($this::BASE_URL.$ipAddress);
138 2
        $response = $this->jsonDecodeResponse($response);
139
140 2
        return new Host($response);
141
    }
142
143
    /**
144
     * Get a specific field value.
145
     *
146
     * @param string $ipAddress The ip address.
147
     * @param string $field     The field.
148
     *
149
     * @return string|\DavidePastore\Ipinfo\Host The value of the given field for the given ip.
150
     *                                           This could returns an Host object if you call it with for the field
151
     *                                           \DavidePastore\Ipinfo\Ipinfo::GEO.
152
     */
153 5 View Code Duplication
    public function getSpecificField($ipAddress, $field)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
154
    {
155 5
        $response = $this->makeCurlRequest($this::BASE_URL.$ipAddress.'/'.$field);
156 5
        $response = $this->checkGeo($field, $response);
157
158 5
        return $response;
159
    }
160
161
    /**
162
     * Get a specific field value of your own ip address.
163
     *
164
     * @param string $field The field.
165
     *
166
     * @return string|\DavidePastore\Ipinfo\Host The value of the given field for your own ip.
167
     *                                           This could returns an Host object if you call it with for the field
168
     *                                           \DavidePastore\Ipinfo\Ipinfo::GEO.
169
     */
170 1 View Code Duplication
    public function getYourOwnIpSpecificField($field)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
    {
172 1
        $response = $this->makeCurlRequest($this::BASE_URL.$field);
173 1
        $response = $this->checkGeo($field, $response);
174
175 1
        return $response;
176
    }
177
178
    /**
179
     * Use the /geo call to get just the geolocation information, which will often be
180
     * faster than getting the full response.
181
     *
182
     * @param string $ipAddress The ip address.
183
     *
184
     * @return \DavidePastore\Ipinfo\Host
185
     */
186 2
    public function getIpGeoDetails($ipAddress)
187
    {
188 2
        return $this->getSpecificField($ipAddress, $this::GEO);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getSpecificField($ipAddress, $this::GEO); of type string|DavidePastore\Ipinfo\Host adds the type string to the return on line 188 which is incompatible with the return type documented by DavidePastore\Ipinfo\Ipinfo::getIpGeoDetails of type DavidePastore\Ipinfo\Host.
Loading history...
189
    }
190
191
    /**
192
     * Check if the response is GEO and set the parameters accordingly.
193
     *
194
     * @param string $field    The field value.
195
     * @param string $response The response from the server.
196
     *
197
     * @return Ambigous <\DavidePastore\Ipinfo\Host, string> Returns an Host object if the request is
198
     *                  of the GEO type, a string otherwise. If the field value is different from the GEO type, it will
199
     *                  delete the last character ('\n').
200
     */
201 6
    private function checkGeo($field, $response)
202
    {
203 6
        if ($field == $this::GEO) {
204 2
            $response = $this->jsonDecodeResponse($response);
205 2
            $response = new Host($response);
206
        } else {
207 4
            $response = substr($response, 0, -1);
208
        }
209
210 6
        return $response;
211
    }
212
213
    /**
214
     * Make a curl request.
215
     *
216
     * @param string $address The address of the request.
217
     *
218
     * @return string Returns the response from the request.
219
     */
220 9
    private function makeCurlRequest($address)
221
    {
222 9
        $curl = curl_init();
223
224 9
        if (!empty($this->settings['token'])) {
225 1
            $address .= '?token='.$this->settings['token'];
226
        }
227
228 9
        if ($this->settings['debug']) {
229 1
            echo 'Request address: '.$address."\n";
230
        }
231
232 9
        curl_setopt_array($curl, array(
233 9
            CURLOPT_RETURNTRANSFER => 1,
234 9
            CURLOPT_URL => $address,
235
        ));
236
237 9
        $response = curl_exec($curl);
238
239 9
        curl_close($curl);
240
241 9
        return $response;
242
    }
243
244
    /**
245
     * Returns the json decoded associative array.
246
     * @param  string $response Response from the http call.
247
     * @return array           Returns the associative array with the response.
248
     * @throws RateLimitExceedException    If you exceed the rate limit.
249
     */
250 5
    private function jsonDecodeResponse($response)
251
    {
252 5
        if ($response) {
253
            // Check if the response contains an error message
254 4
            if(strpos($response, 'Rate limit exceeded.')) {
255
                throw new RateLimitExceedException("You exceed the rate limit. The complete response is $response");
256
            } else {
257 4
                $response = json_decode($response, true);
258
            }
259
        } else {
260 1
            $response = array();
261
        }
262 5
        return $response;
263
    }
264
}
265