PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.3.1
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.3.1
4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Backup / Ajax / Delete.php
wp-staging / Backup / Ajax Last commit date
Backup 2 years ago FileList 2 years ago Restore 3 years ago Backup.php 2 years ago BackupSpeedIndex.php 2 years ago Cancel.php 3 years ago Delete.php 3 years ago Edit.php 3 years ago FileInfo.php 3 years ago FileList.php 3 years ago Listing.php 2 years ago Parts.php 3 years ago PrepareJob.php 2 years ago Restore.php 2 years ago ScheduleList.php 2 years ago Status.php 3 years ago Upload.php 2 years ago
Delete.php
152 lines
1 <?php
2
3 // TODO PHP7.x; declare(strict_type=1);
4 // TODO PHP7.x; type hints & return types
5
6 namespace WPStaging\Backup\Ajax;
7
8 use Exception;
9 use WPStaging\Framework\Component\AbstractTemplateComponent;
10 use WPStaging\Framework\TemplateEngine\TemplateEngine;
11 use WPStaging\Backup\Exceptions\BackupRuntimeException;
12 use WPStaging\Backup\Service\BackupsFinder;
13 use SplFileInfo;
14 use WPStaging\Core\WPStaging;
15 use WPStaging\Framework\Filesystem\FileObject;
16 use WPStaging\Backup\Entity\BackupMetadata;
17 use WPStaging\Framework\Utils\Cache\TransientCache;
18
19 use function WPStaging\functions\debug_log;
20
21 class Delete extends AbstractTemplateComponent
22 {
23 private $backupsFinder;
24
25 public function __construct(BackupsFinder $backupsFinder, TemplateEngine $templateEngine)
26 {
27 parent::__construct($templateEngine);
28 $this->backupsFinder = $backupsFinder;
29 }
30
31 /**
32 * @throws BackupRuntimeException
33 */
34 public function render()
35 {
36 if (!$this->canRenderAjax()) {
37 return;
38 }
39
40 $md5 = isset($_POST['md5']) ? sanitize_text_field($_POST['md5']) : '';
41
42 if (strlen($md5) !== 32) {
43 wp_send_json([
44 'error' => true,
45 'message' => __('Invalid request.', 'wp-staging'),
46 ]);
47 }
48
49 $backups = $this->backupsFinder->findBackups();
50
51 // Early bail: No backups found, nothing to delete
52 if (empty($backups)) {
53 wp_send_json([
54 'error' => true,
55 'message' => __('No backups found, nothing to delete.', 'wp-staging'),
56 ]);
57 }
58
59 foreach ($backups as $backup) {
60 if ($md5 === md5($backup->getBasename())) {
61 $this->deleteBackup($backup);
62 }
63 }
64 }
65
66 /**
67 * @param SplFileInfo $backup
68 * @throws BackupRuntimeException
69 */
70 protected function deleteBackup($backup)
71 {
72 if (!$this->deleteSplitBackupParts($backup)) {
73 return;
74 }
75
76 $deleted = unlink($backup->getRealPath());
77
78 if ($deleted) {
79 delete_transient(TransientCache::KEY_INVALID_BACKUP_FILE_INDEX);
80 wp_send_json([
81 'error' => false,
82 'message' => __('Successfully deleted the backup.', 'wp-staging'),
83 ]);
84 } else {
85 debug_log('WP STAGING: User tried to delete backup but "unlink" returned false. Backup that couldn\'t be deleted: ' . $backup->getRealPath());
86
87 wp_send_json([
88 'error' => true,
89 'message' => __('Could not delete the backup. Maybe a permission issue?', 'wp-staging'),
90 ]);
91 }
92 }
93
94 /**
95 * @param SplFileInfo $backup
96 *
97 * @return bool
98 * @throws BackupRuntimeException
99 */
100 protected function deleteSplitBackupParts($backup)
101 {
102 clearstatcache();
103
104 try {
105 $file = new FileObject($backup->getRealPath(), FileObject::MODE_APPEND_AND_READ);
106 $backupMetadata = new BackupMetadata();
107 $backupMetadata->hydrate($file->readBackupMetadata());
108 } catch (Exception $e) {
109 // Couldn't read backup metadata, continue deleting the main file but log error
110 debug_log('WP STAGING: User tried to delete backup but "unlink" returned false on deleting backup parts. Backup that couldn\'t be deleted: ' . $backup->getRealPath());
111
112 return true;
113 }
114
115 // Early bail: Not a split backup
116 if (!$backupMetadata->getIsMultipartBackup()) {
117 return true;
118 }
119
120 $errors = [];
121
122 $backupsDirectory = WPStaging::make(BackupsFinder::class)->getBackupsDirectory();
123
124 foreach ($backupMetadata->getMultipartMetadata()->getBackupParts() as $part) {
125 $backupPart = $backupsDirectory . $part;
126 if (!file_exists($backupPart)) {
127 continue;
128 }
129
130 $deleted = unlink($backupPart);
131 if (!$deleted) {
132 $error = "Couldn't delete backup part. Maybe Permission Issue? Part: " . $backupPart;
133 debug_log('WP STAGING: ' . $error);
134
135 $errors[] = $error;
136 }
137 }
138
139 if (count($errors) === 0) {
140 return false;
141 }
142
143 wp_send_json([
144 'error' => true,
145 'message' => '',
146 'messages' => $errors
147 ]);
148
149 return false;
150 }
151 }
152