From 037e7538e8415cb4d0461d3c687d492279e2b648 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Mon, 16 Mar 2026 02:09:30 -0700 Subject: [PATCH 1/5] fix: manually set modified time to SFTP files after editing Signed-off-by: Hendrik Leidinger --- apps/files_external/lib/Lib/Storage/SFTP.php | 15 ++++++++++++++- .../lib/Lib/Storage/SFTPWriteStream.php | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php index 6504ea610f345..91d3e77c8101f 100644 --- a/apps/files_external/lib/Lib/Storage/SFTP.php +++ b/apps/files_external/lib/Lib/Storage/SFTP.php @@ -333,7 +333,10 @@ public function fopen(string $path, string $mode) { $fh = fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context); if ($fh) { $fh = CallbackWrapper::wrap($fh, null, null, function () use ($path): void { - $this->knownMTimes->set($path, time()); + $mtime = time(); + $this->knownMTimes->set($path, $mtime); + $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); + $this->getConnection()->clearStatCache(); }); } return $fh; @@ -429,6 +432,11 @@ public function constructUrl(string $path): string { public function file_put_contents(string $path, mixed $data): int|float|false { /** @psalm-suppress InternalMethod */ $result = $this->getConnection()->put($this->absPath($path), $data); + $mtime = time(); + $this->knownMTimes->set($path, $mtime); + $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); + $this->getConnection()->clearStatCache(); + if ($result) { return strlen($data); } else { @@ -448,6 +456,11 @@ public function writeStream(string $path, $stream, ?int $size = null): int { /** @psalm-suppress InternalMethod */ $result = $this->getConnection()->put($this->absPath($path), $stream); fclose($stream); + $mtime = time(); + $this->knownMTimes->set($path, $mtime); + $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); + $this->getConnection()->clearStatCache(); + if ($result) { if ($size === null) { throw new \Exception('Failed to get written size from sftp storage wrapper'); diff --git a/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php b/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php index d64e89b546217..c6713de193e85 100644 --- a/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php +++ b/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php @@ -32,6 +32,8 @@ class SFTPWriteStream implements File { private $buffer = ''; + private string $path; + public static function register($protocol = 'sftpwrite') { if (in_array($protocol, stream_get_wrappers(), true)) { return false; @@ -71,6 +73,8 @@ public function stream_open($path, $mode, $options, &$opened_path) { } $remote_file = $this->sftp->_realpath($path); + + $this->path = $remote_file; if ($remote_file === false) { return false; } @@ -160,6 +164,8 @@ public function stream_close() { if (!$this->sftp->_close_handle($this->handle)) { return false; } + $this->sftp->touch($this->path, time(), time()); + return true; } } From 0037b118c5f75e4512a239e0049ce1474c6e25b7 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Thu, 26 Mar 2026 09:49:09 -0700 Subject: [PATCH 2/5] fix: modified touch function of the SFTP storage to update mtimes instead Signed-off-by: Hendrik Leidinger --- apps/files_external/lib/Lib/Storage/SFTP.php | 34 ++++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php index 91d3e77c8101f..62a4a5174eeb0 100644 --- a/apps/files_external/lib/Lib/Storage/SFTP.php +++ b/apps/files_external/lib/Lib/Storage/SFTP.php @@ -333,10 +333,7 @@ public function fopen(string $path, string $mode) { $fh = fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context); if ($fh) { $fh = CallbackWrapper::wrap($fh, null, null, function () use ($path): void { - $mtime = time(); - $this->knownMTimes->set($path, $mtime); - $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); - $this->getConnection()->clearStatCache(); + $this->touch($path, time()); }); } return $fh; @@ -360,18 +357,17 @@ public function fopen(string $path, string $mode) { } public function touch(string $path, ?int $mtime = null): bool { - try { + + $result = $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); + + if ($result) { + $this->getConnection()->clearStatCache($this->absPath($path)); if (!is_null($mtime)) { - return false; - } - if (!$this->file_exists($path)) { - return $this->getConnection()->put($this->absPath($path), ''); - } else { - return false; + $this->knownMTimes->set($path, $mtime); } - } catch (\Exception $e) { - return false; } + + return $result; } /** @@ -432,10 +428,8 @@ public function constructUrl(string $path): string { public function file_put_contents(string $path, mixed $data): int|float|false { /** @psalm-suppress InternalMethod */ $result = $this->getConnection()->put($this->absPath($path), $data); - $mtime = time(); - $this->knownMTimes->set($path, $mtime); - $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); - $this->getConnection()->clearStatCache(); + + $this->touch($path, time()); if ($result) { return strlen($data); @@ -456,10 +450,8 @@ public function writeStream(string $path, $stream, ?int $size = null): int { /** @psalm-suppress InternalMethod */ $result = $this->getConnection()->put($this->absPath($path), $stream); fclose($stream); - $mtime = time(); - $this->knownMTimes->set($path, $mtime); - $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); - $this->getConnection()->clearStatCache(); + + $this->touch($path, time()); if ($result) { if ($size === null) { From c60bcfb6d7be63946a47545544af81424bb5cc70 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Thu, 26 Mar 2026 10:18:49 -0700 Subject: [PATCH 3/5] fix: make psalm and rector happy Signed-off-by: Hendrik Leidinger --- apps/files_external/lib/Lib/Storage/SFTP.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php index 62a4a5174eeb0..4ac6b28b9fc94 100644 --- a/apps/files_external/lib/Lib/Storage/SFTP.php +++ b/apps/files_external/lib/Lib/Storage/SFTP.php @@ -357,11 +357,11 @@ public function fopen(string $path, string $mode) { } public function touch(string $path, ?int $mtime = null): bool { - + $result = $this->getConnection()->touch($this->absPath($path), $mtime, $mtime); if ($result) { - $this->getConnection()->clearStatCache($this->absPath($path)); + $this->getConnection()->clearStatCache(); if (!is_null($mtime)) { $this->knownMTimes->set($path, $mtime); } From 158ea675086d8e7fa92efccb12900beef71ce9ef Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Tue, 21 Apr 2026 13:55:43 -0700 Subject: [PATCH 4/5] chore: update psalm baseline Signed-off-by: Hendrik Leidinger --- build/psalm-baseline.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index b92298da7d122..e85662b47ec17 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -1454,11 +1454,6 @@ ]]> - - - - - getCode()]]> @@ -3165,7 +3160,6 @@ - From 660759ea405157dadb6a8f47eee8f03dd59cf0e6 Mon Sep 17 00:00:00 2001 From: Hendrik Leidinger Date: Tue, 5 May 2026 10:55:57 -0700 Subject: [PATCH 5/5] fix: weird bug introduced by psalm Signed-off-by: Hendrik Leidinger --- build/psalm-baseline.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index e85662b47ec17..24b8f823832f0 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -3160,6 +3160,7 @@ +