Skip to content

Commit ae01c5d

Browse files
committed
✨ Adds a FTP client
1 parent 17bf74d commit ae01c5d

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ test/coverage
1010
.DS_Store
1111
.nova/*
1212
.php-cs-fixer.cache
13+
docker/

component/Port/Ftp.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phant\Client\Port;
6+
7+
interface Ftp
8+
{
9+
public function listFiles(string $path): array;
10+
11+
/**
12+
* @param string $remotePath The path of the file on the FTP server
13+
* @param string|null $localDirectory The local directory to save the downloaded file. If null, a default temp directory will be used.
14+
* @return string Local file path of the downloaded file
15+
*
16+
* @throws \RuntimeException
17+
*/
18+
public function download(string $remotePath, ?string $localDirectory = null): string;
19+
20+
public function delete(string $remotePath): bool;
21+
}

component/Service/Ftp.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
namespace Phant\Client\Service;
4+
5+
use FTP\Connection;
6+
7+
class Ftp implements \Phant\Client\Port\Ftp
8+
{
9+
private Connection $connection;
10+
11+
public function __construct(
12+
string $host,
13+
string $username,
14+
string $password,
15+
int $port = 21
16+
) {
17+
$this->connection = $this->connect(
18+
host: $host,
19+
username: $username,
20+
password: $password,
21+
port: $port
22+
);
23+
}
24+
25+
private function connect(string $host, string $username, string $password, int $port): Connection
26+
{
27+
$ftp = ftp_connect($host, $port);
28+
if (!$ftp) {
29+
throw new \RuntimeException("Failed to connect to FTP server: {$host}");
30+
}
31+
32+
$login = ftp_login($ftp, $username, $password);
33+
if (!$login) {
34+
throw new \RuntimeException("Failed to log in to FTP server: {$host}");
35+
}
36+
37+
return $ftp;
38+
}
39+
40+
public function listFiles(string $path): array
41+
{
42+
$files = ftp_nlist($this->connection, $path);
43+
if (false === $files) {
44+
return [];
45+
}
46+
47+
return $files;
48+
}
49+
50+
public function download(string $remotePath, ?string $localDirectory = null): string
51+
{
52+
if ($localDirectory) {
53+
$localFilePath = rtrim($localDirectory, '/') . '/' . basename($remotePath);
54+
} else {
55+
$localFilePath = sys_get_temp_dir() . '/' . basename($remotePath);
56+
}
57+
58+
if (!ftp_get($this->connection, $localFilePath, $remotePath, FTP_BINARY)) {
59+
throw new \RuntimeException("Failed to download file from FTP: {$remotePath}");
60+
}
61+
62+
return $localFilePath;
63+
}
64+
65+
public function delete(string $path): bool
66+
{
67+
if (!ftp_delete($this->connection, $path)) {
68+
throw new \RuntimeException("Failed to delete file from FTP: {$path}");
69+
}
70+
71+
return true;
72+
}
73+
74+
public function __destruct()
75+
{
76+
ftp_close($this->connection);
77+
}
78+
}

component/Service/MySQL.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ protected function getPdo(
120120
if ($this->pdo) {
121121
return $this->pdo;
122122
}
123-
123+
124124
$this->pdo = new PDO(
125125
'mysql:host=' . $this->host . ';dbname=' . $this->dbname . ';port=' . $this->port . ';charset=' . $this->charset,
126126
$this->user,

0 commit comments

Comments
 (0)