Passed
Push — master ( cd50f5...3c1055 )
by compolom
05:24
created

Storage::lastInsert()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
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([$this, 'cpFile'], $file);
65
    }
66
67
    protected function cpFile(File $file): array
68
    {
69
        $data = $file->getData();
70
        $md5 = $data['md5'];
71
        $dir = $this->createDir($md5);
72
        $item = $dir . DIRECTORY_SEPARATOR . $md5;
73
        rename($data['path'], $item);
74
        $meta = [
75
            'name' => $data['name'],
76
            'ext' => $data['ext'],
77
            'size' => $data['size'],
78
            'type' => $data['type'],
79
            'path' => $item,
80
            'bin' => $md5
81
        ];
82
        if ($this->config['addMetaFile']) {
83
            file_put_contents($item . '.php', "<?php\n\n" . 'return ' . var_export($meta, true) . ";\n");
84
        }
85
        return $meta;
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 . '.php';
105
        return is_file($fileName) ? include $fileName : 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() != 'php') {
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