Completed
Push — master ( dbe8ee...cfcdbf )
by Michael
02:09
created

TransifexObject::setOption()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
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 83
    public function __construct(
61
        ClientInterface $client,
62
        RequestFactoryInterface $requestFactory,
63
        StreamFactoryInterface $streamFactory,
64
        UriFactoryInterface $uriFactory,
65
        array $options = []
66
    ) {
67 83
        $this->client         = $client;
68 83
        $this->requestFactory = $requestFactory;
69 83
        $this->streamFactory  = $streamFactory;
70 83
        $this->uriFactory     = $uriFactory;
71 83
        $this->options        = $options;
72 83
    }
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 76
    protected function createAuthorizationHeader(): string
82
    {
83 76
        $username = $this->getOption('api.username');
84 76
        $password = $this->getOption('api.password');
85
86
        // The API requires HTTP Basic Authentication, we can't proceed without credentials
87 76
        if ($username === null || $password === null) {
88 1
            throw new \InvalidArgumentException('Missing credentials for API authentication.');
89
        }
90
91 75
        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 76
    protected function createRequest(string $method, UriInterface $uri): RequestInterface
105
    {
106 76
        $request = $this->requestFactory->createRequest($method, $uri);
107
108 76
        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 77
    protected function createUri(string $path): UriInterface
119
    {
120 77
        $baseUrl = $this->getOption('base_uri', 'https://www.transifex.com');
121
122 77
        return $this->uriFactory->createUri($baseUrl . $path);
123
    }
124
125
    /**
126
     * Get an option from the options store.
127
     *
128
     * @param string $key     The name of the option to get
129
     * @param mixed  $default The default value if the option is not set
130
     *
131
     * @return mixed The option value
132
     */
133 77
    protected function getOption(string $key, $default = null)
134
    {
135 77
        return $this->options[$key] ?? $default;
136
    }
137
138
    /**
139
     * Set an option for the Transifex instance.
140
     *
141
     * @param string $key   The name of the option to set
142
     * @param mixed  $value The option value to set
143
     *
144
     * @return $this
145
     */
146 4
    protected function setOption(string $key, $value): self
147
    {
148 4
        $this->options[$key] = $value;
149
150 4
        return $this;
151
    }
152
153
    /**
154
     * Update an API endpoint with resource content.
155
     *
156
     * @param UriInterface $uri     URI object representing the API path to request
157
     * @param string       $content The content of the resource, this can either be a string of data or a file path
158
     * @param string       $type    The type of content in the $content variable, this should be either string or file
159
     *
160
     * @return ResponseInterface
161
     *
162
     * @throws \InvalidArgumentException
163
     */
164 8
    protected function updateResource(UriInterface $uri, string $content, string $type): ResponseInterface
165
    {
166
        // Verify the content type is allowed
167 8
        if (!\in_array($type, ['string', 'file'])) {
168 1
            throw new \InvalidArgumentException('The content type must be specified as file or string.');
169
        }
170
171 7
        $request = $this->createRequest('PUT', $uri);
172 7
        $request = $request->withHeader('Content-Type', 'application/json');
173
174 7
        if ($type == 'file') {
175 3
            if (!\file_exists($content)) {
176 1
                throw new \InvalidArgumentException(
177 1
                    \sprintf('The specified file, "%s", does not exist.', $content)
178
                );
179
            }
180
181 2
            $request = $request->withBody($this->streamFactory->createStreamFromFile($content));
182
        } else {
183
            $data = [
184 4
                'content' => $content,
185
            ];
186
187 4
            $request = $request->withBody($this->streamFactory->createStream(\json_encode($data)));
188
        }
189
190 6
        return $this->client->sendRequest($request);
191
    }
192
}
193