Dir::stats()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 39
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 24
nc 4
nop 2
dl 0
loc 39
rs 9.536
c 0
b 0
f 0
1
<?php
2
3
namespace kalanis\RemoteRequest\Wrappers\Fsp;
4
5
6
use kalanis\RemoteRequest;
7
use kalanis\RemoteRequest\Protocols\Fsp as Protocol;
8
9
10
/**
11
 * Class Dir
12
 * @package kalanis\RemoteRequest\Wrappers\Fsp
13
 * Wrapper to plug FSP info into PHP - directory part
14
 */
15
class Dir extends AOperations
16
{
17
    /** @var Protocol\Answer\GetDir\FileInfo[] */
18
    protected array $files = [];
19
    protected string $path = '';
20
    protected int $seek = 0;
21
22
    public function close(): bool
23
    {
24
        $this->seek = 0;
25
        return true;
26
    }
27
28
    public function open(string $path, /** @scrutinizer ignore-unused */ int $options): bool
29
    {
30
        $this->path = $path;
31
        return true;
32
    }
33
34
    /**
35
     * @throws RemoteRequest\RequestException
36
     * @return string|bool
37
     */
38
    public function read()
39
    {
40
        $part = $this->readFiles($this->path);
41
        if (empty($part)) {
42
            return false;
43
        }
44
        return $part->getFilename();
45
    }
46
47
    public function rewind(): bool
48
    {
49
        $this->seek = 0;
50
        return true;
51
    }
52
53
    /**
54
     * @param string $path
55
     * @param int $mode
56
     * @param int $options
57
     * @throws RemoteRequest\RequestException
58
     * @return bool
59
     */
60
    public function make(string $path, /** @scrutinizer ignore-unused */ int $mode, /** @scrutinizer ignore-unused */ int $options): bool
61
    {
62
        $mkDir = new Protocol\Query\MakeDir($this->runner->getQuery());
63
        $mkDir->setDirPath($this->parsePath($path));
64
        $answer = $this->runner->setActionQuery($mkDir)->process();
65
        if (!$answer instanceof Protocol\Answer\Protection) {
66
            throw new RemoteRequest\RequestException($this->getRRLang()->rrFspBadMkDir(get_class($answer)));
67
        }
68
        // TODO: send protection data - set from $mode
69
//        $this->rights($path, $mode[0], true);
70
        return true;
71
    }
72
73
    /**
74
     * @param string $path
75
     * @param string $right
76
     * @param bool $allow
77
     * @throws RemoteRequest\RequestException
78
     * @return bool
79
     */
80
    public function rights(string $path, string $right, bool $allow): bool
81
    {
82
        $protect = new Protocol\Query\SetProtection($this->runner->getQuery());
83
        $protect
84
            ->setDirPath($this->parsePath($path))
85
            ->setOperation($right)
86
            ->allowOperation($allow)
87
        ;
88
        $answer = $this->runner->setActionQuery($protect)->process();
89
        if (!$answer instanceof Protocol\Answer\Protection) {
90
            throw new RemoteRequest\RequestException($this->getRRLang()->rrFspBadProtection(get_class($answer)));
91
        }
92
        return true;
93
    }
94
95
    /**
96
     * @param string $pathFrom
97
     * @param string $pathTo
98
     * @throws RemoteRequest\RequestException
99
     * @return bool
100
     */
101
    public function rename(string $pathFrom, string $pathTo): bool
102
    {
103
        $rename = new Protocol\Query\Rename($this->runner->getQuery());
104
        $rename
105
            ->setFilePath($this->parsePath($pathFrom))
106
            ->setNewPath($this->parsePath($pathTo, false))
107
        ;
108
        $answer = $this->runner->setActionQuery($rename)->process();
109
        if (!$answer instanceof Protocol\Answer\Nothing) {
110
            throw new RemoteRequest\RequestException($this->getRRLang()->rrFspBadRename(get_class($answer)));
111
        }
112
        return true;
113
    }
114
115
    /**
116
     * @param string $path
117
     * @param int $options
118
     * @throws RemoteRequest\RequestException
119
     * @return bool
120
     */
121
    public function remove(string $path, /** @scrutinizer ignore-unused */ int $options): bool
122
    {
123
        $delDir = new Protocol\Query\DelDir($this->runner->getQuery());
124
        $delDir->setDirPath($this->parsePath($path));
125
        $answer = $this->runner->setActionQuery($delDir)->process();
126
        if (!$answer instanceof Protocol\Answer\Nothing) {
127
            throw new RemoteRequest\RequestException($this->getRRLang()->rrFspBadRmDir(get_class($answer)));
128
        }
129
        return true;
130
    }
131
132
    /**
133
     * @param string $path
134
     * @param int $flags
135
     * @throws RemoteRequest\RequestException
136
     * @return array<int, int>
137
     */
138
    public function stats(string $path, /** @scrutinizer ignore-unused */ int $flags): array
139
    {
140
        $parsedPath = $this->parsePath($path);
141
        $slashPos = strrpos($path, '/');
142
        if (false === $slashPos) {
143
            throw new RemoteRequest\RequestException($this->getRRLang()->rrFspBadParsedPath($parsedPath));
144
        }
145
        $fileName = substr($path, $slashPos + 1);
146
        $dirPath = substr($path, 0, $slashPos);
147
148
        $infoAnswer = null;
149
//        $dirInfo = new Protocol\Query\GetProtection($this->runner->getQuery());
150
//        $dirInfo->setDirPath($dirPath);
151
//        $infoAnswer = $this->runner->setActionQuery($dirInfo)->process();
152
//        if (!$infoAnswer instanceof Protocol\Answer\Protection) {
153
//            throw new RemoteRequest\RequestException('Got something bad with stat protection. Class ' . get_class($infoAnswer));
154
//        }
155
156
        while ($fileInfo = $this->readFiles($dirPath)) {
157
            // seek into the name...
158
            if ($fileInfo->getFileName() == $fileName) {
159
                return [
160
                    0 => 0,
161
                    1 => 0,
162
                    2 => $this->parseMode($infoAnswer, $fileInfo->getOrigType()),
163
                    3 => 0,
164
                    4 => 0,
165
                    5 => 0,
166
                    6 => 0,
167
                    7 => $fileInfo->getSize(),
168
                    8 => $fileInfo->getATime(),
169
                    9 => $fileInfo->getMTime(),
170
                    10 => $fileInfo->getCTime(),
171
                    11 => -1,
172
                    12 => -1,
173
                ];
174
            }
175
        }
176
        throw new RemoteRequest\RequestException($this->getRRLang()->rrFspPathNotFound($path));
177
    }
178
179
    /**
180
     * @param string $path
181
     * @throws RemoteRequest\RequestException
182
     * @return Protocol\Answer\GetDir\FileInfo|null
183
     */
184
    public function readFiles(string $path): ?Protocol\Answer\GetDir\FileInfo
185
    {
186
        if (false === next($this->files)) {
187
            $this->files = $this->readDir($path)->getFiles();
188
            reset($this->files);
189
            $this->seek++;
190
        }
191
        $file = current($this->files);
192
        return false !== $file ? $file : null;
193
    }
194
195
    /**
196
     * @param string $path
197
     * @throws RemoteRequest\RequestException
198
     * @return Protocol\Answer\GetDir
199
     */
200
    protected function readDir(string $path): Protocol\Answer\GetDir
201
    {
202
        $rdDir = new Protocol\Query\GetDir($this->runner->getQuery());
203
        $rdDir->setDirPath($this->parsePath($path))->setPosition($this->seek);
204
        $answer = $this->runner->setActionQuery($rdDir)->process();
205
        if (!$answer instanceof Protocol\Answer\GetDir) {
206
            throw new RemoteRequest\RequestException($this->getRRLang()->rrFspBadMkDir(get_class($answer)));
207
        }
208
        $answer->process();
209
        return $answer;
210
    }
211
212
    /**
213
     * @param Protocol\Answer\Protection $info
214
     * @param int|null $mode
215
     * @throws RemoteRequest\RequestException
216
     * @return int
217
     * @link https://www.php.net/manual/en/function.stat.php
218
     */
219
    protected function parseMode(/** @scrutinizer ignore-unused */ ?Protocol\Answer\Protection $info, ?int $mode): int
220
    {
221
        switch ($mode) {
222
            case Protocol::RDTYPE_DIR:
223
                // recursion to load more about dir?
224
                return 0040755;
225
            case Protocol::RDTYPE_FILE:
226
                return 0100644;
227
            case Protocol::RDTYPE_LINK:
228
                return 0120644;
229
            case Protocol::RDTYPE_END:
230
                throw new RemoteRequest\RequestException($this->getRRLang()->rrFspFileCannotCont());
231
            default:
232
                return 0;
233
        }
234
    }
235
}
236