Skip to content

Commit

Permalink
Use exceptions for connection root error resolving
Browse files Browse the repository at this point in the history
  • Loading branch information
frankdejonge committed May 3, 2022
1 parent aa7119c commit f3a9e41
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 8 deletions.
9 changes: 9 additions & 0 deletions mocked-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ function ftp_pasv(...$arguments)
return return_mocked_value('ftp_pasv');
}

function ftp_pwd(...$arguments)
{
if ( ! is_mocked('ftp_pwd')) {
return \ftp_pwd(...$arguments);
}

return return_mocked_value('ftp_pwd');
}

function ftp_fput(...$arguments)
{
if ( ! is_mocked('ftp_fput')) {
Expand Down
18 changes: 14 additions & 4 deletions src/Ftp/FtpAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
use League\MimeTypeDetection\MimeTypeDetector;
use Throwable;

use function error_clear_last;
use function error_get_last;
use function ftp_chdir;
use function ftp_pwd;
use function is_string;

class FtpAdapter implements FilesystemAdapter
{
Expand Down Expand Up @@ -644,12 +646,20 @@ public function directoryExists(string $path): bool
private function resolveConnectionRoot($connection): string
{
$root = $this->connectionOptions->root();
error_clear_last();

if ($root !== '') {
ftp_chdir($connection, $root);
if ($root !== '' && @ftp_chdir($connection, $root) !== true) {
throw UnableToResolveConnectionRoot::itDoesNotExist($root, error_get_last()['message'] ?? '');
}

return ftp_pwd($connection);
error_clear_last();
$pwd = @ftp_pwd($connection);

if ( ! is_string($pwd)) {
throw UnableToResolveConnectionRoot::couldNotGetCurrentDirectory(error_get_last()['message'] ?? '');
}

return $pwd;
}

/**
Expand Down
50 changes: 50 additions & 0 deletions src/Ftp/FtpAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

use League\Flysystem\FilesystemAdapter;

use function mock_function;
use function reset_function_mocks;

/**
* @group ftp
*/
Expand Down Expand Up @@ -46,4 +49,51 @@ public function disconnect_after_destruct(): void
static::clearFilesystemAdapterCache();
$this->assertFalse((new NoopCommandConnectivityChecker())->isConnected($connection));
}

/**
* @test
*/
public function not_being_able_to_resolve_connection_root(): void
{
$options = FtpConnectionOptions::fromArray([
'host' => 'localhost',
'port' => 2121,
'timestampsOnUnixListingsEnabled' => true,
'root' => '/invalid/root',
'username' => 'foo',
'password' => 'pass',
]);

$adapter = new FtpAdapter($options);

$this->expectExceptionObject(UnableToResolveConnectionRoot::itDoesNotExist('/invalid/root'));

$adapter->delete('something');
}

/**
* @test
*/
public function not_being_able_to_resolve_connection_root_pwd(): void
{
$options = FtpConnectionOptions::fromArray([
'host' => 'localhost',
'port' => 2121,
'timestampsOnUnixListingsEnabled' => true,
'root' => '/home/foo/upload/',
'username' => 'foo',
'password' => 'pass',
]);

$this->expectExceptionObject(UnableToResolveConnectionRoot::couldNotGetCurrentDirectory());
mock_function('ftp_pwd', false);

$adapter = new FtpAdapter($options);
$adapter->delete('something');
}

protected function tearDown(): void
{
reset_function_mocks();
}
}
6 changes: 3 additions & 3 deletions src/Ftp/FtpConnectionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private function enableUtf8Mode(FtpConnectionOptions $options, $connection): voi
return;
}

$response = ftp_raw($connection, "OPTS UTF8 ON");
$response = @ftp_raw($connection, "OPTS UTF8 ON");

if ( ! in_array(substr($response[0], 0, 3), ['200', '202'])) {
throw new UnableToEnableUtf8Mode(
Expand All @@ -88,7 +88,7 @@ private function ignorePassiveAddress(FtpConnectionOptions $options, $connection
return;
}

if ( ! ftp_set_option($connection, FTP_USEPASVADDRESS, ! $ignorePassiveAddress)) {
if ( ! @ftp_set_option($connection, FTP_USEPASVADDRESS, ! $ignorePassiveAddress)) {
throw UnableToSetFtpOption::whileSettingOption('FTP_USEPASVADDRESS');
}
}
Expand All @@ -98,7 +98,7 @@ private function ignorePassiveAddress(FtpConnectionOptions $options, $connection
*/
private function makeConnectionPassive(FtpConnectionOptions $options, $connection): void
{
if ( ! ftp_pasv($connection, $options->passive())) {
if ( ! @ftp_pasv($connection, $options->passive())) {
throw new UnableToMakeConnectionPassive(
'Could not set passive mode for connection: ' . $options->host() . '::' . $options->port()
);
Expand Down
4 changes: 3 additions & 1 deletion src/Ftp/FtpConnectionProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use League\Flysystem\AdapterTestUtilities\RetryOnTestException;
use PHPUnit\Framework\TestCase;

use function ftp_close;

/**
* @group ftp
*/
Expand Down Expand Up @@ -54,7 +56,7 @@ public function connecting_successfully(): void
'root' => '/home/foo/upload',
'username' => 'foo',
'password' => 'pass',
]);
]);

$this->runScenario(function () use ($options) {
$connection = $this->connectionProvider->createConnection($options);
Expand Down
30 changes: 30 additions & 0 deletions src/Ftp/UnableToResolveConnectionRoot.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace League\Flysystem\Ftp;

use RuntimeException;
use Throwable;

final class UnableToResolveConnectionRoot extends RuntimeException implements FtpConnectionException
{
private function __construct(string $message, Throwable $previous = null)
{
parent::__construct($message, 0, $previous);
}

public static function itDoesNotExist(string $root): UnableToResolveConnectionRoot
{
return new UnableToResolveConnectionRoot(
'Unable to resolve connection root. It does not seem to exist: ' . $root
);
}

public static function couldNotGetCurrentDirectory(string $message = ''): UnableToResolveConnectionRoot
{
return new UnableToResolveConnectionRoot(
'Unable to resolve connection root. Could not resolve the current directory. ' . $message
);
}
}

0 comments on commit f3a9e41

Please sign in to comment.