Passed
Push — master ( 57ebbd...f70266 )
by Shahrad
01:49
created

DownloadResult::mergeChunks()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace EasyHttp\Model;
4
5
/**
6
 * Class DownloadResult
7
 *
8
 * @link    https://github.com/shahradelahi/easy-http
9
 * @author  Shahrad Elahi (https://github.com/shahradelahi)
10
 * @license https://github.com/shahradelahi/easy-http/blob/master/LICENSE (MIT License)
11
 */
12
class DownloadResult
13
{
14
15
    /**
16
     * The unique identifier of the download
17
     *
18
     * @var string
19
     */
20
    public string $id;
21
22
    /**
23
     * The final size of the downloaded file
24
     *
25
     * @var int
26
     */
27
    public int $fileSize;
28
29
    /**
30
     * The path of the downloaded chunks
31
     *
32
     * @var string
33
     */
34
    public string $chunksPath;
35
36
    /**
37
     * The size of each chunk
38
     *
39
     * @var int
40
     */
41
    public int $chunkSize;
42
43
    /**
44
     * The count of chunks
45
     *
46
     * @var int
47
     */
48
    public int $chunks;
49
50
    /**
51
     * Start time of the download in microseconds
52
     *
53
     * @var float
54
     */
55
    public float $startTime;
56
57
    /**
58
     * End time of the download in microseconds
59
     *
60
     * @var float
61
     */
62
    public float $endTime;
63
64
    /**
65
     * The downloaded chunks
66
     *
67
     * @var array [{id, size, location, elapsedTime}, ...]
68
     */
69
    public array $downloads;
70
71
    /**
72
     * Add a chunk to the download result
73
     *
74
     * @param string $id The unique identifier of the chunk
75
     * @param ?string $body The chunk body
76
     * @param float $elapsedTime in microseconds
77
     * @return void
78
     */
79
    public function addChunk(string $id, ?string $body, float $elapsedTime): void
80
    {
81
        $save = $this->saveChunk($id, $body);
0 ignored issues
show
Bug introduced by
It seems like $body can also be of type null; however, parameter $body of EasyHttp\Model\DownloadResult::saveChunk() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

81
        $save = $this->saveChunk($id, /** @scrutinizer ignore-type */ $body);
Loading history...
82
        $this->downloads[] = [
83
            'id' => $id,
84
            'location' => $save ?? null,
85
            'size' => strlen($body),
0 ignored issues
show
Bug introduced by
It seems like $body can also be of type null; however, parameter $string of strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

85
            'size' => strlen(/** @scrutinizer ignore-type */ $body),
Loading history...
86
            'elapsed_time' => $elapsedTime,
87
            'status' => $save ? 'saved' : 'failed',
88
        ];
89
    }
90
91
    /**
92
     * Save the chunks to the temp directory
93
     *
94
     * @param string $id The unique identifier of the chunk
95
     * @param string $body The body of the chunk
96
     * @return string|bool
97
     */
98
    private function saveChunk(string $id, string $body): string|bool
99
    {
100
        $path = $this->chunksPath . DIRECTORY_SEPARATOR . $id;
101
        return file_put_contents($path, $body) ? $path : false;
102
    }
103
104
    /**
105
     * Merge the chunks into a single string
106
     *
107
     * @return string
108
     */
109
    public function mergeChunks(): string
110
    {
111
        $result = '';
112
        foreach ($this->downloads as $chunk) {
113
            $result .= file_get_contents($chunk['location']);
114
        }
115
        return $result;
116
    }
117
118
    /**
119
     * Save the merged chunks to a file
120
     *
121
     * @param string $filePath The path/to/file.ext
122
     * @return bool
123
     */
124
    public function save(string $filePath): bool
125
    {
126
        if (!file_exists(pathinfo($filePath, PATHINFO_DIRNAME))) {
0 ignored issues
show
Bug introduced by
It seems like pathinfo($filePath, Easy...Model\PATHINFO_DIRNAME) can also be of type array; however, parameter $filename of file_exists() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

126
        if (!file_exists(/** @scrutinizer ignore-type */ pathinfo($filePath, PATHINFO_DIRNAME))) {
Loading history...
127
            throw new \InvalidArgumentException('The directory does not exist');
128
        }
129
        $result = $this->mergeChunks();
130
        $this->cleanChunks();
131
        return file_put_contents($filePath, $result) !== false;
132
    }
133
134
    /**
135
     * Clean the directory of the chunks
136
     *
137
     * @return void
138
     */
139
    public function cleanChunks(): void
140
    {
141
        foreach (glob($this->chunksPath . DIRECTORY_SEPARATOR . '*') as $file) {
142
            unlink($file);
143
        }
144
        rmdir($this->chunksPath);
145
    }
146
147
}