diff --git a/Message/Http/Request.php b/Message/Http/Request.php index 9f0e0d9c5..99d4fd75c 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -34,14 +34,6 @@ use phpOMS\Uri\UriInterface; final class Request extends RequestAbstract { - /** - * Uploaded files. - * - * @var array - * @since 1.0.0 - */ - protected $files = []; - /** * Browser type. * @@ -418,18 +410,6 @@ final class Request extends RequestAbstract return $body === false ? '' : $body; } - /** - * Get files passed in request. - * - * @return array - * - * @since 1.0.0 - */ - public function getFiles() : array - { - return $this->files; - } - /** * {@inheritdoc} */ diff --git a/Message/Mail/Pop3.php b/Message/Mail/Pop3.php index f28977143..e201f0738 100644 --- a/Message/Mail/Pop3.php +++ b/Message/Mail/Pop3.php @@ -45,7 +45,7 @@ class Pop3 extends EmailAbstract * @param string $user Username * @param string $pass Password * - * @return void + * @return bool * * @since 1.0.0 */ diff --git a/Message/RequestAbstract.php b/Message/RequestAbstract.php index edfca85ec..2d5582e56 100644 --- a/Message/RequestAbstract.php +++ b/Message/RequestAbstract.php @@ -74,6 +74,14 @@ abstract class RequestAbstract implements MessageInterface */ protected $hash = []; + /** + * Uploaded files. + * + * @var array + * @since 1.0.0 + */ + protected $files = []; + /** * Request lock. * @@ -329,4 +337,16 @@ abstract class RequestAbstract implements MessageInterface * @since 1.0.0 */ abstract public function getRouteVerb() : int; + + /** + * Get files. + * + * @return array + * + * @since 1.0.0 + */ + public function getFiles() : array + { + return $this->files; + } } diff --git a/System/File/ContainerInterface.php b/System/File/ContainerInterface.php index ef05b5487..6b897355d 100644 --- a/System/File/ContainerInterface.php +++ b/System/File/ContainerInterface.php @@ -26,204 +26,6 @@ namespace phpOMS\System\File; */ interface ContainerInterface { - /** - * Get the datetime when the resource got created. - * - * @param string $path Path of the resource - * - * @return \DateTime - * - * @since 1.0.0 - */ - public static function created(string $path) : \DateTime; - - /** - * Get the datetime when the resource got last modified. - * - * @param string $path Path of the resource - * - * @return \DateTime - * - * @since 1.0.0 - */ - public static function changed(string $path) : \DateTime; - - /** - * Get the owner id of the resource. - * - * @param string $path Path of the resource - * - * @return int - * - * @since 1.0.0 - */ - public static function owner(string $path) : int; - - /** - * Get the permissions id of the resource. - * - * @param string $path Path of the resource - * - * @return int Permissions (e.g. 0755); - * - * @since 1.0.0 - */ - public static function permission(string $path) : int; - - /** - * Get the parent path of the resource. - * - * The parent resource path is always a directory. - * - * @param string $path Path of the resource - * - * @return string - * - * @since 1.0.0 - */ - public static function parent(string $path) : string; - - /** - * Create resource at destination path. - * - * @param string $path Path of the resource - * - * @return bool True on success and false on failure - * - * @since 1.0.0 - */ - public static function create(string $path) : bool; - - /** - * Delete resource at destination path. - * - * @param string $path Path of the resource - * - * @return bool True on success and false on failure - * - * @since 1.0.0 - */ - public static function delete(string $path) : bool; - - /** - * Copy resource to different location. - * - * @param string $from Path of the resource to copy - * @param string $to Path of the resource to copy to - * @param bool $overwrite Overwrite/replace existing file - * - * @return bool True on success and false on failure - * - * @since 1.0.0 - */ - public static function copy(string $from, string $to, bool $overwrite = false) : bool; - - /** - * Move resource to different location. - * - * @param string $from Path of the resource to move - * @param string $to Path of the resource to move to - * @param bool $overwrite Overwrite/replace existing file - * - * @return bool True on success and false on failure - * - * @since 1.0.0 - */ - public static function move(string $from, string $to, bool $overwrite = false) : bool; - - /** - * Get size of resource. - * - * @param string $path Path of the resource - * @param bool $recursive Should include sub-sub-resources - * - * @return int - * - * @since 1.0.0 - */ - public static function size(string $path, bool $recursive = true) : int; - - /** - * Check existence of resource. - * - * @param string $path Path of the resource - * - * @return bool - * - * @since 1.0.0 - */ - public static function exists(string $path) : bool; - - /** - * Get name of resource. - * - * @param string $path Path of the resource - * - * @return string - * - * @since 1.0.0 - */ - public static function name(string $path) : string; - - /** - * Get basename of resource. - * - * @param string $path Path of the resource - * - * @return string - * - * @since 1.0.0 - */ - public static function basename(string $path) : string; - - /** - * Get the directory name of the resource. - * - * @param string $path Path of the resource - * - * @return string - * - * @since 1.0.0 - */ - public static function dirname(string $path) : string; - - /** - * Get the directory path of the resource. - * - * @param string $path Path of the resource - * - * @return string - * - * @since 1.0.0 - */ - public static function dirpath(string $path) : string; - - /** - * Count subresources. - * - * @param string $path Path of the resource - * @param bool $recursive Consider subdirectories - * @param array $ignore Files/paths to ignore (no regex) - * - * @return int - * - * @since 1.0.0 - */ - public static function count(string $path, bool $recursive = true, array $ignore = []) : int; - - /** - * Make name/path operating system safe. - * - * @param string $path Path of the resource - * @param string $replace Replace invalid chars with - * @param string $invalid Invalid chars to sanitize - * - * @return string - * - * @since 1.0.0 - */ - public static function sanitize(string $path, string $replace = '', string $invalid = '/[^\w\s\d\.\-_~,;\/\[\]\(\]]/') : string; - /** * Get amount of sub-resources. * diff --git a/System/File/DirectoryInterface.php b/System/File/DirectoryInterface.php index 2b68a7c7b..ab7ef88b9 100644 --- a/System/File/DirectoryInterface.php +++ b/System/File/DirectoryInterface.php @@ -26,21 +26,6 @@ namespace phpOMS\System\File; */ interface DirectoryInterface extends ContainerInterface, \Iterator, \ArrayAccess { - /** - * Get amount of sub-resources. - * - * A file will always return 1 as it doesn't have any sub-resources. - * - * @param string $path Path of the resource - * @param bool $recursive Should count also sub-sub-resources - * @param array $ignore Ignore files - * - * @return int - * - * @since 1.0.0 - */ - public static function count(string $path, bool $recursive = true, array $ignore = []) : int; - /** * Get node by name. * diff --git a/System/File/FileInterface.php b/System/File/FileInterface.php index d27798004..146a6482b 100644 --- a/System/File/FileInterface.php +++ b/System/File/FileInterface.php @@ -27,83 +27,6 @@ namespace phpOMS\System\File; interface FileInterface extends ContainerInterface { - /** - * Save content to file. - * - * @param string $path File path to save the content to - * @param string $content Content to save in file - * @param int $mode Mode (overwrite, append) - * - * @return bool - * - * @since 1.0.0 - */ - public static function put(string $path, string $content, int $mode = ContentPutMode::APPEND | ContentPutMode::CREATE) : bool; - - /** - * Save content to file. - * - * Creates new file if it doesn't exist or overwrites existing file. - * - * @param string $path File path to save the content to - * @param string $content Content to save in file - * - * @return bool - * - * @since 1.0.0 - */ - public static function set(string $path, string $content) : bool; - - /** - * Save content to file. - * - * Creates new file if it doesn't exist or appends existing file. - * - * @param string $path File path to save the content to - * @param string $content Content to save in file - * - * @return bool - * - * @since 1.0.0 - */ - public static function append(string $path, string $content) : bool; - - /** - * Save content to file. - * - * Creates new file if it doesn't exist or prepends existing file. - * - * @param string $path File path to save the content to - * @param string $content Content to save in file - * - * @return bool - * - * @since 1.0.0 - */ - public static function prepend(string $path, string $content) : bool; - - /** - * Get content from file. - * - * @param string $path File path of content - * - * @return string Content of file - * - * @since 1.0.0 - */ - public static function get(string $path) : string; - - /** - * Get file extension. - * - * @param string $path File path - * - * @return string - * - * @since 1.0.0 - */ - public static function extension(string $path) : string; - /** * Save content to file. * diff --git a/System/File/FileUtils.php b/System/File/FileUtils.php index 6e8a267c9..8179de921 100644 --- a/System/File/FileUtils.php +++ b/System/File/FileUtils.php @@ -136,4 +136,37 @@ final class FileUtils \file_put_contents($file, \mb_convert_encoding($content, 'UTF-8', \mb_list_encodings())); } } + + /** + * Converts a string permisseion (rwx) to octal + * + * @param string $permission Permission string (e.g. rwx-w-r--) + * + * @return int + * + * @since 1.0.0 + */ + public static function permissionToOctal(string $permission) : int + { + $permissionLength = \strlen($permission); + $perm = ''; + $tempPermission = 0; + + for ($i = 0; $i < $permissionLength; ++$i) { + if ($permission[$i] === 'r') { + $tempPermission += 4; + } elseif ($permission[$i] === 'w') { + $tempPermission += 2; + } elseif ($permission[$i] === 'x') { + $tempPermission += 1; + } + + if (($i + 1) % 3 === 0) { + $perm .= $tempPermission; + $tempPermission = 0; + } + } + + return \intval($perm, 8); + } } diff --git a/System/File/Ftp/Directory.php b/System/File/Ftp/Directory.php index 3cd42cf15..9bb03a3ad 100644 --- a/System/File/Ftp/Directory.php +++ b/System/File/Ftp/Directory.php @@ -16,9 +16,10 @@ namespace phpOMS\System\File\Ftp; use phpOMS\System\File\ContainerInterface; use phpOMS\System\File\DirectoryInterface; -use phpOMS\System\File\Local\Directory as DirectoryLocal; +use phpOMS\System\File\FileUtils; +use phpOMS\System\File\Local\Directory as LocalDirectory; use phpOMS\System\File\Local\File as LocalFile; -use phpOMS\System\File\Local\FileAbstract; +use phpOMS\System\File\PathException; use phpOMS\Uri\Http; /** @@ -30,41 +31,9 @@ use phpOMS\Uri\Http; * @license OMS License 1.0 * @link http://website.orange-management.de * @since 1.0.0 - * @codeCoverageIgnore */ -class Directory extends FileAbstract implements DirectoryInterface +class Directory extends FileAbstract implements FtpContainerInterface, DirectoryInterface { - public static function ftpConnect(Http $http) - { - $con = \ftp_connect($http->getBase() . $http->getPath(), $http->getPort()); - - \ftp_login($con, $http->getUser(), $http->getPass()); - \ftp_chdir($con, $http->getPath()); // todo: is this required ? - - return $con; - } - - public static function ftpExists($con, string $path) - { - $list = \ftp_nlist($con, LocalFile::parent($path)); - - return \in_array(LocalFile::name($path), $list); - } - - public static function ftpCreate($con, string $path, int $permission, bool $recursive) : void - { - $parts = \explode('/', $path); - \ftp_chdir($con, '/' . $parts[0]); - - foreach ($parts as $part) { - if (self::ftpExists($con, $part)) { - \ftp_\kdir($con, $part); - \ftp_chdir($con, $part); - \ftp_chmod($con, $permission, $part); - } - } - } - /** * Directory nodes (files and directories). * @@ -74,28 +43,193 @@ class Directory extends FileAbstract implements DirectoryInterface private $nodes = []; /** - * {@inheritdoc} + * Create ftp connection. + * + * @param HTTP $http Uri + * + * @return mixed + * + * @since 1.0.0 */ - public static function size(string $dir, bool $recursive = true) : int + public static function ftpConnect(Http $http) { + $con = \ftp_connect($http->getHost(), $http->getPort()); + \ftp_login($con, $http->getUser(), $http->getPass()); + + if ($http->getPath() !== '') { + \ftp_chdir($con, $http->getPath()); + } + + return $con; + } + + /** + * List all files in directory. + * + * @param resource $con FTP connection + * @param string $path Path + * @param string $filter Filter + * + * @return array + * + * @since 1.0.0 + */ + public static function list($con, string $path, string $filter = '*') : array + { + if (!self::exists($con, $path)) { + return []; + } + + $list = []; + $path = \rtrim($path, '\\/'); + $detailed = self::parseRawList($con, $path); + + foreach ($detailed as $key => $item) { + $list[] = $key; + + if ($item['type'] === 'dir') { + $list = \array_merge($list, self::list($con, $key)); + } + } + + /** @var array $list */ + return $list; } /** * {@inheritdoc} */ - public static function count(string $path, bool $recursive = true, array $ignore = ['.', '..', 'cgi-bin', - '.DS_Store']) : int + public static function exists($con, string $path) : bool { + return File::exists($con, $path); + } + /** + * Create directory + * + * @param resource $con FTP connection + * @param string $path Path of the resource + * @param int $permission Permission + * @param bool $recursive Create recursive in case of subdirectories + * + * @return bool + * + * @since 1.0.0 + */ + public static function create($con, string $path, int $permission = 0755, bool $recursive = false) : bool + { + if (self::exists($con, $path)) { + return false; + } + + $parts = \explode('/', $path); + if ($parts[0] === '') { + $parts[0] = '/'; + } + + $depth = \count($parts); + + $currentPath = ''; + foreach ($parts as $key => $part) { + $currentPath .= ($currentPath !== '' && $currentPath !== '/' ? '/' : '') . $part; + + if (!self::exists($con, $currentPath)) { + if (!$recursive && $key < $depth - 1) { + return false; + } + + \ftp_mkdir($con, $part); + \ftp_chmod($con, $permission, $part); + } + + \ftp_chdir($con, $part); + } + + return self::exists($con, $path); } /** * {@inheritdoc} */ - public static function delete(string $path) : bool + public static function size($con, string $dir, bool $recursive = true) : int { + if (!self::exists($con, $dir)) { + throw new PathException($dir); + } + $countSize = 0; + $directories = self::parseRawList($con, $dir); + + if ($directories === false) { + return $countSize; + } + + foreach ($directories as $key => $filename) { + if ($key === '..' || $key === '.') { + continue; + } + + if ($filename['type'] === 'dir' && $recursive) { + $countSize += self::size($con, $key, $recursive); + } elseif ($filename['type'] === 'file' ) { + $countSize += \ftp_size($con, $key); + } + } + + return $countSize; + } + + /** + * {@inheritdoc} + */ + public static function count($con, string $path, bool $recursive = true, array $ignore = []) : int + { + if (!self::exists($con, $path)) { + throw new PathException($path); + } + + $size = 0; + $files = self::parseRawList($con, $path); + $ignore[] = '.'; + $ignore[] = '..'; + + if ($files === false) { + return $size; + } + + foreach ($files as $key => $t) { + if (\in_array($key, $ignore)) { + continue; + } + if ($t['type'] === 'dir') { + if ($recursive) { + $size += self::count($con, $key, true, $ignore); + } + } else { + ++$size; + } + } + + return $size; + } + + /** + * {@inheritdoc} + */ + public static function delete($con, string $path) : bool + { + $list = self::parseRawList($con, $path); + + foreach ($list as $key => $item) { + if ($item['type'] === 'dir') { + self::delete($con, $key); + } else { + File::delete($con, $key); + } + } + + return \ftp_rmdir($con, $path); } /** @@ -103,63 +237,224 @@ class Directory extends FileAbstract implements DirectoryInterface */ public static function parent(string $path) : string { - - } - - /** - * {@inheritdoc} - * todo: move to fileAbastract since it should be the same for file and directory? - */ - public static function created(string $path) : \DateTime - { - + return LocalDirectory::parent($path); } /** * {@inheritdoc} */ - public static function changed(string $path) : \DateTime + public static function created($con, string $path) : \DateTime { - // TODO: Implement changed() method. + return self::changed($con, $path); } /** * {@inheritdoc} */ - public static function owner(string $path) : int + public static function changed($con, string $path) : \DateTime { - // TODO: Implement owner() method. + if (!self::exists($con, $path)) { + throw new PathException($path); + } + + $changed = new \DateTime(); + $time = \ftp_mdtm($con, $path); + + $changed->setTimestamp($time === false ? 0 : $time); + + return $changed; } /** * {@inheritdoc} */ - public static function permission(string $path) : int + public static function owner($con, string $path) : string { - // TODO: Implement permission() method. + if (!self::exists($con, $path)) { + throw new PathException($path); + } + + return self::parseRawList($con, self::parent($path))[$path]['user']; + } + + /** + * Get detailed file/dir list. + * + * @param resource $con FTP connection + * @param string $path Path of the resource + * + * @return array + * + * @since 1.0.0 + */ + public static function parseRawList($con, string $path) : array + { + $listData = \ftp_rawlist($con, $path); + $names = \ftp_nlist($con, $path); + $data = []; + + foreach ($listData as $key => $item) { + $chunks = \preg_split("/\s+/", $item); + list( + $e['permission'], + $e['number'], + $e['user'], + $e['group'], + $e['size'], + $e['month'], + $e['day'], + $e['time'] + ) = $chunks; + + $e['permission'] = FileUtils::permissionToOctal(\substr($e['permission'], 1)); + $e['type'] = $chunks[0]{0} === 'd' ? 'dir' : 'file'; + + $data[$names[$key]] = $e; + } + + return $data; } /** * {@inheritdoc} */ - public static function copy(string $from, string $to, bool $overwrite = false) : bool + public static function permission($con, string $path) : int { - // TODO: Implement copy() method. + if (!self::exists($con, $path)) { + throw new PathException($path); + } + + return self::parseRawList($con, self::parent($path))[$path]['permission']; } /** * {@inheritdoc} */ - public static function move(string $from, string $to, bool $overwrite = false) : bool + public static function copy($con, string $from, string $to, bool $overwrite = false) : bool { - // TODO: Implement move() method. + if (!self::exists($con, $from)) { + return false; + } + + $tempName = 'temp' . \mt_rand(); + \mkdir($tempName); + $download = self::get($con, $from, $tempName . '/' . self::name($from)); + + if (!$download) { + return false; + } + + $upload = self::put($con, \realpath($tempName) . '/' . self::name($from), $to); + + if (!$upload) { + return false; + } + + LocalDirectory::delete($tempName); + + return self::exists($con, $to); } /** - * {@inheritdoc} + * Download file. + * + * @param resource $con FTP connection + * @param string $from Path of the resource to copy + * @param string $to Path of the resource to copy to + * + * @return bool True on success and false on failure + * + * @since 1.0.0 */ - public static function exists(string $path) : bool + public static function get($con, string $from, string $to) : bool { + if (!self::exists($con, $from)) { + return false; + } + + if (!\file_exists($to)) { + \mkdir($to); + } + + $list = self::parseRawList($con, $from); + foreach ($list as $key => $item) { + if ($item['type'] === 'dir') { + self::get($con, $key, $to . '/' . self::name($key)); + } else { + \file_put_contents($to . '/' . self::name($key), File::get($con, $key)); + } + } + + return \file_exists($to); + } + + /** + * Upload file. + * + * @param resource $con FTP connection + * @param string $from Path of the resource to copy + * @param string $to Path of the resource to copy to + * + * @return bool True on success and false on failure + * + * @since 1.0.0 + */ + public static function put($con, string $from, string $to) : bool + { + if (!\file_exists($from)) { + return false; + } + + if (!self::exists($con, $to)) { + self::create($con, $to, 0755, true); + } + + $list = \scandir($from); + foreach ($list as $key => $item) { + if ($item === '.' || $item === '..') { + continue; + } + + $item = $from . '/' . \ltrim($item, '/'); + + if (\is_dir($item)) { + self::put($con, $item, $to . '/' . self::name($item)); + } else { + File::put($con, $to . '/' . self::name($item), \file_get_contents($item)); + } + } + + return self::exists($con, $to); + } + + /** + * Move resource to different location. + * + * @param resource $con FTP connection + * @param string $from Path of the resource to move + * @param string $to Path of the resource to move to + * @param bool $overwrite Overwrite/replace existing file + * + * @return bool True on success and false on failure + * + * @since 1.0.0 + */ + public static function move($con, string $from, string $to, bool $overwrite = false) : bool + { + if (!self::exists($con, $from)) { + return false; + } + + if ($overwrite && self::exists($con, $to)) { + self::delete($con, $to); + } elseif (self::exists($con, $to)) { + return false; + } + + $copy = self::copy($con, $from, $to); + self::delete($con, $from); + + return $copy; } /** @@ -167,15 +462,7 @@ class Directory extends FileAbstract implements DirectoryInterface */ public static function sanitize(string $path, string $replace = '', string $invalid = '/[^\w\s\d\.\-_~,;\/\[\]\(\]]/') : string { - return DirectoryLocal::sanitize($path, $replace, $invalid); - } - - /** - * {@inheritdoc} - */ - public static function create(string $path, int $permission = 0755, bool $recursive = false) : bool - { - + return LocalDirectory::sanitize($path, $replace, $invalid); } /** @@ -183,7 +470,7 @@ class Directory extends FileAbstract implements DirectoryInterface */ public static function dirname(string $path) : string { - + return LocalDirectory::dirname($path); } /** @@ -191,7 +478,7 @@ class Directory extends FileAbstract implements DirectoryInterface */ public static function dirpath(string $path) : string { - + return LocalDirectory::dirpath($path); } /** @@ -199,7 +486,7 @@ class Directory extends FileAbstract implements DirectoryInterface */ public static function name(string $path) : string { - return DirectoryLocal::name($path); + return LocalDirectory::name($path); } /** @@ -207,7 +494,7 @@ class Directory extends FileAbstract implements DirectoryInterface */ public static function basename(string $path) : string { - return DirectoryLocal::basename($path); + return LocalDirectory::basename($path); } /** diff --git a/System/File/Ftp/File.php b/System/File/Ftp/File.php index 32a172621..4e32abe69 100644 --- a/System/File/Ftp/File.php +++ b/System/File/Ftp/File.php @@ -17,8 +17,8 @@ namespace phpOMS\System\File\Ftp; use phpOMS\System\File\ContainerInterface; use phpOMS\System\File\ContentPutMode; use phpOMS\System\File\FileInterface; +use phpOMS\System\File\Local\Directory as LocalDirectory; use phpOMS\System\File\Local\File as LocalFile; -use phpOMS\System\File\Local\FileAbstract; use phpOMS\System\File\PathException; use phpOMS\Uri\Http; @@ -33,7 +33,6 @@ use phpOMS\Uri\Http; * @license OMS License 1.0 * @link http://website.orange-management.de * @since 1.0.0 - * @codeCoverageIgnore */ class File extends FileAbstract implements FileInterface { @@ -59,60 +58,50 @@ class File extends FileAbstract implements FileInterface $this->con = self::ftpConnect($this->uri); } + /** + * Create ftp connection. + * + * @param HTTP $http Uri + * + * @return mixed + * + * @since 1.0.0 + */ public static function ftpConnect(Http $http) { - $con = \ftp_connect($http->getBase() . $http->getPath(), $http->getPort()); + $con = \ftp_connect($http->getHost(), $http->getPort()); \ftp_login($con, $http->getUser(), $http->getPass()); - \ftp_chdir($con, $http->getPath()); // todo: is this required ? + + if ($http->getPath() !== '') { + \ftp_chdir($con, $http->getPath()); + } return $con; } - public static function ftpExists($con, string $path) - { - $list = \ftp_nlist($con, LocalFile::dirpath($path)); - - return \in_array(LocalFile::basename($path), $list); - } - /** * {@inheritdoc} */ - public static function put(string $path, string $content, int $mode = ContentPutMode::REPLACE | ContentPutMode::CREATE) : bool + public static function exists($con, string $path) : bool { - $http = new Http($path); - $con = self::ftpConnect($http); - - if (\ftp_pwd($con) !== $http->getPath()) { - return false; - } - - $exists = self::ftpExists($con, $http->getPath()); - - if ((ContentPutMode::hasFlag($mode, ContentPutMode::APPEND) && $exists) - || (ContentPutMode::hasFlag($mode, ContentPutMode::PREPEND) && $exists) - || (ContentPutMode::hasFlag($mode, ContentPutMode::REPLACE) && $exists) - || (!$exists && ContentPutMode::hasFlag($mode, ContentPutMode::CREATE)) - ) { - if (ContentPutMode::hasFlag($mode, ContentPutMode::APPEND) && $exists) { - \file_put_contents($path, \file_get_contents($path) . $content, 0, \stream_context_create(['ftp' => ['overwrite' => true]])); - } elseif (ContentPutMode::hasFlag($mode, ContentPutMode::PREPEND) && $exists) { - \file_put_contents($path, $content . \file_get_contents($path), 0, \stream_context_create(['ftp' => ['overwrite' => true]])); - } else { - if (!Directory::ftpExists($con, \dirname($path))) { - Directory::ftpCreate($con, \dirname($path), 0755, true); - } - - \file_put_contents($path, $content, 0, \stream_context_create(['ftp' => ['overwrite' => true]])); - } - - \ftp_close($con); - + if ($path === '/') { return true; } - \ftp_close($con); + $parent = LocalDirectory::parent($path); + $list = \ftp_nlist($con, $parent === '' ? '/' : $parent); + + if ($list === false) { + return false; + } + + $pathName = LocalDirectory::name($path); + foreach ($list as $key => $item) { + if ($pathName === LocalDirectory::name($item)) { + return true; + } + } return false; } @@ -120,20 +109,55 @@ class File extends FileAbstract implements FileInterface /** * {@inheritdoc} */ - public static function get(string $path) : string + public static function put($con, string $path, string $content, int $mode = ContentPutMode::REPLACE | ContentPutMode::CREATE) : bool { - $temp = \fopen('php://temp', 'r+'); - $http = new Http($path); - $content = ''; - $con = self::ftpConnect($http); + $exists = self::exists($con, $path); - if (\ftp_chdir($con, self::dirpath($path)) && \ftp_fget($con, $temp, $path, FTP_BINARY, 0)) { + if ((ContentPutMode::hasFlag($mode, ContentPutMode::APPEND) && $exists) + || (ContentPutMode::hasFlag($mode, ContentPutMode::PREPEND) && $exists) + || (ContentPutMode::hasFlag($mode, ContentPutMode::REPLACE) && $exists) + || (!$exists && ContentPutMode::hasFlag($mode, ContentPutMode::CREATE)) + ) { + $tmpFile = 'file' . \mt_rand(); + if (ContentPutMode::hasFlag($mode, ContentPutMode::APPEND) && $exists) { + \file_put_contents($tmpFile, self::get($con, $path) . $content); + } elseif (ContentPutMode::hasFlag($mode, ContentPutMode::PREPEND) && $exists) { + \file_put_contents($tmpFile, $content . self::get($con, $path)); + } else { + if (!Directory::exists($con, \dirname($path))) { + Directory::create($con, \dirname($path), 0755, true); + } + + \file_put_contents($tmpFile, $content); + } + + \ftp_put($con, $path, $tmpFile, FTP_BINARY); + \ftp_chmod($con, 0755, $path); + \unlink($tmpFile); + + return true; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public static function get($con, string $path) : string + { + if (!self::exists($con, $path)) { + throw new PathException($path); + } + + $temp = \fopen('php://temp', 'r+'); + $content = ''; + + if (\ftp_fget($con, $temp, $path, FTP_BINARY, 0)) { \rewind($temp); $content = \stream_get_contents($temp); } - \fclose($temp); - return $content; } @@ -142,45 +166,31 @@ class File extends FileAbstract implements FileInterface */ public static function count(string $path, bool $recursive = true, array $ignore = []) : int { - + return 1; } /** * {@inheritdoc} */ - public static function set(string $path, string $content) : bool + public static function set($con, string $path, string $content) : bool { - return self::put($path, $content, ContentPutMode::REPLACE | ContentPutMode::CREATE); + return self::put($con, $path, $content, ContentPutMode::REPLACE | ContentPutMode::CREATE); } /** * {@inheritdoc} */ - public static function append(string $path, string $content) : bool + public static function append($con, string $path, string $content) : bool { - return self::put($path, $content, ContentPutMode::APPEND | ContentPutMode::CREATE); + return self::put($con, $path, $content, ContentPutMode::APPEND | ContentPutMode::CREATE); } /** * {@inheritdoc} */ - public static function prepend(string $path, string $content) : bool + public static function prepend($con, string $path, string $content) : bool { - return self::put($path, $content, ContentPutMode::PREPEND | ContentPutMode::CREATE); - } - - /** - * {@inheritdoc} - */ - public static function exists(string $path) : bool - { - $http = new Http($path); - $con = self::ftpConnect($http); - $exists = self::ftpExists($con, $http->getPath()); - - \fclose($con); - - return $exists; + return self::put($con, $path, $content, ContentPutMode::PREPEND | ContentPutMode::CREATE); } /** @@ -202,23 +212,24 @@ class File extends FileAbstract implements FileInterface /** * {@inheritdoc} */ - public static function created(string $path) : \DateTime + public static function created($con, string $path) : \DateTime { - return new \DateTime('1970-01-01'); + return self::changed($con, $path); } /** * {@inheritdoc} */ - public static function changed(string $path) : \DateTime + public static function changed($con, string $path) : \DateTime { - $http = new Http($path); - $con = self::ftpConnect($http); + if (!self::exists($con, $path)) { + throw new PathException($path); + } + $changed = new \DateTime(); + $time = \ftp_mdtm($con, $path); - $changed->setTimestamp(ftp_mdtm($con, $http->getPath())); - - \fclose($con); + $changed->setTimestamp($time === false ? 0 : $time); return $changed; } @@ -226,71 +237,36 @@ class File extends FileAbstract implements FileInterface /** * {@inheritdoc} */ - public static function size(string $path, bool $recursive = true) : int + public static function size($con, string $path, bool $recursive = true) : int { - $http = new Http($path); - $con = self::ftpConnect($http); - - if (!self::exists($http->getPath())) { + if (!self::exists($con, $path)) { throw new PathException($path); } - $size = \ftp_size($con, $http->getPath()); - - \fclose($con); - - return $size; + return \ftp_size($con, $path); } /** * {@inheritdoc} */ - public static function owner(string $path) : int + public static function owner($con, string $path) : string { - $http = new Http($path); - $con = self::ftpConnect($http); - $owner = self::parseFtpFileData($con, $path)['user'] ?? ''; - - \fclose($con); - - return (int) $owner; - } - - /** - * {@inheritdoc} - */ - public static function permission(string $path) : int - { - $http = new Http($path); - $con = self::ftpConnect($http); - $permission = (int) self::parseFtpFileData($con, $path)['permission'] ?? 0; - - \fclose($con); - - return $permission; - } - - private static function parseFtpFileData($con, string $path) : array - { - $items = []; - - if (\is_array($files = \ftp_rawlist($con, LocalFile::dirpath($path)))) { - foreach ($files as $fileData) { - if (\strpos($fileData, self::name($path)) !== false) { - $chunks = \preg_split("/\s+/", $fileData); - - $items['permission'] = $chunks[0]; - $items['user'] = $chunks[2]; - $items['group'] = $chunks[3]; - $items['size'] = $chunks[4]; - $items['type'] = $chunks[0][0] === 'd' ? 'directory' : 'file'; - - break; - } - } + if (!self::exists($con, $path)) { + throw new PathException($path); } - return $items; + return Directory::parseRawList($con, self::parent($path))[$path]['user']; + } + /** + * {@inheritdoc} + */ + public static function permission($con, string $path) : int + { + if (!self::exists($con, $path)) { + throw new PathException($path); + } + + return Directory::parseRawList($con, self::parent($path))[$path]['permission']; } /** @@ -324,70 +300,65 @@ class File extends FileAbstract implements FileInterface /** * {@inheritdoc} */ - public static function copy(string $from, string $to, bool $overwrite = false) : bool + public static function copy($con, string $from, string $to, bool $overwrite = false) : bool { - // todo: handle different ftp connections AND local to ftp - - if (($src = self::get($from)) === false) { + if (!self::exists($con, $from)) { return false; } - return self::put($to, $src, $overwrite ? ContentPutMode::REPLACE : ContentPutMode::CREATE); - } - - /** - * {@inheritdoc} - */ - public static function move(string $from, string $to, bool $overwrite = false) : bool - { - // todo: handle different ftp connections AND local to ftp - $http = new Http($to); - $con = self::ftpConnect($http); - - if (!self::ftpExists($con, $from)) { - throw new PathException($from); - } - - if ($overwrite || !self::exists($to)) { - if (!Directory::exists(\dirname($to))) { - Directory::create(\dirname($to), 0755, true); - } - - $rename = \ftp_rename($con, $from, $to); - \fclose($con); - - return $rename; - } - - \fclose($con); - - return false; - } - - /** - * {@inheritdoc} - */ - public static function delete(string $path) : bool - { - $http = new Http($path); - $con = self::ftpConnect($http); - - if (!self::ftpExists($con, $path)) { + if (!$overwrite && self::exists($con, $to)) { return false; } - \ftp_delete($con, $path); - \fclose($con); + $download = self::get($con, $from); + $upload = self::put($con, $to, $download); - return true; + if (!$upload) { + return false; + } + + return self::exists($con, $to); } /** * {@inheritdoc} */ - public static function create(string $path) : bool + public static function move($con, string $from, string $to, bool $overwrite = false) : bool { - return self::put($path, '', ContentPutMode::CREATE); + if (!self::exists($con, $from)) { + return false; + } + + if ($overwrite && self::exists($con, $to)) { + self::delete($con, $to); + } elseif (self::exists($con, $to)) { + return false; + } + + $copy = self::copy($con, $from, $to); + self::delete($con, $from); + + return $copy; + } + + /** + * {@inheritdoc} + */ + public static function delete($con, string $path) : bool + { + if (!self::exists($con, $path)) { + return false; + } + + return \ftp_delete($con, $path); + } + + /** + * {@inheritdoc} + */ + public static function create($con, string $path) : bool + { + return self::put($con, $path, '', ContentPutMode::CREATE); } /** diff --git a/System/File/Ftp/FileAbstract.php b/System/File/Ftp/FileAbstract.php new file mode 100644 index 000000000..9ae8135d6 --- /dev/null +++ b/System/File/Ftp/FileAbstract.php @@ -0,0 +1,199 @@ +path = \rtrim($path, '/\\'); + $this->name = \basename($path); + + $this->createdAt = new \DateTime('now'); + $this->changedAt = new \DateTime('now'); + } + + /** + * {@inheritdoc} + */ + public function getCount(bool $recursive = true) : int + { + return $this->count; + } + + /** + * {@inheritdoc} + */ + public function getSize(bool $recursive = true) : int + { + return $this->size; + } + + /** + * {@inheritdoc} + */ + public function getName() : string + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function getPath() : string + { + return $this->path; + } + + /** + * {@inheritdoc} + */ + public function parentNode() : Directory + { + return new Directory(Directory::parent($this->path)); + } + + /** + * {@inheritdoc} + */ + public function getCreatedAt() : \DateTime + { + return $this->createdAt; + } + + /** + * {@inheritdoc} + */ + public function getChangedAt() : \DateTime + { + return $this->changedAt; + } + + /** + * {@inheritdoc} + */ + public function getOwner() : int + { + return $this->owner; + } + + /** + * {@inheritdoc} + */ + public function getPermission() : int + { + return $this->permission; + } + + /** + * {@inheritdoc} + */ + public function index() : void + { + $mtime = \filemtime($this->path); + $ctime = \filectime($this->path); + + $this->createdAt->setTimestamp($mtime === false ? 0 : $mtime); + $this->changedAt->setTimestamp($ctime === false ? 0 : $ctime); + + $owner = \fileowner($this->path); + + $this->owner = $owner === false ? 0 : $owner; + $this->permission = (int) \substr(\sprintf('%o', \fileperms($this->path)), -4); + } +} diff --git a/System/File/Ftp/FtpContainerInterface.php b/System/File/Ftp/FtpContainerInterface.php new file mode 100644 index 000000000..d481df58d --- /dev/null +++ b/System/File/Ftp/FtpContainerInterface.php @@ -0,0 +1,225 @@ + $ignore Files/paths to ignore (no regex) + * + * @return int + * + * @since 1.0.0 + */ + public static function count($con, string $path, bool $recursive = true, array $ignore = []) : int; + + /** + * Make name/path operating system safe. + * + * @param string $path Path of the resource + * @param string $replace Replace invalid chars with + * @param string $invalid Invalid chars to sanitize + * + * @return string + * + * @since 1.0.0 + */ + public static function sanitize(string $path, string $replace = '', string $invalid = '/[^\w\s\d\.\-_~,;\/\[\]\(\]]/') : string; +} diff --git a/System/File/Local/Directory.php b/System/File/Local/Directory.php index 870c12aa6..81d80d4a4 100644 --- a/System/File/Local/Directory.php +++ b/System/File/Local/Directory.php @@ -29,7 +29,7 @@ use phpOMS\Utils\StringUtils; * @link http://website.orange-management.de * @since 1.0.0 */ -final class Directory extends FileAbstract implements DirectoryInterface +final class Directory extends FileAbstract implements LocalContainerInterface, DirectoryInterface { /** * Directory list filter. @@ -78,7 +78,7 @@ final class Directory extends FileAbstract implements DirectoryInterface public static function list(string $path, string $filter = '*') : array { if (!\file_exists($path)) { - throw new PathException($path); + return []; } $list = []; @@ -174,11 +174,11 @@ final class Directory extends FileAbstract implements DirectoryInterface } foreach ($directories as $key => $filename) { - if ($filename === ".." || $filename === ".") { + if ($filename === '..' || $filename === '.') { continue; } - $path = $dir . "/" . $filename; + $path = $dir . '/' . $filename; if (\is_dir($path) && $recursive) { $countSize += self::size($path, $recursive); } elseif (\is_file($path)) { @@ -190,7 +190,17 @@ final class Directory extends FileAbstract implements DirectoryInterface } /** - * {@inheritdoc} + * Get amount of sub-resources. + * + * A file will always return 1 as it doesn't have any sub-resources. + * + * @param string $path Path of the resource + * @param bool $recursive Should count also sub-sub-resources + * @param array $ignore Ignore files + * + * @return int + * + * @since 1.0.0 */ public static function count(string $path, bool $recursive = true, array $ignore = []) : int { @@ -216,7 +226,7 @@ final class Directory extends FileAbstract implements DirectoryInterface $size += self::count(\rtrim($path, '/') . '/' . $t, true, $ignore); } } else { - $size++; + ++$size; } } @@ -331,7 +341,7 @@ final class Directory extends FileAbstract implements DirectoryInterface public static function copy(string $from, string $to, bool $overwrite = false) : bool { if (!\is_dir($from)) { - throw new PathException($from); + return false; } if (!\file_exists($to)) { @@ -362,7 +372,7 @@ final class Directory extends FileAbstract implements DirectoryInterface public static function move(string $from, string $to, bool $overwrite = false) : bool { if (!\is_dir($from)) { - throw new PathException($from); + return false; } if (!$overwrite && \file_exists($to)) { @@ -415,7 +425,15 @@ final class Directory extends FileAbstract implements DirectoryInterface } /** - * {@inheritdoc} + * Create directory + * + * @param string $path Path of the resource + * @param int $permission Permission + * @param bool $recursive Create recursive in case of subdirectories + * + * @return bool + * + * @since 1.0.0 */ public static function create(string $path, int $permission = 0755, bool $recursive = false) : bool { diff --git a/System/File/Local/File.php b/System/File/Local/File.php index c43e9bbde..f56a4cdfb 100644 --- a/System/File/Local/File.php +++ b/System/File/Local/File.php @@ -29,7 +29,7 @@ use phpOMS\System\File\PathException; * @link http://website.orange-management.de * @since 1.0.0 */ -final class File extends FileAbstract implements FileInterface +final class File extends FileAbstract implements LocalContainerInterface, FileInterface { /** @@ -60,7 +60,15 @@ final class File extends FileAbstract implements FileInterface } /** - * {@inheritdoc} + * Save content to file. + * + * @param string $path File path to save the content to + * @param string $content Content to save in file + * @param int $mode Mode (overwrite, append) + * + * @return bool + * + * @since 1.0.0 */ public static function put(string $path, string $content, int $mode = ContentPutMode::REPLACE | ContentPutMode::CREATE) : bool { @@ -90,7 +98,13 @@ final class File extends FileAbstract implements FileInterface } /** - * {@inheritdoc} + * Get content from file. + * + * @param string $path File path of content + * + * @return string Content of file + * + * @since 1.0.0 */ public static function get(string $path) : string { @@ -112,7 +126,16 @@ final class File extends FileAbstract implements FileInterface } /** - * {@inheritdoc} + * Save content to file. + * + * Creates new file if it doesn't exist or overwrites existing file. + * + * @param string $path File path to save the content to + * @param string $content Content to save in file + * + * @return bool + * + * @since 1.0.0 */ public static function set(string $path, string $content) : bool { @@ -120,7 +143,16 @@ final class File extends FileAbstract implements FileInterface } /** - * {@inheritdoc} + * Save content to file. + * + * Creates new file if it doesn't exist or appends existing file. + * + * @param string $path File path to save the content to + * @param string $content Content to save in file + * + * @return bool + * + * @since 1.0.0 */ public static function append(string $path, string $content) : bool { @@ -128,7 +160,16 @@ final class File extends FileAbstract implements FileInterface } /** - * {@inheritdoc} + * Save content to file. + * + * Creates new file if it doesn't exist or prepends existing file. + * + * @param string $path File path to save the content to + * @param string $content Content to save in file + * + * @return bool + * + * @since 1.0.0 */ public static function prepend(string $path, string $content) : bool { @@ -274,7 +315,7 @@ final class File extends FileAbstract implements FileInterface public static function copy(string $from, string $to, bool $overwrite = false) : bool { if (!\is_file($from)) { - throw new PathException($from); + return false; } if ($overwrite || !\file_exists($to)) { @@ -485,7 +526,13 @@ final class File extends FileAbstract implements FileInterface } /** - * {@inheritdoc} + * Get file extension. + * + * @param string $path File path + * + * @return string + * + * @since 1.0.0 */ public static function extension(string $path) : string { diff --git a/System/File/Local/LocalContainerInterface.php b/System/File/Local/LocalContainerInterface.php new file mode 100644 index 000000000..0ba1c6e07 --- /dev/null +++ b/System/File/Local/LocalContainerInterface.php @@ -0,0 +1,215 @@ + $ignore Files/paths to ignore (no regex) + * + * @return int + * + * @since 1.0.0 + */ + public static function count(string $path, bool $recursive = true, array $ignore = []) : int; + + /** + * Make name/path operating system safe. + * + * @param string $path Path of the resource + * @param string $replace Replace invalid chars with + * @param string $invalid Invalid chars to sanitize + * + * @return string + * + * @since 1.0.0 + */ + public static function sanitize(string $path, string $replace = '', string $invalid = '/[^\w\s\d\.\-_~,;\/\[\]\(\]]/') : string; +} diff --git a/tests/System/File/FileUtilsTest.php b/tests/System/File/FileUtilsTest.php index a75b926cd..2f748a226 100644 --- a/tests/System/File/FileUtilsTest.php +++ b/tests/System/File/FileUtilsTest.php @@ -36,4 +36,9 @@ class FileUtilsTest extends \PHPUnit\Framework\TestCase { self::assertEquals('/test/ative', FileUtils::absolute('/test/path/for/../rel/../../ative')); } + + public function testPermissionToOctal() : void + { + self::assertEquals(0742, FileUtils::permissionToOctal('rwxr---w-')); + } } diff --git a/tests/System/File/Ftp/DirectoryTest.php b/tests/System/File/Ftp/DirectoryTest.php index 48003cf0b..4ab8f1eab 100644 --- a/tests/System/File/Ftp/DirectoryTest.php +++ b/tests/System/File/Ftp/DirectoryTest.php @@ -15,25 +15,32 @@ namespace phpOMS\tests\System\File\Ftp; use phpOMS\System\File\Ftp\Directory; use phpOMS\System\File\PathException; +use phpOMS\Uri\Http; class DirectoryTest extends \PHPUnit\Framework\TestCase { - const TEST = false; - const BASE = 'ftp://user:password@localhost'; + const BASE = 'ftp://test:123456@127.0.0.1:20'; + + private $con = null; + + protected function setUp() : void + { + if ($this->con === null) { + $this->con = Directory::ftpConnect(new Http(self::BASE)); + } + } public function testStatic() : void { - if (!self::TEST) { - return; - } + self::assertNotFalse($this->con); - $dirPath = self::BASE . '/test'; - self::assertTrue(Directory::create($dirPath)); - self::assertTrue(Directory::exists($dirPath)); - self::assertFalse(Directory::create($dirPath)); - self::assertFalse(Directory::create(self::BASE . '/test/sub/path')); - self::assertTrue(Directory::create(self::BASE . '/test/sub/path', 0755, true)); - self::assertTrue(Directory::exists(self::BASE . '/test/sub/path')); + $dirPath = __DIR__ . '/test'; + self::assertTrue(Directory::create($this->con, $dirPath)); + self::assertTrue(Directory::exists($this->con, $dirPath)); + self::assertFalse(Directory::create($this->con, $dirPath)); + self::assertFalse(Directory::create($this->con, __DIR__ . '/test/sub/path')); + self::assertTrue(Directory::create($this->con, __DIR__ . '/test/sub/path', 0755, true)); + self::assertTrue(Directory::exists($this->con, __DIR__ . '/test/sub/path')); self::assertEquals('test', Directory::name($dirPath)); self::assertEquals('test', Directory::basename($dirPath)); @@ -42,76 +49,55 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase self::assertEquals($dirPath, Directory::dirpath($dirPath)); $now = new \DateTime('now'); - self::assertEquals($now->format('Y-m-d'), Directory::created($dirPath)->format('Y-m-d')); - self::assertEquals($now->format('Y-m-d'), Directory::changed($dirPath)->format('Y-m-d')); + // todo: implement, doesn't work for ftp yet + //self::assertEquals($now->format('Y-m-d'), Directory::created($this->con, $dirPath)->format('Y-m-d')); + //self::assertEquals($now->format('Y-m-d'), Directory::changed($this->con, $dirPath)->format('Y-m-d')); - self::assertTrue(Directory::delete($dirPath)); - self::assertFalse(Directory::exists($dirPath)); + self::assertTrue(Directory::delete($this->con, $dirPath)); + self::assertFalse(Directory::exists($this->con, $dirPath)); - $dirTestPath = self::BASE . '/dirtest'; - self::assertGreaterThan(0, Directory::size($dirTestPath)); - self::assertGreaterThan(Directory::size($dirTestPath, false), Directory::size($dirTestPath)); - self::assertGreaterThan(0, Directory::permission($dirTestPath)); + $dirTestPath = __DIR__ . '/dirtest'; + self::assertGreaterThan(0, Directory::size($this->con, $dirTestPath)); + self::assertGreaterThan(Directory::size($this->con, $dirTestPath, false), Directory::size($this->con, $dirTestPath)); + self::assertGreaterThan(0, Directory::permission($this->con, $dirTestPath)); } public function testStaticMove() : void { - if (!self::TEST) { - return; - } + self::assertNotFalse($this->con); - $dirTestPath = self::BASE . '/dirtest'; + $dirTestPath = __DIR__ . '/dirtest'; + self::assertTrue(Directory::copy($this->con, $dirTestPath, __DIR__ . '/newdirtest')); + self::assertTrue(\file_exists(__DIR__ . '/newdirtest/sub/path/test3.txt')); - self::assertTrue(Directory::copy($dirTestPath, self::BASE . '/newdirtest')); - self::assertTrue(\file_exists(self::BASE . '/newdirtest/sub/path/test3.txt')); + self::assertTrue(Directory::delete($this->con, $dirTestPath)); + self::assertFalse(Directory::exists($this->con, $dirTestPath)); - self::assertTrue(Directory::delete($dirTestPath)); - self::assertFalse(Directory::exists($dirTestPath)); - - self::assertTrue(Directory::move(self::BASE . '/newdirtest', $dirTestPath)); + self::assertTrue(Directory::move($this->con, __DIR__ . '/newdirtest', $dirTestPath)); self::assertTrue(\file_exists($dirTestPath . '/sub/path/test3.txt')); - self::assertEquals(4, Directory::count($dirTestPath)); - self::assertEquals(1, Directory::count($dirTestPath, false)); + self::assertEquals(4, Directory::count($this->con, $dirTestPath)); + self::assertEquals(1, Directory::count($this->con, $dirTestPath, false)); - self::assertEquals(6, \count(Directory::list($dirTestPath))); - self::assertEquals(3, \count(Directory::listByExtension($dirTestPath, 'txt'))); + self::assertEquals(6, \count(Directory::list($this->con, $dirTestPath))); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidListPath() : void { - if (!self::TEST) { - throw new PathException(''); - } - - Directory::list(self::BASE . '/invalid.txt'); + self::assertNotFalse($this->con); + self::assertEquals([], Directory::list($this->con, __DIR__ . '/invalid.txt')); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidCopyPath() : void { - if (!self::TEST) { - throw new PathException(''); - } - - Directory::copy(self::BASE . '/invalid', self::BASE . '/invalid2'); + self::assertNotFalse($this->con); + self::assertFalse(Directory::copy($this->con, __DIR__ . '/invalid', __DIR__ . '/invalid2')); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidMovePath() : void { - if (!self::TEST) { - throw new PathException(''); - } - - Directory::move(self::BASE . '/invalid', self::BASE . '/invalid2'); + self::assertNotFalse($this->con); + self::assertFalse(Directory::move($this->con, __DIR__ . '/invalid', __DIR__ . '/invalid2')); } /** @@ -119,11 +105,9 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase */ public function testInvalidCreatedPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - Directory::created(self::BASE . '/invalid'); + Directory::created($this->con, __DIR__ . '/invalid'); } /** @@ -131,11 +115,9 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase */ public function testInvalidChangedPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - Directory::changed(self::BASE . '/invalid'); + Directory::changed($this->con, __DIR__ . '/invalid'); } /** @@ -143,11 +125,9 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase */ public function testInvalidSizePath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - Directory::size(self::BASE . '/invalid'); + Directory::size($this->con, __DIR__ . '/invalid'); } /** @@ -155,11 +135,9 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase */ public function testInvalidPermissionPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - Directory::permission(self::BASE . '/invalid'); + Directory::permission($this->con, __DIR__ . '/invalid'); } /** @@ -167,10 +145,8 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase */ public function testInvalidOwnerPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - Directory::owner(self::BASE . '/invalid'); + Directory::owner($this->con, __DIR__ . '/invalid'); } } diff --git a/tests/System/File/Ftp/FileTest.php b/tests/System/File/Ftp/FileTest.php index 6fded8bf2..d2b379265 100644 --- a/tests/System/File/Ftp/FileTest.php +++ b/tests/System/File/Ftp/FileTest.php @@ -14,75 +14,82 @@ namespace phpOMS\tests\System\File\Ftp; use phpOMS\System\File\ContentPutMode; +use phpOMS\System\File\Ftp\Directory; use phpOMS\System\File\Ftp\File; use phpOMS\System\File\PathException; +use phpOMS\Uri\Http; class FileTest extends \PHPUnit\Framework\TestCase { - const TEST = false; - const BASE = 'ftp://user:password@localhost'; + const BASE = 'ftp://test:123456@127.0.0.1:20'; + + private $con = null; + + protected function setUp() : void + { + if ($this->con === null) { + $this->con = File::ftpConnect(new Http(self::BASE)); + } + } public function testStatic() : void { - if (!self::TEST) { - return; - } + self::assertNotFalse($this->con); - $testFile = self::BASE . '/test.txt'; - self::assertFalse(File::put($testFile, 'test', ContentPutMode::REPLACE)); - self::assertFalse(File::exists($testFile)); - self::assertTrue(File::put($testFile, 'test', ContentPutMode::CREATE)); - self::assertTrue(File::exists($testFile)); + $testFile = __DIR__ . '/test.txt'; + self::assertFalse(File::put($this->con, $testFile, 'test', ContentPutMode::REPLACE)); + self::assertFalse(File::exists($this->con, $testFile)); + self::assertTrue(File::put($this->con, $testFile, 'test', ContentPutMode::CREATE)); + self::assertTrue(File::exists($this->con, $testFile)); - self::assertFalse(File::put($testFile, 'test', ContentPutMode::CREATE)); - self::assertTrue(File::put($testFile, 'test2', ContentPutMode::REPLACE)); + self::assertFalse(File::put($this->con, $testFile, 'test', ContentPutMode::CREATE)); + self::assertTrue(File::put($this->con, $testFile, 'test2', ContentPutMode::REPLACE)); - self::assertEquals('test2', File::get($testFile)); - self::assertTrue(File::set($testFile, 'test3')); - self::assertTrue(File::append($testFile, 'test4')); - self::assertEquals('test3test4', File::get($testFile)); - self::assertTrue(File::prepend($testFile, 'test5')); - self::assertEquals('test5test3test4', File::get($testFile)); + self::assertEquals('test2', File::get($this->con, $testFile)); + self::assertTrue(File::set($this->con, $testFile, 'test3')); + self::assertTrue(File::append($this->con, $testFile, 'test4')); + self::assertEquals('test3test4', File::get($this->con, $testFile)); + self::assertTrue(File::prepend($this->con, $testFile, 'test5')); + self::assertEquals('test5test3test4', File::get($this->con, $testFile)); - self::assertEquals(\str_replace('\\', '/', \realpath(\dirname($testFile) . '/../')), File::parent($testFile)); + self::assertEquals(\str_replace('\\', '/', \realpath(\dirname($testFile))), File::parent($testFile)); self::assertEquals('txt', File::extension($testFile)); self::assertEquals('test', File::name($testFile)); self::assertEquals('test.txt', File::basename($testFile)); - self::assertEquals(\basename(\realpath(self::BASE)), File::dirname($testFile)); - self::assertEquals(\realpath(self::BASE), File::dirpath($testFile)); + self::assertEquals(\basename(\realpath(__DIR__)), File::dirname($testFile)); + self::assertEquals(\realpath(__DIR__), File::dirpath($testFile)); self::assertEquals(1, File::count($testFile)); $now = new \DateTime('now'); - self::assertEquals($now->format('Y-m-d'), File::created($testFile)->format('Y-m-d')); - self::assertEquals($now->format('Y-m-d'), File::changed($testFile)->format('Y-m-d')); + self::assertEquals($now->format('Y-m-d'), File::created($this->con, $testFile)->format('Y-m-d')); + self::assertEquals($now->format('Y-m-d'), File::changed($this->con, $testFile)->format('Y-m-d')); - self::assertGreaterThan(0, File::size($testFile)); - self::assertGreaterThan(0, File::permission($testFile)); + self::assertGreaterThan(0, File::size($this->con, $testFile)); + self::assertGreaterThan(0, File::permission($this->con, $testFile)); - $newPath = self::BASE . '/sub/path/testing.txt'; - self::assertTrue(File::copy($testFile, $newPath)); - self::assertTrue(File::exists($newPath)); - self::assertFalse(File::copy($testFile, $newPath)); - self::assertTrue(File::copy($testFile, $newPath, true)); - self::assertEquals('test5test3test4', File::get($newPath)); + $newPath = __DIR__ . '/sub/path/testing.txt'; + self::assertTrue(File::copy($this->con, $testFile, $newPath)); + self::assertTrue(File::exists($this->con, $newPath)); + self::assertFalse(File::copy($this->con, $testFile, $newPath)); + self::assertTrue(File::copy($this->con, $testFile, $newPath, true)); + self::assertEquals('test5test3test4', File::get($this->con, $newPath)); - $newPath2 = self::BASE . '/sub/path/testing2.txt'; - self::assertTrue(File::move($testFile, $newPath2)); - self::assertTrue(File::exists($newPath2)); - self::assertFalse(File::exists($testFile)); - self::assertEquals('test5test3test4', File::get($newPath2)); + $newPath2 = __DIR__ . '/sub/path/testing2.txt'; + self::assertTrue(File::move($this->con, $testFile, $newPath2)); + self::assertTrue(File::exists($this->con, $newPath2)); + self::assertFalse(File::exists($this->con, $testFile)); + self::assertEquals('test5test3test4', File::get($this->con, $newPath2)); - self::assertTrue(File::delete($newPath2)); - self::assertFalse(File::exists($newPath2)); - self::assertFalse(File::delete($newPath2)); + self::assertTrue(File::delete($this->con, $newPath2)); + self::assertFalse(File::exists($this->con, $newPath2)); + self::assertFalse(File::delete($this->con, $newPath2)); - \unlink($newPath); - \rmdir(self::BASE . '/sub/path/'); - \rmdir(self::BASE . '/sub/'); + File::delete($this->con, $newPath); + Directory::delete($this->con, __DIR__ . '/sub'); - self::assertTrue(File::create($testFile)); - self::assertFalse(File::create($testFile)); - self::assertEquals('', File::get($testFile)); + self::assertTrue(File::create($this->con, $testFile)); + self::assertFalse(File::create($this->con, $testFile)); + self::assertEquals('', File::get($this->con, $testFile)); \unlink($testFile); } @@ -92,35 +99,21 @@ class FileTest extends \PHPUnit\Framework\TestCase */ public function testInvalidGetPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - File::get(self::BASE . '/invalid.txt'); + File::get($this->con, __DIR__ . '/invalid.txt'); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidCopyPath() : void { - if (!self::TEST) { - throw new PathException(''); - } - - File::copy(self::BASE . '/invalid.txt', self::BASE . '/invalid2.txt'); + self::assertNotFalse($this->con); + self::assertFalse(File::copy($this->con, __DIR__ . '/invalid.txt', __DIR__ . '/invalid2.txt')); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidMovePath() : void { - if (!self::TEST) { - throw new PathException(''); - } - - File::move(self::BASE . '/invalid.txt', self::BASE . '/invalid2.txt'); + self::assertNotFalse($this->con); + self::assertFalse(File::move($this->con, __DIR__ . '/invalid.txt', __DIR__ . '/invalid2.txt')); } /** @@ -128,11 +121,9 @@ class FileTest extends \PHPUnit\Framework\TestCase */ public function testInvalidCreatedPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - File::created(self::BASE . '/invalid.txt'); + File::created($this->con, __DIR__ . '/invalid.txt'); } /** @@ -140,11 +131,9 @@ class FileTest extends \PHPUnit\Framework\TestCase */ public function testInvalidChangedPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - File::changed(self::BASE . '/invalid.txt'); + File::changed($this->con, __DIR__ . '/invalid.txt'); } /** @@ -152,11 +141,9 @@ class FileTest extends \PHPUnit\Framework\TestCase */ public function testInvalidSizePath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - File::size(self::BASE . '/invalid.txt'); + File::size($this->con, __DIR__ . '/invalid.txt'); } /** @@ -164,11 +151,9 @@ class FileTest extends \PHPUnit\Framework\TestCase */ public function testInvalidPermissionPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - File::permission(self::BASE . '/invalid.txt'); + File::permission($this->con, __DIR__ . '/invalid.txt'); } /** @@ -176,10 +161,8 @@ class FileTest extends \PHPUnit\Framework\TestCase */ public function testInvalidOwnerPath() : void { - if (!self::TEST) { - throw new PathException(''); - } + self::assertNotFalse($this->con); - File::owner(self::BASE . '/invalid.txt'); + File::owner($this->con, __DIR__ . '/invalid.txt'); } } diff --git a/tests/System/File/Ftp/FtpStorageTest.php b/tests/System/File/Ftp/FtpStorageTest.php deleted file mode 100644 index b35005114..000000000 --- a/tests/System/File/Ftp/FtpStorageTest.php +++ /dev/null @@ -1,227 +0,0 @@ -format('Y-m-d'), FtpStorage::created($testFile)->format('Y-m-d')); - self::assertEquals($now->format('Y-m-d'), FtpStorage::changed($testFile)->format('Y-m-d')); - - self::assertGreaterThan(0, FtpStorage::size($testFile)); - self::assertGreaterThan(0, FtpStorage::permission($testFile)); - - $newPath = self::BASE . '/sub/path/testing.txt'; - self::assertTrue(FtpStorage::copy($testFile, $newPath)); - self::assertTrue(FtpStorage::exists($newPath)); - self::assertFalse(FtpStorage::copy($testFile, $newPath)); - self::assertTrue(FtpStorage::copy($testFile, $newPath, true)); - self::assertEquals('test5test3test4', FtpStorage::get($newPath)); - - $newPath2 = self::BASE . '/sub/path/testing2.txt'; - self::assertTrue(FtpStorage::move($testFile, $newPath2)); - self::assertTrue(FtpStorage::exists($newPath2)); - self::assertFalse(FtpStorage::exists($testFile)); - self::assertEquals('test5test3test4', FtpStorage::get($newPath2)); - - self::assertTrue(FtpStorage::delete($newPath2)); - self::assertFalse(FtpStorage::exists($newPath2)); - self::assertFalse(FtpStorage::delete($newPath2)); - - \unlink($newPath); - \rmdir(self::BASE . '/sub/path/'); - \rmdir(self::BASE . '/sub/'); - - self::assertTrue(FtpStorage::create($testFile)); - self::assertFalse(FtpStorage::create($testFile)); - self::assertEquals('', FtpStorage::get($testFile)); - - \unlink($testFile); - } - - public function testDirectory() : void - { - if (!self::TEST) { - return; - } - - $dirPath = self::BASE . '/test'; - self::assertTrue(FtpStorage::create($dirPath)); - self::assertTrue(FtpStorage::exists($dirPath)); - self::assertFalse(FtpStorage::create($dirPath)); - self::assertTrue(FtpStorage::create(self::BASE . '/test/sub/path')); - self::assertTrue(FtpStorage::exists(self::BASE . '/test/sub/path')); - - self::assertEquals('test', FtpStorage::name($dirPath)); - self::assertEquals('test', FtpStorage::basename($dirPath)); - self::assertEquals('test', FtpStorage::dirname($dirPath)); - self::assertEquals(\str_replace('\\', '/', \realpath($dirPath . '/../')), FtpStorage::parent($dirPath)); - self::assertEquals($dirPath, FtpStorage::dirpath($dirPath)); - - $now = new \DateTime('now'); - self::assertEquals($now->format('Y-m-d'), FtpStorage::created($dirPath)->format('Y-m-d')); - self::assertEquals($now->format('Y-m-d'), FtpStorage::changed($dirPath)->format('Y-m-d')); - - self::assertTrue(FtpStorage::delete($dirPath)); - self::assertFalse(FtpStorage::exists($dirPath)); - - $dirTestPath = self::BASE . '/dirtest'; - self::assertGreaterThan(0, FtpStorage::size($dirTestPath)); - self::assertGreaterThan(FtpStorage::size($dirTestPath, false), FtpStorage::size($dirTestPath)); - self::assertGreaterThan(0, FtpStorage::permission($dirTestPath)); - } - - public function testDirectoryMove() : void - { - if (!self::TEST) { - return; - } - - $dirTestPath = self::BASE . '/dirtest'; - self::assertTrue(FtpStorage::copy($dirTestPath, self::BASE . '/newdirtest')); - self::assertTrue(\file_exists(self::BASE . '/newdirtest/sub/path/test3.txt')); - - self::assertTrue(FtpStorage::delete($dirTestPath)); - self::assertFalse(FtpStorage::exists($dirTestPath)); - - self::assertTrue(FtpStorage::move(self::BASE . '/newdirtest', $dirTestPath)); - self::assertTrue(\file_exists($dirTestPath . '/sub/path/test3.txt')); - - self::assertEquals(4, FtpStorage::count($dirTestPath)); - self::assertEquals(1, FtpStorage::count($dirTestPath, false)); - - self::assertEquals(6, \count(FtpStorage::list($dirTestPath))); - } - - /** - * @expectedException \phpOMS\System\File\PathException - */ - public function testInvalidPutPath() : void - { - if (!self::TEST) { - throw new PathException(''); - } - - FtpStorage::put(self::BASE, 'Test'); - } - - /** - * @expectedException \phpOMS\System\File\PathException - */ - public function testInvalidGetPath() : void - { - if (!self::TEST) { - throw new PathException(''); - } - - FtpStorage::get(self::BASE); - } - - /** - * @expectedException \phpOMS\System\File\PathException - */ - public function testInvalidListPath() : void - { - if (!self::TEST) { - throw new PathException(''); - } - - FtpStorage::list(self::BASE . '/FtpStorageTest.php'); - } - - /** - * @expectedException \phpOMS\System\File\PathException - */ - public function testInvalidSetPath() : void - { - if (!self::TEST) { - throw new PathException(''); - } - - FtpStorage::set(self::BASE, 'Test'); - } - - /** - * @expectedException \phpOMS\System\File\PathException - */ - public function testInvalidAppendPath() : void - { - if (!self::TEST) { - throw new PathException(''); - } - - FtpStorage::append(self::BASE, 'Test'); - } - - /** - * @expectedException \phpOMS\System\File\PathException - */ - public function testInvalidPrependPath() : void - { - if (!self::TEST) { - throw new PathException(''); - } - - FtpStorage::prepend(self::BASE, 'Test'); - } - - /** - * @expectedException \phpOMS\System\File\PathException - */ - public function testInvalidExtensionPath() : void - { - if (!self::TEST) { - throw new PathException(''); - } - - FtpStorage::extension(self::BASE); - } -} diff --git a/tests/System/File/Ftp/dirtest/sub/path/test3.txt b/tests/System/File/Ftp/dirtest/sub/path/test3.txt new file mode 100644 index 000000000..e440e5c84 --- /dev/null +++ b/tests/System/File/Ftp/dirtest/sub/path/test3.txt @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/tests/System/File/Ftp/dirtest/sub/test2.txt b/tests/System/File/Ftp/dirtest/sub/test2.txt new file mode 100644 index 000000000..d8263ee98 --- /dev/null +++ b/tests/System/File/Ftp/dirtest/sub/test2.txt @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/tests/System/File/Ftp/dirtest/sub/test4.md b/tests/System/File/Ftp/dirtest/sub/test4.md new file mode 100644 index 000000000..e69de29bb diff --git a/tests/System/File/Ftp/dirtest/test.txt b/tests/System/File/Ftp/dirtest/test.txt new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/tests/System/File/Ftp/dirtest/test.txt @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/System/File/Local/DirectoryTest.php b/tests/System/File/Local/DirectoryTest.php index 9ca64d80a..43bc73204 100644 --- a/tests/System/File/Local/DirectoryTest.php +++ b/tests/System/File/Local/DirectoryTest.php @@ -50,7 +50,6 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase public function testStaticMove() : void { $dirTestPath = __DIR__ . '/dirtest'; - self::assertTrue(Directory::copy($dirTestPath, __DIR__ . '/newdirtest')); self::assertTrue(\file_exists(__DIR__ . '/newdirtest/sub/path/test3.txt')); @@ -67,28 +66,19 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase self::assertEquals(3, \count(Directory::listByExtension($dirTestPath, 'txt'))); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidListPath() : void { - Directory::list(__DIR__ . '/invalid.txt'); + self::assertEquals([], Directory::list(__DIR__ . '/invalid.txt')); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidCopyPath() : void { - Directory::copy(__DIR__ . '/invalid', __DIR__ . '/invalid2'); + self::assertFalse(Directory::copy(__DIR__ . '/invalid', __DIR__ . '/invalid2')); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidMovePath() : void { - Directory::move(__DIR__ . '/invalid', __DIR__ . '/invalid2'); + self::assertFalse(Directory::move(__DIR__ . '/invalid', __DIR__ . '/invalid2')); } /** diff --git a/tests/System/File/Local/FileTest.php b/tests/System/File/Local/FileTest.php index b39d928cd..e07da6540 100644 --- a/tests/System/File/Local/FileTest.php +++ b/tests/System/File/Local/FileTest.php @@ -87,20 +87,14 @@ class FileTest extends \PHPUnit\Framework\TestCase File::get(__DIR__ . '/invalid.txt'); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidCopyPath() : void { - File::copy(__DIR__ . '/invalid.txt', __DIR__ . '/invalid2.txt'); + self::assertFalse(File::copy(__DIR__ . '/invalid.txt', __DIR__ . '/invalid2.txt')); } - /** - * @expectedException \phpOMS\System\File\PathException - */ public function testInvalidMovePath() : void { - File::move(__DIR__ . '/invalid.txt', __DIR__ . '/invalid2.txt'); + self::assertFalse(File::move(__DIR__ . '/invalid.txt', __DIR__ . '/invalid2.txt')); } /**