PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 2.1.4
Backup Migration v2.1.4
2.1.6 2.1.5.2 trunk 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.7 1.4.8 1.4.9 1.4.9.1 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.5.1
backup-backup / includes / external / controller.php
backup-backup / includes / external Last commit date
backupbliss.php 2 months ago controller.php 2 months ago dropbox.php 2 months ago ftp.php 2 months ago google-drive.php 2 months ago s3.php 2 months ago
controller.php
432 lines
1 <?php
2
3 // Namespace
4 namespace BMI\Plugin\External;
5
6 // Use
7 use BMI\Plugin\BMI_Logger as Logger;
8 use BMI\Plugin\External\BMI_External_BackupBliss as BackupBliss;
9 use BMI\Plugin\Dashboard as Dashboard;
10 use BMI\Plugin\External\BMI_External_Storage_Premium as ExternalStoragePremium;
11 use BMI\Plugin\External\BMI_External_Dropbox as Dropbox;
12 use BMI\Plugin\External\BMI_External_GDrive as GDrive;
13 use BMI\Plugin\External\BMI_External_FTP as FTP;
14 use BMI\Plugin\External\BMI_External_S3 as S3;
15
16 // Exit on direct access
17 if (!defined('ABSPATH')) {
18 exit;
19 }
20
21 /**
22 * BMI_External_Storage
23 */
24 class BMI_External_Storage {
25
26 public $backupbliss;
27 public $dropbox;
28 public $gdrive;
29 public $ftp;
30 public $aws;
31 public $wasabi;
32
33 public function __construct() {
34
35 require_once BMI_INCLUDES . '/external/backupbliss.php';
36 $this->backupbliss = new BackupBliss();
37
38 require_once BMI_INCLUDES . '/external/dropbox.php';
39 $this->dropbox = new Dropbox();
40
41 require_once BMI_INCLUDES . '/external/google-drive.php';
42 $this->gdrive = new GDrive();
43
44 require_once BMI_INCLUDES . '/external/ftp.php';
45 $this->ftp = new FTP();
46
47 //S3 Includes
48 require_once BMI_INCLUDES . '/external/s3.php';
49 $this->aws = new S3('aws');
50 $this->wasabi = new S3('wasabi');
51 }
52
53 public function getExternalBackups() {
54
55 $backups = [];
56
57 // Google Drive
58 $backups['backupbliss'] = $this->getBackupBlissBackupsParsedForList();
59
60 // Dropbox
61 $backups['dropbox'] = $this->getDropboxBackupsParsedForList();
62
63 // Google Drive
64 $backups['gdrive'] = $this->getGoogleDriveBackupsParsedForList();
65
66 //FTP
67 $backups['FTP'] = $this->getFTPBackupsParsedForList();
68
69 // AWS S3
70 $backups['aws'] = $this->getAWSBackupsParsedForList();
71
72 // Wasabi
73 $backups['wasabi'] = $this->getWasabiBackupsParsedForList();
74
75 if (defined('BMI_BACKUP_PRO') && defined('BMI_PRO_INC')) {
76 $proPath = BMI_PRO_INC . 'external/controller.php';
77 if (file_exists($proPath)) {
78 require_once $proPath;
79
80 $externalStorage = new ExternalStoragePremium();
81 $external = $externalStorage->getExternalBackups();
82 $backups = array_merge($backups, $external);
83 }
84 }
85
86
87 //Here we check and remove if there are any failed tasks but backups are successfully uploaded.
88
89 $toBeUploaded = get_option('bmip_to_be_uploaded', [
90 'current_upload' => [],
91 'queue' => [],
92 'failed' => []
93 ]);
94
95 if (isset($toBeUploaded['failed'])) {
96 foreach($backups as $cloudName => $cloudBackups) {
97 $cloudName = strtolower($cloudName);
98 foreach($cloudBackups as $md5 => $backupDetails) {
99 if (isset($toBeUploaded['failed'][$cloudName . "_" . $md5]))
100 unset($toBeUploaded['failed'][$cloudName . "_" . $md5]);
101 }
102 }
103
104 //Remove failed tasks if any of the cloud storages are disabled or empty
105 $failed = $toBeUploaded['failed'];
106 foreach($failed as $failed_task => $failed_count) {
107 $data = explode("_", $failed_task);
108
109
110 if (count($data) == 2) {
111 $cloudtype = $data[0];
112 $cloudtype = isset($backups[$cloudtype]) ? $cloudtype : strtoupper($cloudtype);
113 if (isset($backups[$cloudtype]) && count($backups[$cloudtype]) == 0) {
114 unset($toBeUploaded["failed"][$failed_task]); //Removes the failed task as there's no backups found or disabled.
115 }
116 }
117 }
118
119 update_option('bmip_to_be_uploaded', $toBeUploaded);
120 }
121
122
123 return $backups;
124
125 }
126
127
128 public function getAWSBackupsParsedForList()
129 {
130 $isEnabled = Dashboard\bmi_get_config('STORAGE::EXTERNAL::AWS');
131 if (!($isEnabled === true || $isEnabled === 'true')) {
132 return [];
133 }
134
135 $parsedBackups = [];
136 $parsedAWSFiles = $this->aws->getParsedFiles();
137 $backupsFileName = isset($parsedAWSFiles['zipFilesName']) ? $parsedAWSFiles['zipFilesName'] : [];
138 $manifestFilesPath = isset($parsedAWSFiles['jsonFilesPath']) ? $parsedAWSFiles['jsonFilesPath'] : [];
139
140 foreach ($manifestFilesPath as $manifestPath) {
141 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath))) {
142 $manifest = file_get_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath));
143 $manifest = json_decode($manifest, true);
144 } else {
145 $manifest = $this->aws->getFileContent($manifestPath);
146 if (!$manifest) continue;
147 file_put_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath), $manifest);
148 $manifest = json_decode($manifest, true);
149 }
150 $md5 = pathinfo($manifestPath, PATHINFO_FILENAME);
151 $backupName = $manifest['name'];
152 if (!in_array($backupName, array_keys($backupsFileName))) continue; // Skip if the backup is not found
153 $parsedBackups[$md5] = [];
154 $parsedBackups[$md5][] = $manifest['name'];
155 $parsedBackups[$md5][] = $manifest['date'];
156 $parsedBackups[$md5][] = $manifest['files'];
157 $parsedBackups[$md5][] = $manifest['manifest'];
158 $parsedBackups[$md5][] = $backupsFileName[$backupName]['size'];
159 $parsedBackups[$md5][] = $manifest['is_locked'];
160 $parsedBackups[$md5][] = $manifest['cron'];
161 $parsedBackups[$md5][] = $md5;
162 $parsedBackups[$md5][] = $backupsFileName[$backupName]['id'];
163 $parsedBackups[$md5][] = sanitize_text_field(isset($manifest['domain']) ? $manifest['domain'] : '');
164 }
165 return $parsedBackups;
166 }
167
168 public function getWasabiBackupsParsedForList()
169 {
170 $isEnabled = Dashboard\bmi_get_config('STORAGE::EXTERNAL::WASABI');
171 if (!($isEnabled === true || $isEnabled === 'true')) {
172 return [];
173 }
174
175 $parsedBackups = [];
176 $parsedWasabiFiles = $this->wasabi->getParsedFiles();
177 $backupsFileName = isset($parsedWasabiFiles['zipFilesName']) ? $parsedWasabiFiles['zipFilesName'] : [];
178 $manifestFilesPath = isset($parsedWasabiFiles['jsonFilesPath']) ? $parsedWasabiFiles['jsonFilesPath'] : [];
179
180 foreach ($manifestFilesPath as $manifestPath) {
181 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath))) {
182 $manifest = file_get_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath));
183 $manifest = json_decode($manifest, true);
184 } else {
185 $manifest = $this->wasabi->getFileContent($manifestPath);
186 if (!$manifest) continue;
187 file_put_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath), $manifest);
188 $manifest = json_decode($manifest, true);
189 }
190 $md5 = pathinfo($manifestPath, PATHINFO_FILENAME);
191 $backupName = $manifest['name'];
192 if (!in_array($backupName, array_keys($backupsFileName))) continue; // Skip if the backup is not found
193 $parsedBackups[$md5] = [];
194 $parsedBackups[$md5][] = $manifest['name'];
195 $parsedBackups[$md5][] = $manifest['date'];
196 $parsedBackups[$md5][] = $manifest['files'];
197 $parsedBackups[$md5][] = $manifest['manifest'];
198 $parsedBackups[$md5][] = $backupsFileName[$backupName]['size'];
199 $parsedBackups[$md5][] = $manifest['is_locked'];
200 $parsedBackups[$md5][] = $manifest['cron'];
201 $parsedBackups[$md5][] = $md5;
202 $parsedBackups[$md5][] = $backupsFileName[$backupName]['id'];
203 $parsedBackups[$md5][] = sanitize_text_field(isset($manifest['domain']) ? $manifest['domain'] : '');
204 }
205 return $parsedBackups;
206 }
207
208 private function getGoogleDriveBackupsParsedForList() {
209
210 $isEnabled = Dashboard\bmi_get_config('STORAGE::EXTERNAL::GDRIVE');
211 if (!($isEnabled === true || $isEnabled === 'true')) {
212 return [];
213 }
214
215 $backups = [];
216 $googleDriveBackups = $this->gdrive->getGoogleDriveBackups();
217 if ($googleDriveBackups && is_object($googleDriveBackups['data']) && isset($googleDriveBackups['data']->files)) {
218 $backups = $this->gdrive->parseGoogleDriveFiles($googleDriveBackups['data']->files);
219 } else $backups = [];
220
221 $parsedBackups = [];
222 foreach ($backups as $key => $value) {
223 if (in_array(pathinfo($key, PATHINFO_EXTENSION), ['zip', 'tar', 'gz'])) {
224
225 $md5 = $value['md5'];
226 $size = $value['size'];
227 $backupFileId = $value['id'];
228 if (isset($backups['file_' . $md5 . '.json'])) {
229
230 $localManifest = BMI_BACKUPS . DIRECTORY_SEPARATOR. $md5 . '.json';
231 if (file_exists($localManifest)) {
232
233 $manifest = file_get_contents($localManifest);
234 $manifest = json_decode($manifest);
235
236 } else {
237
238 $manifestFileId = $backups['file_' . $md5 . '.json']['id'];
239 $manifest = $this->gdrive->getGoogleDriveFileContents($manifestFileId);
240 if (isset($manifest['status']) && isset($manifest['data']) && $manifest['status'] == 'success') {
241
242 $manifest = $manifest['data'];
243 file_put_contents($localManifest, json_encode($manifest));
244
245 } else continue;
246
247 }
248
249 $parsedBackups[$md5] = [];
250 $parsedBackups[$md5][] = $manifest->name;
251 $parsedBackups[$md5][] = $manifest->date;
252 $parsedBackups[$md5][] = $manifest->files;
253 $parsedBackups[$md5][] = $manifest->manifest;
254 $parsedBackups[$md5][] = $size;
255 $parsedBackups[$md5][] = $manifest->is_locked;
256 $parsedBackups[$md5][] = $manifest->cron;
257 $parsedBackups[$md5][] = $md5;
258 $parsedBackups[$md5][] = $backupFileId;
259 $parsedBackups[$md5][] = sanitize_text_field($manifest->domain);
260 }
261 }
262 }
263
264 return $parsedBackups;
265 }
266
267 private function getFTPBackupsParsedForList()
268 {
269 $isEnabled = Dashboard\bmi_get_config('STORAGE::EXTERNAL::FTP');
270 if (!($isEnabled === true || $isEnabled === 'true')) {
271 return [];
272 }
273
274 $backups = [];
275 $FtpBackups = $this->ftp->getFtpBackups();
276 if ($FtpBackups && isset($FtpBackups['data'])) {
277 $backups = $this->ftp->parseFtpFiles($FtpBackups['data']);
278 } else $backups = [];
279 $backupsFiles = isset($backups['zipFiles']) ? $backups['zipFiles'] : [];
280 $manifestFiles = isset($backups['jsonFiles']) ? $backups['jsonFiles'] : [];
281 $parsedBackups = [];
282
283 foreach ($manifestFiles as $manifestFile) {
284 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestFile['name']))) {
285 $manifest = file_get_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . $manifestFile['name']);
286 $manifest = json_decode($manifest, true);
287 } else {
288 $manifest = $this->ftp->getFtpFileContents($manifestFile['name']);
289 if ($manifest['status'] !== 'success' || $manifest['data'] === '') continue;
290 $manifest = $manifest['data'];
291
292 file_put_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . $manifestFile['name'], $manifest);
293 $manifest = json_decode($manifest, true);
294 }
295 $md5 = pathinfo($manifestFile['name'], PATHINFO_FILENAME);
296
297 $backupName = $manifest['name'];
298 if (!in_array($backupName, array_column($backupsFiles, 'name'))) continue; // Skip if the backup is not found
299 $backupFile = array_values(array_filter($backupsFiles, function ($file) use ($backupName) {
300 return $file['name'] === $backupName;
301 }))[0];
302 $parsedBackups[$md5] = [];
303 $parsedBackups[$md5][] = $manifest['name'];
304 $parsedBackups[$md5][] = $manifest['date'];
305 $parsedBackups[$md5][] = $manifest['files'];
306 $parsedBackups[$md5][] = $manifest['manifest'];
307 $parsedBackups[$md5][] = $backupFile['size'];
308 $parsedBackups[$md5][] = $manifest['is_locked'];
309 $parsedBackups[$md5][] = $manifest['cron'];
310 $parsedBackups[$md5][] = $md5;
311 $parsedBackups[$md5][] = $backupFile['name'];
312 $parsedBackups[$md5][] = sanitize_text_field(isset($manifest['domain']) ? $manifest['domain'] : '');
313 }
314
315 return $parsedBackups;
316 }
317
318 /**
319 * Get Dropbox backups list
320 *
321 * @return array[] An array of backups, where each backup is an array of details keyed by MD5 hash
322 * Each backup array contains the following elements:
323 * [
324 * 0 => string Backup name
325 * 1 => string Backup date
326 * 2 => int Number of files in backup
327 * 3 => string Date of the backup
328 * 4 => int Backup size in bytes
329 * 5 => string Backup lock status ("unlocked" or "locked")
330 * 6 => bool Whether the backup was created by cron
331 * 7 => string Backup MD5 hash
332 * 8 => string Backup file ID in Dropbox
333 * 9 => string Backup domain used for tooltip in backups list
334 * ]
335 */
336 public function getDropboxBackupsParsedForList()
337 {
338 $isEnabled = Dashboard\bmi_get_config('STORAGE::EXTERNAL::DROPBOX');
339 if (!($isEnabled === true || $isEnabled === 'true') || $this->dropbox->verifyConnection()['result'] != 'connected') {
340 return [];
341 }
342
343 $parsedBackups = [];
344 $parsedDropboxFiles = $this->dropbox->getParsedFiles();
345 $backupsFileName = isset($parsedDropboxFiles['zipFilesName']) ? $parsedDropboxFiles['zipFilesName'] : [];
346 $manifestFilesPath = isset($parsedDropboxFiles['jsonFilesPath']) ? $parsedDropboxFiles['jsonFilesPath'] : [];
347
348 foreach ($manifestFilesPath as $manifestPath) {
349 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath))) {
350 $manifest = file_get_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath));
351 $manifest = json_decode($manifest, true);
352 } else {
353 $manifest = $this->dropbox->getFileContent($manifestPath);
354 if (!$manifest || $manifest == 'error') continue;
355 file_put_contents(BMI_BACKUPS . DIRECTORY_SEPARATOR . basename($manifestPath), $manifest);
356 $manifest = json_decode($manifest, true);
357 }
358 $md5 = pathinfo($manifestPath, PATHINFO_FILENAME);
359 $backupName = $manifest['name'];
360 if (!in_array($backupName, array_keys($backupsFileName))) continue; // Skip if the backup is not found
361 $parsedBackups[$md5] = [];
362 $parsedBackups[$md5][] = $manifest['name'];
363 $parsedBackups[$md5][] = $manifest['date'];
364 $parsedBackups[$md5][] = $manifest['files'];
365 $parsedBackups[$md5][] = $manifest['manifest'];
366 $parsedBackups[$md5][] = $backupsFileName[$backupName]['size'];
367 $parsedBackups[$md5][] = $manifest['is_locked'];
368 $parsedBackups[$md5][] = $manifest['cron'];
369 $parsedBackups[$md5][] = $md5;
370 $parsedBackups[$md5][] = $backupsFileName[$backupName]['id'];
371 $parsedBackups[$md5][] = sanitize_text_field(isset($manifest['domain']) ? $manifest['domain'] : '');
372 }
373 return $parsedBackups;
374 }
375
376 private function getBackupBlissBackupsParsedForList() {
377
378
379 $files = $this->backupbliss->parseFiles($this->backupbliss->getAllFiles());
380
381 $parsedBackups = [];
382
383
384 if ($files) {
385 foreach ($files['manifests'] as $manifestFileName => $filedetail) {
386
387 $localManifest = BMI_BACKUPS . DIRECTORY_SEPARATOR. $manifestFileName;
388
389 if (file_exists($localManifest)) {
390
391 $manifestData = file_get_contents($localManifest);
392 $manifest = json_decode($manifestData);
393
394 } else {
395
396 $manifestData = $this->backupbliss->getFile($manifestFileName);
397 if (is_array($manifestData) && $manifestData["file_data"]) {
398
399 file_put_contents($localManifest, $manifestData["file_data"]);
400 $manifest = json_decode($manifestData["file_data"]);
401
402 } else continue;
403
404 }
405
406 if (!isset($manifest))
407 continue;
408
409 $md5 = pathinfo($manifestFileName, PATHINFO_FILENAME);
410 $backupFileName = $manifest->name;
411
412 if (!isset($files["backups"][$backupFileName]))
413 continue;
414
415 $parsedBackups[$md5] = [];
416 $parsedBackups[$md5][] = $backupFileName;
417 $parsedBackups[$md5][] = $manifest->date;
418 $parsedBackups[$md5][] = $manifest->files;
419 $parsedBackups[$md5][] = $manifest->manifest;
420 $parsedBackups[$md5][] = $files["backups"][$backupFileName]["size"];
421 $parsedBackups[$md5][] = $manifest->is_locked;
422 $parsedBackups[$md5][] = $manifest->cron;
423 $parsedBackups[$md5][] = $md5;
424 $parsedBackups[$md5][] = $backupFileName;
425 $parsedBackups[$md5][] = sanitize_text_field($manifest->domain);
426 }
427 }
428
429 return $parsedBackups;
430 }
431 }
432