Completed
Push — master ( d0dd0d...df62c5 )
by ARCANEDEV
12s
created

GeoIP::find()   C

Complexity

Conditions 7
Paths 17

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 7.0957

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 14
cts 16
cp 0.875
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 15
nc 17
nop 1
crap 7.0957
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\Support\GeoIPLogger;
7
use Arcanedev\GeoIP\Support\IpDetector;
8
use Arcanedev\GeoIP\Support\IpValidator;
9
use Illuminate\Support\Arr;
10
11
/**
12
 * Class     GeoIP
13
 *
14
 * @package  Arcanedev\GeoIP
15
 * @author   ARCANEDEV <[email protected]>
16
 */
17
class GeoIP implements GeoIPContract
18
{
19
    /* ------------------------------------------------------------------------------------------------
20
     |  Properties
21
     | ------------------------------------------------------------------------------------------------
22
     */
23
    /** @var \Arcanedev\GeoIP\Contracts\GeoIPDriver  */
24
    private $driver;
25
26
    /** @var \Arcanedev\GeoIP\Contracts\GeoIPCache  */
27
    private $cache;
28
29
    /** @var array */
30
    protected $config = [];
31
32
    /** @var  \Arcanedev\GeoIP\Location */
33
    protected $location;
34
35
    /** @var array */
36
    protected $defaultLocation = [];
37
38
    /** @var string */
39
    protected $remoteIp;
40
41
    /** @var array */
42
    protected $currencies;
43
44
    /* ------------------------------------------------------------------------------------------------
45
     |  Constructor
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 36
    public function __construct(GeoIPDriver $driver, GeoIPCache $cache, array $config)
56
    {
57 36
        $this->driver = $driver;
58 36
        $this->cache  = $cache;
59 36
        $this->config = $config;
60
61 36
        $this->setDefaultLocation($this->config('location.default', []));
62 36
        $this->remoteIp = $this->defaultLocation['ip'] = IpDetector::detect();
63 36
    }
64
65
    /* ------------------------------------------------------------------------------------------------
66
     |  Getters & Setters
67
     | ------------------------------------------------------------------------------------------------
68
     */
69
    /**
70
     * Get the GeoIP driver instance.
71
     *
72
     * @return \Arcanedev\GeoIP\Contracts\GeoIPDriver
73
     */
74 18
    public function driver()
75
    {
76 18
        return $this->driver;
77
    }
78
79
    /**
80
     * Get cache instance.
81
     *
82
     * @return \Arcanedev\GeoIP\Contracts\GeoIPCache
83
     */
84 18
    public function cache()
85
    {
86 18
        return $this->cache;
87
    }
88
89
    /**
90
     * Get configuration value.
91
     *
92
     * @param  string  $key
93
     * @param  mixed   $default
94
     *
95
     * @return mixed
96
     */
97 36
    private function config($key, $default = null)
98
    {
99 36
        return Arr::get($this->config, $key, $default);
100
    }
101
102
    /**
103
     * Set the default location.
104
     *
105
     * @param  array  $location
106
     *
107
     * @return self
108
     */
109 36
    public function setDefaultLocation(array $location)
110
    {
111 36
        $this->defaultLocation = array_merge($this->defaultLocation, $location);
112
113 36
        return $this;
114
    }
115
116
    /**
117
     * Get the currency code from ISO.
118
     *
119
     * @param  string  $iso
120
     *
121
     * @return string
122
     */
123 12
    public function getCurrency($iso)
124
    {
125 12
        if ($this->currencies === null && $this->config('currencies.included', false)) {
126 12
            $this->currencies = $this->config('currencies.data', []);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->config('currencies.data', array()) of type * is incompatible with the declared type array of property $currencies.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
127 2
        }
128
129 12
        return Arr::get($this->currencies, $iso);
130
    }
131
132
    /* ------------------------------------------------------------------------------------------------
133
     |  Main Functions
134
     | ------------------------------------------------------------------------------------------------
135
     */
136
    /**
137
     * Get the location from the provided IP.
138
     *
139
     * @param  string  $ipAddress
140
     *
141
     * @return \Arcanedev\GeoIP\Location
142
     */
143 12
    public function location($ipAddress = null)
144
    {
145 12
        $this->location = $this->find($ipAddress);
146
147 12
        if ($this->shouldCache($ipAddress, $this->location)) {
148 12
            $this->cache()->set($ipAddress, $this->location->toArray());
149 2
        }
150
151 12
        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 12
    private function find($ip = null)
164
    {
165 12
        if ($this->config('cache.mode', 'none') !== 'none' && $location = $this->cache()->get($ip)) {
166
            $location->setAttribute('cached', true);
167
168
            return $location;
169
        }
170
171 12
        $ip = $ip ?: $this->remoteIp;
172
173 12
        if (IpValidator::validate($ip)) {
174
            try {
175 12
                $location = $this->driver()->locate($ip);
176
177 6
                if (is_null($location->currency)) {
178 6
                    $location->setAttribute('currency', $this->getCurrency($location->iso_code));
179 1
                }
180
181 6
                $location->setAttribute('default', false);
182
183 6
                return $location;
184
            }
185 6
            catch (\Exception $e) {
186 6
                GeoIPLogger::log($e);
187
            }
188 1
        }
189
190 6
        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 12
    private function shouldCache($ipAddress = null, Location $location)
202
    {
203 12
        if ($location->default === true || $location->cached === true)
204 2
            return false;
205
206 12
        switch ($this->config('cache.mode', 'none')) {
207 12
            case 'all':
208 12
                return true;
209
210
            case 'some':
211
                if ($ipAddress === null)
212
                    return true;
213
        }
214
215
        return false;
216
    }
217
}
218