1
|
|
|
<?php |
2
|
|
|
namespace phpbu\App\Backup\Collector; |
3
|
|
|
|
4
|
|
|
use phpbu\App\Backup\Collector; |
5
|
|
|
use phpbu\App\Backup\File; |
6
|
|
|
use phpbu\App\Backup\Path; |
7
|
|
|
use phpbu\App\Backup\Target; |
8
|
|
|
use phpbu\App\Util; |
9
|
|
|
use SebastianFeldmann\Ftp\Client; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Ftp class. |
13
|
|
|
* |
14
|
|
|
* @package phpbu |
15
|
|
|
* @subpackage Backup |
16
|
|
|
* @author Sebastian Feldmann <[email protected]> |
17
|
|
|
* @author Vitaly Baev <[email protected]> |
18
|
|
|
* @copyright Sebastian Feldmann <[email protected]> |
19
|
|
|
* @license https://opensource.org/licenses/MIT The MIT License (MIT) |
20
|
|
|
* @link http://phpbu.de/ |
21
|
|
|
* @since Class available since Release 5.1.0 |
22
|
|
|
*/ |
23
|
|
|
class Ftp extends Remote implements Collector |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* FTP connection stream |
27
|
|
|
* |
28
|
|
|
* @var \SebastianFeldmann\Ftp\Client |
29
|
|
|
*/ |
30
|
|
|
private $ftpClient; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Ftp constructor. |
34
|
|
|
* |
35
|
|
|
* @param \phpbu\App\Backup\Target $target |
36
|
|
|
* @param \phpbu\App\Backup\Path $remotePath |
37
|
|
|
* @param \SebastianFeldmann\Ftp\Client $ftpClient |
38
|
|
|
*/ |
39
|
|
|
public function __construct(Target $target, Path $remotePath, Client $ftpClient) |
40
|
|
|
{ |
41
|
|
|
$this->setUp($target, $remotePath); |
42
|
|
|
$this->ftpClient = $ftpClient; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Collect all created backups. |
47
|
|
|
* |
48
|
|
|
* @throws \Exception |
49
|
|
|
*/ |
50
|
|
|
protected function collectBackups() |
51
|
|
|
{ |
52
|
|
|
$this->ftpClient->chHome(); |
53
|
|
|
|
54
|
|
|
$initialDepth = $this->path->getPathThatIsNotChangingDepth(); |
55
|
|
|
$initialPath = $this->path->getPathThatIsNotChanging(); |
56
|
|
|
|
57
|
|
|
$this->collect($initialPath, $initialDepth); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Collect all synced backup files regarding to the remote path configuration. |
62
|
|
|
* |
63
|
|
|
* @param string $remotePath |
64
|
|
|
* @param int $depth |
65
|
|
|
* @throws \Exception |
66
|
|
|
*/ |
67
|
|
|
private function collect(string $remotePath, int $depth) |
68
|
|
|
{ |
69
|
|
|
if ($depth < $this->path->getPathDepth()) { |
70
|
|
|
$this->collectDirectories($remotePath, $depth); |
71
|
|
|
return; |
72
|
|
|
} |
73
|
|
|
$this->collectFiles($remotePath); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* If path not fully satisfied look for matching directories. |
78
|
|
|
* |
79
|
|
|
* @param string $remotePath |
80
|
|
|
* @param int $depth |
81
|
|
|
* @return void |
82
|
|
|
* @throws \Exception |
83
|
|
|
*/ |
84
|
|
|
private function collectDirectories(string $remotePath, int $depth) |
85
|
|
|
{ |
86
|
|
|
/** @var \SebastianFeldmann\Ftp\File $ftpDir */ |
87
|
|
|
foreach ($this->ftpClient->lsDirs($remotePath) as $ftpDir) { |
88
|
|
|
$element = $this->path->getPathElementAtIndex($depth); |
89
|
|
|
$expected = '#' . Util\Path::datePlaceholdersToRegex($element) . '#i'; |
90
|
|
|
if (\preg_match($expected, $ftpDir->getFilename())) { |
91
|
|
|
// look for files in a "deeper" directory |
92
|
|
|
$this->collect($remotePath . '/' . $ftpDir->getFilename(), $depth + 1); |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Collect all matching files in a given remote directory. |
99
|
|
|
* |
100
|
|
|
* @param string $remotePath |
101
|
|
|
* @return void |
102
|
|
|
* @throws \Exception |
103
|
|
|
*/ |
104
|
|
|
private function collectFiles(string $remotePath) |
105
|
|
|
{ |
106
|
|
|
foreach ($this->ftpClient->lsFiles($remotePath) as $ftpFile) { |
107
|
|
View Code Duplication |
if ($this->isFilenameMatch($ftpFile->getFilename())) { |
108
|
|
|
$file = new File\Ftp($this->ftpClient, $ftpFile, $remotePath); |
109
|
|
|
$index = $this->getFileIndex($file); |
110
|
|
|
$this->files[$index] = $file; |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|