Completed
Push — master ( 519f76...318dd5 )
by Raffael
24:13 queued 15:29
created

Balloon::syncWriteStream()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 50
ccs 28
cts 28
cp 1
rs 8.7797
c 0
b 0
f 0
cc 5
nc 5
nop 2
crap 5
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * tubee
7
 *
8
 * @copyright   Copryright (c) 2017-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Tubee\Storage;
13
14
use Generator;
15
use MongoDB\BSON\ObjectIdInterface;
16
use Psr\Log\LoggerInterface;
17
use Tubee\Storage\Balloon\ApiClient;
18
19
class Balloon implements StorageInterface
20
{
21
    /**
22
     * Logger.
23
     *
24
     * @var LoggerInterface
25
     */
26
    protected $logger;
27
28
    /**
29
     * Balloon.
30
     *
31
     * @var ApiClient
32
     */
33
    protected $balloon;
34
35
    /**
36
     * Collection ID.
37
     *
38
     * @var string
39
     */
40
    protected $collection;
41
42
    /**
43
     * Init storage.
44
     */
45 7
    public function __construct(ApiClient $balloon, LoggerInterface $logger, ?ObjectIdInterface $collection = null)
46
    {
47 7
        $this->balloon = $balloon;
48 7
        $this->logger = $logger;
49 7
        $this->collection = $collection;
50 7
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 1
    public function openReadStreams(string $pattern): Generator
56
    {
57 1
        $files = $this->getFiles($pattern);
58 1
        if (count($files) === 0) {
59
            throw new Exception\NoFilesFound('no files found for '.$pattern);
60
        }
61
62 1
        $streams = [];
0 ignored issues
show
Unused Code introduced by
$streams is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
63 1
        foreach ($files as $file) {
64 1
            $this->logger->debug('open read stream from file ['.$file['id'].']', [
65 1
                'category' => get_class($this),
66
            ]);
67
68 1
            $stream = $this->balloon->openSocket('/api/v2/nodes/'.$file['id'].'/content');
69 1
            if ($stream === false) {
70
                throw new Exception\OpenStreamFailed('failed open read stream for '.$file['id']);
71
            }
72
73 1
            yield $file['name'] => $stream;
74
        }
75 1
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 2
    public function openReadStream(string $file)
81
    {
82 2
        $path = '/api/v2/nodes/'.$file.'/content';
83
84 2
        $this->logger->debug('open read stream from file ['.$path.']', [
85 2
            'category' => get_class($this),
86
        ]);
87
88 2
        $stream = $this->balloon->openSocket($path);
89 2
        if ($stream === false) {
90 1
            throw new Exception\OpenStreamFailed('failed open read stream for '.$path);
91
        }
92
93 1
        return $stream;
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 1
    public function openWriteStream(string $file)
100
    {
101 1
        $this->logger->debug('open write stream for [php://temp]', [
102 1
            'category' => get_class($this),
103
        ]);
104
105 1
        $stream = fopen('php://temp', 'a+');
106
107 1
        if ($stream === false) {
108
            throw new Exception\OpenStreamFailed('failed open write stream for '.$file);
109
        }
110
111 1
        return $stream;
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 3
    public function syncWriteStream($stream, string $file): bool
118
    {
119 3
        $size = fstat($stream)['size'];
120
121 3
        if ($size === 0) {
122 1
            $this->logger->info('skip file of 0 bytes upload to balloon', [
123 1
                'category' => get_class($this),
124
            ]);
125
126 1
            return true;
127
        }
128
129 2
        $chunks = $size / 8388608;
130 2
        if ($chunks < 1) {
131 1
            $chunks = 1;
132
        }
133
134 2
        $this->logger->info('upload file to balloon as ['.$file.']', [
135 2
            'category' => get_class($this),
136
        ]);
137
138
        $query = [
139 2
            'collection' => $this->collection,
140 2
            'name' => $file,
141 2
            'size' => $size,
142 2
            'chunks' => $chunks,
143
        ];
144
145 2
        rewind($stream);
146
147 2
        $index = 0;
148 2
        $session = null;
149 2
        while (!feof($stream) && $index !== $chunks) {
150 2
            $buffer = fread($stream, 8388608);
0 ignored issues
show
Unused Code introduced by
$buffer is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
151
            $query += [
152 2
                'index' => $index,
153 2
                'session' => $session,
154
            ];
155
156 2
            $this->logger->debug('upload file chunk ['.$index.'/'.$chunks.'] of total ['.$size.'] bytes to balloon', [
157 2
                'category' => get_class($this),
158
            ]);
159 2
            $result = $this->balloon->restCall('/api/v2/files/chunk', $query, 'PUT');
160
161 2
            ++$index;
162 2
            $session = $result['session'];
163
        }
164
165 2
        return fclose($stream);
166
    }
167
168
    /**
169
     * Search balloon for files matching pattern.
170
     */
171 1
    protected function getFiles(string $pattern): array
172
    {
173
        $query = [
174 1
            'filter' => [
175
                'directory' => false,
176
                'name' => [
177 1
                    '$regex' => $pattern,
178
                ],
179
            ],
180
        ];
181
182 1
        if ($this->collection === null) {
183 1
            $url = '/api/v2/collections/children';
184
        } else {
185
            $url = '/api/v2/collections/'.$this->collection.'/children';
186
        }
187
188 1
        $result = $this->balloon->restCall($url, $query);
189
190 1
        return $result['data'];
191
    }
192
}
193