Синхронизировал частично с CMS2

This commit is contained in:
origami11 2017-02-09 17:14:11 +03:00
parent 6b412f5d6f
commit f2938b1353
30 changed files with 1447 additions and 1099 deletions

View file

@ -1,33 +1,58 @@
<?php
/*.
require_module 'standard';
.*/
/**
* Класс для работы с папками и путями
* Для итерации над файлами возможно лучше использовать SPL
*
* @package utils
*/
class Path
class Path
{
const SEPARATOR = "/";
protected $path;
protected $path = array();
protected $url = array();
protected $absolute = false;
public function __construct ($path)
public function __construct($path)
{
assert(is_string($path));
// assert(is_string($path));
$this->path = $this->fromString($path);
$this->optimize();
}
$this->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);
}
/**
* Возвращает расширение файла
*
@ -35,13 +60,22 @@ class Path
*
* @return string
*/
static function getExtension ($fileName)
static function getExtension($fileName)
{
assert(is_string($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);
}
}
/**
* Полное имя файла без расширения
*
@ -49,7 +83,7 @@ class Path
*
* @return string
*/
static function skipExtension ($fileName)
static function skipExtension($fileName)
{
assert(is_string($fileName));
@ -68,118 +102,13 @@ class Path
*
* @return string
*/
static function getFileName ($fileName)
static function getFileName($fileName)
{
assert(is_string($fileName));
return pathinfo($fileName, PATHINFO_FILENAME);
}
/**
* Список файлов в директории
*
* @param array $allow массив расширений для файлов
* @param array $ignore массив имен пааок которые не нужно обрабатывать
*
* @return array
*/
public function getContent ($allow = null, $ignore = array())
{
$ignore = array_merge(array (".", "..", $ignore));
return self::fileList($this->__toString(), $allow, $ignore);
}
// Использовать SPL ???
protected function fileList ($base, &$allow, &$ignore)
{
$result = array ();
if ($handle = opendir($base)) {
while (false !== ($file = readdir($handle))) {
if (! in_array ($file, $ignore)) {
$isDir = is_dir (Path::join ($base, $file));
if ($isDir || ($allow == null) || in_array (self::getExtension($file), $allow)) {
$result[] = $file;
}
}
}
closedir($handle);
}
return $result;
}
protected 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 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;
}
/**
* Рекурсивно копирует директорию
*
* @param string $source Папка из которой копируется
* @param string $target Папка в которую копируется
*/
public static function copy ($source, $target)
{
if (is_dir($source)) {
if (! file_exists($target)) mkdir ($target);
$path = new Path($source);
$files = $path->getContent();
foreach ($files as $file) {
$entry = self::join($source, $file);
if (is_dir($entry)) {
self::copy($entry, Path::join($target, $file));
} else {
copy($entry, Path::join($target, $file));
}
}
}
}
/**
* Рекурсивно удаляет директорию
*
* @param string $path Папка
*/
public static function delete ($path)
{
assert(is_string($path));
if (is_dir($path)) {
foreach(glob($path . '/*') as $sf) {
if (is_dir($sf) && !is_link($sf)) {
self::delete($sf);
} else {
unlink($sf);
}
}
rmdir($path);
}
}
/**
* Преобразует строку путя в массив
@ -192,28 +121,60 @@ class Path
{
assert(is_string($path));
$list = preg_split("/[\/\\\\]/", $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 function optimize ()
public static function optimize($path) //
{
$result = array(current($this->path));
while (next($this->path) !== false) {
$n = current ($this->path);
$result = array();
foreach ($path as $n) {
switch ($n) {
// Может быть относительным или абсолютным путем
case "": break;
case ".": break;
case "..": if (count($result) > 0) array_pop($result); break;
case "..":
if (count($result) > 0) { array_pop($result); break; }
default:
array_push($result, $n);
}
}
reset($this->path);
$this->path = $result;
}
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'] : '');
}
/**
@ -221,10 +182,11 @@ class Path
*
* @return string
*/
public function __toString ()
public function __toString()
{
$result = implode($this->path, self::SEPARATOR);
return $result;
$result = (($this->absolute) ? '/' : '') . implode(self::SEPARATOR, $this->path);
$this->url['path'] = $result;
return self::makeUrl($this->url);
}
/**
@ -234,8 +196,11 @@ class Path
*
* @return boolean
*/
public function isParent ($path)
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]) {
@ -246,6 +211,12 @@ class Path
}
return false;
}
public static function _isParent($path1, $path2)
{
$path = new Path($path1);
return $path->isParent(new Path($path2));
}
/**
* Находит путь относительно текущего путя
@ -254,34 +225,97 @@ class Path
*
* @return string Относительный путь к файлу
*/
public function relPath ($name)
public function relPath($name)
{
$path = new Path ($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();
}
public function append ($path)
// Вычисляет относительный путь в виде строки
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);
}
}
/**
* Создает недастающие папки для записи файла
*
* @param string $dst Полное имя файла
*
* @return void
* Обьединяет строки в путь соединяя необходимым разделителем
* fixme не обрабатывает параметры урла, решение Path::join(SITE_WWW_PATH) . '?param=pampam'
* @return string
*/
static function prepare ($dst)
static function join($_rest)
{
$path_dst = pathinfo($dst, PATHINFO_DIRNAME);
if (! file_exists($path_dst)) {
mkdir($path_dst, 0700, true);
$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;
}
/**
@ -291,7 +325,7 @@ class Path
*
* @return string Новое имя файла
*/
static function resolveFile ($dst)
static function resolveFile($dst)
{
$i = 0;
$file = self::skipExtension($dst);
@ -304,14 +338,93 @@ class Path
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);
}
/**
* Обьединяет строки в путь соединяя необходимым разделителем
*
* @return string
*/
static function join ()
* @param array $allow массив расширений разрешеных для файлов
* @param array $ignore массив имен пааок которые не нужно обрабатывать
*
* @return array
*/
function getContentRec($allow = null, $ignore = array())
{
$args = func_get_args();
return implode(self::SEPARATOR, $args);
$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);
}
}
}