[ Index ] |
PHP Cross Reference of phpBB-3.3.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 namespace phpbb\filesystem; 15 16 use phpbb\filesystem\exception\filesystem_exception; 17 18 /** 19 * A class with various functions that are related to paths, files and the filesystem 20 */ 21 class filesystem implements filesystem_interface 22 { 23 /** 24 * Store some information about file ownership for phpBB's chmod function 25 * 26 * @var array 27 */ 28 protected $chmod_info; 29 30 /** 31 * Stores current working directory 32 * 33 * @var string|bool current working directory or false if it cannot be recovered 34 */ 35 protected $working_directory; 36 37 /** 38 * Symfony's Filesystem component 39 * 40 * @var \Symfony\Component\Filesystem\Filesystem 41 */ 42 protected $symfony_filesystem; 43 44 /** 45 * Constructor 46 */ 47 public function __construct() 48 { 49 $this->chmod_info = array(); 50 $this->symfony_filesystem = new \Symfony\Component\Filesystem\Filesystem(); 51 $this->working_directory = null; 52 } 53 54 /** 55 * {@inheritdoc} 56 */ 57 public function chgrp($files, $group, $recursive = false) 58 { 59 try 60 { 61 $this->symfony_filesystem->chgrp($files, $group, $recursive); 62 } 63 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 64 { 65 // Try to recover filename 66 // By the time this is written that is at the end of the message 67 $error = trim($e->getMessage()); 68 $file = substr($error, strrpos($error, ' ')); 69 70 throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_GROUP', $file, array(), $e); 71 } 72 } 73 74 /** 75 * {@inheritdoc} 76 */ 77 public function chmod($files, $perms = null, $recursive = false, $force_chmod_link = false) 78 { 79 if (is_null($perms)) 80 { 81 // Default to read permission for compatibility reasons 82 $perms = self::CHMOD_READ; 83 } 84 85 // Check if we got a permission flag 86 if ($perms > self::CHMOD_ALL) 87 { 88 $file_perm = $perms; 89 90 // Extract permissions 91 //$owner = ($file_perm >> 6) & 7; // This will be ignored 92 $group = ($file_perm >> 3) & 7; 93 $other = ($file_perm >> 0) & 7; 94 95 // Does any permissions provided? if so we add execute bit for directories 96 $group = ($group !== 0) ? ($group | self::CHMOD_EXECUTE) : $group; 97 $other = ($other !== 0) ? ($other | self::CHMOD_EXECUTE) : $other; 98 99 // Compute directory permissions 100 $dir_perm = (self::CHMOD_ALL << 6) + ($group << 3) + ($other << 3); 101 } 102 else 103 { 104 // Add execute bit to owner if execute bit is among perms 105 $owner_perm = (self::CHMOD_READ | self::CHMOD_WRITE) | ($perms & self::CHMOD_EXECUTE); 106 $file_perm = ($owner_perm << 6) + ($perms << 3) + ($perms << 0); 107 108 // Compute directory permissions 109 $perm = ($perms !== 0) ? ($perms | self::CHMOD_EXECUTE) : $perms; 110 $dir_perm = (($owner_perm | self::CHMOD_EXECUTE) << 6) + ($perm << 3) + ($perm << 0); 111 } 112 113 // Symfony's filesystem component does not support extra execution flags on directories 114 // so we need to implement it again 115 foreach ($this->to_iterator($files) as $file) 116 { 117 if ($recursive && is_dir($file) && !is_link($file)) 118 { 119 $this->chmod(new \FilesystemIterator($file), $perms, true); 120 } 121 122 // Don't chmod links as mostly those require 0777 and that cannot be changed 123 if (is_dir($file) || (is_link($file) && $force_chmod_link)) 124 { 125 if (true !== @chmod($file, $dir_perm)) 126 { 127 throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_PERMISSIONS', $file, array()); 128 } 129 } 130 else if (is_file($file)) 131 { 132 if (true !== @chmod($file, $file_perm)) 133 { 134 throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_PERMISSIONS', $file, array()); 135 } 136 } 137 } 138 } 139 140 /** 141 * {@inheritdoc} 142 */ 143 public function chown($files, $user, $recursive = false) 144 { 145 try 146 { 147 $this->symfony_filesystem->chown($files, $user, $recursive); 148 } 149 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 150 { 151 // Try to recover filename 152 // By the time this is written that is at the end of the message 153 $error = trim($e->getMessage()); 154 $file = substr($error, strrpos($error, ' ')); 155 156 throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_GROUP', $file, array(), $e); 157 } 158 } 159 160 /** 161 * {@inheritdoc} 162 */ 163 public function clean_path($path) 164 { 165 $exploded = explode('/', $path); 166 $filtered = array(); 167 foreach ($exploded as $part) 168 { 169 if ($part === '.' && !empty($filtered)) 170 { 171 continue; 172 } 173 174 if ($part === '..' && !empty($filtered) && $filtered[count($filtered) - 1] !== '.' && $filtered[count($filtered) - 1] !== '..') 175 { 176 array_pop($filtered); 177 } 178 else 179 { 180 $filtered[] = $part; 181 } 182 } 183 $path = implode('/', $filtered); 184 return $path; 185 } 186 187 /** 188 * {@inheritdoc} 189 */ 190 public function copy($origin_file, $target_file, $override = false) 191 { 192 try 193 { 194 $this->symfony_filesystem->copy($origin_file, $target_file, $override); 195 } 196 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 197 { 198 throw new filesystem_exception('FILESYSTEM_CANNOT_COPY_FILES', '', array(), $e); 199 } 200 } 201 202 /** 203 * {@inheritdoc} 204 */ 205 public function dump_file($filename, $content) 206 { 207 try 208 { 209 $this->symfony_filesystem->dumpFile($filename, $content); 210 } 211 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 212 { 213 throw new filesystem_exception('FILESYSTEM_CANNOT_DUMP_FILE', $filename, array(), $e); 214 } 215 } 216 217 /** 218 * {@inheritdoc} 219 */ 220 public function exists($files) 221 { 222 return $this->symfony_filesystem->exists($files); 223 } 224 225 /** 226 * {@inheritdoc} 227 */ 228 public function is_absolute_path($path) 229 { 230 return (isset($path[0]) && $path[0] === '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false; 231 } 232 233 /** 234 * {@inheritdoc} 235 */ 236 public function is_readable($files, $recursive = false) 237 { 238 foreach ($this->to_iterator($files) as $file) 239 { 240 if ($recursive && is_dir($file) && !is_link($file)) 241 { 242 if (!$this->is_readable(new \FilesystemIterator($file), true)) 243 { 244 return false; 245 } 246 } 247 248 if (!is_readable($file)) 249 { 250 return false; 251 } 252 } 253 254 return true; 255 } 256 257 /** 258 * {@inheritdoc} 259 */ 260 public function is_writable($files, $recursive = false) 261 { 262 if (defined('PHP_WINDOWS_VERSION_MAJOR') || !function_exists('is_writable')) 263 { 264 foreach ($this->to_iterator($files) as $file) 265 { 266 if ($recursive && is_dir($file) && !is_link($file)) 267 { 268 if (!$this->is_writable(new \FilesystemIterator($file), true)) 269 { 270 return false; 271 } 272 } 273 274 if (!$this->phpbb_is_writable($file)) 275 { 276 return false; 277 } 278 } 279 } 280 else 281 { 282 // use built in is_writable 283 foreach ($this->to_iterator($files) as $file) 284 { 285 if ($recursive && is_dir($file) && !is_link($file)) 286 { 287 if (!$this->is_writable(new \FilesystemIterator($file), true)) 288 { 289 return false; 290 } 291 } 292 293 if (!is_writable($file)) 294 { 295 return false; 296 } 297 } 298 } 299 300 return true; 301 } 302 303 /** 304 * {@inheritdoc} 305 */ 306 public function make_path_relative($end_path, $start_path) 307 { 308 return $this->symfony_filesystem->makePathRelative($end_path, $start_path); 309 } 310 311 /** 312 * {@inheritdoc} 313 */ 314 public function mirror($origin_dir, $target_dir, \Traversable $iterator = null, $options = array()) 315 { 316 try 317 { 318 $this->symfony_filesystem->mirror($origin_dir, $target_dir, $iterator, $options); 319 } 320 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 321 { 322 $msg = $e->getMessage(); 323 $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); 324 325 throw new filesystem_exception('FILESYSTEM_CANNOT_MIRROR_DIRECTORY', $filename, array(), $e); 326 } 327 } 328 329 /** 330 * {@inheritdoc} 331 */ 332 public function mkdir($dirs, $mode = 0777) 333 { 334 try 335 { 336 $this->symfony_filesystem->mkdir($dirs, $mode); 337 } 338 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 339 { 340 $msg = $e->getMessage(); 341 $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); 342 343 throw new filesystem_exception('FILESYSTEM_CANNOT_CREATE_DIRECTORY', $filename, array(), $e); 344 } 345 } 346 347 /** 348 * {@inheritdoc} 349 */ 350 public function phpbb_chmod($files, $perms = null, $recursive = false, $force_chmod_link = false) 351 { 352 if (is_null($perms)) 353 { 354 // Default to read permission for compatibility reasons 355 $perms = self::CHMOD_READ; 356 } 357 358 if (empty($this->chmod_info)) 359 { 360 if (!function_exists('fileowner') || !function_exists('filegroup')) 361 { 362 $this->chmod_info['process'] = false; 363 } 364 else 365 { 366 $common_php_owner = @fileowner(__FILE__); 367 $common_php_group = @filegroup(__FILE__); 368 369 // And the owner and the groups PHP is running under. 370 $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false; 371 $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false; 372 373 // If we are unable to get owner/group, then do not try to set them by guessing 374 if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group) 375 { 376 $this->chmod_info['process'] = false; 377 } 378 else 379 { 380 $this->chmod_info = array( 381 'process' => true, 382 'common_owner' => $common_php_owner, 383 'common_group' => $common_php_group, 384 'php_uid' => $php_uid, 385 'php_gids' => $php_gids, 386 ); 387 } 388 } 389 } 390 391 if ($this->chmod_info['process']) 392 { 393 try 394 { 395 foreach ($this->to_iterator($files) as $file) 396 { 397 $file_uid = @fileowner($file); 398 $file_gid = @filegroup($file); 399 400 // Change owner 401 if (is_writable($file) && $file_uid !== $this->chmod_info['common_owner']) 402 { 403 $this->chown($file, $this->chmod_info['common_owner'], $recursive); 404 } 405 406 // Change group 407 if (is_writable($file) && $file_gid !== $this->chmod_info['common_group']) 408 { 409 $this->chgrp($file, $this->chmod_info['common_group'], $recursive); 410 } 411 412 clearstatcache(); 413 $file_uid = @fileowner($file); 414 $file_gid = @filegroup($file); 415 } 416 } 417 catch (filesystem_exception $e) 418 { 419 $this->chmod_info['process'] = false; 420 } 421 } 422 423 // Still able to process? 424 if ($this->chmod_info['process']) 425 { 426 if ($file_uid === $this->chmod_info['php_uid']) 427 { 428 $php = 'owner'; 429 } 430 else if (in_array($file_gid, $this->chmod_info['php_gids'])) 431 { 432 $php = 'group'; 433 } 434 else 435 { 436 // Since we are setting the everyone bit anyway, no need to do expensive operations 437 $this->chmod_info['process'] = false; 438 } 439 } 440 441 // We are not able to determine or change something 442 if (!$this->chmod_info['process']) 443 { 444 $php = 'other'; 445 } 446 447 switch ($php) 448 { 449 case 'owner': 450 try 451 { 452 $this->chmod($files, $perms, $recursive, $force_chmod_link); 453 clearstatcache(); 454 if ($this->is_readable($files) && $this->is_writable($files)) 455 { 456 break; 457 } 458 } 459 catch (filesystem_exception $e) 460 { 461 // Do nothing 462 } 463 case 'group': 464 try 465 { 466 $this->chmod($files, $perms, $recursive, $force_chmod_link); 467 clearstatcache(); 468 if ((!($perms & self::CHMOD_READ) || $this->is_readable($files, $recursive)) && (!($perms & self::CHMOD_WRITE) || $this->is_writable($files, $recursive))) 469 { 470 break; 471 } 472 } 473 catch (filesystem_exception $e) 474 { 475 // Do nothing 476 } 477 case 'other': 478 default: 479 $this->chmod($files, $perms, $recursive, $force_chmod_link); 480 break; 481 } 482 } 483 484 /** 485 * {@inheritdoc} 486 */ 487 public function realpath($path) 488 { 489 if (!function_exists('realpath')) 490 { 491 return $this->phpbb_own_realpath($path); 492 } 493 494 $realpath = realpath($path); 495 496 // Strangely there are provider not disabling realpath but returning strange values. :o 497 // We at least try to cope with them. 498 if ((!$this->is_absolute_path($path) && $realpath === $path) || $realpath === false) 499 { 500 return $this->phpbb_own_realpath($path); 501 } 502 503 // Check for DIRECTORY_SEPARATOR at the end (and remove it!) 504 if (substr($realpath, -1) === DIRECTORY_SEPARATOR) 505 { 506 $realpath = substr($realpath, 0, -1); 507 } 508 509 return $realpath; 510 } 511 512 /** 513 * {@inheritdoc} 514 */ 515 public function remove($files) 516 { 517 try 518 { 519 $this->symfony_filesystem->remove($files); 520 } 521 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 522 { 523 // Try to recover filename 524 // By the time this is written that is at the end of the message 525 $error = trim($e->getMessage()); 526 $file = substr($error, strrpos($error, ' ')); 527 528 throw new filesystem_exception('FILESYSTEM_CANNOT_DELETE_FILES', $file, array(), $e); 529 } 530 } 531 532 /** 533 * {@inheritdoc} 534 */ 535 public function rename($origin, $target, $overwrite = false) 536 { 537 try 538 { 539 $this->symfony_filesystem->rename($origin, $target, $overwrite); 540 } 541 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 542 { 543 $msg = $e->getMessage(); 544 $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); 545 546 throw new filesystem_exception('FILESYSTEM_CANNOT_RENAME_FILE', $filename, array(), $e); 547 } 548 } 549 550 /** 551 * {@inheritdoc} 552 */ 553 public function symlink($origin_dir, $target_dir, $copy_on_windows = false) 554 { 555 try 556 { 557 $this->symfony_filesystem->symlink($origin_dir, $target_dir, $copy_on_windows); 558 } 559 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 560 { 561 throw new filesystem_exception('FILESYSTEM_CANNOT_CREATE_SYMLINK', $origin_dir, array(), $e); 562 } 563 } 564 565 /** 566 * {@inheritdoc} 567 */ 568 public function touch($files, $time = null, $access_time = null) 569 { 570 try 571 { 572 $this->symfony_filesystem->touch($files, $time, $access_time); 573 } 574 catch (\Symfony\Component\Filesystem\Exception\IOException $e) 575 { 576 // Try to recover filename 577 // By the time this is written that is at the end of the message 578 $error = trim($e->getMessage()); 579 $file = substr($error, strrpos($error, ' ')); 580 581 throw new filesystem_exception('FILESYSTEM_CANNOT_TOUCH_FILES', $file, array(), $e); 582 } 583 } 584 585 /** 586 * phpBB's implementation of is_writable 587 * 588 * @todo Investigate if is_writable is still buggy 589 * 590 * @param string $file file/directory to check if writable 591 * 592 * @return bool true if the given path is writable 593 */ 594 protected function phpbb_is_writable($file) 595 { 596 if (file_exists($file)) 597 { 598 // Canonicalise path to absolute path 599 $file = $this->realpath($file); 600 601 if (is_dir($file)) 602 { 603 // Test directory by creating a file inside the directory 604 $result = @tempnam($file, 'i_w'); 605 606 if (is_string($result) && file_exists($result)) 607 { 608 unlink($result); 609 610 // Ensure the file is actually in the directory (returned realpathed) 611 return (strpos($result, $file) === 0) ? true : false; 612 } 613 } 614 else 615 { 616 $handle = new \SplFileInfo($file); 617 618 // Returns TRUE if writable, FALSE otherwise 619 return $handle->isWritable(); 620 } 621 } 622 else 623 { 624 // file does not exist test if we can write to the directory 625 $dir = dirname($file); 626 627 if (file_exists($dir) && is_dir($dir) && $this->phpbb_is_writable($dir)) 628 { 629 return true; 630 } 631 } 632 633 return false; 634 } 635 636 /** 637 * Try to resolve real path when PHP's realpath fails to do so 638 * 639 * @param string $path 640 * @return bool|string 641 */ 642 protected function phpbb_own_realpath($path) 643 { 644 // Replace all directory separators with '/' 645 $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); 646 647 $is_absolute_path = false; 648 $path_prefix = ''; 649 650 if ($this->is_absolute_path($path)) 651 { 652 $is_absolute_path = true; 653 } 654 else 655 { 656 // Resolve working directory and store it 657 if (is_null($this->working_directory)) 658 { 659 if (function_exists('getcwd')) 660 { 661 $this->working_directory = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()); 662 } 663 664 // 665 // From this point on we really just guessing 666 // If chdir were called we screwed 667 // 668 else if (function_exists('debug_backtrace')) 669 { 670 $call_stack = debug_backtrace(0); 671 $this->working_directory = str_replace(DIRECTORY_SEPARATOR, '/', dirname($call_stack[count($call_stack) - 1]['file'])); 672 } 673 else 674 { 675 // 676 // Assuming that the working directory is phpBB root 677 // we could use this as a fallback, when phpBB will use controllers 678 // everywhere this will be a safe assumption 679 // 680 //$dir_parts = explode(DIRECTORY_SEPARATOR, __DIR__); 681 //$namespace_parts = explode('\\', trim(__NAMESPACE__, '\\')); 682 683 //$namespace_part_count = count($namespace_parts); 684 685 // Check if we still loading from root 686 //if (array_slice($dir_parts, -$namespace_part_count) === $namespace_parts) 687 //{ 688 // $this->working_directory = implode('/', array_slice($dir_parts, 0, -$namespace_part_count)); 689 //} 690 //else 691 //{ 692 // $this->working_directory = false; 693 //} 694 695 $this->working_directory = false; 696 } 697 } 698 699 if ($this->working_directory !== false) 700 { 701 $is_absolute_path = true; 702 $path = $this->working_directory . '/' . $path; 703 } 704 } 705 706 if ($is_absolute_path) 707 { 708 if (defined('PHP_WINDOWS_VERSION_MAJOR')) 709 { 710 $path_prefix = $path[0] . ':'; 711 $path = substr($path, 2); 712 } 713 else 714 { 715 $path_prefix = ''; 716 } 717 } 718 719 $resolved_path = $this->resolve_path($path, $path_prefix, $is_absolute_path); 720 if ($resolved_path === false) 721 { 722 return false; 723 } 724 725 if (!@file_exists($resolved_path) || (!@is_dir($resolved_path . '/') && !is_file($resolved_path))) 726 { 727 return false; 728 } 729 730 // Return OS specific directory separators 731 $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved_path); 732 733 // Check for DIRECTORY_SEPARATOR at the end (and remove it!) 734 if (substr($resolved, -1) === DIRECTORY_SEPARATOR) 735 { 736 return substr($resolved, 0, -1); 737 } 738 739 return $resolved; 740 } 741 742 /** 743 * Convert file(s) to \Traversable object 744 * 745 * This is the same function as Symfony's toIterator, but that is private 746 * so we cannot use it. 747 * 748 * @param string|array|\Traversable $files filename/list of filenames 749 * @return \Traversable 750 */ 751 protected function to_iterator($files) 752 { 753 if (!$files instanceof \Traversable) 754 { 755 $files = new \ArrayObject(is_array($files) ? $files : array($files)); 756 } 757 758 return $files; 759 } 760 761 /** 762 * Try to resolve symlinks in path 763 * 764 * @param string $path The path to resolve 765 * @param string $prefix The path prefix (on windows the drive letter) 766 * @param bool $absolute Whether or not the path is absolute 767 * @param bool $return_array Whether or not to return path parts 768 * 769 * @return string|array|bool returns the resolved path or an array of parts of the path if $return_array is true 770 * or false if path cannot be resolved 771 */ 772 protected function resolve_path($path, $prefix = '', $absolute = false, $return_array = false) 773 { 774 if ($return_array) 775 { 776 $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); 777 } 778 779 trim ($path, '/'); 780 $path_parts = explode('/', $path); 781 $resolved = array(); 782 $resolved_path = $prefix; 783 $file_found = false; 784 785 foreach ($path_parts as $path_part) 786 { 787 if ($file_found) 788 { 789 return false; 790 } 791 792 if (empty($path_part) || ($path_part === '.' && ($absolute || !empty($resolved)))) 793 { 794 continue; 795 } 796 else if ($absolute && $path_part === '..') 797 { 798 if (empty($resolved)) 799 { 800 // No directories above root 801 return false; 802 } 803 804 array_pop($resolved); 805 $resolved_path = false; 806 } 807 else if ($path_part === '..' && !empty($resolved) && !in_array($resolved[count($resolved) - 1], array('.', '..'))) 808 { 809 array_pop($resolved); 810 $resolved_path = false; 811 } 812 else 813 { 814 if ($resolved_path === false) 815 { 816 if (empty($resolved)) 817 { 818 $resolved_path = ($absolute) ? $prefix . '/' . $path_part : $path_part; 819 } 820 else 821 { 822 $tmp_array = $resolved; 823 if ($absolute) 824 { 825 array_unshift($tmp_array, $prefix); 826 } 827 828 $resolved_path = implode('/', $tmp_array); 829 } 830 } 831 832 $current_path = $resolved_path . '/' . $path_part; 833 834 // Resolve symlinks 835 if (@is_link($current_path)) 836 { 837 if (!function_exists('readlink')) 838 { 839 return false; 840 } 841 842 $link = readlink($current_path); 843 844 // Is link has an absolute path in it? 845 if ($this->is_absolute_path($link)) 846 { 847 if (defined('PHP_WINDOWS_VERSION_MAJOR')) 848 { 849 $prefix = $link[0] . ':'; 850 $link = substr($link, 2); 851 } 852 else 853 { 854 $prefix = ''; 855 } 856 857 $resolved = $this->resolve_path($link, $prefix, true, true); 858 $absolute = true; 859 } 860 else 861 { 862 $resolved = $this->resolve_path($resolved_path . '/' . $link, $prefix, $absolute, true); 863 } 864 865 if (!$resolved) 866 { 867 return false; 868 } 869 870 $resolved_path = false; 871 } 872 else if (@is_dir($current_path . '/')) 873 { 874 $resolved[] = $path_part; 875 $resolved_path = $current_path; 876 } 877 else if (@is_file($current_path)) 878 { 879 $resolved[] = $path_part; 880 $resolved_path = $current_path; 881 $file_found = true; 882 } 883 else 884 { 885 return false; 886 } 887 } 888 } 889 890 // If at the end of the path there were a .. or . 891 // we need to build the path again. 892 // Only doing this when a string is expected in return 893 if ($resolved_path === false && $return_array === false) 894 { 895 if (empty($resolved)) 896 { 897 $resolved_path = ($absolute) ? $prefix . '/' : './'; 898 } 899 else 900 { 901 $tmp_array = $resolved; 902 if ($absolute) 903 { 904 array_unshift($tmp_array, $prefix); 905 } 906 907 $resolved_path = implode('/', $tmp_array); 908 } 909 } 910 911 return ($return_array) ? $resolved : $resolved_path; 912 } 913 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Jun 23 12:25:44 2024 | Cross-referenced by PHPXref 0.7.1 |