Passed
Push — master ( 84c32b...3332dd )
by Pol
02:08
created

PhpVfs::stream_read()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 6
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace drupol\phpvfs;
6
7
use drupol\phpvfs\Commands\Cd;
8
use drupol\phpvfs\Commands\Exist;
9
use drupol\phpvfs\Commands\Get;
10
use drupol\phpvfs\Filesystem\Filesystem;
11
use drupol\phpvfs\Filesystem\FilesystemInterface;
12
use drupol\phpvfs\Node\File;
13
use drupol\phpvfs\Node\FileInterface;
14
use drupol\phpvfs\Utils\Path;
15
16
class PhpVfs
17
{
18
    public const SCHEME = 'phpvfs';
19
20
    /**
21
     * @var array
22
     */
23
    public $context;
24
25
    /**
26
     * @var null|\drupol\phpvfs\Node\FileInterface
27
     */
28
    private $currentFile;
29
30
    /**
31
     * @return \drupol\phpvfs\Filesystem\FilesystemInterface
32
     */
33 1
    public static function fs(): FilesystemInterface
34
    {
35 1
        $options = \stream_context_get_options(
36 1
            \stream_context_get_default()
37
        );
38
39 1
        return $options[static::SCHEME]['filesystem'];
40
    }
41
42
    /**
43
     * @param \drupol\phpvfs\Filesystem\Filesystem $filesystem
44
     * @param array $options
45
     */
46 1
    public static function register(Filesystem $filesystem, array $options = [])
47
    {
48
        $options = [
49 1
            static::SCHEME => [
50 1
                'filesystem' => $filesystem,
51 1
            ] + $options,
52
        ];
53
54 1
        \stream_context_set_default($options);
55 1
        \stream_wrapper_register(self::SCHEME, __CLASS__);
56 1
    }
57
58
    /**
59
     * @param string $from
60
     * @param string $to
61
     *
62
     * @throws \Exception
63
     *
64
     * @return bool
65
     */
66 1
    public function rename(string $from, string $to): bool
67
    {
68 1
        $from = $this->stripScheme($from);
69 1
        $to = $this->stripScheme($to);
70
71 1
        if (Exist::exec($this::fs(), $from)) {
72 1
            $from = Get::exec($this::fs(), $from);
73
        } else {
74
            throw new \Exception('Source resource does not exist.');
75
76
            return false;
0 ignored issues
show
Unused Code introduced by
return false is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
77
        }
78
79 1
        if (Exist::exec($this::fs(), $to)) {
80
            throw new \Exception('Destination already exist.');
81
82
            return false;
83
        }
84
85 1
        $toPath = Path::fromString($to);
86
87 1
        $this::fs()
88 1
            ->getCwd()
89 1
            ->mkdir($toPath->dirname());
90
91 1
        if (null !== $parent = $from->getParent()) {
92 1
            $parent->delete($from);
93
        }
94
95 1
        Cd::exec($this::fs(), $toPath->dirname());
96
97 1
        $from->setAttribute('id', $toPath->basename());
98
99 1
        if ($from instanceof FileInterface) {
100 1
            $from->setPosition(0);
101
        }
102
103 1
        $this::fs()
104 1
            ->getCwd()
105 1
            ->add($from);
106
107 1
        return true;
108
    }
109
110
    /**
111
     * @see http://php.net/streamwrapper.stream-close
112
     */
113 1
    public function stream_close() // phpcs:ignore
114
    {
115 1
        if (null !== $this->currentFile) {
116 1
            $this->currentFile->setPosition(0);
117
        }
118
119 1
        $this->currentFile = null;
120 1
    }
121
122
    /**
123
     * @return bool
124
     *
125
     * @see http://php.net/streamwrapper.stream-eof
126
     */
127
    public function stream_eof(): bool // phpcs:ignore
128
    {
129
        return true;
130
    }
131
132
    /**
133
     * @param string $resource
134
     *
135
     * @throws \Exception
136
     *
137
     * @return bool
138
     */
139 1
    public function stream_open(string $resource) // phpcs:ignore
140
    {
141 1
        $resource = $this->stripScheme($resource);
142
143 1
        if (true === $this::fs()->exist($resource)) {
144
            $file = $this::fs()->get($resource);
145
146
            if ($file instanceof FileInterface) {
147
                $this->currentFile = $file;
148
            }
149
        } else {
150 1
            $this->currentFile = File::create($resource);
151 1
            $this::fs()->getCwd()->add($this->currentFile->root());
152
        }
153
154 1
        if (null === $this->currentFile) {
155
            return false;
156
        }
157
158 1
        $this->currentFile->setPosition(0);
159
160 1
        return true;
161
    }
162
163
    /**
164
     * @see http://php.net/streamwrapper.stream-read
165
     *
166
     * @param int $bytes
167
     *
168
     * @return mixed
169
     */
170
    public function stream_read(int $bytes) // phpcs:ignore
171
    {
172
        if (null !== $this->currentFile) {
173
            return $this->currentFile->read($bytes);
174
        }
175
176
        return false;
177
    }
178
179
    /**
180
     * @param string $data
181
     *
182
     * @return int
183
     */
184 1
    public function stream_write(string $data) // phpcs:ignore
185
    {
186 1
        if (null !== $this->currentFile) {
187 1
            return $this->currentFile->write($data);
188
        }
189
190
        return 0;
191
    }
192
193
    /**
194
     * @param string $path
195
     *
196
     * @throws \Exception
197
     */
198 1
    public function unlink(string $path)
199
    {
200 1
        $path = $this->stripScheme($path);
201
202 1
        if (true === Exist::exec($this::fs(), $path)) {
203 1
            $file = Get::exec($this::fs(), $path);
204
205 1
            if (null !== $parent = $file->getParent()) {
206 1
                $parent->delete($file);
207
            }
208
        }
209 1
    }
210
211
    /**
212
     * Returns path stripped of url scheme (http://, ftp://, test:// etc.).
213
     *
214
     * @param string $path
215
     *
216
     * @return string
217
     */
218 1
    protected function stripScheme(string $path): string
219
    {
220 1
        return '/' . \ltrim(\substr($path, 9), '/');
221
    }
222
}
223