PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.9.5
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.9.5
4.9.5 4.9.4 4.9.3 4.9.2 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 weeks ago FileList 6 days ago Restore 3 months ago Backup.php 2 years ago BackupDownloader.php 1 month ago BackupSizeCalculator.php 1 month ago BackupSpeedIndex.php 10 months ago BaseFileList.php 1 year ago BaseListing.php 10 months ago Delete.php 6 days ago Edit.php 6 days ago Explore.php 4 months ago ExploreCache.php 4 months ago FileInfo.php 6 days ago FileList.php 1 year ago Listing.php 8 months ago Parts.php 6 days ago Restore.php 2 years ago ScheduleList.php 1 year ago Upload.php 2 months ago
Delete.php
153 lines
1 <?php
2
3 namespace WPStaging\Backup\Ajax;
4
5 use Exception;
6 use SplFileInfo;
7 use WPStaging\Backup\Entity\BackupMetadata;
8 use WPStaging\Backup\Exceptions\BackupRuntimeException;
9 use WPStaging\Backup\Service\BackupsFinder;
10 use WPStaging\Backup\Utils\BackupPathResolver;
11 use WPStaging\Framework\Component\AbstractTemplateComponent;
12 use WPStaging\Framework\Filesystem\FileObject;
13 use WPStaging\Framework\TemplateEngine\TemplateEngine;
14 use WPStaging\Framework\Utils\Cache\TransientCache;
15
16 use function WPStaging\functions\debug_log;
17
18 class Delete extends AbstractTemplateComponent
19 {
20 /** @var BackupsFinder */
21 private $backupsFinder;
22
23 /** @var BackupPathResolver */
24 private $backupPathResolver;
25
26 public function __construct(BackupsFinder $backupsFinder, BackupPathResolver $backupPathResolver, TemplateEngine $templateEngine)
27 {
28 parent::__construct($templateEngine);
29 $this->backupsFinder = $backupsFinder;
30 $this->backupPathResolver = $backupPathResolver;
31 }
32
33 public function render()
34 {
35 if (!$this->canRenderAjax()) {
36 return;
37 }
38
39 $md5 = isset($_POST['md5']) ? sanitize_text_field($_POST['md5']) : '';
40
41 if (strlen($md5) !== 32) {
42 wp_send_json([
43 'error' => true,
44 'message' => __('Invalid request.', 'wp-staging'),
45 ]);
46 }
47
48 $backups = $this->backupsFinder->findBackups();
49
50 // Early bail: No backups found, nothing to delete
51 if (empty($backups)) {
52 wp_send_json([
53 'error' => true,
54 'message' => __('No backups found, nothing to delete.', 'wp-staging'),
55 ]);
56 }
57
58 foreach ($backups as $backup) {
59 if ($md5 === md5($backup->getBasename())) {
60 $this->deleteBackup($backup);
61 }
62 }
63 }
64
65 /**
66 * @param SplFileInfo $backup
67 * @throws BackupRuntimeException
68 */
69 protected function deleteBackup($backup)
70 {
71 if (!$this->deleteSplitBackupParts($backup)) {
72 return;
73 }
74
75 $deleted = unlink($backup->getRealPath());
76
77 if ($deleted) {
78 delete_transient(TransientCache::KEY_INVALID_BACKUP_FILE_INDEX);
79 wp_send_json([
80 'error' => false,
81 'message' => __('Successfully deleted the backup.', 'wp-staging'),
82 ]);
83 } else {
84 debug_log('WP STAGING: User tried to delete backup but "unlink" returned false. Backup that couldn\'t be deleted: ' . $backup->getRealPath());
85
86 wp_send_json([
87 'error' => true,
88 'message' => __('Could not delete the backup. Maybe a permission issue?', 'wp-staging'),
89 ]);
90 }
91 }
92
93 /**
94 * @param SplFileInfo $backup
95 * @return bool
96 * @throws BackupRuntimeException
97 */
98 protected function deleteSplitBackupParts($backup)
99 {
100 clearstatcache();
101
102 try {
103 $file = new FileObject($backup->getRealPath(), FileObject::MODE_APPEND_AND_READ);
104 $backupMetadata = new BackupMetadata();
105 $backupMetadata = $backupMetadata->hydrateByFile($file);
106 } catch (Exception $e) {
107 // Couldn't read backup metadata, continue deleting the main file but log error
108 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());
109
110 return true;
111 }
112
113 // Early bail: Not a split backup
114 if (!$backupMetadata->getIsMultipartBackup()) {
115 return true;
116 }
117
118 $errors = [];
119
120 foreach ($backupMetadata->getMultipartMetadata()->getBackupParts() as $part) {
121 $backupPart = $this->backupPathResolver->resolveBackupPartPath($part, $backup->getFilename());
122 if ($backupPart === '') {
123 debug_log('WP STAGING: Refused to delete a backup part that does not belong to this backup: ' . $part);
124 continue;
125 }
126
127 if (!file_exists($backupPart)) {
128 continue;
129 }
130
131 $deleted = unlink($backupPart);
132 if (!$deleted) {
133 $error = "Couldn't delete backup part. Maybe Permission Issue? Part: " . $backupPart;
134 debug_log('WP STAGING: ' . $error);
135
136 $errors[] = $error;
137 }
138 }
139
140 if (count($errors) === 0) {
141 return false;
142 }
143
144 wp_send_json([
145 'error' => true,
146 'message' => '',
147 'messages' => $errors,
148 ]);
149
150 return false;
151 }
152 }
153