Passed
Push — master ( f209fe...f1a18e )
by Frank
01:53
created

Client::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * This file is part of the package neoblack/free-at-home-api.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE file that was distributed with this source code.
9
 */
10
11
namespace NeoBlack\FreeAtHomeApi;
12
13
use GuzzleHttp\ClientInterface;
14
use GuzzleHttp\Exception\ClientException;
15
use GuzzleHttp\Exception\ServerException;
16
use NeoBlack\FreeAtHomeApi\Entity\Credentials;
17
use NeoBlack\FreeAtHomeApi\Entity\Route;
18
use NeoBlack\FreeAtHomeApi\Exception\InvalidEndpointException;
19
use NeoBlack\FreeAtHomeApi\Exception\MissingCredentialsException;
20
use NeoBlack\FreeAtHomeApi\Exception\MissingEndpointException;
21
use NeoBlack\FreeAtHomeApi\Service\Router;
22
23
class Client
24
{
25
    /**
26
     * @var string
27
     */
28
    protected $endpoint;
29
30
    /**
31
     * @var Credentials
32
     */
33
    protected $credentials;
34
35
    /**
36
     * @var \GuzzleHttp\Client
37
     */
38
    protected $client;
39 13
40
    public function __construct(ClientInterface $client = null)
41 13
    {
42 3
        $this->client = $client;
43
    }
44 10
45 10
    public function withEndpoint(string $endpoint): self
46
    {
47
        /** @noinspection BypassedUrlValidationInspection */
48 1
        if (!filter_var($endpoint, FILTER_VALIDATE_URL)) {
49
            throw new InvalidEndpointException('the endpoint has an invalid format', 1536354983);
50 1
        }
51 1
        $this->endpoint = $endpoint;
52
        return $this;
53
    }
54 3
55
    public function withCredentials(string $username, string $password): self
56 3
    {
57 1
        $this->credentials = new Credentials($username, $password);
58
        return $this;
59 2
    }
60 1
61
    public function getClient(): self
62 1
    {
63 1
        if ($this->endpoint === null) {
64
            throw new MissingEndpointException('no endpoint is set, call withEndpoint() before getClient()', 1536354535);
65 1
        }
66
        if ($this->credentials === null) {
67
            throw new MissingCredentialsException('no credentials is set, call withCredentials() before getClient()', 1536354568);
68
        }
69
        if ($this->client === null) {
70
            $this->client = new \GuzzleHttp\Client([
71
                'base_uri' => $this->endpoint,
72
            ]);
73
        }
74
        return $this;
75
    }
76
77
    /**
78
     * @return array
79
     * @throws \GuzzleHttp\Exception\GuzzleException
80
     */
81
    public function getDevices(): array
82
    {
83
        return $this->callApi((new Router())->get(Router::DEVICES_GET));
84
    }
85
86
    /**
87
     * @param string $id
88
     * @return array
89
     * @throws \GuzzleHttp\Exception\GuzzleException
90
     */
91
    public function getDevice(string $id): array
92
    {
93
        return $this->callApi((new Router())->get(Router::DEVICE_GET, ['id' => $id]));
94
    }
95
96
    /**
97
     * @param string $id
98
     * @param array $data
99
     * @return array
100
     * @throws \GuzzleHttp\Exception\GuzzleException
101
     */
102
    public function updateDevice(string $id, array $data): array
103
    {
104
        return $this->callApi((new Router())->get(Router::DEVICE_UPDATE, ['id' => $id]), $data);
105
    }
106
107
    /**
108
     * @param string $id
109
     * @return array
110
     * @throws \GuzzleHttp\Exception\GuzzleException
111
     */
112
    public function deleteDevice(string $id): array
113
    {
114
        return $this->callApi((new Router())->get(Router::DEVICE_DELETE, ['id' => $id]));
115
    }
116
117
    /**
118
     * @param Route $route
119
     * @param array $data
120
     * @return array
121
     * @throws \GuzzleHttp\Exception\GuzzleException
122
     */
123
    private function callApi(Route $route, array $data = []): array
124
    {
125
        $options = [
126
            'headers' => [],
127
        ];
128
        if (!empty($data)) {
129
            $options['body'] = json_encode($data);
130
        }
131
        try {
132
            $response = $this->client->request($route->getMethod(), $route->getPath(), $options);
133
        } catch (ClientException | ServerException $exception) {
134
            // 400-level & 500-level errors
135
            $response = $exception->getResponse();
136
        }
137
        return json_decode($response->getBody()->getContents(), true);
138
    }
139
}
140