url = parse_url($path); if (isset($this->url['path'])) { $path = $this->url['path']; // $path = preg_replace('/\/{2,}/', '/', $path); $this->path = self::optimize($this->fromString($path)); } } static function factory($path) { return new Path($path); } public function getParts() { return $this->path; } public static function normalize($pathName) { $path = new Path($pathName); return $path->__toString(); } /** * Базовое имя * @param $path * @return mixed */ public static function basename($path) { $list = preg_split('#\\\\|/#s', $path); return end($list); } /** * Возвращает расширение файла * * @param string $fileName Полное имя файла * * @return string */ static function getExtension($fileName) { assert(is_string($fileName) || is_null($fileName)); return pathinfo($fileName, PATHINFO_EXTENSION); } static function isType($fileName, $extension) { if (is_array($extension)) { return in_array(pathinfo($fileName, PATHINFO_EXTENSION), $extension); } else { return (pathinfo($fileName, PATHINFO_EXTENSION) == $extension); } } /** * Полное имя файла без расширения * * @param string $fileName Имя файла * * @return string */ static function skipExtension($fileName) { assert(is_string($fileName)); $path = pathinfo($fileName); if ($path['dirname'] == ".") { return $path['filename']; } else { return self::join($path['dirname'], $path['filename']); } } /** * Возвращает имя файла без расширения * * @param string $fileName Полное имя файла * * @return string */ static function getFileName($fileName) { assert(is_string($fileName)); return pathinfo($fileName, PATHINFO_FILENAME); } /** * Преобразует строку путя в массив * * @param string $path Путь * * @return array */ public function fromString ($path) { assert(is_string($path)); $list = preg_split('#\\\\|/#s', $path); if (isset($this->url['scheme']) && !isset($this->url['host'])) { $this->absolute = false; } else if ($list[0] == '' && count($list) > 1) { $this->absolute = true; } return $list; } /** * Преобразует относительный путь в абсолютный */ public static function optimize($path) // { $result = array(); foreach ($path as $n) { switch ($n) { // Может быть относительным или абсолютным путем case "": break; case ".": break; case "..": if (count($result) > 0) { array_pop($result); break; } default: array_push($result, $n); } } return $result; } // Сравнение двух путей на равентство public function equal(/*.Path.*/ $path) { if (count($this->path) == count($path->path)) { for ($i = 0; $i < count($this->path); $i++) { if ($this->path[$i] != $path->path[$i]) { return false; } } return true; } return false; } public static function makeUrl($path) { return (isset($path['scheme']) ? $path['scheme'] . ':/' : '') . (isset($path['host']) ? ('/' . (isset($path['user']) ? $path['user'] . (isset($path['pass']) ? ':' . $path['pass'] : '') . '@' : '') . $path['host'] . (isset($path['port']) ? ':' . $path['port'] : '')) : '') . $path['path'] . (isset($path['query']) ? '?' . $path['query'] : '') . (isset($path['fragment']) ? '#' . $path['fragment'] : ''); } /** * Преобразует путь в строку * * @return string */ public function __toString() { $result = (($this->absolute) ? '/' : '') . implode(self::SEPARATOR, $this->path); $this->url['path'] = $result; return self::makeUrl($this->url); } /** * Проверяет является ли папка родительской для другой папки * * @parma Path $path * * @return boolean */ public function isParent(/*.Path.*/ $path) { if (isset($this->url['host']) && isset($path->url['host']) && ($this->url['host'] != $path->url['host'])) return false; if (count($path->path) > count($this->path)) { for ($i = 0; $i < count($this->path); $i++) { if ($path->path[$i] != $this->path[$i]) { return false; } } return true; } return false; } public static function _isParent($path1, $path2) { $path = new Path($path1); return $path->isParent(new Path($path2)); } /** * Находит путь относительно текущего путя * * @param string $name Полный путь к файлу * * @return string Относительный путь к файлу */ public function relPath($name) { $path = new Path($name); unset($path->url['scheme']); // $this->absolute = false; $path->absolute = false; foreach ($this->path as $n) { array_shift($path->path); } return $path->__toString(); } // Вычисляет относительный путь в виде строки static function relative($rpath, $lpath) { // Нужно проверять диск!! $self = new Path($rpath); $list = new Path($lpath); $self_path = $self->getParts(); $list_path = $list->getParts(); $result = array(); for ($i = 0; $i < count($list_path); $i++) { if (($i >= count($self_path)) || $list_path[$i] != $self_path[$i]) { break; } } for($j = $i; $j < count($list_path); $j++) { array_push($result, '..'); } for($j = $i; $j < count($self_path); $j++) { array_push($result, $self_path[$j]); } return implode("/", $result); } public function append($path) { $base = $this->__toString(); return self::join($base, $path); } /** * Обьединяет строки в путь соединяя необходимым разделителем * fixme не обрабатывает параметры урла, решение Path::join(SITE_WWW_PATH) . '?param=pampam' * @return string */ static function join($_rest) { $args = func_get_args(); $result = array(); $parts0 = new Path(array_shift($args)); $result [] = $parts0->getParts(); foreach ($args as $file) { $parts = new Path($file); $result [] = $parts->getParts(); } // При обьединении ссылок можно обьеденить path, query, fragment $path = implode(self::SEPARATOR, call_user_func_array('array_merge', $result)); $parts0->url['path'] = ($parts0->isAbsolute()) ? '/' . $path : $path; return self::makeUrl($parts0->url); } // Проверка структуры имени файла static function checkName($name, $extension) { return (strlen(pathinfo($name, PATHINFO_FILENAME)) > 0) && (pathinfo($name, PATHINFO_EXTENSION) == $extension); } static function isCharName($char) { $ch = ord($char); return ((($ch >= ord('a')) && ($ch <= ord('z'))) || (strpos('-._', $char) !== false) || (($ch >= ord('0')) && ($ch <= ord('9')))); } // Проверка имени файла static function isName($name) { if (strlen(trim($name)) == 0) { return false; } for ($i = 0; $i < strlen($name); $i++) { if (!self::isCharName($name[$i])) { return false; } } return true; } public function isAbsolute() { return $this->absolute; } /** * Подбирает новое временное имя для файла * * @param string $dst Предпологаемое имя файла * * @return string Новое имя файла */ static function resolveFile($dst) { $i = 0; $file = self::skipExtension($dst); $suffix = self::getExtension($dst); $temp = $dst; while (file_exists($temp)) { $i ++; $temp = $file . "." . $i . "." . $suffix; } return $temp; } /** * Список файлов в директории * * @param array $allow массив расширений для файлов * @param array $ignore массив имен пааок которые не нужно обрабатывать * * @returnarray */ public function getContent($allow = null, $ignore = array()) { $ignore = array_merge(array(".", ".."), $ignore); return self::fileList($this->__toString(), $allow, $ignore); } /** * Обьединяет строки в путь соединяя необходимым разделителем * * @param array $allow массив расширений разрешеных для файлов * @param array $ignore массив имен пааок которые не нужно обрабатывать * * @return array */ function getContentRec($allow = null, $ignore = array()) { $result = array (); $ignore = array_merge(array (".", ".."), $ignore); self::fileListAll($result, $this->__toString(), $allow, $ignore); return $result; } // Использовать SPL ??? protected static function fileList($base, &$allow, &$ignore) { if ($base == '') $base = '.'; $result = array (); $handle = opendir($base); if (is_resource($handle)) { while (true) { $file = readdir($handle); if (is_string($file)) { if (! in_array($file, $ignore)) { $isDir = is_dir(Path::join($base, $file)); if ($isDir || ($allow == null) || in_array(self::getExtension($file), $allow)) { $result[] = $file; } } continue; } break; } closedir($handle); } // При обьединении ссылок можно обьеденить path, query, fragment return $result; } protected static function fileListAll(&$result, $base, &$allow, &$ignore) { $files = self::fileList($base, $allow, $ignore); foreach ($files as $name) { $fullname = self::join($base, $name); if (is_dir($fullname)) { self::fileListAll($result, $fullname, $allow, $ignore); } else { array_push($result, $fullname); } } } /** * Создает недастающие папки для записи файла * * @param string $dst Полное имя файла * * @return void */ static function prepare($dst, $filename = true) { if ($filename) { $path_dst = pathinfo($dst, PATHINFO_DIRNAME); } else { $path_dst = $dst; } if (! file_exists($path_dst)) { mkdir($path_dst, 0777, true); } } /** * Обновить относительную ссылку при переносе файла * * @param String $relativePath - относительная ссылка до переноса * @param String $srcFile - абсолютный путь к папке содержащей файл со ссылкой до переноса * @param String $dstFile - абсолютный путь к папке содержащей файл со ссылкой после переноса * * @return String */ static function updateRelativePathOnFileMove($relativePath, $srcFile, $dstFile) { $srcToDst = self::relative($srcFile, $dstFile); return self::join($srcToDst, $relativePath); } /** * Обновить относительную ссылку при переносе папки * * @param String $relativePath - относительная ссылка до переноса * @param String $file - абсолютный путь к файлу содержащему ссылку до переноса * @param String $srcDir - абсолютный путь к переносимой папке до переноса * @param String $dstDir - абсолютный путь к переносимой папке после переноса * * @return */ static function updateRelativePathOnDirectoryMove($relativePath, $file, $srcDir = NULL , $dstFile = NULL) { } }