Completed
Push — develop ( 66130e...e39ec3 )
by Adam
14:00
created

Builder::withPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace IBM\Watson\Common\HttpClient;
6
7
use DateTime;
8
use Http\Client\Common\Plugin;
9
use Http\Client\Common\Plugin\AuthenticationPlugin;
10
use Http\Client\Common\PluginClient;
11
use Http\Client\HttpClient;
12
use Http\Message\Authentication\BasicAuth;
13
use Http\Message\UriFactory;
14
use IBM\Watson\Common\Exception\Api\InvalidArgumentException;
15
use IBM\Watson\Common\Util\DiscoveryTrait;
16
use Psr\Http\Message\UriInterface;
17
18
/**
19
 * HttpClient builder
20
 */
21
final class Builder
22
{
23
    use DiscoveryTrait;
24
25
    /**
26
     * @var \Http\Client\HttpClient|null
27
     */
28
    private $httpClient;
29
30
    /**
31
     * @var \Http\Message\UriFactory|null
32
     */
33
    private $uriFactory;
34
35
    /**
36
     * @var array
37
     */
38
    private $plugins = [];
39
40
    /**
41
     * @var string
42
     */
43
    private $username;
44
45
    /**
46
     * @var string
47
     */
48
    private $password;
49
50
    /**
51
     * @var string
52
     */
53
    private $host;
54
55
    /**
56
     * @var string
57
     */
58
    private $path;
59
60
    /**
61
     * @var string
62
     */
63
    private $version;
64
65
    /**
66
     * @param \Http\Client\HttpClient|null  $httpClient
67
     * @param \Http\Message\UriFactory|null $uriFactory
68
     */
69
    public function __construct(
70
        HttpClient $httpClient = null,
71
        UriFactory $uriFactory = null
72
    ) {
73
        $this->httpClient = $httpClient ?: $this->discoverHttpClient();
74
        $this->uriFactory = $uriFactory ?: $this->discoverUriFactory();
75
    }
76
77
    /**
78
     * Create a configured HTTP client
79
     *
80
     * @return \Http\Client\Common\PluginClient
81
     * @throws \Exception
82
     */
83
    public function createConfiguredClient(): PluginClient
84
    {
85
        $this->addHostPlugin();
86
        $this->addPathPlugin();
87
        $this->addVersionQueryPlugin();
88
        $this->addAuthenticationPlugin();
89
90
        return new PluginClient($this->httpClient, $this->plugins);
0 ignored issues
show
Bug introduced by
It seems like $this->httpClient can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
91
    }
92
93
    /**
94
     * Add username to client
95
     *
96
     * @param string $username
97
     *
98
     * @return $this
99
     */
100
    public function withUsername(string $username): self
101
    {
102
        $this->username = $username;
103
104
        return $this;
105
    }
106
107
    /**
108
     * Add password to client
109
     *
110
     * @param string $password
111
     *
112
     * @return $this
113
     */
114
    public function withPassword(string $password): self
115
    {
116
        $this->password = $password;
117
118
        return $this;
119
    }
120
121
    /**
122
     * Add username and password to client
123
     *
124
     * @param string $username
125
     * @param string $password
126
     *
127
     * @return \IBM\Watson\Common\HttpClient\Builder
128
     */
129
    public function withCredentials(string $username, string $password): self
130
    {
131
        return $this
132
            ->withUsername($username)
133
            ->withPassword($password);
134
    }
135
136
    /**
137
     * @param string $host
138
     *
139
     * @return $this
140
     */
141
    public function withHost(string $host): self
142
    {
143
        $this->host = $host;
144
145
        return $this;
146
    }
147
148
    /**
149
     * @param string $version
150
     *
151
     * @return $this
152
     */
153
    public function withVersion($version): self
154
    {
155
        $this->version = $version;
156
157
        return $this;
158
    }
159
160
    /**
161
     * @param string $path
162
     *
163
     * @return $this
164
     */
165
    public function withPath(string $path): self
166
    {
167
        $this->path = $path;
168
169
        return $this;
170
    }
171
172
    /**
173
     * @param \Http\Client\Common\Plugin ...$plugins
174
     *
175
     * @return $this
176
     */
177
    public function addPlugin(Plugin ...$plugins): self
178
    {
179
        foreach ($plugins as $plugin) {
180
            $this->plugins[] = $plugin;
181
        }
182
183
        return $this;
184
    }
185
186
    /**
187
     * @return \Psr\Http\Message\UriInterface
188
     */
189
    private function getHostUri(): UriInterface
190
    {
191
        return $this->uriFactory->createUri($this->host);
192
    }
193
194
    /**
195
     * @param string $version
196
     *
197
     * @return boolean
198
     */
199
    private function validateVersion($version): bool
200
    {
201
        $date = DateTime::createFromFormat('Y-m-d', $version);
202
203
        return $date && $date->format('Y-m-d') === $version;
204
    }
205
206
    /**
207
     * @return $this
208
     */
209
    private function addHostPlugin(): self
210
    {
211
        if (null !== $this->host) {
212
            $this->plugins[] = new Plugin\AddHostPlugin($this->getHostUri());
213
        }
214
215
        return $this;
216
    }
217
218
    /**
219
     * @return $this
220
     */
221
    private function addAuthenticationPlugin(): self
222
    {
223
        if (null !== $this->username && null !== $this->password) {
224
            $this->plugins[] = new AuthenticationPlugin(new BasicAuth($this->username, $this->password));
225
        }
226
227
        return $this;
228
    }
229
230
    /**
231
     * @return $this
232
     *
233
     * @throws InvalidArgumentException
234
     */
235
    private function addVersionQueryPlugin(): self
236
    {
237
        if (null === $this->version) {
238
            $this->version = date('Y-m-d');
239
        }
240
241
        if (!$this->validateVersion($this->version)) {
242
            throw new InvalidArgumentException('Version must be a date in the Y-m-d format');
243
        }
244
245
        $this->plugins[] = new Plugin\QueryDefaultsPlugin([
246
            'version' => $this->version
247
        ]);
248
249
        return $this;
250
    }
251
252
    /**
253
     * @return $this
254
     */
255
    private function addPathPlugin(): self
256
    {
257
        if (null !== $this->path) {
258
            $this->plugins[] = new Plugin\AddPathPlugin($this->uriFactory->createUri($this->path));
259
        }
260
261
        return $this;
262
    }
263
}
264