GeoIP::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 7
cts 7
cp 1
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 3
crap 1
1
<?php namespace Arcanedev\GeoIP;
2
3
use Arcanedev\GeoIP\Contracts\GeoIP as GeoIPContract;
4
use Arcanedev\GeoIP\Contracts\GeoIPCache;
5
use Arcanedev\GeoIP\Contracts\GeoIPDriver;
6
use Arcanedev\GeoIP\Entities\Currencies;
7
use Arcanedev\GeoIP\Support\GeoIPLogger;
8
use Arcanedev\GeoIP\Support\IpDetector;
9
use Arcanedev\GeoIP\Support\IpValidator;
10
use Illuminate\Support\Arr;
11
12
/**
13
 * Class     GeoIP
14
 *
15
 * @package  Arcanedev\GeoIP
16
 * @author   ARCANEDEV <[email protected]>
17
 */
18
class GeoIP implements GeoIPContract
19
{
20
    /* -----------------------------------------------------------------
21
     |  Properties
22
     | -----------------------------------------------------------------
23
     */
24
25
    /** @var \Arcanedev\GeoIP\Contracts\GeoIPDriver  */
26
    private $driver;
27
28
    /** @var \Arcanedev\GeoIP\Contracts\GeoIPCache  */
29
    private $cache;
30
31
    /** @var array */
32
    protected $config = [];
33
34
    /** @var  \Arcanedev\GeoIP\Location */
35
    protected $location;
36
37
    /** @var array */
38
    protected $defaultLocation = [];
39
40
    /** @var string */
41
    protected $remoteIp;
42
43
    /* -----------------------------------------------------------------
44
     |  Constructor
45
     | -----------------------------------------------------------------
46
     */
47
48
    /**
49
     * Create a new GeoIP instance.
50
     *
51
     * @param  \Arcanedev\GeoIP\Contracts\GeoIPDriver  $driver
52
     * @param  \Arcanedev\GeoIP\Contracts\GeoIPCache   $cache
53
     * @param  array                                   $config
54
     */
55 18
    public function __construct(GeoIPDriver $driver, GeoIPCache $cache, array $config)
56
    {
57 18
        $this->driver = $driver;
58 18
        $this->cache  = $cache;
59 18
        $this->config = $config;
60
61 18
        $this->setDefaultLocation($this->config('location.default', []));
62 18
        $this->remoteIp = $this->defaultLocation['ip'] = IpDetector::detect();
63 18
    }
64
65
    /* -----------------------------------------------------------------
66
     |  Getters & Setters
67
     | -----------------------------------------------------------------
68
     */
69
70
    /**
71
     * Get the GeoIP driver instance.
72
     *
73
     * @return \Arcanedev\GeoIP\Contracts\GeoIPDriver
74
     */
75 9
    public function driver()
76
    {
77 9
        return $this->driver;
78
    }
79
80
    /**
81
     * Get cache instance.
82
     *
83
     * @return \Arcanedev\GeoIP\Contracts\GeoIPCache
84
     */
85 9
    public function cache()
86
    {
87 9
        return $this->cache;
88
    }
89
90
    /**
91
     * Get configuration value.
92
     *
93
     * @param  string  $key
94
     * @param  mixed   $default
95
     *
96
     * @return mixed
97
     */
98 18
    private function config($key, $default = null)
99
    {
100 18
        return Arr::get($this->config, $key, $default);
101
    }
102
103
    /**
104
     * Set the default location.
105
     *
106
     * @param  array  $location
107
     *
108
     * @return self
109
     */
110 18
    public function setDefaultLocation(array $location)
111
    {
112 18
        $this->defaultLocation = array_merge($this->defaultLocation, $location);
113
114 18
        return $this;
115
    }
116
117
    /**
118
     * Get the currency code from ISO.
119
     *
120
     * @param  string  $iso
121
     *
122
     * @return string
123
     */
124 6
    public function getCurrency($iso)
125
    {
126 6
        return (bool) $this->config('currencies.included', false)
127 6
            ? Currencies::load()->get($iso, $iso)
128 6
            : $iso;
129
    }
130
131
    /* -----------------------------------------------------------------
132
     |  Main Methods
133
     | -----------------------------------------------------------------
134
     */
135
136
    /**
137
     * Get the location from the provided IP.
138
     *
139
     * @param  string  $ipAddress
140
     *
141
     * @return \Arcanedev\GeoIP\Location
142
     */
143 6
    public function location($ipAddress = null)
144
    {
145 6
        $this->location = $this->find($ipAddress);
146
147 6
        if ($this->shouldCache($ipAddress, $this->location)) {
148 6
            $this->cache()->set($ipAddress, $this->location->toArray());
149
        }
150
151 6
        return $this->location;
152
    }
153
154
    /**
155
     * Find location from IP.
156
     *
157
     * @param  string  $ip
158
     *
159
     * @return \Arcanedev\GeoIP\Location
160
     *
161
     * @throws \Exception
162
     */
163 6
    private function find($ip = null)
164
    {
165 6
        if ($this->config('cache.mode', 'none') !== 'none' && $location = $this->cache()->get($ip)) {
166
            $location->setAttribute('cached', true);
167
168
            return $location;
169
        }
170
171 6
        $ip = $ip ?: $this->remoteIp;
172
173 6
        if (IpValidator::validate($ip)) {
174
            try {
175 6
                $location = $this->driver()->locate($ip);
176
177 3
                if (is_null($location->currency)) {
178 3
                    $location->setAttribute('currency', $this->getCurrency($location->iso_code));
179
                }
180
181 3
                $location->setAttribute('default', false);
182
183 3
                return $location;
184
            }
185 3
            catch (\Exception $e) {
186 3
                GeoIPLogger::log($e);
187
            }
188
        }
189
190 3
        return new Location($this->defaultLocation);
191
    }
192
193
    /**
194
     * Determine if the location should be cached.
195
     *
196
     * @param  string|null                $ipAddress
197
     * @param  \Arcanedev\GeoIP\Location  $location
198
     *
199
     * @return bool
200
     */
201 6
    private function shouldCache($ipAddress = null, Location $location)
202
    {
203 6
        if ($location->default === true || $location->cached === true)
204
            return false;
205
206 6
        switch ($this->config('cache.mode', 'none')) {
207 6
            case 'all':
208 6
                return true;
209
210
            case 'some':
211
                if (is_null($ipAddress))
212
                    return true;
213
        }
214
215
        return false;
216
    }
217
}
218