Passed
Push — master ( 10edf6...2d3456 )
by Michael
01:51
created

TransifexObject::createAuthorizationHeader()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 11
ccs 0
cts 6
cp 0
rs 10
c 0
b 0
f 0
cc 3
nc 2
nop 0
crap 12
1
<?php declare(strict_types=1);
2
3
namespace BabDev\Transifex;
4
5
use Psr\Http\Client\ClientInterface;
6
use Psr\Http\Message\RequestFactoryInterface;
7
use Psr\Http\Message\RequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\StreamFactoryInterface;
10
use Psr\Http\Message\UriFactoryInterface;
11
use Psr\Http\Message\UriInterface;
12
13
/**
14
 * Transifex API object class.
15
 */
16
abstract class TransifexObject
17
{
18
    /**
19
     * The HTTP client.
20
     *
21
     * @var ClientInterface
22
     */
23
    protected $client;
24
25
    /**
26
     * The request factory.
27
     *
28
     * @var RequestFactoryInterface
29
     */
30
    protected $requestFactory;
31
32
    /**
33
     * The stream factory.
34
     *
35
     * @var StreamFactoryInterface
36
     */
37
    protected $streamFactory;
38
39
    /**
40
     * The URI factory.
41
     *
42
     * @var UriFactoryInterface
43
     */
44
    protected $uriFactory;
45
46
    /**
47
     * Options for the Transifex object.
48
     *
49
     * @var array
50
     */
51
    protected $options;
52
53
    /**
54
     * @param ClientInterface         $client         The HTTP client
55
     * @param RequestFactoryInterface $requestFactory The request factory
56
     * @param StreamFactoryInterface  $streamFactory  The stream factory
57
     * @param UriFactoryInterface     $uriFactory     The URI factory
58
     * @param array                   $options        Transifex options array
59
     */
60
    public function __construct(
61
        ClientInterface $client,
62
        RequestFactoryInterface $requestFactory,
63
        StreamFactoryInterface $streamFactory,
64
        UriFactoryInterface $uriFactory,
65
        array $options = []
66
    ) {
67
        $this->client         = $client;
68
        $this->requestFactory = $requestFactory;
69
        $this->streamFactory  = $streamFactory;
70
        $this->uriFactory     = $uriFactory;
71
        $this->options        = $options;
72
    }
73
74
    /**
75
     * Creates the Authorization header for the request
76
     *
77
     * @return string
78
     *
79
     * @throws \InvalidArgumentException if credentials are not set
80
     */
81
    protected function createAuthorizationHeader(): string
82
    {
83
        $username = $this->getOption('api.username');
84
        $password = $this->getOption('api.password');
85
86
        // The API requires HTTP Basic Authentication, we can't proceed without credentials
87
        if ($username === null || $password === null) {
88
            throw new \InvalidArgumentException('Missing credentials for API authentication.');
89
        }
90
91
        return 'Basic ' . \base64_encode("$username:$password");
92
    }
93
94
    /**
95
     * Create a Request object for the given URI
96
     *
97
     * This method will also set the Authorization header for the request
98
     *
99
     * @param string       $method
100
     * @param UriInterface $uri
101
     *
102
     * @return RequestInterface
103
     */
104
    protected function createRequest(string $method, UriInterface $uri): RequestInterface
105
    {
106
        $request = $this->requestFactory->createRequest($method, $uri);
107
108
        return $request->withHeader('Authorization', $this->createAuthorizationHeader());
109
    }
110
111
    /**
112
     * Create a Uri object for the path
113
     *
114
     * @param string $path
115
     *
116
     * @return UriInterface
117
     */
118
    protected function createUri(string $path): UriInterface
119
    {
120
        $baseUrl = $this->getOption('base_uri', 'https://www.transifex.com');
121
122
        return $this->uriFactory->createUri($baseUrl . $path);
123
    }
124
125
    /**
126
     * Get the authentication credentials for the API request.
127
     *
128
     * @return array
129
     *
130
     * @throws \InvalidArgumentException if credentials are not set
131
     */
132
    protected function getAuthData(): array
133
    {
134
        $username = $this->getOption('api.username');
135
        $password = $this->getOption('api.password');
136
137
        // The API requires HTTP Basic Authentication, we can't proceed without credentials
138
        if ($username === null || $password === null) {
139
            throw new \InvalidArgumentException('Missing credentials for API authentication.');
140
        }
141
142
        return [$username, $password];
143
    }
144
145
    /**
146
     * Get an option from the options store.
147
     *
148
     * @param string $key     The name of the option to get
149
     * @param mixed  $default The default value if the option is not set
150
     *
151
     * @return mixed The option value
152
     */
153 1
    protected function getOption(string $key, $default = null)
154
    {
155 1
        return $this->options[$key] ?? $default;
156
    }
157
158
    /**
159
     * Update an API endpoint with resource content.
160
     *
161
     * @param UriInterface $uri     URI object representing the API path to request
162
     * @param string       $content The content of the resource, this can either be a string of data or a file path
163
     * @param string       $type    The type of content in the $content variable, this should be either string or file
164
     *
165
     * @return ResponseInterface
166
     *
167
     * @throws \InvalidArgumentException
168
     */
169 9
    protected function updateResource(UriInterface $uri, string $content, string $type): ResponseInterface
170
    {
171
        // Verify the content type is allowed
172 9
        if (!\in_array($type, ['string', 'file'])) {
173 2
            throw new \InvalidArgumentException('The content type must be specified as file or string.');
174
        }
175
176 7
        $request = $this->createRequest('PUT', $uri);
177 7
        $request = $request->withHeader('Content-Type', 'application/json');
178
179 7
        if ($type == 'file') {
180 3
            if (!\file_exists($content)) {
181 2
                throw new \InvalidArgumentException(
182 2
                    \sprintf('The specified file, "%s", does not exist.', $content)
183
                );
184
            }
185
186 1
            $request = $request->withBody($this->streamFactory->createStreamFromFile($content));
187
        } else {
188
            $data = [
189 4
                'content' => $content,
190
            ];
191
192 4
            $request = $request->withBody($this->streamFactory->createStream(\json_encode($data)));
193
        }
194
195 5
        return $this->client->sendRequest($request);
196
    }
197
}
198