ClientConfigurator::getEndpoint()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Shoman4eg\Nalog\Http;
5
6
use Http\Client\Common\Plugin;
7
use Http\Client\Common\PluginClient;
8
use Http\Discovery\Psr17FactoryDiscovery;
9
use Http\Discovery\Psr18ClientDiscovery;
10
use Psr\Http\Client\ClientInterface;
11
use Psr\Http\Message\UriFactoryInterface;
12
use Psr\Http\Message\UriInterface;
13
use Shoman4eg\Nalog\DTO\DeviceInfo;
14
15
/**
16
 * Configure an HTTP client.
17
 *
18
 * @author Artem Dubinin <[email protected]>
19
 */
20
final class ClientConfigurator
21
{
22
    private string $endpoint = 'https://lknpd.nalog.ru/api';
23
    private string $version = 'v1';
24
    private UriFactoryInterface $uriFactory;
25
26
    /**
27
     * This is the client we use for actually sending the requests.
28
     */
29
    private ClientInterface $httpClient;
30
31
    /**
32
     * This is the client wrapping the $httpClient.
33
     */
34
    private PluginClient $configuredClient;
35
36
    /**
37
     * @var Plugin[]
38
     */
39
    private array $prependPlugins = [];
40
41
    /**
42
     * @var Plugin[]
43
     */
44
    private array $appendPlugins = [];
45
46
    /**
47
     * True if we should create a new Plugin client at next request.
48
     */
49
    private bool $configurationModified = true;
50
51
    public function __construct(?ClientInterface $httpClient = null, ?UriFactoryInterface $uriFactory = null)
52
    {
53
        $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find();
54
        $this->uriFactory = $uriFactory ?? Psr17FactoryDiscovery::findUriFactory();
55
    }
56
57
    public function createConfiguredClient(): PluginClient
58
    {
59
        if ($this->configurationModified) {
60
            $this->configurationModified = false;
61
            $plugins = $this->prependPlugins;
62
            $plugins[] = new Plugin\BaseUriPlugin($this->getEndpoint());
63
            $plugins[] = new Plugin\HeaderDefaultsPlugin([
64
                'User-Agent' => DeviceInfo::USER_AGENT,
65
                'Content-type' => 'application/json',
66
                'Accept' => 'application/json, text/plain, */*',
67
                'Accept-language' => 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
68
            ]);
69
70
            $this->configuredClient = new PluginClient(
71
                $this->httpClient,
72
                \array_merge($plugins, $this->appendPlugins)
73
            );
74
        }
75
76
        return $this->configuredClient;
77
    }
78
79
    public function setEndpoint(string $endpoint): void
80
    {
81
        $this->endpoint = $endpoint;
82
    }
83
84
    public function setVersion(string $version): void
85
    {
86
        $this->version = $version;
87
    }
88
89
    public function appendPlugin(Plugin ...$plugin): void
90
    {
91
        $this->configurationModified = true;
92
        foreach ($plugin as $p) {
93
            $this->appendPlugins[] = $p;
94
        }
95
    }
96
97
    public function prependPlugin(Plugin ...$plugin): void
98
    {
99
        $this->configurationModified = true;
100
        $plugin = \array_reverse($plugin);
101
        foreach ($plugin as $p) {
102
            \array_unshift($this->prependPlugins, $p);
103
        }
104
    }
105
106
    /**
107
     * Remove a plugin by its fully qualified class name (FQCN).
108
     */
109
    public function removePlugin(string $fqcn): void
110
    {
111
        foreach ($this->prependPlugins as $idx => $plugin) {
112
            if ($plugin instanceof $fqcn) {
113
                unset($this->prependPlugins[$idx]);
114
                $this->configurationModified = true;
115
            }
116
        }
117
118
        foreach ($this->appendPlugins as $idx => $plugin) {
119
            if ($plugin instanceof $fqcn) {
120
                unset($this->appendPlugins[$idx]);
121
                $this->configurationModified = true;
122
            }
123
        }
124
    }
125
126
    public function getEndpoint(): UriInterface
127
    {
128
        return $this->uriFactory->createUri(sprintf('%s/%s', $this->endpoint, $this->version));
129
    }
130
}
131