diff --git a/src/PhpseclibV3/SftpAdapter.php b/src/PhpseclibV3/SftpAdapter.php index 96780f7ef..fe9f8bb87 100644 --- a/src/PhpseclibV3/SftpAdapter.php +++ b/src/PhpseclibV3/SftpAdapter.php @@ -327,13 +327,19 @@ public function move(string $source, string $destination, Config $config): void return; } - if ($this->fileExists($destination)) { - $this->delete($destination); + if ($connection->rename($sourceLocation, $destinationLocation)) { + return; } - if ( ! $connection->rename($sourceLocation, $destinationLocation)) { - throw UnableToMoveFile::fromLocationTo($source, $destination); + // Overwrite existing file / dir + if ($connection->is_file($destinationLocation)) { + $this->delete($destination); + if ($connection->rename($sourceLocation, $destinationLocation)) { + return; + } } + + throw UnableToMoveFile::fromLocationTo($source, $destination); } public function copy(string $source, string $destination, Config $config): void diff --git a/src/PhpseclibV3/SftpAdapterTest.php b/src/PhpseclibV3/SftpAdapterTest.php index 92d9a505f..50678aae2 100644 --- a/src/PhpseclibV3/SftpAdapterTest.php +++ b/src/PhpseclibV3/SftpAdapterTest.php @@ -12,6 +12,7 @@ use League\Flysystem\UnableToMoveFile; use League\Flysystem\UnableToReadFile; use League\Flysystem\UnableToWriteFile; +use League\Flysystem\Visibility; use phpseclib3\Net\SFTP; use function class_exists; @@ -230,6 +231,37 @@ public function it_can_proactively_close_a_connection(): void self::assertFalse(static::$connectionProvider->connection->isConnected()); } + /** + * @test + * @fixme Move to FilesystemAdapterTestCase once all adapters pass + */ + public function moving_a_file_and_overwriting(): void + { + $this->runScenario(function() { + $adapter = $this->adapter(); + $adapter->write( + 'source.txt', + 'contents to be moved', + new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC]) + ); + $adapter->write( + 'destination.txt', + 'contents to be overwritten', + new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC]) + ); + $adapter->move('source.txt', 'destination.txt', new Config()); + $this->assertFalse( + $adapter->fileExists('source.txt'), + 'After moving a file should no longer exist in the original location.' + ); + $this->assertTrue( + $adapter->fileExists('destination.txt'), + 'After moving, a file should be present at the new location.' + ); + $this->assertEquals(Visibility::PUBLIC, $adapter->visibility('destination.txt')->visibility()); + $this->assertEquals('contents to be moved', $adapter->read('destination.txt')); + }); + } private static function connectionProvider(): StubSftpConnectionProvider {