GdaemonFiles::put()   B
last analyzed

Complexity

Conditions 11
Paths 23

Size

Total Lines 60
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 11.014

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 11
eloc 40
c 2
b 1
f 0
nc 23
nop 3
dl 0
loc 60
ccs 39
cts 41
cp 0.9512
crap 11.014
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\Gameap\Exception\GdaemonClientException;
6
use InvalidArgumentException;
7
8
class GdaemonFiles extends Gdaemon
9
{
10
    const FSERV_AUTH            = 1;
11
    const FSERV_FILESEND        = 3;
12
    const FSERV_READDIR         = 4;
13
    const FSERV_MKDIR           = 5;
14
    const FSERV_MOVE            = 6;
15
    const FSERV_REMOVE          = 7;
16
    const FSERV_FILEINFO        = 8;
17
    const FSERV_CHMOD           = 9;
18
19
    const FSERV_UPLOAD_TO_SERVER        = 1;
20
    const FSERV_DOWNLOAD_FR_SERVER      = 2;
21
22
    const FSERV_STATUS_ERROR                = 1;
23
    const FSERV_STATUS_UNKNOWN_COMMAND      = 3;
24
    const FSERV_STATUS_OK                   = 100;
25
    const FSERV_STATUS_FILE_TRANSFER_READY  = 101;
26
27
    const LIST_FILES_WITHOUT_DETAILS  = 0;
28
    const LIST_FILES_WITH_DETAILS     = 1;
29
30
    /**
31
     * @var int
32
     */
33
    protected $mode = self::DAEMON_SERVER_MODE_FILES;
34
35
    /**
36
     * Upload file to server
37
     *
38
     * @param string|resource $locFile path to local file or file stream
39
     * @param string $remFile path to remote file
40
     * @param int $permission
41
     *
42 21
     * @return bool|resource
43
     */
44 21
    public function put($locFile, string $remFile, int $permission = 0644)
45
    {
46 15
        if (is_string($locFile)) {
47 15
            set_error_handler(function () {});
48 11
            $fileHandle = fopen($locFile, 'r');
49 3
            restore_error_handler();
50 1
        } else if (is_resource($locFile)) {
51 3
            $fileHandle = $locFile;
52
        } else {
53
            throw new InvalidArgumentException('Invalid local file');
54 18
        }
55 3
56
        if ($fileHandle === false) {
0 ignored issues
show
introduced by
The condition $fileHandle === false is always false.
Loading history...
57
            throw new GdaemonClientException('File open error');
58 15
        }
59 15
60 15
        $stat = fstat($fileHandle);
61
        $filesize = $stat['size'];
62 15
        unset($stat);
63
64 15
        $message = $this->binn->serialize([
65 15
            self::FSERV_FILESEND,
66 15
            self::FSERV_UPLOAD_TO_SERVER,
67 15
            $remFile,
68 15
            $filesize,
69 15
            true,           // Make dirs
70
            $permission
71 15
        ]);
72
73 15
        $read = $this->writeAndReadSocket($message);
74 15
75 15
        $results = $this->binn->unserialize($read);
76
77 15
        if ($results[0] == self::FSERV_STATUS_OK) {
78 3
            throw new GdaemonClientException('Unexpected \'OK\' status. Expected \'ready to transfer\'');
79 12
        } else if ($results[0] != self::FSERV_STATUS_FILE_TRANSFER_READY) {
80 3
            throw new GdaemonClientException('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
        if (!is_string($read)) {
0 ignored issues
show
introduced by
The condition is_string($read) is always true.
Loading history...
89 9
            throw new GdaemonClientException('Failed to read socket');
90 9
        }
91 9
92
        $results = $this->binn->unserialize($read);
93 9
94 3
        if ($results[0] != self::FSERV_STATUS_OK) {
95
            throw new GdaemonClientException('Couldn\'t send file: ' . ($results[1] ?? 'Unknown'));
96
        }
97 6
98 3
        if (is_resource($locFile)) {
99 3
            rewind($fileHandle);
100
            return $fileHandle;
101 3
        } else {
102 3
            fclose($fileHandle);
103
            return true;
104
        }
105
    }
106
107
    /**
108
     * Download file
109
     *
110
     * @param string $remFile path to remote file
111
     * @param string|resource $locFile path to local file or file stream
112
     *
113
     * @return boolean|resource
114 24
     */
115
    public function get(string $remFile, $locFile)
116 24
    {
117
        if (is_string($locFile)) {
118 18
            set_error_handler(function () {});
119 18
            $fileHandle = fopen($locFile, 'w+b');
120 12
            restore_error_handler();
121 3
        } else if (is_resource($locFile)) {
122 1
            $fileHandle = $locFile;
123 3
        } else {
124
            throw new InvalidArgumentException('Invalid local file');
125
        }
126 21
127 3
        if ($fileHandle === false) {
0 ignored issues
show
introduced by
The condition $fileHandle === false is always false.
Loading history...
128
            throw new GdaemonClientException('File open error');
129
        }
130 18
131
        $message = $this->binn->serialize([
132 18
            self::FSERV_FILESEND,
133 18
            self::FSERV_DOWNLOAD_FR_SERVER,
134 18
            $remFile,
135
        ]);
136 18
137
        $read = $this->writeAndReadSocket($message);
138 18
139 18
        $results = $this->binn->unserialize($read);
140 18
141
        if ($results[0] == self::FSERV_STATUS_OK) {
142 18
            throw new GdaemonClientException('Unexpected `OK` status. Expected `ready to transfer`');
143 3
        } else if ($results[0] != self::FSERV_STATUS_FILE_TRANSFER_READY) {
144 15
            throw new GdaemonClientException('Couldn\'t upload file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
145 3
        }
146
147
        $filesize = $results[2];
148 12
        $writed = 0;
149
150 12
        while($writed < $filesize) {
151 12
            if ($filesize - $writed > $this->maxBufsize) {
152
                $readlen = $this->maxBufsize;
153 12
            }
154 12
            else {
155 3
                $readlen = $filesize - $writed;
156 1
            }
157
158 12
            $socketRead = $this->readSocket($readlen, true);
159
160
            $writed += fwrite($fileHandle, $socketRead, $readlen);
161 12
        }
162
163 12
        if (is_resource($locFile)) {
164 4
            rewind($fileHandle);
165
            return $fileHandle;
166 12
        } else {
167 3
            fclose($fileHandle);
168 3
            return true;
169
        }
170 9
    }
171 9
172
    public function listFiles(string $directory): array
173
    {
174
        $message = $this->binn->serialize([
175
            self::FSERV_READDIR,
176
            $directory,
177
            self::LIST_FILES_WITHOUT_DETAILS,
178
        ]);
179
180
        $read = $this->writeAndReadSocket($message);
181
182 12
        $results = $this->binn->unserialize($read);
183
184 12
        if ($results[0] != self::FSERV_STATUS_OK) {
185
            throw new GdaemonClientException('GDaemon List files error:' . (isset($results[1]) ? $results[1] : 'Unknown'));
186 12
        }
187 12
188 12
        $filesList = $results[2] ?? [];
189
        $returnList = [];
190 12
191
        foreach($filesList as $file) {
192 12
193
            if (in_array(basename($file[0]), ['.', '..'])) {
194 12
                continue;
195 12
            }
196
197 12
            $returnList[] = basename($file[0]);
198
        }
199 3
200
        return $returnList;
201
    }
202 9
203 9
    public function directoryContents(string $directory): array
204
    {
205 9
        $message = $this->binn->serialize([
206
            self::FSERV_READDIR,
207 9
            $directory,
208 3
            self::LIST_FILES_WITH_DETAILS,
209
        ]);
210
211 9
        $read = $this->writeAndReadSocket($message);
212 3
213
        $results = $this->binn->unserialize($read);
214 9
215
        if ($results[0] != self::FSERV_STATUS_OK) {
216
            // Error
217
            throw new GdaemonClientException('GDaemon List files error:' . (isset($results[1]) ? $results[1] : 'Unknown'));
218
        }
219
220
        $filesList = $results[2];
221 9
        $returnList = [];
222
223 9
        foreach($filesList as $file) {
224
            if (in_array(basename($file[0]), ['.', '..'])) {
225 9
                continue;
226 9
            }
227 9
228
            $returnList[] = [
229 9
                'name' => basename($file[0]),
230
                'size' => $file[1],
231 9
                'mtime' => $file[2],
232
                'type' => ($file[3] == 1) ? 'dir' : 'file',
233 9
                'permissions' => $file[4],
234 9
            ];
235
        }
236 9
237
        return $returnList;
238 3
    }
239
240
    public function mkdir(string $path, int $permissions = 0755): bool
241 6
    {
242 6
        $message = $this->binn->serialize([
243
            self::FSERV_MKDIR,
244 6
            $path,
245 3
            $permissions,
246 3
        ]);
247
248
        $read = $this->writeAndReadSocket($message);
249 3
250 3
        $results = $this->binn->unserialize($read);
251 3
252 3
        if ($results[0] != self::FSERV_STATUS_OK) {
253 3
            throw new GdaemonClientException(
254 3
                'Couldn\'t make directory: ' . isset($results[1]) ? $results[1] : 'Unknown'
255
            );
256 2
        }
257
258 6
        return true;
259
    }
260
261
    public function rename(string $oldPath, string $newPath): bool
262
    {
263
        return $this->move($oldPath, $newPath);
264
    }
265
266
    public function move(string $oldPath, string $newPath): bool
267
    {
268 6
        $message = $this->binn->serialize([
269
            self::FSERV_MOVE,
270 6
            $oldPath,
271
            $newPath,
272 6
            false           // Copy file
273 6
        ]);
274 6
275
        $read = $this->writeAndReadSocket($message);
276 6
277
        $results = $this->binn->unserialize($read);
278 6
279 6
        if ($results[0] != self::FSERV_STATUS_OK) {
280 6
            throw new GdaemonClientException('Couldn\'t move file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
281
        }
282 6
283 3
        return true;
284
    }
285
286 3
    public function copy(string $oldPath, string $newPath): bool
287
    {
288
        $message = $this->binn->serialize([
289
            self::FSERV_MOVE,
290
            $oldPath,
291
            $newPath,
292
            true           // Copy file
293
        ]);
294
295
        $read = $this->writeAndReadSocket($message);
296 9
297
        $results = $this->binn->unserialize($read);
298 9
299
        if ($results[0] != self::FSERV_STATUS_OK) {
300
            throw new GdaemonClientException('Couldn\'t copy file: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
301
        }
302
303
        return true;
304
    }
305
306
    public function delete(string $path, bool $recursive = false): bool
307
    {
308 9
        $message = $this->binn->serialize([
309
            self::FSERV_REMOVE,
310 9
            $path,
311
            $recursive,
312 9
        ]);
313 9
314 9
        $read = $this->writeAndReadSocket($message);
315 9
316
        $results = $this->binn->unserialize($read);
317 9
318
        if ($results[0] != self::FSERV_STATUS_OK) {
319 9
            throw new GdaemonClientException('Couldn\'t delete: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
320
        }
321 9
322 9
        return true;
323 9
    }
324
325 9
    public function metadata(string $path): array
326 3
    {
327
        $message = $this->binn->serialize([
328
            self::FSERV_FILEINFO,
329 6
            $path,
330
        ]);
331
332
        $read = $this->writeAndReadSocket($message);
333
334
        $results = $this->binn->unserialize($read);
335
336
        if ($results[0] != self::FSERV_STATUS_OK) {
337
            throw new GdaemonClientException('GDaemon metadata error: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
338
        }
339 6
340
        $fileInfo = $results[2];
341 6
342
        return [
343 6
            'name' => basename($fileInfo[0]),
344 6
            'size' => $fileInfo[1],
345 6
            'type' => ($fileInfo[2] == 1) ? 'dir' : 'file',
346 6
            'mtime' => $fileInfo[3],
347
            'atime' => $fileInfo[4],
348 6
            'ctime' => $fileInfo[5],
349
            'permissions' => $fileInfo[6],
350 6
            'mimetype' => $fileInfo[7],
351 6
        ];
352 6
    }
353
354 6
    public function chmod(int $mode, string $path): bool
355 3
    {
356
        $message = $this->binn->serialize([
357
            self::FSERV_CHMOD,
358 3
            $path,
359
            $mode,
360
        ]);
361
362
        $read = $this->writeAndReadSocket($message);
363
364
        $results = $this->binn->unserialize($read);
365
366
        if ($results[0] != self::FSERV_STATUS_OK) {
367
            throw new GdaemonClientException('Couldn\'t chmod: ' . (isset($results[1]) ? $results[1] : 'Unknown'));
368 6
        }
369
370 6
        return true;
371
    }
372 6
373 6
    public function exist(string $path): bool
374 6
    {
375
        return in_array(basename($path), $this->listFiles(dirname($path)));
376 6
    }
377
}
378