Issues (5)

src/Drivers/Driver.php (3 issues)

Labels
Severity
1
<?php
2
3
namespace Stevebauman\Location\Drivers;
4
5
use Illuminate\Support\Fluent;
6
use Stevebauman\Location\Position;
7
8
abstract class Driver
9
{
10
    const CURL_MAX_TIME = 2;
11
    const CURL_CONNECT_TIMEOUT = 2;
12
13
    /**
14
     * The fallback driver.
15
     *
16
     * @var Driver
17
     */
18
    protected $fallback;
19
20
    /**
21
     * Append a fallback driver to the end of the chain.
22
     *
23
     * @param Driver $handler
24
     */
25
    public function fallback(Driver $handler)
26
    {
27
        if (is_null($this->fallback)) {
28
            $this->fallback = $handler;
29
        } else {
30
            $this->fallback->fallback($handler);
31
        }
32
    }
33
34
    /**
35
     * Handle the driver request.
36
     *
37
     * @param string $ip
38
     *
39
     * @return Position|bool
40
     */
41
    public function get($ip)
42
    {
43
        $data = $this->process($ip);
44
45
        $position = $this->getNewPosition();
46
47
        // Here we will ensure the locations data we received isn't empty.
48
        // Some IP location providers will return empty JSON. We want
49
        // to avoid this so we can go to a fallback driver.
50
        if ($data instanceof Fluent && $this->fluentDataIsNotEmpty($data)) {
51
            $position = $this->hydrate($position, $data);
52
53
            $position->ip = $ip;
54
            $position->driver = get_class($this);
55
        }
56
57
        if (! $position->isEmpty()) {
58
            return $position;
59
        }
60
61
        return $this->fallback ? $this->fallback->get($ip) : false;
62
    }
63
64
    /**
65
     * Create a new position instance.
66
     *
67
     * @return Position
68
     */
69
    protected function getNewPosition()
70
    {
71
        $position = config('location.position', Position::class);
72
73
        return new $position;
74
    }
75
76
    /**
77
     * Determine if the given fluent data is not empty.
78
     *
79
     * @param Fluent $data
80
     *
81
     * @return bool
82
     */
83
    protected function fluentDataIsNotEmpty(Fluent $data)
84
    {
85
        return ! empty(array_filter($data->getAttributes()));
86
    }
87
88
    /**
89
     * Retrieves content from the given URL using cURL.
90
     *
91
     * @param string $url
92
     *
93
     * @return mixed
94
     */
95
    protected function getUrlContent($url)
96
    {
97
        $session = curl_init();
98
99
        curl_setopt($session, CURLOPT_URL, $url);
0 ignored issues
show
It seems like $session can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

99
        curl_setopt(/** @scrutinizer ignore-type */ $session, CURLOPT_URL, $url);
Loading history...
100
        curl_setopt($session, CURLOPT_RETURNTRANSFER, 1);
101
        curl_setopt($session, CURLOPT_TIMEOUT, static::CURL_MAX_TIME);
102
        curl_setopt($session, CURLOPT_CONNECTTIMEOUT, static::CURL_CONNECT_TIMEOUT);
103
104
        $content = curl_exec($session);
0 ignored issues
show
It seems like $session can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

104
        $content = curl_exec(/** @scrutinizer ignore-type */ $session);
Loading history...
105
106
        curl_close($session);
0 ignored issues
show
It seems like $session can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

106
        curl_close(/** @scrutinizer ignore-type */ $session);
Loading history...
107
108
        return $content;
109
    }
110
111
    /**
112
     * Returns the URL to use for querying the current driver.
113
     *
114
     * @param string $ip
115
     *
116
     * @return string
117
     */
118
    abstract protected function url($ip);
119
120
    /**
121
     * Hydrates the Position object with the given location data.
122
     *
123
     * @param Position $position
124
     * @param Fluent   $location
125
     *
126
     * @return \Stevebauman\Location\Position
127
     */
128
    abstract protected function hydrate(Position $position, Fluent $location);
129
130
    /**
131
     * Process the specified driver.
132
     *
133
     * @param string $ip
134
     *
135
     * @return Fluent|bool
136
     */
137
    abstract protected function process($ip);
138
}
139