GeoModelTrait   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 233
Duplicated Lines 0 %

Test Coverage

Coverage 98.81%

Importance

Changes 0
Metric Value
eloc 93
dl 0
loc 233
ccs 83
cts 84
cp 0.9881
rs 10
c 0
b 0
f 0
wmc 29

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setIpstackUrl() 0 3 1
A setOpencageKey() 0 3 1
A setOpencageUrl() 0 3 1
A isCoord() 0 4 1
A setErrorMessage() 0 3 1
B fetchGeoInfo() 0 43 9
A getGeoInfo() 0 13 1
A getGeoFromIp() 0 6 1
B validateCoord() 0 12 7
A setCoord() 0 6 2
A getAllInfo() 0 3 1
A getZoomLevel() 0 11 3
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 public function isValidIp();
42
    abstract public function validateIp();
43
    abstract public function getInfo();
44
    abstract public function fillInfo($result, $keys);
45
46
    /**
47
     * Sets ipstackurl property.
48
     *
49
     * @param string $url ipstack url.
50
     */
51 27
    public function setIpstackUrl($url)
52
    {
53 27
        $this->ipUrl = $url;
54 27
    }
55
56
    /**
57
     * Sets opencageurl property.
58
     *
59
     * @param string $url opencage url.
60
     */
61 27
    public function setOpencageUrl($url)
62
    {
63 27
        $this->openCageUrl = $url;
64 27
    }
65
66
    /**
67
     * Sets opencagekey property.
68
     *
69
     * @param string $key opencage key.
70
     */
71 27
    public function setOpencageKey($key)
72
    {
73 27
        $this->opencagekey = $key;
74 27
    }
75
76
    /**
77
     * Returns specific fetched key properties.
78
     *
79
     * @return array Geographic data
80
     */
81 18
    public function getGeoInfo()
82
    {
83 18
        return array_merge(
84
            array(
85 18
                'continent_name' => $this->continent_name,
86 18
                'country_name' => $this->country_name,
87 18
                'city' => $this->city,
88 18
                'zip' => $this->zip,
89 18
                'latitude' => str_replace(",", ".", $this->latitude),
90 18
                'longitude' => str_replace(",", ".", $this->longitude),
91 18
                'mapUrl' => "https://www.openstreetmap.org/#map=12/$this->latitude/$this->longitude&layers=H"
92
            ),
93 18
            $this->getZoomLevel()
94
        );
95
    }
96
97
    /**
98
     * Calculates zoom level and radius for the map and returns it.
99
     *
100
     * @return array Array containing zoom level and marker radius.
101
     */
102 18
    public function getZoomLevel()
103
    {
104 18
        $retArray = array();
105 18
        if (!$this->isValidIp()) {
106 6
            $retArray = array("zoomLevel" => "12", "radius" => "600");
107 12
        } elseif ($this->city !== null) {
108 4
            $retArray = array("zoomLevel" => "12", "radius" => "600");
109
        } else {
110 8
            $retArray = array("zoomLevel" => "3", "radius" => "400000");
111
        }
112 18
        return $retArray;
113
    }
114
115
    /**
116
     * Returns geographic info together with IP-info
117
     *
118
     * @return array Ip-info + geographic info
119
     */
120 18
    public function getAllInfo()
121
    {
122 18
        return array_merge($this->getInfo(), $this->getGeoInfo());
123
    }
124
125
    /**
126
     * Validates provided coordinate with regexp.
127
     *
128
     * @param string $subject Coordinate.
129
     *
130
     * @return integer
131
     */
132 6
    public function isCoord($subject)
133
    {
134 6
        $pattern = "/\d+\.\d+[\,\ ]+\d+\.\d+/";
135 6
        return preg_match($pattern, $subject);
136
    }
137
138
    /**
139
     * Fetches geographic information from callUrl module using ip address.
140
     *
141
     * @return array Data array with geographic info.
142
     */
143 12
    public function getGeoFromIp()
144
    {
145 12
        $cUrl = $this->di->get("callurl");
146 12
        $query = ["access_key" => $this->ipstackkey];
147 12
        $url = $this->ipUrl . $this->ipAddress;
148 12
        return $cUrl->fetch($url, $query);
149
    }
150
151
    /**
152
     * Fetches and returns Geographic info from multiple sources.
153
     *
154
     * @return array Geographic data.
155
     */
156 18
    public function fetchGeoInfo()
157
    {
158 18
        $cUrl = $this->di->get("callurl");
159 18
        $this->validateIp();
160 18
        if (!$this->isValidIp() && $this->isCoord($this->ipAddress)) {
161 3
            $this->setCoord();
162 15
        } elseif ($this->isValidIp()) {
163 12
            $apiResult = $this->getGeoFromIp();
164
165 12
            if (!empty($apiResult)) {
166 12
                $this->fillInfo($apiResult, $this->dataList);
167
            } else {
168 12
                $this->setErrorMessage("Ingen positionsdata kunde hämtas utifrån platsnamnet.");
169
            }
170
        } else {
171
            $query = [
172 3
                "key" => $this->opencagekey,
173 3
                "q" => $this->ipAddress,
174 3
                "pretty" => "1",
175 3
                "language" => "sv"
176
            ];
177 3
            $url = $this->openCageUrl;
178 3
            $geocode = $cUrl->fetch($url, $query);
179
180 3
            if (isset($geocode["results"][0])) {
181 2
                $this->latitude = $geocode["results"][0]["geometry"]["lat"];
182 2
                $this->longitude = $geocode["results"][0]["geometry"]["lng"];
183 2
                $nodeType = $geocode["results"][0]["components"]["_type"];
184 2
                if (isset($geocode["results"][0]["components"][$nodeType])) {
185
                    $this->city = $geocode["results"][0]["components"][$nodeType];
186
                }
187 2
                if (isset($geocode["results"][0]["components"]["country"])) {
188 2
                    $this->country_name = $geocode["results"][0]["components"]["country"];
189
                }
190 2
                if (isset($geocode["results"][0]["components"]["postcode"])) {
191 2
                    $this->zip = $geocode["results"][0]["components"]["postcode"];
192
                }
193
            } else {
194 1
                $this->setErrorMessage("Ingen positionsdata kunde hämtas utifrån platsnamnet.");
195
            }
196
        }
197 18
        $this->validateCoord();
198 18
        return $this->getAllInfo();
199
    }
200
201
202
    /**
203
     * Sets the error message provided.
204
     *
205
     * @param string $msg Error message
206
     */
207 10
    public function setErrorMessage($msg)
208
    {
209 10
        $this->errorMsg .= $msg . "\n";
210 10
    }
211
212
    /**
213
     * Checks wether the coordinate is within the map bounds
214
     *
215
     * @return boolean
216
     */
217 18
    public function validateCoord()
218
    {
219 18
        $lat = str_replace(".", ",", $this->latitude);
220 18
        $lon = str_replace(".", ",", $this->longitude);
221 18
        if (!$lat && !$lon) {
222 9
            $this->setErrorMessage("Kunde inte hämta position utifrån den angivna platsen.");
223
        }
224 18
        if ($lat < -85.05112878 || $lat > 85.05112878) {
225 1
            $this->setErrorMessage("Y-koordinaten är utanför maxgränsen.");
226
        }
227 18
        if ($lon < -180 || $lon > 180) {
228 1
            $this->setErrorMessage("X-koordinaten är utanför maxgränsen.");
229
        }
230 18
    }
231
232
    /**
233
     * Turns the provided string into a map coordinate.
234
     *
235
     * @return void
236
     */
237 3
    public function setCoord()
238
    {
239 3
        if ($this->ipAddress) {
240 3
            $latLon = explode(",", $this->ipAddress);
241 3
            $this->latitude = $latLon[0];
242 3
            $this->longitude = $latLon[1];
243
        }
244 3
    }
245
}
246