Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
WindowsStreamWrapper.php
001 <?php
002
003 /*
004 * Copyright (C) 2014 Nicolas Grekas - p@tchwork.com
005 *
006 * This library is free software; you can redistribute it and/or modify it
007 * under the terms of the (at your option):
008 * Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
009 * GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
010 */
011
012 namespace Patchwork\Utf8;
013
014 /**
015 * Unicode UTF-8 aware stream based filesystem access on MS-Windows.
016 *
017 * Based on COM Scripting.FileSystemObject object and short paths.
018 * See Patchwork\Utf8::wrapPath()
019 *
020 * See also https://code.google.com/p/php-wfio/ for a PHP extension
021 * and comments on http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php
022 */
023 class WindowsStreamWrapper
024 {
025 public $context;
026
027 protected $handle;
028
029 public static function hide($path)
030 {
031 list($fs, $path) = self::fs($path);
032 if ($fs->FileExists($path)) {
033 $fs->GetFile($path)->Attributes |= 2;
034 } elseif ($fs->FolderExists($path)) {
035 $fs->GetFolder($path)->Attributes |= 2;
036 } else {
037 return false;
038 }
039
040 return true;
041 }
042
043 public static function fs($path, $is_utf8 = true)
044 {
045 static $fs;
046
047 if (!class_exists('COM', false)) {
048 throw new \RuntimeException('The `wfio` or `com_dotnet` extension is required to handle UTF-8 filesystem access on Windows');
049 }
050
051 isset($fs) or $fs = new \COM('Scripting.FileSystemObject', null, CP_UTF8);
052
053 $path = explode('://', $path, 2);
054 $path = $path[(int) isset($path[1])];
055 $path = strtr($path, '/', '\\');
056 $pre = '';
057
058 if (!isset($path[0]) || ('/' !== $path[0] && '\\' !== $path[0] && false === strpos($path, ':'))) {
059 $pre = getcwd().'\\';
060 }
061
062 $pre = new \VARIANT($pre);
063
064 if ($is_utf8) {
065 $path = new \VARIANT($path, VT_BSTR, CP_UTF8);
066 } else {
067 $path = new \VARIANT($path);
068 }
069
070 return array($fs, $fs->getAbsolutePathName(variant_cat($pre, $path)));
071 }
072
073 public function dir_closedir()
074 {
075 $this->handle = null;
076
077 return true;
078 }
079
080 public function dir_opendir($path, $options)
081 {
082 list($fs, $path) = self::fs($path);
083 if (!$fs->FolderExists($path)) {
084 return false;
085 }
086
087 $dir = $fs->GetFolder($path);
088
089 try {
090 $f = array('.', '..');
091
092 foreach ($dir->SubFolders() as $v) {
093 $f[] = $v->Name;
094 }
095 foreach ($dir->Files as $v) {
096 $f[] = $v->Name;
097 }
098 } catch (\Exception $f) {
099 $f = array();
100 }
101
102 $this->handle = $f;
103
104 return true;
105 }
106
107 public function dir_readdir()
108 {
109 if (list(, $c) = each($this->handle)) {
110 return $c;
111 }
112
113 return false;
114 }
115
116 public function dir_rewinddir()
117 {
118 reset($this->handle);
119
120 return true;
121 }
122
123 public function mkdir($path, $mode, $options)
124 {
125 list($fs, $path) = self::fs($path);
126
127 try {
128 if ($options & STREAM_MKDIR_RECURSIVE) {
129 $path = $fs->GetAbsolutePathName($path);
130
131 $path = explode('\\', $path);
132
133 if (isset($path[3]) && '' === $path[0].$path[1]) {
134 $pre = '\\\\'.$path[2].'\\'.$path[3].'\\';
135 $i = 4;
136 } elseif (isset($path[1])) {
137 $pre = $path[0].'\\';
138 $i = 1;
139 } else {
140 $pre = '';
141 $i = 0;
142 }
143
144 while (isset($path[$i]) && $fs->FolderExists($pre.$path[$i])) {
145 $pre .= $path[$i++].'\\';
146 }
147
148 if (!isset($path[$i])) {
149 return false;
150 }
151
152 while (isset($path[$i])) {
153 $fs->CreateFolder($pre .= $path[$i++].'\\');
154 }
155
156 return true;
157 } else {
158 $fs->CreateFolder($path);
159 }
160
161 return true;
162 } catch (\Exception $e) {
163 return false;
164 }
165 }
166
167 public function rename($from, $to)
168 {
169 list($fs, $to) = self::fs($to);
170
171 if ($fs->FileExists($to) || $fs->FolderExists($to)) {
172 return false;
173 }
174
175 list(, $from) = self::fs($from);
176
177 try {
178 if ($fs->FileExists($from)) {
179 $fs->MoveFile($from, $to);
180
181 return true;
182 }
183
184 if ($fs->FolderExists($from)) {
185 $fs->MoveFolder($from, $to);
186
187 return true;
188 }
189 } catch (\Exception $e) {
190 }
191
192 return false;
193 }
194
195 public function rmdir($path, $options)
196 {
197 list($fs, $path) = self::fs($path);
198
199 if ($fs->FolderExists($path)) {
200 return rmdir($fs->GetFolder($path)->ShortPath);
201 }
202
203 return false;
204 }
205
206 public function stream_close()
207 {
208 fclose($this->handle);
209 $this->handle = null;
210 }
211
212 public function stream_eof()
213 {
214 return feof($this->handle);
215 }
216
217 public function stream_flush()
218 {
219 return fflush($this->handle);
220 }
221
222 public function stream_lock($operation)
223 {
224 return flock($this->handle, $operation);
225 }
226
227 public function stream_metadata($path, $option, $value)
228 {
229 list($fs, $path) = self::fs($path);
230
231 if ($fs->FileExists($path)) {
232 $f = $fs->GetFile($path);
233 } elseif ($fs->FileExists($path)) {
234 $f = $fs->GetFolder($path);
235 } else {
236 $f = false;
237 }
238
239 if (STREAM_META_TOUCH === $option) {
240 if ($f) {
241 return touch($f->ShortPath);
242 }
243
244 try {
245 $fs->OpenTextFile($path, 8, true, 0)->Close();
246
247 return true;
248 } catch (\Exception $e) {
249 }
250 }
251
252 if (!$f) {
253 return false;
254 }
255
256 switch ($option) {
257 case STREAM_META_ACCESS: return chmod($f->ShortPath, $value);
258 case STREAM_META_OWNER:
259 case STREAM_META_OWNER_NAME: return chown($f->ShortPath, $value);
260 case STREAM_META_GROUP:
261 case STREAM_META_GROUP_NAME: return chgrp($f->ShortPath, $value);
262 default: return false;
263 }
264 }
265
266 public function stream_open($path, $mode, $options, &$opened_path)
267 {
268 $mode .= '';
269 list($fs, $path) = self::fs($path);
270
271 if ($fs->FolderExists($path)) {
272 return false;
273 }
274
275 try {
276 if ('x' === $m = substr($mode, 0, 1)) {
277 $fs->CreateTextFile($path, false)->Close();
278 $f = $fs->GetFile($path);
279 $mode[0] = 'w';
280 } else {
281 $f = $fs->GetFile($path);
282 }
283 } catch (\Exception $f) {
284 try {
285 switch ($m) {
286 case 'w':
287 case 'c':
288 case 'a':
289 $h = $fs->CreateTextFile($path, true);
290 $f = $fs->GetFile($path);
291 $h->Close();
292 break;
293
294 default: return false;
295 }
296 } catch (\Exception $e) {
297 return false;
298 }
299 }
300
301 if (!(STREAM_REPORT_ERRORS & $options)) {
302 set_error_handler('var_dump', 0);
303 $e = error_reporting(0);
304 }
305
306 $this->handle = fopen($f->ShortPath, $mode);
307
308 if (!(STREAM_REPORT_ERRORS & $options)) {
309 error_reporting($e);
310 restore_error_handler();
311 }
312
313 if ($this->handle) {
314 return true;
315 }
316 if (isset($h)) {
317 $f->Delete(true);
318 }
319
320 return false;
321 }
322
323 public function stream_read($count)
324 {
325 return fread($this->handle, $count);
326 }
327
328 public function stream_seek($offset, $whence = SEEK_SET)
329 {
330 return fseek($this->handle, $offset, $whence);
331 }
332
333 public function stream_set_option($option, $arg1, $arg2)
334 {
335 switch ($option) {
336 case STREAM_OPTION_BLOCKING: return stream_set_blocking($this->handle, $arg1);
337 case STREAM_OPTION_READ_TIMEOUT: return stream_set_timeout($this->handle, $arg1, $arg2);
338 case STREAM_OPTION_WRITE_BUFFER: return stream_set_write_buffer($this->handle, $arg1, $arg2);
339 default: return false;
340 }
341 }
342
343 public function stream_stat()
344 {
345 return fstat($this->handle);
346 }
347
348 public function stream_tell()
349 {
350 return ftell($this->handle);
351 }
352
353 public function stream_truncate($new_size)
354 {
355 return ftruncate($this->handle, $new_size);
356 }
357
358 public function stream_write($data)
359 {
360 return fwrite($this->handle, $data, strlen($data));
361 }
362
363 public function unlink($path)
364 {
365 list($fs, $path) = self::fs($path);
366
367 if ($fs->FileExists($path)) {
368 return unlink($fs->GetFile($path)->ShortPath);
369 }
370
371 return false;
372 }
373
374 public function url_stat($path, $flags)
375 {
376 list($fs, $path) = self::fs($path);
377
378 if ($fs->FileExists($path)) {
379 $f = $fs->GetFile($path);
380 } elseif ($fs->FolderExists($path)) {
381 $f = $fs->GetFolder($path);
382 } else {
383 return false;
384 }
385
386 if (STREAM_URL_STAT_QUIET & $flags) {
387 set_error_handler('var_dump', 0);
388 $e = error_reporting(0);
389 }
390
391 if (STREAM_URL_STAT_LINK & $flags) {
392 $f = @lstat($f->ShortPath) ?: stat($f->ShortPath);
393 } else {
394 $f = stat($f->ShortPath);
395 }
396
397 if (STREAM_URL_STAT_QUIET & $flags) {
398 error_reporting($e);
399 restore_error_handler();
400 }
401
402 return $f;
403 }
404 }
405