path.php
177 lines
| 1 | <?php |
| 2 | /** |
| 3 | * @package VikWP - Libraries |
| 4 | * @subpackage adapter.filesystem |
| 5 | * @author E4J s.r.l. |
| 6 | * @copyright Copyright (C) 2023 E4J s.r.l. All Rights Reserved. |
| 7 | * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL |
| 8 | * @link https://vikwp.com |
| 9 | */ |
| 10 | |
| 11 | // No direct access |
| 12 | defined('ABSPATH') or die('No script kiddies please!'); |
| 13 | |
| 14 | /** |
| 15 | * This class provides a common interface for |
| 16 | * Path handling in the Wordpress CMS plugins. |
| 17 | * |
| 18 | * @since 10.0 |
| 19 | */ |
| 20 | class JPath |
| 21 | { |
| 22 | /** |
| 23 | * Chmods files and directories recursively to given permissions. |
| 24 | * |
| 25 | * @param string $path Root path to begin changing mode [without trailing slash]. |
| 26 | * @param string $filemode Octal representation of the value to change file mode to [null = no change]. |
| 27 | * @param string $foldermode Octal representation of the value to change folder mode to [null = no change]. |
| 28 | * |
| 29 | * @return boolean True if successful (one fail means the whole operation failed). |
| 30 | */ |
| 31 | public static function setPermissions($path, $filemode = '0644', $foldermode = '0755') |
| 32 | { |
| 33 | // initialise return value |
| 34 | $ret = true; |
| 35 | |
| 36 | if (is_dir($path)) |
| 37 | { |
| 38 | $dh = opendir($path); |
| 39 | |
| 40 | while ($file = readdir($dh)) |
| 41 | { |
| 42 | if ($file != '.' && $file != '..') |
| 43 | { |
| 44 | $fullpath = $path . '/' . $file; |
| 45 | |
| 46 | if (is_dir($fullpath)) |
| 47 | { |
| 48 | if (!self::setPermissions($fullpath, $filemode, $foldermode)) |
| 49 | { |
| 50 | $ret = false; |
| 51 | } |
| 52 | } |
| 53 | else |
| 54 | { |
| 55 | if (isset($filemode)) |
| 56 | { |
| 57 | if (!@chmod($fullpath, octdec($filemode))) |
| 58 | { |
| 59 | $ret = false; |
| 60 | } |
| 61 | } |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | closedir($dh); |
| 67 | |
| 68 | if (isset($foldermode)) |
| 69 | { |
| 70 | if (!@chmod($path, octdec($foldermode))) |
| 71 | { |
| 72 | $ret = false; |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | else |
| 77 | { |
| 78 | if (isset($filemode)) |
| 79 | { |
| 80 | $ret = @chmod($path, octdec($filemode)); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | return $ret; |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * Function to strip additional / or \ in a path name. |
| 89 | * |
| 90 | * @param string $path The path to clean. |
| 91 | * @param string $ds Directory separator (optional). |
| 92 | * |
| 93 | * @return string The cleaned path. |
| 94 | */ |
| 95 | public static function clean($path, $ds = DIRECTORY_SEPARATOR) |
| 96 | { |
| 97 | if (!is_string($path) && !empty($path)) |
| 98 | { |
| 99 | $path = ''; |
| 100 | } |
| 101 | |
| 102 | $path = trim($path); |
| 103 | |
| 104 | if (empty($path)) |
| 105 | { |
| 106 | throw new InvalidArgumentException('JPath::clean() does not accept empty paths.', 500); |
| 107 | } |
| 108 | |
| 109 | // Remove double slashes and backslashes and convert all slashes and backslashes to DIRECTORY_SEPARATOR. |
| 110 | // If dealing with a UNC path don't forget to prepend the path with a backslash. |
| 111 | if (($ds == '\\') && substr($path, 0, 2) == '\\\\') |
| 112 | { |
| 113 | $path = "\\" . preg_replace('#[/\\\\]+#', $ds, $path); |
| 114 | } |
| 115 | else |
| 116 | { |
| 117 | $path = preg_replace('#[/\\\\]+#', $ds, $path); |
| 118 | } |
| 119 | |
| 120 | return $path; |
| 121 | } |
| 122 | |
| 123 | /** |
| 124 | * Searches the directory paths for a given file. |
| 125 | * |
| 126 | * @param mixed $paths A path string or array of path strings to search in. |
| 127 | * @param string $file The file name to look for. |
| 128 | * |
| 129 | * @return mixed The full path and file name for the target file, |
| 130 | * or boolean false if the file is not found in any of the paths. |
| 131 | * |
| 132 | * @since 10.1.18 |
| 133 | */ |
| 134 | public static function find($paths, $file) |
| 135 | { |
| 136 | // force to array |
| 137 | if (!is_array($paths) && !($paths instanceof Iterator)) |
| 138 | { |
| 139 | settype($paths, 'array'); |
| 140 | } |
| 141 | |
| 142 | // start looping through the path set |
| 143 | foreach ($paths as $path) |
| 144 | { |
| 145 | // make path safe |
| 146 | $path = rtrim(str_replace('/', DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR); |
| 147 | // get the path to the file |
| 148 | $fullname = $path . DIRECTORY_SEPARATOR . $file; |
| 149 | |
| 150 | // is the path based on a stream? |
| 151 | if (strpos($path, '://') === false) |
| 152 | { |
| 153 | // not a stream, so do a realpath() to avoid directory |
| 154 | // traversal attempts on the local file system. |
| 155 | |
| 156 | // needed for substr() later |
| 157 | $path = realpath($path); |
| 158 | $fullname = realpath($fullname); |
| 159 | } |
| 160 | |
| 161 | /* |
| 162 | * The substr() check added to make sure that the realpath() |
| 163 | * results in a directory registered so that |
| 164 | * non-registered directories are not accessible via directory |
| 165 | * traversal attempts. |
| 166 | */ |
| 167 | if (file_exists($fullname) && substr($fullname, 0, strlen($path)) == $path) |
| 168 | { |
| 169 | return $fullname; |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | // could not find the file in the set of paths |
| 174 | return false; |
| 175 | } |
| 176 | } |
| 177 |