diff options
Diffstat (limited to 'apps/files_external/lib/Lib/Storage/FTP.php')
-rw-r--r-- | apps/files_external/lib/Lib/Storage/FTP.php | 131 |
1 files changed, 59 insertions, 72 deletions
diff --git a/apps/files_external/lib/Lib/Storage/FTP.php b/apps/files_external/lib/Lib/Storage/FTP.php index d424ffe3cdd..944964de7a6 100644 --- a/apps/files_external/lib/Lib/Storage/FTP.php +++ b/apps/files_external/lib/Lib/Storage/FTP.php @@ -1,23 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2021 Robin Appelman <robin@icewind.nl> - * - * @author Robin Appelman <robin@icewind.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Storage; @@ -28,7 +13,11 @@ use OC\Files\Storage\Common; use OC\Files\Storage\PolyFill\CopyDirectory; use OCP\Constants; use OCP\Files\FileInfo; +use OCP\Files\IMimeTypeDetector; use OCP\Files\StorageNotAvailableException; +use OCP\ITempManager; +use OCP\Server; +use Psr\Log\LoggerInterface; class FTP extends Common { use CopyDirectory; @@ -44,23 +33,23 @@ class FTP extends Common { /** @var FtpConnection|null */ private $connection; - public function __construct($params) { - if (isset($params['host']) && isset($params['user']) && isset($params['password'])) { - $this->host = $params['host']; - $this->username = $params['user']; - $this->password = $params['password']; - if (isset($params['secure'])) { - if (is_string($params['secure'])) { - $this->secure = ($params['secure'] === 'true'); + public function __construct(array $parameters) { + if (isset($parameters['host']) && isset($parameters['user']) && isset($parameters['password'])) { + $this->host = $parameters['host']; + $this->username = $parameters['user']; + $this->password = $parameters['password']; + if (isset($parameters['secure'])) { + if (is_string($parameters['secure'])) { + $this->secure = ($parameters['secure'] === 'true'); } else { - $this->secure = (bool)$params['secure']; + $this->secure = (bool)$parameters['secure']; } } else { $this->secure = false; } - $this->root = isset($params['root']) ? '/' . ltrim($params['root']) : '/'; - $this->port = $params['port'] ?? 21; - $this->utf8Mode = isset($params['utf8']) && $params['utf8']; + $this->root = isset($parameters['root']) ? '/' . ltrim($parameters['root']) : '/'; + $this->port = $parameters['port'] ?? 21; + $this->utf8Mode = isset($parameters['utf8']) && $parameters['utf8']; } else { throw new \Exception('Creating ' . self::class . ' storage failed, required parameters not set'); } @@ -81,11 +70,11 @@ class FTP extends Common { $this->password ); } catch (\Exception $e) { - throw new StorageNotAvailableException("Failed to create ftp connection", 0, $e); + throw new StorageNotAvailableException('Failed to create ftp connection', 0, $e); } if ($this->utf8Mode) { if (!$this->connection->setUtf8Mode()) { - throw new StorageNotAvailableException("Could not set UTF-8 mode"); + throw new StorageNotAvailableException('Could not set UTF-8 mode'); } } } @@ -93,15 +82,15 @@ class FTP extends Common { return $this->connection; } - public function getId() { + public function getId(): string { return 'ftp::' . $this->username . '@' . $this->host . '/' . $this->root; } - protected function buildPath($path) { + protected function buildPath(string $path): string { return rtrim($this->root . '/' . $path, '/'); } - public static function checkDependencies() { + public static function checkDependencies(): array|bool { if (function_exists('ftp_login')) { return true; } else { @@ -109,27 +98,28 @@ class FTP extends Common { } } - public function filemtime($path) { + public function filemtime(string $path): int|false { $result = $this->getConnection()->mdtm($this->buildPath($path)); if ($result === -1) { if ($this->is_dir($path)) { $list = $this->getConnection()->mlsd($this->buildPath($path)); if (!$list) { - \OC::$server->getLogger()->warning("Unable to get last modified date for ftp folder ($path), failed to list folder contents"); + Server::get(LoggerInterface::class)->warning("Unable to get last modified date for ftp folder ($path), failed to list folder contents"); return time(); } $currentDir = current(array_filter($list, function ($item) { return $item['type'] === 'cdir'; })); if ($currentDir) { - $time = \DateTime::createFromFormat('YmdHis', $currentDir['modify']); + [$modify] = explode('.', $currentDir['modify'] ?? '', 2); + $time = \DateTime::createFromFormat('YmdHis', $modify); if ($time === false) { throw new \Exception("Invalid date format for directory: $currentDir"); } return $time->getTimestamp(); } else { - \OC::$server->getLogger()->warning("Unable to get last modified date for ftp folder ($path), folder contents doesn't include current folder"); + Server::get(LoggerInterface::class)->warning("Unable to get last modified date for ftp folder ($path), folder contents doesn't include current folder"); return time(); } } else { @@ -140,7 +130,7 @@ class FTP extends Common { } } - public function filesize($path) { + public function filesize(string $path): false|int|float { $result = $this->getConnection()->size($this->buildPath($path)); if ($result === -1) { return false; @@ -149,7 +139,7 @@ class FTP extends Common { } } - public function rmdir($path) { + public function rmdir(string $path): bool { if ($this->is_dir($path)) { $result = $this->getConnection()->rmdir($this->buildPath($path)); // recursive rmdir support depends on the ftp server @@ -165,11 +155,7 @@ class FTP extends Common { } } - /** - * @param string $path - * @return bool - */ - private function recursiveRmDir($path): bool { + private function recursiveRmDir(string $path): bool { $contents = $this->getDirectoryContent($path); $result = true; foreach ($contents as $content) { @@ -184,7 +170,7 @@ class FTP extends Common { return $result; } - public function test() { + public function test(): bool { try { return $this->getConnection()->systype() !== false; } catch (\Exception $e) { @@ -192,7 +178,7 @@ class FTP extends Common { } } - public function stat($path) { + public function stat(string $path): array|false { if (!$this->file_exists($path)) { return false; } @@ -202,14 +188,14 @@ class FTP extends Common { ]; } - public function file_exists($path) { + public function file_exists(string $path): bool { if ($path === '' || $path === '.' || $path === '/') { return true; } return $this->filetype($path) !== false; } - public function unlink($path) { + public function unlink(string $path): bool { switch ($this->filetype($path)) { case 'dir': return $this->rmdir($path); @@ -220,20 +206,20 @@ class FTP extends Common { } } - public function opendir($path) { + public function opendir(string $path) { $files = $this->getConnection()->nlist($this->buildPath($path)); return IteratorDirectory::wrap($files); } - public function mkdir($path) { + public function mkdir(string $path): bool { if ($this->is_dir($path)) { return false; } return $this->getConnection()->mkdir($this->buildPath($path)) !== false; } - public function is_dir($path) { - if ($path === "") { + public function is_dir(string $path): bool { + if ($path === '') { return true; } if ($this->getConnection()->chdir($this->buildPath($path)) === true) { @@ -244,11 +230,11 @@ class FTP extends Common { } } - public function is_file($path) { + public function is_file(string $path): bool { return $this->filesize($path) !== false; } - public function filetype($path) { + public function filetype(string $path): string|false { if ($this->is_dir($path)) { return 'dir'; } elseif ($this->is_file($path)) { @@ -258,7 +244,7 @@ class FTP extends Common { } } - public function fopen($path, $mode) { + public function fopen(string $path, string $mode) { $useExisting = true; switch ($mode) { case 'r': @@ -269,7 +255,7 @@ class FTP extends Common { case 'wb': case 'wb+': $useExisting = false; - // no break + // no break case 'a': case 'ab': case 'r+': @@ -288,10 +274,10 @@ class FTP extends Common { if (!$this->isCreatable(dirname($path))) { return false; } - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); + $tmpFile = Server::get(ITempManager::class)->getTemporaryFile(); } $source = fopen($tmpFile, $mode); - return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $path) { + return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $path): void { $this->writeStream($path, fopen($tmpFile, 'r')); unlink($tmpFile); }); @@ -299,9 +285,9 @@ class FTP extends Common { return false; } - public function writeStream(string $path, $stream, int $size = null): int { + public function writeStream(string $path, $stream, ?int $size = null): int { if ($size === null) { - $stream = CountWrapper::wrap($stream, function ($writtenSize) use (&$size) { + $stream = CountWrapper::wrap($stream, function ($writtenSize) use (&$size): void { $size = $writtenSize; }); } @@ -324,7 +310,7 @@ class FTP extends Common { return $stream; } - public function touch($path, $mtime = null) { + public function touch(string $path, ?int $mtime = null): bool { if ($this->file_exists($path)) { return false; } else { @@ -333,14 +319,14 @@ class FTP extends Common { } } - public function rename($path1, $path2) { - $this->unlink($path2); - return $this->getConnection()->rename($this->buildPath($path1), $this->buildPath($path2)); + public function rename(string $source, string $target): bool { + $this->unlink($target); + return $this->getConnection()->rename($this->buildPath($source), $this->buildPath($target)); } - public function getDirectoryContent($directory): \Traversable { + public function getDirectoryContent(string $directory): \Traversable { $files = $this->getConnection()->mlsd($this->buildPath($directory)); - $mimeTypeDetector = \OC::$server->getMimeTypeDetector(); + $mimeTypeDetector = Server::get(IMimeTypeDetector::class); foreach ($files as $file) { $name = $file['name']; @@ -355,10 +341,11 @@ class FTP extends Common { $data = []; $data['mimetype'] = $isDir ? FileInfo::MIMETYPE_FOLDER : $mimeTypeDetector->detectPath($name); - $data['mtime'] = \DateTime::createFromFormat('YmdGis', $file['modify'])->getTimestamp(); - if ($data['mtime'] === false) { - $data['mtime'] = time(); - } + + // strip fractional seconds + [$modify] = explode('.', $file['modify'], 2); + $mtime = \DateTime::createFromFormat('YmdGis', $modify); + $data['mtime'] = $mtime === false ? time() : $mtime->getTimestamp(); if ($isDir) { $data['size'] = -1; //unknown } elseif (isset($file['size'])) { |