WeatherFactory::__construct()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 3
eloc 7
c 2
b 1
f 0
nc 2
nop 0
dl 0
loc 14
rs 10
1
<?php
2
3
namespace Rawaby88\OpenWeatherMap;
4
5
use GuzzleHttp\Exception\ClientException;
6
use Rawaby88\OpenWeatherMap\Clients\WeatherClient;
7
use Rawaby88\OpenWeatherMap\Exception\NotFoundException;
8
9
/**
10
 * Class WeatherFactory.
11
 */
12
abstract class WeatherFactory
13
{
14
    /**
15
     * @var \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
16
     * Description language
17
     */
18
    private $language;
19
20
    /**
21
     * @var \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
22
     * Unit type standard | metric | imperial
23
     */
24
    private $unitType;
25
26
    /**
27
     * @var mixed|WeatherClient
28
     */
29
    private $client;
30
31
    /**
32
     * @var string Temperature unit Kelvin | Celsius | Fahrenheit.
33
     */
34
    public $tempUnit;
35
36
    /**
37
     * @var string Distance unit meter/sec | miles/hour.
38
     */
39
    public $distUnit;
40
41
    /**
42
     * @var string Precipitation and snow Volume unit mm.
43
     */
44
    public $volUnit = 'mm';
45
46
    /**
47
     * @var string Pressure unit hPa.
48
     */
49
    public $presUnit = 'hPa';
50
51
    /**
52
     * WeatherFactory constructor.
53
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
54
     */
55
    public function __construct()
56
    {
57
        $apiKey = config('open-weather.api_token');
58
59
        if (! is_string($apiKey) || empty($apiKey)) {
60
            throw new \InvalidArgumentException('You must provide valid API key.');
61
        }
62
63
        $this->client = app()->make(WeatherClient::class);
64
65
        $this->unitType = config('open-weather.unit');
66
        $this->language = config('open-weather.language');
67
68
        $this->setUnitsFormat();
69
    }
70
71
    /**
72
     * Set the correct values for distance unit and temperature unit.
73
     */
74
    public function setUnitsFormat(): void
75
    {
76
        switch ($this->unitType) {
77
            case 'metric':
78
                $this->tempUnit = 'Celsius';
79
                $this->distUnit = 'meter/sec';
80
                break;
81
            case 'imperial':
82
                $this->tempUnit = 'Fahrenheit';
83
                $this->distUnit = 'miles/hour';
84
                break;
85
            default:
86
                $this->tempUnit = 'Kelvin';
87
                $this->distUnit = 'meter/sec';
88
        }
89
    }
90
91
    /**
92
     * @param \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed $unitType
93
     */
94
    public function setUnitType($unitType): void
95
    {
96
        $this->unitType = $unitType;
97
    }
98
99
    /**
100
     * @param \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed $language
101
     */
102
    public function setLanguage($language): void
103
    {
104
        $this->language = $language;
105
    }
106
107
    /**
108
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
109
     */
110
    public function getLanguage()
111
    {
112
        return $this->language;
113
    }
114
115
    /**
116
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
117
     */
118
    public function getUnitType()
119
    {
120
        return $this->unitType;
121
    }
122
123
    /**
124
     * @param $apiCall
125
     * @param array $queryData
126
     * @throws NotFoundException
127
     * @throws \GuzzleHttp\Exception\GuzzleException
128
     * @throws \Exception
129
     */
130
    protected function queryOrFail($apiCall, array $queryData = []): object
131
    {
132
        $query = [
133
            'query' => [
134
                'lang'  => $this->language,
135
                'units' => $this->unitType,
136
                'appid' => config('open-weather.api_token'),
137
            ],
138
        ];
139
140
        foreach ($queryData as $key => $value) {
141
            $query['query'][$key] = $value;
142
        }
143
        try {
144
            $response = $this->client->get($apiCall, $query);
145
146
            return json_decode((string) $response->getBody());
147
        } catch (ClientException $exception) {
148
            $responseBodyAsString = json_decode(
149
                $exception->getResponse()
150
                          ->getBody()
151
                          ->getContents()
152
            );
153
            if ($responseBodyAsString->cod == 404 || $responseBodyAsString->cod == 400) {
154
                throw new NotFoundException($responseBodyAsString->message.' '.$exception->getMessage());
155
            } else {
156
                throw new \Exception($exception->getMessage());
157
            }
158
        }
159
    }
160
}
161