aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_external/lib/Lib/Storage/FTP.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_external/lib/Lib/Storage/FTP.php')
-rw-r--r--apps/files_external/lib/Lib/Storage/FTP.php125
1 files changed, 56 insertions, 69 deletions
diff --git a/apps/files_external/lib/Lib/Storage/FTP.php b/apps/files_external/lib/Lib/Storage/FTP.php
index 284f438fccd..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':
@@ -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($source, $target) {
+ 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'])) {