Passed
Push — master ( 95ec1e...702df7 )
by Petr
02:32
created

CanDirFlat::readDir()   B

Complexity

Conditions 10
Paths 58

Size

Total Lines 48
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 10

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 10
eloc 32
nc 58
nop 3
dl 0
loc 48
rs 7.6666
c 1
b 0
f 1
ccs 34
cts 34
cp 1
crap 10

How to fix   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 kalanis\kw_files\Processing\Storage\Dirs;
4
5
6
use kalanis\kw_files\FilesException;
7
use kalanis\kw_files\Interfaces\IFLTranslations;
8
use kalanis\kw_files\Interfaces\ITypes;
9
use kalanis\kw_files\Node;
10
use kalanis\kw_paths\PathsException;
11
use kalanis\kw_storage\Interfaces\IPassDirs;
12
use kalanis\kw_storage\StorageException;
13
14
15
/**
16
 * Class CanDirDirect
17
 * @package kalanis\kw_files\Processing\Storage\Dirs
18
 * Process dirs via predefined api
19
 */
20
class CanDirFlat extends ADirs
21
{
22
    /** @var IPassDirs */
23
    protected $storage = null;
24
25 12
    public function __construct(IPassDirs $storage, ?IFLTranslations $lang = null)
26
    {
27 12
        $this->storage = $storage;
28 12
        $this->setLang($lang);
29 12
    }
30
31 3
    public function createDir(array $entry, bool $deep = false): bool
32
    {
33 3
        $path = $this->getStorageSeparator() . $this->compactName($entry, $this->getStorageSeparator());
34
        try {
35 3
            return $this->storage->mkDir($path, $deep);
36 1
        } catch (StorageException $ex) {
37 1
            throw new FilesException($this->getLang()->flCannotCreateDir($path), $ex->getCode(), $ex);
38
        }
39
    }
40
41
    /**
42
     * @param string[] $entry
43
     * @param bool $loadRecursive
44
     * @param bool $wantSize
45
     * @throws FilesException
46
     * @throws PathsException
47
     * @return Node[]
48
     */
49 6
    public function readDir(array $entry, bool $loadRecursive = false, bool $wantSize = false): array
50
    {
51 6
        $entryPath = $this->removeSeparator($this->compactName(array_filter($entry), $this->getStorageSeparator()));
52 6
        $entryPath = empty($entryPath) ? '' : $this->getStorageSeparator() . $entryPath;
53
        try {
54 6
            if (!$this->isNode($entryPath)) {
55 1
                throw new FilesException($this->getLang()->flCannotReadDir($entryPath));
56
            }
57
            /** @var array<string, Node> */
58 4
            $files = [];
59 4
            $sepLen = mb_strlen($this->getStorageSeparator());
60 4
            foreach ($this->storage->lookup($entryPath) as $item) {
61 4
                $usePath = mb_substr($item, $sepLen);
62 4
                if (!$loadRecursive && (false !== mb_strpos($usePath, $this->getStorageSeparator()))) {
63
                    // pass sub when not need
64 2
                    continue;
65
                }
66
67 4
                $sub = new Node();
68 4
                $currentPath = $this->removeSeparator($this->compactName(array_merge(
69 4
                    $entry,
70 4
                    $this->expandName($item, $this->getStorageSeparator())
71 4
                ), $this->getStorageSeparator()));
72 4
                if (empty($item)) {
73 4
                    $sub->setData(
74 4
                        [],
75 4
                        0,
76 4
                        ITypes::TYPE_DIR
77
                    );
78 4
                } elseif ($this->isNode($this->getStorageSeparator(). $currentPath)) {
79 3
                    $sub->setData(
80 3
                        $this->expandName($usePath),
81 3
                        0,
82 3
                        ITypes::TYPE_DIR
83
                    );
84
                } else {
85
                    // normal node - file
86 4
                    $sub->setData(
87 4
                        $this->expandName($usePath),
88 4
                        $wantSize ? $this->getSize($this->getStorageSeparator() . $currentPath) : 0,
89 4
                        ITypes::TYPE_FILE
90
                    );
91
                }
92 4
                $files[] = $sub;
93
            }
94 4
            return $files;
95 2
        } catch (StorageException $ex) {
96 1
            throw new FilesException($this->getLang()->flCannotReadDir($entryPath), $ex->getCode(), $ex);
97
        }
98
    }
99
100 2
    public function copyDir(array $source, array $dest): bool
101
    {
102 2
        $src = $this->getStorageSeparator() . $this->compactName($source, $this->getStorageSeparator());
103 2
        $dst = $this->getStorageSeparator() . $this->compactName($dest, $this->getStorageSeparator());
104
        try {
105 2
            return $this->storage->copy($src, $dst);
106 1
        } catch (StorageException $ex) {
107 1
            throw new FilesException($this->getLang()->flCannotCopyDir($src, $dst), $ex->getCode(), $ex);
108
        }
109
    }
110
111 2
    public function moveDir(array $source, array $dest): bool
112
    {
113 2
        $src = $this->getStorageSeparator() . $this->compactName($source, $this->getStorageSeparator());
114 2
        $dst = $this->getStorageSeparator() . $this->compactName($dest, $this->getStorageSeparator());
115
        try {
116 2
            return $this->storage->move($src, $dst);
117 1
        } catch (StorageException $ex) {
118 1
            throw new FilesException($this->getLang()->flCannotMoveDir($src, $dst), $ex->getCode(), $ex);
119
        }
120
    }
121
122 2
    public function deleteDir(array $entry, bool $deep = false): bool
123
    {
124 2
        $path = $this->getStorageSeparator() . $this->compactName($entry, $this->getStorageSeparator());
125
        try {
126 2
            if ($this->storage->isDir($path)) {
127 1
                return $this->storage->rmDir($path, $deep);
128
            } else {
129 1
                return false;
130
            }
131 1
        } catch (StorageException $ex) {
132 1
            throw new FilesException($this->getLang()->flCannotRemoveDir($path), $ex->getCode(), $ex);
133
        }
134
    }
135
136 6
    protected function removeSeparator(string $path): string
137
    {
138 6
        $sepLen = mb_strlen($this->getStorageSeparator());
139 6
        $first = mb_substr($path, 0, $sepLen);
140 6
        return $this->getStorageSeparator() == $first ? mb_substr($path, $sepLen) : $path;
141
    }
142
143
    /**
144
     * @param string $entry
145
     * @throws StorageException
146
     * @return bool
147
     */
148 6
    protected function isNode(string $entry): bool
149
    {
150 6
        return $this->storage->exists($entry) && $this->storage->isDir($entry);
151
    }
152
153
    /**
154
     * @param string $file
155
     * @throws FilesException
156
     * @throws StorageException
157
     * @return int
158
     */
159 1
    protected function getSize(string $file): int
160
    {
161 1
        $content = $this->storage->read($file);
162 1
        if (is_resource($content)) {
163
            // @codeCoverageIgnoreStart
164
            // usually not need to use
165
            // a bit workaround
166
            $tempStream = fopen("php://temp", "w+b");
167
            if (false === $tempStream) {
168
                throw new FilesException($this->getLang()->flCannotLoadFile($file));
169
            }
170
            rewind($content);
171
            $size = stream_copy_to_stream($content, $tempStream, -1, 0);
172
            if (false === $size) {
173
                throw new FilesException($this->getLang()->flCannotGetSize($file));
174
            }
175
            return intval($size);
176
        } else {
177
        // @codeCoverageIgnoreEnd
178 1
            return strlen(strval($content));
179
        }
180
    }
181
182
    /**
183
     * @return string
184
     * @codeCoverageIgnore only when path fails
185
     */
186
    protected function noDirectoryDelimiterSet(): string
187
    {
188
        return $this->getLang()->flNoDirectoryDelimiterSet();
189
    }
190
}
191