Passed
Push — master ( 304f84...5965ff )
by Nikita
02:10
created

GdaemonFiles::put()   B

Complexity

Conditions 11
Paths 19

Size

Total Lines 61
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 11.013

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 42
c 1
b 0
f 0
nc 19
nop 3
dl 0
loc 61
ccs 40
cts 42
cp 0.9524
crap 11.013
rs 7.3166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Knik\Gameap;
4
5
use Knik\Binn\BinnList;
6
use RuntimeException;
7
use InvalidArgumentException;
8
9
class GdaemonFiles extends Gdaemon
10
{
11
    const FSERV_AUTH            = 1;
12
    const FSERV_FILESEND        = 3;
13
    const FSERV_READDIR         = 4;
14
    const FSERV_MKDIR           = 5;
15
    const FSERV_MOVE            = 6;
16
    const FSERV_REMOVE          = 7;
17
    const FSERV_FILEINFO        = 8;
18
    const FSERV_CHMOD           = 9;
19
20
    const FSERV_UPLOAD_TO_SERVER        = 1;
21
    const FSERV_DOWNLOAD_FR_SERVER      = 2;
22
23
    const FSERV_STATUS_ERROR                = 1;
24
    const FSERV_STATUS_UNKNOWN_COMMAND      = 3;
25
    const FSERV_STATUS_OK                   = 100;
26
    const FSERV_STATUS_FILE_TRANSFER_READY  = 101;
27
28
    /**
29
     * @var int
30
     */
31
    protected $mode = self::DAEMON_SERVER_MODE_FILES;
32
33
    /**
34
     * Upload file to server
35
     *
36
     * @param string|resource $locFile path to local file or file stream
37
     * @param string $remFile path to remote file
38
     * @param int $permission
39
     *
40
     * @return bool|resource
41
     */
42 21
    public function put($locFile, $remFile, $permission = 0644)
43
    {
44 21
        if (is_string($locFile)) {
45
            set_error_handler(function () {});
46 15
            $fileHandle = fopen($locFile, 'r');
47 15
            restore_error_handler();
48 11
        } else if (is_resource($locFile)) {
49 3
            $fileHandle = $locFile;
50 1
        } else {
51 3
            throw new InvalidArgumentException('Invalid local file');
52
        }
53
54 18
        if ($fileHandle === false) {
55 3
            throw new RuntimeException('File open error');
56
        }
57
58 15
        $stat = fstat($fileHandle);
59 15
        $filesize = $stat['size'];
60 15
        unset($stat);
61
62 15
        $writeBinn = new BinnList;
63
64 15
        $writeBinn->addUint8(self::FSERV_FILESEND);
65 15
        $writeBinn->addUint8(self::FSERV_UPLOAD_TO_SERVER);
66 15
        $writeBinn->addStr($remFile);
67 15
        $writeBinn->addUint64($filesize);
68 15
        $writeBinn->addBool(true); // Make dirs
69 15
        $writeBinn->addUint8($permission);
70
71 15
        $read = $this->writeAndReadSocket($writeBinn->serialize());
72
73 15
        $readBinn = new BinnList;
74 15
        $readBinn->binnOpen($read);
75 15
        $results = $readBinn->unserialize();
76
77 15
        if ($results[0] == self::FSERV_STATUS_OK) {
78 3
            throw new RuntimeException('Unexpected \'OK\' status. Expected \'ready to transfer\'');
79 12
        } else if ($results[0] != self::FSERV_STATUS_FILE_TRANSFER_READY) {
80 3
            throw new RuntimeException('Couldn\'t upload file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
81
        }
82
83 9
        while(!feof($fileHandle)) {
84
            $this->writeSocket(fread($fileHandle, $this->maxBufsize));
85
        }
86
87 9
        $read = $this->readSocket();
88
89 9
        $readBinn = new BinnList;
90 9
        $readBinn->binnOpen($read);
91 9
        $results = $readBinn->unserialize();
92
93 9
        if ($results[0] != self::FSERV_STATUS_OK) {
94 3
            throw new RuntimeException('Couldn\'t send file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
95
        }
96
97 6
        if (is_resource($locFile)) {
98 3
            rewind($fileHandle);
99 3
            return $fileHandle;
100
        } else {
101 3
            fclose($fileHandle);
102 3
            return true;
103
        }
104
    }
105
106
    /**
107
     * Download file
108
     *
109
     * @param string $remFile path to remote file
110
     * @param string|resource $locFile path to local file or file stream
111
     *
112
     * @return boolean|resource
113
     */
114 24
    public function get($remFile, $locFile)
115
    {
116 24
        if (is_string($locFile)) {
117
            set_error_handler(function () {});
118 18
            $fileHandle = fopen($locFile, 'w+b');
119 18
            restore_error_handler();
120 12
        } else if (is_resource($locFile)) {
121 3
            $fileHandle = $locFile;
122 1
        } else {
123 3
            throw new InvalidArgumentException('Invalid local file');
124
        }
125
126 21
        if ($fileHandle === false) {
127 3
            throw new RuntimeException('File open error');
128
        }
129
130 18
        $writeBinn = new BinnList;
131
132 18
        $writeBinn->addUint8(self::FSERV_FILESEND);
133 18
        $writeBinn->addUint8(self::FSERV_DOWNLOAD_FR_SERVER);
134 18
        $writeBinn->addStr($remFile);
135
136 18
        $read = $this->writeAndReadSocket($writeBinn->serialize());
137
138 18
        $readBinn = new BinnList;
139 18
        $readBinn->binnOpen($read);
140 18
        $results = $readBinn->unserialize();
141
142 18
        if ($results[0] == self::FSERV_STATUS_OK) {
143 3
            throw new RuntimeException('Unexpected `OK` status. Expected `ready to transfer`');
144 15
        } else if ($results[0] != self::FSERV_STATUS_FILE_TRANSFER_READY) {
145 3
            throw new RuntimeException('Couldn\'t upload file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
146
        }
147
148 12
        $this->writeSocket(self::SOCKET_MSG_ENDL);
149
150 12
        $filesize = $results[2];
151 12
        $writed = 0;
152
153 12
        while($writed < $filesize) {
154 12
            if ($filesize - $writed > $this->maxBufsize) {
155 3
                $readlen = $this->maxBufsize;
156 1
            }
157
            else {
158 12
                $readlen = $filesize - $writed;
159
            }
160
161 12
            $socketRead = $this->readSocket($readlen, true);
162
163 12
            $writed += fwrite($fileHandle, $socketRead, $readlen);
164 4
        }
165
166 12
        if (is_resource($locFile)) {
167 3
            rewind($fileHandle);
168 3
            return $fileHandle;
169
        } else {
170 9
            fclose($fileHandle);
171 9
            return true;
172
        }
173
    }
174
175
    /**
176
     * List files
177
     *
178
     * @param string $directory
179
     *
180
     * @return array Files names list
181
     */
182 12
    public function listFiles($directory)
183
    {
184 12
        $writeBinn= new BinnList;
185
186 12
        $writeBinn->addUint8(self::FSERV_READDIR);
187 12
        $writeBinn->addStr($directory);     // Dir path
188 12
        $writeBinn->addUint8(0);       // Mode
189
190 12
        $read = $this->writeAndReadSocket($writeBinn->serialize());
191
192 12
        $readBinn = new BinnList;
193
194 12
        $readBinn->binnOpen($read);
195 12
        $results = $readBinn->unserialize();
196
197 12
        if ($results[0] != self::FSERV_STATUS_OK) {
198
            // Error
199 3
            throw new RuntimeException('GDaemon List files error:' . (isset($results[1]) ? $results[1] : 'Unknown'));
200
        }
201
202 9
        $filesList = $results[2];
203 9
        $returnList = [];
204
205 9
        foreach($filesList as &$file) {
206
207 9
            if (in_array(basename($file[0]), ['.', '..'])) {
208 3
                continue;
209
            }
210
211 9
            $returnList[] = basename($file[0]);
212 3
        }
213
214 9
        return $returnList;
215
    }
216
217
    /**
218
     * @param string $directory
219
     * @return array
220
     */
221 9
    public function directoryContents($directory)
222
    {
223 9
        $writeBinn= new BinnList;
224
225 9
        $writeBinn->addUint8(self::FSERV_READDIR);
226 9
        $writeBinn->addStr($directory);     // Dir path
227 9
        $writeBinn->addUint8(1);       // Mode
228
229 9
        $read = $this->writeAndReadSocket($writeBinn->serialize());
230
231 9
        $readBinn = new BinnList;
232
233 9
        $readBinn->binnOpen($read);
234 9
        $results = $readBinn->unserialize();
235
236 9
        if ($results[0] != self::FSERV_STATUS_OK) {
237
            // Error
238 3
            throw new RuntimeException('GDaemon List files error:' . (isset($results[1]) ? $results[1] : 'Unknown'));
239
        }
240
241 6
        $filesList = $results[2];
242 6
        $returnList = [];
243
244 6
        foreach($filesList as &$file) {
245 3
            if (in_array(basename($file[0]), ['.', '..'])) {
246 3
                continue;
247
            }
248
249 3
            $returnList[] = array(
250 3
                'name' => basename($file[0]),
251 3
                'size' => $file[1],
252 3
                'mtime' => $file[2],
253 3
                'type' => ($file[3] == 1) ? 'dir' : 'file',
254 3
                'permissions' => $file[4],
255
            );
256 2
        }
257
258 6
        return $returnList;
259
    }
260
261
    /**
262
     * Make directory
263
     *
264
     * @param string $path
265
     * @param int $permissions
266
     * @return bool
267
     */
268 6
    public function mkdir($path, $permissions = 0755)
269
    {
270 6
        $writeBinn = new BinnList;
271
272 6
        $writeBinn->addUint8(self::FSERV_MKDIR);
273 6
        $writeBinn->addStr($path);
274 6
        $writeBinn->addStr($permissions);
275
276 6
        $read = $this->writeAndReadSocket($writeBinn->serialize());
277
278 6
        $readBinn = new BinnList;
279 6
        $readBinn->binnOpen($read);
280 6
        $results = $readBinn->unserialize();
281
282 6
        if ($results[0] != self::FSERV_STATUS_OK) {
283 3
            throw new RuntimeException('Couldn\'t make directory: ' . isset($results[1]) ? $results[1] : 'Unknown');
284
        }
285
286 3
        return true;
287
    }
288
289
    /**
290
     * Rename file
291
     *
292
     * @param string $oldPath
293
     * @param string $newPath
294
     * @return bool
295
     */
296 9
    public function rename($oldPath, $newPath)
297
    {
298 9
        return $this->move($oldPath, $newPath);
299
    }
300
301
    /**
302
     * Move file
303
     *
304
     * @param string $oldPath
305
     * @param string $newPath
306
     * @return bool
307
     */
308 9
    public function move($oldPath, $newPath)
309
    {
310 9
        $writeBinn = new BinnList;
311
312 9
        $writeBinn->addUint8(self::FSERV_MOVE);
313 9
        $writeBinn->addStr($oldPath);
314 9
        $writeBinn->addStr($newPath);
315 9
        $writeBinn->addBool(false);
316
317 9
        $binn = $writeBinn->serialize();
318
319 9
        $read = $this->writeAndReadSocket($binn);
320
321 9
        $readBinn = new BinnList;
322 9
        $readBinn->binnOpen($read);
323 9
        $results = $readBinn->unserialize();
324
325 9
        if ($results[0] != self::FSERV_STATUS_OK) {
326 3
            throw new RuntimeException('Couldn\'t move file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
327
        }
328
329 6
        return true;
330
    }
331
332
    /**
333
     * Copy file
334
     *
335
     * @param string $oldPath
336
     * @param string $newPath
337
     * @return bool
338
     */
339 6
    public function copy($oldPath, $newPath)
340
    {
341 6
        $writeBinn = new BinnList;
342
343 6
        $writeBinn->addUint8(self::FSERV_MOVE);
344 6
        $writeBinn->addStr($oldPath);
345 6
        $writeBinn->addStr($newPath);
346 6
        $writeBinn->addBool(true);            // Copy
347
348 6
        $read = $this->writeAndReadSocket($writeBinn->serialize());
349
350 6
        $readBinn = new BinnList;
351 6
        $readBinn->binnOpen($read);
352 6
        $results = $readBinn->unserialize();
353
354 6
        if ($results[0] != self::FSERV_STATUS_OK) {
355 3
            throw new RuntimeException('Couldn\'t copy file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
356
        }
357
358 3
        return true;
359
    }
360
361
    /**
362
     * Delete file/directory
363
     *
364
     * @param string $path
365
     * @param bool $recursive
366
     * @return bool
367
     */
368 6
    public function delete($path, $recursive = false)
369
    {
370 6
        $writeBinn = new BinnList;
371
372 6
        $writeBinn->addUint8(self::FSERV_REMOVE);
373 6
        $writeBinn->addStr($path);
374 6
        $writeBinn->addBool($recursive);
375
376 6
        $read = $this->writeAndReadSocket($writeBinn->serialize());
377
378 6
        $readBinn = new BinnList;
379 6
        $readBinn->binnOpen($read);
380 6
        $results = $readBinn->unserialize();
381
382 6
        if ($results[0] != self::FSERV_STATUS_OK) {
383 3
            throw new RuntimeException('Couldn\'t delete: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
384
        }
385
386 3
        return true;
387
    }
388
389
    /**
390
     * Get file metadata
391
     *
392
     * @param string $path
393
     * @return array
394
     */
395 6
    public function metadata($path)
396
    {
397 6
        $writeBinn= new BinnList;
398
399 6
        $writeBinn->addUint8(self::FSERV_FILEINFO);
400 6
        $writeBinn->addStr($path);
401
402 6
        $read = $this->writeAndReadSocket($writeBinn->serialize());
403
404 6
        $readBinn = new BinnList;
405
406 6
        $readBinn->binnOpen($read);
407 6
        $results = $readBinn->unserialize();
408
409 6
        if ($results[0] != self::FSERV_STATUS_OK) {
410 3
            throw new RuntimeException('GDaemon metadata error: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
411
        }
412
413 3
        $fileInfo = $results[2];
414
415
        return [
416 3
            'name' => basename($fileInfo[0]),
417 3
            'size' => $fileInfo[1],
418 3
            'type' => ($fileInfo[2] == 1) ? 'dir' : 'file',
419 3
            'mtime' => $fileInfo[3],
420 3
            'atime' => $fileInfo[4],
421 3
            'ctime' => $fileInfo[5],
422 3
            'permissions' => $fileInfo[6],
423 3
            'mimetype' => $fileInfo[7],
424 1
        ];
425
    }
426
427
    /**
428
     * Change file mode
429
     *
430
     * @param integer $mode
431
     * @param string $path
432
     * @return bool
433
     */
434 6
    public function chmod($mode, $path)
435
    {
436 6
        $writeBinn = new BinnList;
437
438 6
        $writeBinn->addUint8(self::FSERV_CHMOD);
439 6
        $writeBinn->addStr($path);
440 6
        $writeBinn->addUint16($mode);
441
442 6
        $read = $this->writeAndReadSocket($writeBinn->serialize());
443
444 6
        $readBinn = new BinnList;
445 6
        $readBinn->binnOpen($read);
446 6
        $results = $readBinn->unserialize();
447
448 6
        if ($results[0] != self::FSERV_STATUS_OK) {
449 3
            throw new RuntimeException('Couldn\'t chmod: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
450
        }
451
452 3
        return true;
453
    }
454
455
    /**
456
     * Check file exist
457
     *
458
     * @param $path
459
     * @return bool
460
     */
461 6
    public function exist($path)
462
    {
463 6
        return in_array(basename($path), $this->listFiles(dirname($path)));
464
    }
465
}