Passed
Branch master (cd50f5)
by compolom
02:57 queued 01:13
created

Storage::sortByTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Compolomus\BinaryFileStorage;
4
5
class Storage
6
{
7
    protected $dir;
8
9
    protected $count;
10
11
    protected $config;
12
13
    protected $upload;
14
15
    public function __construct(array $config = [])
16
    {
17
        $defaultConfig = [
18
            'uploadDir' => 'upload',
19
            'prefix' => '',
20
            'addMetaFile' => true,
21
            'firstDirLen' => 2,
22
            'secondDirLen' => 2
23
        ];
24
        $this->config = \array_merge($defaultConfig, $config);
25
        $this->dir = $this->createStorageDir($config['uploadDir'] . DIRECTORY_SEPARATOR . $config['prefix']);
26
        $this->upload = new Upload($this->dir);
27
        $this->count = \count($this->map());
28
    }
29
30
    private function createStorageDir(string $dir): string
31
    {
32
        if (!is_dir($dir)) {
33
            \mkdir(\rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'tmp', 0750, true);
34
        }
35
        return $dir;
36
    }
37
38
    public function check(array $input): ?array
39
    {
40
        if (\count($input)) {
41
            return $this->add($this->upload->process($input));
42
        }
43
        return null;
44
    }
45
46
    public function count(): int
47
    {
48
        return $this->count;
49
    }
50
51
    public function lastInsert(int $files = 1, int $offset = 0): ?\LimitIterator
52
    {
53
        return ($this->count >= $files ? new \LimitIterator($this->map(), $offset, $files) : null);
54
    }
55
56
    public function download(string $file): ?\SplFileObject
57
    {
58
        $fileName = \is_file($file) ? $file : $this->dirName($file) . DIRECTORY_SEPARATOR . $file;
59
        return \is_file($fileName) ? new \SplFileObject($fileName) : null;
60
    }
61
62
    private function add(array $file): array
63
    {
64
        return array_map(
65
            function (File $file) {
66
                $data = $file->getData();
67
                $md5 = $data['md5'];
68
                $dir = $this->createDir($md5);
69
                $item = $dir . DIRECTORY_SEPARATOR . $md5;
70
                \rename($data['path'], $item);
71
                $meta = [
72
                    'name' => $data['name'],
73
                    'ext' => $data['ext'],
74
                    'size' => $data['size'],
75
                    'type' => $data['type'],
76
                    'path' => $item,
77
                    'bin' => $md5
78
                ];
79
                if ($this->config['addMetaFile']) {
80
                    \file_put_contents($item . '.json',
81
                        json_encode($meta));
82
                }
83
                return $meta;
84
            }
85
            , $file);
86
    }
87
88
    public function fileSize(int $size): string
89
    {
90
        $alpha = [" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"];
91
        return $size ? \round($size / \pow(1024, ($iterator = \floor(\log($size, 1024)))),
92
                2) . $alpha[(int)$iterator] : '0 Bytes';
93
    }
94
95
    public function dirName(string $file): string
96
    {
97
        return $this->dir . DIRECTORY_SEPARATOR . \substr($file, 0,
98
                $this->config['firstDirLen']) . DIRECTORY_SEPARATOR . \substr($file, $this->config['firstDirLen'],
99
                $this->config['secondDirLen']);
100
    }
101
102
    public function getInfoFile(string $file): ?array
103
    {
104
        $fileName = $this->dirName($file) . DIRECTORY_SEPARATOR . $file . '.json';
105
        return \is_file($fileName) ? \json_decode(\file_get_contents($fileName), true) : null;
106
    }
107
108
    public function map(): \ArrayIterator
109
    {
110
        $files = [];
111
        foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->dir),
112
            \RecursiveIteratorIterator::CHILD_FIRST) as $fullFileName => $splFileObject) {
113
            if ($splFileObject->isFile() && $splFileObject->getExtension() != 'json') {
114
                $files[\basename($fullFileName)] = [
115
                    'file' => $splFileObject->getRealPath(),
116
                    'time' => $splFileObject->getMTime()
117
                ];
118
            }
119
            \uasort($files, function (array $first, array $second): int {
120
                return ($first['time'] <=> $second['time']);
121
            });
122
        }
123
        return new \ArrayIterator($files);
124
    }
125
126
    private function createDir(string $md5): string
127
    {
128
        $dir = $this->dirName($md5);
129
        if (!is_dir($dir)) {
130
            \mkdir($dir . DIRECTORY_SEPARATOR, 0750, true);
131
        }
132
        return $dir;
133
    }
134
}
135