FileUploader::upload()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 2
nop 5
1
<?php
2
3
namespace ArgentCrusade\Selectel\CloudStorage;
4
5
use ArgentCrusade\Selectel\CloudStorage\Contracts\FileUploaderContract;
6
use ArgentCrusade\Selectel\CloudStorage\Contracts\Api\ApiClientContract;
7
use ArgentCrusade\Selectel\CloudStorage\Exceptions\UploadFailedException;
8
9
class FileUploader implements FileUploaderContract
10
{
11
    /**
12
     * Upload file from string or stream resource.
13
     *
14
     * @param \ArgentCrusade\Selectel\CloudStorage\Contracts\Api\ApiClientContract $api
15
     * @param string                                                               $path           Remote path.
16
     * @param string|resource                                                      $body           File contents.
17
     * @param array                                                                $params         = [] Upload params.
18
     * @param bool                                                                 $verifyChecksum = true
19
     *
20
     * @throws \ArgentCrusade\Selectel\CloudStorage\Exceptions\UploadFailedException
21
     *
22
     * @return string
23
     */
24
    public function upload(ApiClientContract $api, $path, $body, array $params = [], $verifyChecksum = true)
25
    {
26
        $response = $api->request('PUT', $path, [
27
            'headers' => $this->convertUploadParamsToHeaders($body, $params, $verifyChecksum),
28
            'body' => $body,
29
            'query' => $this->extractQueryParameters($params),
30
        ]);
31
32
        if ($response->getStatusCode() !== 201) {
33
            throw new UploadFailedException('Unable to upload file.', $response->getStatusCode());
34
        }
35
36
        return $response->getHeaderLine('ETag');
37
    }
38
39
    /**
40
     * Parses upload parameters and assigns them to appropriate HTTP headers.
41
     *
42
     * @param string|resource $body           = null
43
     * @param array           $params         = []
44
     * @param bool            $verifyChecksum = true
45
     *
46
     * @return array
47
     */
48
    protected function convertUploadParamsToHeaders($body = null, array $params = [], $verifyChecksum = true)
49
    {
50
        $headers = [];
51
52
        if ($verifyChecksum) {
53
            $headers['ETag'] = md5($body);
54
        }
55
56
        $availableParams = [
57
            'contentType' => 'Content-Type',
58
            'contentDisposition' => 'Content-Disposition',
59
            'deleteAfter' => 'X-Delete-After',
60
            'deleteAt' => 'X-Delete-At',
61
        ];
62
63
        foreach ($availableParams as $key => $header) {
64
            if (isset($params[$key])) {
65
                $headers[$header] = $params[$key];
66
            }
67
        }
68
69
        return $headers;
70
    }
71
72
    /**
73
     * Parses upload parameters and assigns them to appropriate query parameters.
74
     *
75
     * @param array $params
76
     *
77
     * @return array
78
     */
79
    protected function extractQueryParameters(array $params)
80
    {
81
        $availableParams = ['extract-archive'];
82
        $query = [];
83
84
        foreach ($params as $key => $value) {
85
            if (in_array($key, $availableParams)) {
86
                $query[$key] = $value;
87
            }
88
        }
89
90
        return $query;
91
    }
92
}
93