Client::delete()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Urvin\Gokaru;
6
7
use GuzzleHttp\Client as GuzzleClient;
8
use GuzzleHttp\Exception\GuzzleException;
9
use GuzzleHttp\Exception\RequestException;
10
use Urvin\Gokaru\Exception;
11
use Urvin\Gokaru\Signature\Generator;
12
13
class Client
14
{
15
    /** @var string */
16
    protected string $url;
17
    /** @var Generator */
18
    protected Generator $signature;
19
    /** @var array<string,string> */
20
    protected array $urlPublic;
21
22
    /** @var GuzzleClient|null */
23
    protected ?GuzzleClient $httpClient = null;
24
25
    /**
26
     * @param string $url
27
     * @param Generator $signature
28
     */
29 18
    public function __construct(string $url, Generator $signature)
30
    {
31 18
        $this->setUrl($url);
32 18
        $this->setSignature($signature);
33 18
    }
34
35
    /**
36
     * @return string
37
     */
38 8
    public function getUrl(): string
39
    {
40 8
        return $this->url;
41
    }
42
43
    /**
44
     * @param string $url
45
     */
46 18
    public function setUrl(string $url): void
47
    {
48 18
        $url = rtrim($url, '/');
49 18
        if (empty($url)) {
50 1
            throw new Exception\InvalidArgumentException('Url should not be empty');
51
        }
52 18
        $this->url = $url;
53 18
    }
54
55
    /**
56
     * @return Generator
57
     */
58 2
    public function getSignature(): Generator
59
    {
60 2
        return $this->signature;
61
    }
62
63
    /**
64
     * @param Generator $signature
65
     */
66 18
    public function setSignature(Generator $signature): void
67
    {
68 18
        $this->signature = $signature;
69 18
    }
70
71
    /**
72
     * @param string $type
73
     * @param string $url
74
     */
75 4
    public function setUrlPublic(string $type, string $url): void
76
    {
77 4
        $this->validateSourceType($type);
78 2
        $url = rtrim($url, '/');
79 2
        if (empty($url) && isset($this->urlPublic[$type])) {
80 1
            unset($this->urlPublic[$type]);
81 1
            return;
82
        }
83
84 2
        $this->urlPublic[$type] = $url;
85 2
    }
86
87
    /**
88
     * @param string $type
89
     * @return string
90
     */
91 3
    public function getPublicUrl(string $type): string
92
    {
93 3
        $this->validateSourceType($type);
94 3
        if (!empty($this->urlPublic[$type])) {
95 2
            return $this->urlPublic[$type];
96
        }
97 3
        return $this->getUrl() . '/' . $type;
98
    }
99
100
    /**
101
     * Upload sourceFilename into Gokaru
102
     *
103
     * @param string $sourceFilename
104
     * @param string $type
105
     * @param string $category
106
     * @param string $filename
107
     * @throws GuzzleException
108
     */
109 4
    public function upload(string $sourceFilename, string $type, string $category, string $filename): void
110
    {
111 4
        if (empty($sourceFilename)) {
112 1
            throw new Exception\InvalidArgumentException('Source file name is empty');
113
        }
114 3
        $this->validateCredentials($type, $category, $filename);
115
116 3
        $streamContext = stream_context_create([
117
            'ssl' => [
118 3
                'verify_peer' => false,
119
                'verify_peer_name' => false,
120
            ]
121
        ]);
122 3
        $fileHandler = @fopen($sourceFilename, 'rb', false, $streamContext);
123
124 3
        if ($fileHandler === false) {
125 2
            throw new Exception\SourceErrorException('Source file is not readable');
126
        }
127
        try {
128 1
            $this->getHttpClient()->put(
129 1
                $this->createUrl($type, $category, $filename),
130
                [
131 1
                    'body' => $fileHandler
132
                ]
133
            );
134 1
        } catch (RequestException $e) {
135 1
            throw  new  Exception\RuntimeException('Upload exception: ' . $e->getMessage(), 0, $e);
136 1
        } finally {
137 1
            if (is_resource($fileHandler)) {
138 1
                fclose($fileHandler);
139
            }
140
        }
141 1
    }
142
143
    /**
144
     * Delete origin file and thumbnails from Gokaru
145
     *
146
     * @param string $type
147
     * @param string $category
148
     * @param string $filename
149
     * @throws GuzzleException
150
     */
151 1
    public function delete(string $type, string $category, string $filename): void
152
    {
153 1
        $this->validateCredentials($type, $category, $filename);
154 1
        $this->getHttpClient()->delete($this->createUrl($type, $category, $filename));
155 1
    }
156
157
    /**
158
     * Get service origin file URL
159
     *
160
     * @param string $type
161
     * @param string $category
162
     * @param string $filename
163
     * @return string
164
     */
165 3
    public function origin(string $type, string $category, string $filename): string
166
    {
167 3
        $this->validateCredentials($type, $category, $filename);
168 1
        return $this->createUrl($type, $category, $filename);
169
    }
170
171
    /**
172
     * Get public file url
173
     *
174
     * @param string $category
175
     * @param string $filename
176
     * @return string
177
     */
178 1
    public function file(string $category, string $filename): string
179
    {
180 1
        $type = SourceType::SOURCE_TYPE_FILE;
181 1
        $this->validateCredentials($type, $category, $filename);
182 1
        return $this->createUrl($type, $category, $filename, true);
183
    }
184
185
    /**
186
     * Create Thumbnail url builder castable to string
187
     *
188
     * @param int|null $width
189
     * @param int|null $height
190
     * @param int|null $cast
191
     * @param string|null $filename
192
     * @param string|null $extension
193
     * @return ThumbnailUrlBuilder
194
     */
195 1
    public function thumbnail(
196
        ?int $width = null,
197
        ?int $height = null,
198
        ?int $cast = null,
199
        ?string $category = null,
200
        ?string $filename = null,
201
        ?string $extension = null
202
    ): ThumbnailUrlBuilder {
203 1
        $builder = new ThumbnailUrlBuilder(
204 1
            $this->getPublicUrl(SourceType::SOURCE_TYPE_IMAGE),
205 1
            SourceType::SOURCE_TYPE_IMAGE,
206 1
            $this->signature
207
        );
208
209 1
        if ($width !== null) {
210 1
            $builder->width($width);
211
        }
212 1
        if ($height !== null) {
213 1
            $builder->height($height);
214
        }
215 1
        if ($cast !== null) {
216 1
            $builder->cast($cast);
217
        }
218 1
        if (!empty($category)) {
219 1
            $builder->category($category);
220
        }
221 1
        if (!empty($filename)) {
222 1
            $builder->filename($filename);
223
        }
224 1
        if (!empty($extension)) {
225 1
            $builder->extension($extension);
226
        }
227
228 1
        return $builder;
229
    }
230
231
    /**
232
     * @param string $type
233
     * @param string $category
234
     * @param string $filename
235
     */
236 8
    protected function validateCredentials(string $type, string $category, string $filename): void
237
    {
238 8
        $this->validateSourceType($type);
239 8
        if (empty($category)) {
240 1
            throw new Exception\InvalidArgumentException("Storage category should not be empty");
241
        }
242 7
        if (empty($filename)) {
243 1
            throw new Exception\InvalidArgumentException("Storage file name should not be empty");
244
        }
245 6
    }
246
247
    /**
248
     * @param string $type
249
     */
250 12
    protected function validateSourceType(string $type): void
251
    {
252 12
        if (empty($type)) {
253 1
            throw new Exception\InvalidArgumentException('File type not specified');
254
        }
255 11
        if (!in_array($type, SourceType::SOURCE_TYPES)) {
256 1
            throw new Exception\DomainException('Wrong file type specified');
257
        }
258 10
    }
259
260
    /**
261
     * @return GuzzleClient
262
     */
263 3
    protected function getHttpClient(): GuzzleClient
264
    {
265 3
        if ($this->httpClient === null) {
266 1
            $this->httpClient = new GuzzleClient();
267
        }
268 3
        return $this->httpClient;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->httpClient could return the type null which is incompatible with the type-hinted return GuzzleHttp\Client. Consider adding an additional type-check to rule them out.
Loading history...
269
    }
270
271
    /**
272
     * @param string $type
273
     * @param string $category
274
     * @param string $filename
275
     * @param bool $public
276
     * @return string
277
     */
278 4
    protected function createUrl(string $type, string $category, string $filename, bool $public = false): string
279
    {
280 4
        $baseUrl = $public ? $this->getPublicUrl($type) : $this->getUrl();
281 4
        $path = [
282 4
            $category,
283 4
            $filename
284
        ];
285 4
        if (!$public) {
286 3
            array_unshift($path, $type);
287
        }
288
289 4
        return $baseUrl . '/' . implode('/', array_map('urlencode', $path));
290
    }
291
}