1<?php 2 3/** 4 * @see https://github.com/laminas/laminas-filter for the canonical source repository 5 * @copyright https://github.com/laminas/laminas-filter/blob/master/COPYRIGHT.md 6 * @license https://github.com/laminas/laminas-filter/blob/master/LICENSE.md New BSD License 7 */ 8 9namespace Laminas\Filter; 10 11use Laminas\Stdlib\ErrorHandler; 12use Traversable; 13 14class RealPath extends AbstractFilter 15{ 16 /** 17 * @var array $options 18 */ 19 protected $options = [ 20 'exists' => true 21 ]; 22 23 /** 24 * Class constructor 25 * 26 * @param bool|Traversable $existsOrOptions Options to set 27 */ 28 public function __construct($existsOrOptions = true) 29 { 30 if ($existsOrOptions !== null) { 31 if (! static::isOptions($existsOrOptions)) { 32 $this->setExists($existsOrOptions); 33 } else { 34 $this->setOptions($existsOrOptions); 35 } 36 } 37 } 38 39 /** 40 * Sets if the path has to exist 41 * TRUE when the path must exist 42 * FALSE when not existing paths can be given 43 * 44 * @param bool $flag Path must exist 45 * @return self 46 */ 47 public function setExists($flag = true) 48 { 49 $this->options['exists'] = (bool) $flag; 50 return $this; 51 } 52 53 /** 54 * Returns true if the filtered path must exist 55 * 56 * @return bool 57 */ 58 public function getExists() 59 { 60 return $this->options['exists']; 61 } 62 63 /** 64 * Defined by Laminas\Filter\FilterInterface 65 * 66 * Returns realpath($value) 67 * 68 * If the value provided is non-scalar, the value will remain unfiltered 69 * 70 * @param string $value 71 * @return string|mixed 72 */ 73 public function filter($value) 74 { 75 if (! is_string($value)) { 76 return $value; 77 } 78 $path = (string) $value; 79 80 if ($this->options['exists']) { 81 return realpath($path); 82 } 83 84 ErrorHandler::start(); 85 $realpath = realpath($path); 86 ErrorHandler::stop(); 87 if ($realpath) { 88 return $realpath; 89 } 90 91 $drive = ''; 92 if (stripos(PHP_OS, 'WIN') === 0) { 93 $path = preg_replace('/[\\\\\/]/', DIRECTORY_SEPARATOR, $path); 94 if (preg_match('/([a-zA-Z]\:)(.*)/', $path, $matches)) { 95 list(, $drive, $path) = $matches; 96 } else { 97 $cwd = getcwd(); 98 $drive = substr($cwd, 0, 2); 99 if (strpos($path, DIRECTORY_SEPARATOR) !== 0) { 100 $path = substr($cwd, 3) . DIRECTORY_SEPARATOR . $path; 101 } 102 } 103 } elseif (strpos($path, DIRECTORY_SEPARATOR) !== 0) { 104 $path = getcwd() . DIRECTORY_SEPARATOR . $path; 105 } 106 107 $stack = []; 108 $parts = explode(DIRECTORY_SEPARATOR, $path); 109 foreach ($parts as $dir) { 110 if ($dir !== '' && $dir !== '.') { 111 if ($dir === '..') { 112 array_pop($stack); 113 } else { 114 $stack[] = $dir; 115 } 116 } 117 } 118 119 return $drive . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $stack); 120 } 121} 122