Completed
Push — master ( 06c7d6...3f9f5f )
by Eric
02:52
created

GeoModelTrait::setIpstackUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Showing off a standard class with methods and properties.
4
 */
5
namespace Erjh17\CallUrlModel;
6
7
/**
8
 * A trait implementing GeoModelTrait.
9
 */
10
trait GeoModelTrait
11
{
12
    // use \Erjh17\CallUrl;
13
    /**
14
     * @var int        $ip  The ip address.
15
     * @var string     $message  The message.
16
     * @var boolean    $valid  If the ip address is valid.
17
     * @var string     $host  The ip adress' host.
18
     */
19
20
    private $continent_name;
21
    private $country_name;
22
    private $city;
23
    private $zip;
24
    private $latitude;
25
    private $ipUrl;
26
    private $longitude;
27
    private $openCageUrl;
28
    private $opencagekey;
29
    public $dataList = [
30
        "continent_name",
31
        "country_name",
32
        "city",
33
        "zip",
34
        "latitude",
35
        "longitude",
36
        "lat",
37
        "lon",
38
        "display_name"
39
    ];
40
41
    abstract function isValidIp();
42
    abstract function getInfo();
43
    abstract function fillInfo($result, $keys);
44
45
    /**
46
     * Sets ipstackurl property.
47
     *
48
     * @param string $url ipstack url.
49
     */
50
    public function setIpstackUrl($url)
51
    {
52
        $this->ipUrl = $url;
53
    }
54
55
    /**
56
     * Sets opencageurl property.
57
     *
58
     * @param string $url opencage url.
59
     */
60
    public function setOpencageUrl($url)
61
    {
62
        $this->openCageUrl = $url;
63
    }
64
65
    /**
66
     * Sets opencagekey property.
67
     *
68
     * @param string $key opencage key.
69
     */
70
    public function setOpencageKey($key)
71
    {
72
        $this->opencagekey = $key;
73
    }
74
75
    /**
76
     * Returns specific fetched key properties.
77
     *
78
     * @return [array] Geographic data
0 ignored issues
show
Documentation Bug introduced by
The doc comment [array] at position 0 could not be parsed: Unknown type name '[' at position 0 in [array].
Loading history...
79
     */
80
    public function getGeoInfo()
81
    {
82
        return array_merge(
83
            array(
84
                'continent_name' => $this->continent_name,
85
                'country_name' => $this->country_name,
86
                'city' => $this->city,
87
                'zip' => $this->zip,
88
                'latitude' => str_replace(",", ".", $this->latitude),
89
                'longitude' => str_replace(",", ".", $this->longitude),
90
                'mapUrl' => "https://www.openstreetmap.org/#map=12/$this->latitude/$this->longitude&layers=H"
91
            ),
92
            $this->getZoomLevel()
93
        );
94
    }
95
96
    /**
97
     * Calculates zoom level and radius for the map and returns it.
98
     *
99
     * @return array Array containing zoom level and marker radius.
100
     */
101
    public function getZoomLevel()
102
    {
103
        $retArray;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $retArray seems to be never defined.
Loading history...
104
        if (!$this->isValidIp()) {
105
            $retArray = array("zoomLevel" => "12", "radius" => "600");
106
        } elseif ($this->city !== null) {
107
            $retArray = array("zoomLevel" => "12", "radius" => "600");
108
        } else {
109
            $retArray = array("zoomLevel" => "3", "radius" => "400000");
110
        }
111
        return $retArray;
112
    }
113
114
    /**
115
     * Returns geographic info together with IP-info
116
     *
117
     * @return array Ip-info + geographic info
118
     */
119
    public function getAllInfo()
120
    {
121
        return array_merge($this->getInfo(), $this->getGeoInfo());
122
    }
123
124
    /**
125
     * Validates provided coordinate with regexp.
126
     *
127
     * @param string $subject Coordinate.
128
     *
129
     * @return integer
130
     */
131
    public function isCoord($subject)
132
    {
133
        $pattern = "/\d+\.\d+[\,\ ]+\d+\.\d+/";
134
        return preg_match($pattern, $subject);
135
    }
136
137
    /**
138
     * Fetches geographic information from callUrl module using ip address.
139
     *
140
     * @return array Data array with geographic info.
141
     */
142
    public function getGeoFromIp()
143
    {
144
        $cUrl = $this->di->get("callurl");
145
        $query = ["access_key" => $this->ipstackkey];
146
        $url = $this->ipUrl . $this->ipAddress;
147
        return $cUrl->fetch($url, $query);
148
    }
149
150
    /**
151
     * Fetches and returns Geographic info from multiple sources.
152
     *
153
     * @return array Geographic data.
154
     */
155
    public function fetchGeoInfo()
156
    {
157
        $cUrl = $this->di->get("callurl");
158
        $this->validateIp();
0 ignored issues
show
Bug introduced by
The method validateIp() does not exist on Erjh17\CallUrlModel\GeoModelTrait. Did you maybe mean validateCoord()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

158
        $this->/** @scrutinizer ignore-call */ 
159
               validateIp();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
159
        if (!$this->isValidIp() && $this->isCoord($this->ipAddress)) {
160
            $this->setCoord();
161
        } elseif ($this->isValidIp()) {
162
            $apiResult = $this->getGeoFromIp();
163
164
            if ($apiResult) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $apiResult of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
165
                $this->fillInfo($apiResult, $this->dataList);
166
            } else {
167
                $this->setErrorMessage("Ingen positionsdata kunde hämtas utifrån platsnamnet.");
168
            }
169
        } else {
170
            $query = [
171
                "key" => $this->opencagekey,
172
                "q" => $this->ipAddress,
173
                "pretty" => "1",
174
                "language" => "sv"
175
            ];
176
            $url = $this->openCageUrl;
177
            $geocode = $cUrl->fetch($url, $query);
178
179
            if (isset($geocode["results"][0])) {
180
                $this->latitude = $geocode["results"][0]["geometry"]["lat"];
181
                $this->longitude = $geocode["results"][0]["geometry"]["lng"];
182
                $nodeType = $geocode["results"][0]["components"]["_type"];
183
                if (isset($geocode["results"][0]["components"][$nodeType])) {
184
                    $this->city = $geocode["results"][0]["components"][$nodeType];
185
                }
186
                if (isset($geocode["results"][0]["components"]["country"])) {
187
                    $this->country_name = $geocode["results"][0]["components"]["country"];
188
                }
189
                if (isset($geocode["results"][0]["components"]["postcode"])) {
190
                    $this->zip = $geocode["results"][0]["components"]["postcode"];
191
                }
192
            } else {
193
                $this->setErrorMessage("Ingen positionsdata kunde hämtas utifrån platsnamnet.");
194
            }
195
        }
196
        $this->validateCoord();
197
        return $this->getAllInfo();
198
    }
199
200
201
    /**
202
     * Sets the error message provided.
203
     *
204
     * @param string $msg Error message
205
     */
206
    public function setErrorMessage($msg)
207
    {
208
        $this->errorMsg .= $msg . "\n";
209
    }
210
211
    /**
212
     * Checks wether the coordinate is within the map bounds
213
     *
214
     * @return boolean
215
     */
216
    public function validateCoord()
217
    {
218
        $lat = str_replace(".", ",", $this->latitude);
219
        $lon = str_replace(".", ",", $this->longitude);
220
        if (!$lat && !$lon) {
221
            $this->setErrorMessage("Kunde inte hämta position utifrån den angivna platsen.");
222
        }
223
        if ($lat < -85.05112878 || $lat > 85.05112878) {
224
            $this->setErrorMessage("Y-koordinaten är utanför maxgränsen.");
225
        }
226
        if ($lon < -180 || $lon > 180) {
227
            $this->setErrorMessage("X-koordinaten är utanför maxgränsen.");
228
        }
229
    }
230
231
    /**
232
     * Turns the provided string into a map coordinate.
233
     *
234
     * @return void
235
     */
236
    public function setCoord()
237
    {
238
        if ($this->ipAddress) {
239
            $latLon = explode(",", $this->ipAddress);
240
            $this->latitude = $latLon[0];
241
            $this->longitude = $latLon[1];
242
        }
243
    }
244
}
245