GeoIp::resolveSearch()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Gemz\GeoIp;
4
5
use Gemz\GeoIp\Exceptions\BadRequestException;
6
use Gemz\GeoIp\Exceptions\InvalidArgument;
7
use Gemz\HttpClient\Client;
8
9
class GeoIp
10
{
11
    const LOCALE_DE = 'de';
12
    const LOCALE_EN = 'en';
13
    const LOCALE_FR = 'fr';
14
    const LOCALE_ES = 'es';
15
16
    /** @var string */
17
    protected $search;
18
19
    /** @var string */
20
    protected $locale = 'en';
21
22
    /** @var Client */
23
    protected $client;
24
25
    /** @var string */
26
    protected $baseUrl = 'http://ip-api.com';
27
28
    /** @var array */
29
    protected $fields = [
30
        'status',
31
        'query',
32
        'country',
33
        'countryCode',
34
        'region',
35
        'regionName',
36
        'city',
37
        'zip',
38
        'lat',
39
        'lon',
40
        'timezone',
41
        'isp',
42
        'org',
43
        'as',
44
        'asname',
45
        'proxy',
46
        'reverse',
47
    ];
48
49
    /** @var array */
50
    protected $allowedLocales = [
51
        self::LOCALE_DE,
52
        self::LOCALE_EN,
53
        self::LOCALE_FR,
54
        self::LOCALE_ES
55
    ];
56
57
    public static function for(string $search): self
58
    {
59
        return new self($search);
60
    }
61
62
    public function __construct(string $search)
63
    {
64
        $this->client = Client::create();
65
66
        $this->resolveSearch($search);
67
    }
68
69
    public function locale(string $locale): self
70
    {
71
        if (! in_array($locale, $this->allowedLocales)) {
72
            throw InvalidArgument::localeNotValid($locale);
73
        }
74
75
        $this->locale = $locale;
76
77
        return $this;
78
    }
79
80
    public function baseUrl(string $baseUrl): self
81
    {
82
        $this->baseUrl = $baseUrl;
83
84
        return $this;
85
    }
86
87
    public function get(): array
88
    {
89
        return $this->getResult();
90
    }
91
92
    protected function resolveSearch(string $search): string
93
    {
94
        if (empty($search)) {
95
            throw InvalidArgument::emptyQuery();
96
        }
97
98
        $search = str_replace(['http://', 'https://'], '', $search);
99
        $search = strtolower($search);
100
101
        return $this->search = $search;
102
    }
103
104
    protected function getResult(): array
105
    {
106
        $this->prepareClient();
107
108
        try {
109
            $response = $this->client->get("json/{$this->search}");
110
111
            if (! $response->isOk()) {
112
                throw BadRequestException::requestNotValid($response->body());
113
            }
114
115
            return $response->asArray();
116
        } catch (\Exception $e) {
117
            throw BadRequestException::requestNotValid($e->getMessage());
118
        }
119
    }
120
121
    protected function prepareClient(): void
122
    {
123
        $this->client
124
            ->baseUri($this->baseUrl)
125
            ->doNotVerifySsl()
126
            ->throwErrors()
127
            ->queryParam('lang', $this->locale);
128
129
        if ($this->fields) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->fields of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
130
            $this->client->queryParam('fields', implode(',', $this->fields));
131
        }
132
    }
133
}
134