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

GeoIP::cache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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