[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * Copyright (C) 2014 Nicolas Grekas - p@tchwork.com 5 * 6 * This library is free software; you can redistribute it and/or modify it 7 * under the terms of the (at your option): 8 * Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or 9 * GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt). 10 */ 11 12 namespace Patchwork\Utf8; 13 14 /** 15 * Unicode UTF-8 aware stream based filesystem access on MS-Windows. 16 * 17 * Based on COM Scripting.FileSystemObject object and short paths. 18 * See Patchwork\Utf8::wrapPath() 19 * 20 * See also https://code.google.com/p/php-wfio/ for a PHP extension 21 * and comments on http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php 22 */ 23 class WindowsStreamWrapper 24 { 25 public $context; 26 27 protected $handle; 28 29 public static function hide($path) 30 { 31 list($fs, $path) = self::fs($path); 32 if ($fs->FileExists($path)) { 33 $fs->GetFile($path)->Attributes |= 2; 34 } elseif ($fs->FolderExists($path)) { 35 $fs->GetFolder($path)->Attributes |= 2; 36 } else { 37 return false; 38 } 39 40 return true; 41 } 42 43 public static function fs($path, $is_utf8 = true) 44 { 45 static $fs; 46 47 if (!class_exists('COM', false)) { 48 throw new \RuntimeException('The `wfio` or `com_dotnet` extension is required to handle UTF-8 filesystem access on Windows'); 49 } 50 51 isset($fs) or $fs = new \COM('Scripting.FileSystemObject', null, CP_UTF8); 52 53 $path = explode('://', $path, 2); 54 $path = $path[(int) isset($path[1])]; 55 $path = strtr($path, '/', '\\'); 56 $pre = ''; 57 58 if (!isset($path[0]) || ('/' !== $path[0] && '\\' !== $path[0] && false === strpos($path, ':'))) { 59 $pre = getcwd().'\\'; 60 } 61 62 $pre = new \VARIANT($pre); 63 64 if ($is_utf8) { 65 $path = new \VARIANT($path, VT_BSTR, CP_UTF8); 66 } else { 67 $path = new \VARIANT($path); 68 } 69 70 return array($fs, $fs->getAbsolutePathName(variant_cat($pre, $path))); 71 } 72 73 public function dir_closedir() 74 { 75 $this->handle = null; 76 77 return true; 78 } 79 80 public function dir_opendir($path, $options) 81 { 82 list($fs, $path) = self::fs($path); 83 if (!$fs->FolderExists($path)) { 84 return false; 85 } 86 87 $dir = $fs->GetFolder($path); 88 89 try { 90 $f = array('.', '..'); 91 92 foreach ($dir->SubFolders() as $v) { 93 $f[] = $v->Name; 94 } 95 foreach ($dir->Files as $v) { 96 $f[] = $v->Name; 97 } 98 } catch (\Exception $f) { 99 $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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |