PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.13.4
JetBackup – Backup, Restore & Migrate v3.1.13.4
3.1.22.4 3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / Ajax / Calls / AddToQueue.php
backup / src / JetBackup / Ajax / Calls Last commit date
.htaccess 9 months ago AbortQueueItem.php 9 months ago AddToQueue.php 9 months ago ClearAlerts.php 9 months ago ClearCompletedQueueItems.php 9 months ago CreateSupportUser.php 9 months ago DeleteBackupJob.php 9 months ago DeleteDestination.php 9 months ago DeleteDownload.php 9 months ago DeleteSchedule.php 9 months ago DeleteSnapshot.php 9 months ago DestinationSetExportConfig.php 9 months ago DuplicateBackupJob.php 9 months ago EditBackupNotes.php 9 months ago EnableBackupJob.php 9 months ago EnableDestination.php 9 months ago ExecuteCron.php 9 months ago FileManager.php 9 months ago GetBackup.php 9 months ago GetBackupJob.php 9 months ago GetDashboard.php 9 months ago GetDatabaseTables.php 9 months ago GetDestination.php 9 months ago GetLog.php 9 months ago GetQRCode.php 9 months ago GetQueueItem.php 9 months ago GetSchedule.php 9 months ago GetSettingsAutomation.php 9 months ago GetSettingsGeneral.php 9 months ago GetSettingsIntegrations.php 9 months ago GetSettingsLogging.php 9 months ago GetSettingsMaintenance.php 9 months ago GetSettingsNotifications.php 9 months ago GetSettingsPerformance.php 9 months ago GetSettingsRestore.php 9 months ago GetSettingsSecurity.php 9 months ago GetSettingsUpdates.php 9 months ago GetSystemInfo.php 9 months ago ListAlerts.php 9 months ago ListBackupJobs.php 9 months ago ListBackups.php 9 months ago ListDatabaseTables.php 9 months ago ListDestinations.php 9 months ago ListDownloads.php 9 months ago ListQueueItems.php 9 months ago ListSchedules.php 9 months ago LockSnapshot.php 9 months ago ManageBackupJob.php 9 months ago ManageDestination.php 9 months ago ManageSchedule.php 9 months ago ManageSettingsAutomation.php 9 months ago ManageSettingsGeneral.php 9 months ago ManageSettingsIntegrations.php 9 months ago ManageSettingsLogging.php 9 months ago ManageSettingsMaintenance.php 9 months ago ManageSettingsNotifications.php 9 months ago ManageSettingsPerformance.php 9 months ago ManageSettingsRestore.php 9 months ago ManageSettingsSecurity.php 9 months ago ManageSettingsUpdates.php 9 months ago ManageShowcase.php 9 months ago PanelPreload.php 9 months ago SendTestEmail.php 9 months ago StartOverQueueItem.php 9 months ago ValidateDestination.php 9 months ago ValidateMFA.php 9 months ago index.html 9 months ago web.config 9 months ago
AddToQueue.php
382 lines
1 <?php
2
3 namespace JetBackup\Ajax\Calls;
4
5 if (!defined( '__JETBACKUP__' )) die('Direct access is not allowed');
6
7 use JetBackup\Ajax\aAjax;
8 use JetBackup\Archive\Archive;
9 use JetBackup\BackupJob\BackupJob;
10 use JetBackup\Data\Engine;
11 use JetBackup\Destination\Destination;
12 use JetBackup\Download\Download;
13 use JetBackup\Entities\Util;
14 use JetBackup\Exception\AjaxException;
15 use JetBackup\Exception\DBException;
16 use JetBackup\Exception\DestinationException;
17 use JetBackup\Exception\JetBackupLinuxException;
18 use JetBackup\Exception\QueueException;
19 use JetBackup\Export\Vendor\Vendor;
20 use JetBackup\Factory;
21 use JetBackup\JetBackup;
22 use JetBackup\JetBackupLinux\JetBackupLinux;
23 use JetBackup\Queue\Queue;
24 use JetBackup\Queue\QueueItem;
25 use JetBackup\Queue\QueueItemRestore;
26 use JetBackup\Snapshot\Snapshot;
27 use JetBackup\Upload\Upload;
28 use JetBackup\UserInput\UserInput;
29 use JetBackup\Wordpress\Helper;
30 use JetBackup\Wordpress\Wordpress;
31 use SleekDB\Exceptions\InvalidArgumentException;
32 use SleekDB\Exceptions\IOException;
33
34 class AddToQueue extends aAjax {
35
36 /**
37 * @return int
38 * @throws AjaxException
39 */
40 private function _getId():int { return $this->getUserInput(JetBackup::ID_FIELD, 0, UserInput::UINT); }
41
42 /**
43 * @return string
44 * @throws AjaxException
45 */
46 private function _snapshotPath():string { return $this->getUserInput('snapshot_path', '', UserInput::STRING); }
47
48 /**
49 * @return int
50 * @throws AjaxException
51 */
52 private function _getType():int { return $this->getUserInput(QueueItem::TYPE, 0, UserInput::UINT); }
53
54 /**
55 * @return int
56 * @throws AjaxException
57 */
58 private function _getPanelType():int { return $this->getUserInput(Vendor::PANEL_TYPE, 0, UserInput::UINT); }
59
60 /**
61 * @return string
62 * @throws AjaxException
63 */
64 private function _getFileName():string { return $this->getUserInput('fileName', '', UserInput::STRING); }
65
66 /**
67 * @return int
68 * @throws AjaxException
69 */
70 private function _getFileSize():int { return $this->getUserInput('fileSize', 0, UserInput::UINT); }
71
72 /**
73 * @return string
74 * @throws AjaxException
75 */
76 private function _getFileUploadId():string { return $this->getUserInput('fileUploadId', '', UserInput::STRING); }
77
78 /**
79 * @return bool
80 * @throws AjaxException
81 */
82 private function _getMixedSites():bool { return $this->getUserInput('mixedSites', false, UserInput::BOOL); }
83
84 /**
85 * @throws AjaxException
86 */
87 private function _getFileManagerList():array { return $this->getUserInput('fileManager', [], UserInput::ARRAY, UserInput::ARRAY);}
88
89 /**
90 * @throws AjaxException
91 */
92 private function _getRestoreOptions(): int { return $this->getUserInput('restoreOptions', 0, UserInput::UINT); }
93
94 /**
95 * Returns an array of homedir paths, these can be used for either include (restore only X), or exclude (restore all but Y)
96 * @return array
97 * @throws AjaxException
98 */
99 private function _getHomedirFolders():array { return $this->getUserInput('folderList', [], UserInput::ARRAY, UserInput::STRING);}
100
101 /**
102 * Returns an array of database tables, these can be used for either include (restore only X), or exclude (restore all but Y)
103 * @return array
104 * @throws AjaxException
105 */
106 private function _getDatabaseTables():array { return $this->getUserInput('selectedTables', [], UserInput::ARRAY, UserInput::STRING);}
107
108
109
110 /**
111 * @return void
112 * @throws AjaxException
113 * @throws DBException
114 * @throws DestinationException
115 * @throws IOException
116 * @throws InvalidArgumentException
117 * @throws \JetBackup\Exception\IOException
118 */
119 public function execute(): void {
120
121 try {
122 switch ($this->_getType()) {
123 case Queue::QUEUE_TYPE_BACKUP: $this->_queueBackup(); break;
124 case Queue::QUEUE_TYPE_RESTORE: $this->_queueRestore(); break;
125 case Queue::QUEUE_TYPE_DOWNLOAD: $this->_queueDownload(); break;
126 case Queue::QUEUE_TYPE_DOWNLOAD_BACKUP_LOG: $this->_queueDownloadBackupLog(); break;
127 case Queue::QUEUE_TYPE_REINDEX: $this->_queueReindex(); break;
128 case Queue::QUEUE_TYPE_EXPORT: $this->_queueExport(); break;
129 case Queue::QUEUE_TYPE_EXTRACT: $this->_queueExtract(); break;
130
131
132 // Both of those should be automatic and shouldn't be triggered by the user
133 //case Queue::QUEUE_TYPE_RETENTION_CLEANUP: break;
134 //case Queue::QUEUE_TYPE_SYSTEM: break;
135
136 default: throw new AjaxException("Invalid queue type specified: %s", [$this->_getType()]);
137 }
138 } catch(QueueException $e) {
139 throw new AjaxException("Failed adding to queue. Error: %s", [$e->getMessage()]);
140 }
141
142 }
143
144 /**
145 * Checks if the listed destinations are valid, could be useful for manual delete from DB, but still listed in the job
146 *
147 * @throws DBException
148 * @throws InvalidArgumentException
149 * @throws IOException
150 * @throws AjaxException
151 */
152 private static function _validateDestinations(?array $destinations): void {
153 if (empty($destinations)) throw new AjaxException("No valid destinations provided.");
154 $validDestinations = array_filter($destinations, function ($destination_id) {return (new Destination($destination_id))->getId();});
155 if (empty($validDestinations)) throw new AjaxException("No valid destination found.");
156 }
157
158 /**
159 * @return void
160 * @throws AjaxException
161 * @throws QueueException
162 * @throws IOException
163 * @throws InvalidArgumentException|DBException
164 */
165 private function _queueBackup():void {
166 if (!$this->_getId()) throw new AjaxException("No backup job id was provided");
167 $job = new BackupJob($this->_getId());
168 self::_validateDestinations($job->getDestinations());
169 if (!$job->getId()) throw new AjaxException("Invalid backup job id provided");
170 $job->addToQueue(true);
171 $this->setResponseMessage($job->getName(). " Added to queue!");
172 $this->setResponseData($this->isCLI() ? $job->getDisplayCLI() : $job->getDisplay());
173 }
174
175 /**
176 * @return void
177 * @throws AjaxException
178 * @throws DBException
179 * @throws IOException
180 * @throws InvalidArgumentException
181 * @throws QueueException
182 * @throws \JetBackup\Exception\IOException
183 */
184 private function _queueRestore():void {
185
186 $options = $this->_getRestoreOptions();
187
188 /**
189 * Determine which files and database tables should be included or excluded
190 * based on the provided restore options.
191 *
192 * - `$included_files`: Restore only listed folders/files
193 * - `$excluded_files`: Exclude listed folders/files
194 * - `$exclude_db`: Exclude listed database tables
195 * - `$include_db`: Restore only listed databases tables
196 */
197
198 $included_files = ($options & (QueueItemRestore::OPTION_RESTORE_FILES_INCLUDE)) ? $this->_getHomedirFolders() : [];
199 $excluded_files = ($options & (QueueItemRestore::OPTION_RESTORE_FILES_EXCLUDE)) ? $this->_getHomedirFolders() : [];
200 $exclude_db = ($options & QueueItemRestore::OPTION_RESTORE_DATABASE_EXCLUDE) ? $this->_getDatabaseTables() : [];
201 $include_db = ($options & QueueItemRestore::OPTION_RESTORE_DATABASE_INCLUDE) ? $this->_getDatabaseTables() : [];
202
203 if ($this->_getId()) {
204 $snap = new Snapshot($this->_getId());
205 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
206 if ($snap->getBackupType() != BackupJob::TYPE_ACCOUNT) throw new AjaxException("Can only restore account backups");
207 if (($options & QueueItemRestore::OPTION_RESTORE_FILES_INCLUDE) && !Helper::isMultisite() && $snap->getEngine() != Engine::ENGINE_JB) throw new AjaxException("This restore feature is not supported");
208 if( $snap->getEngine() != Engine::ENGINE_JB) self::_validateDestinations([$snap->getDestinationId()]);
209 $snap->addToRestoreQueue($options, $excluded_files, $included_files, $exclude_db, $include_db, $this->_getFileManagerList());
210 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
211 $this->setResponseMessage("Added to queue!");
212 } elseif($this->_snapshotPath()) {
213 Snapshot::addToRestoreQueueByPath($this->_snapshotPath(), $options, $excluded_files, $include_db, $exclude_db);
214 $this->setResponseMessage("Added to queue!");
215 } elseif($this->_getFileName()) {
216
217 $tmp_name = isset($_FILES['file']['tmp_name']) ? Wordpress::sanitizeTextField($_FILES['file']['tmp_name']) : null;
218 if(!$tmp_name)
219 throw new AjaxException("No upload file was provided");
220
221 $upload = new Upload();
222
223 if(!$this->_getFileUploadId()) {
224 if(!$this->_getFileSize()) throw new AjaxException("No upload file size was provided");
225
226 $upload->setFilename($this->_getFileName());
227 $upload->setSize($this->_getFileSize());
228 $upload->setCreated(time());
229 $upload->save();
230 } else {
231 $upload->loadByUploadId($this->_getFileUploadId());
232 if(!$upload->getId()) throw new AjaxException("Invalid upload id was provided");
233 }
234
235 try {
236 $upload->writeChunk($tmp_name);
237 } catch(IOException $e) {
238 throw new AjaxException("Failed writing chunk to upload file. Error: %s", [$e->getMessage()]);
239 }
240
241 if($upload->isCompleted()) {
242
243 if (!( Archive::isTar($upload->getFileLocation()) || Archive::isGzCompressed($upload->getFileLocation()) ) ) {
244 Util::rm(dirname($upload->getFileLocation()));
245 throw new AjaxException("Invalid backup file provided. Only .tar or .tar.gz files are allowed.");
246 }
247
248 Snapshot::addToRestoreQueueByPath($upload->getFileLocation());
249 $this->setResponseMessage("Added to queue!");
250 } else {
251 $this->setResponseMessage("Waiting for next file chunk");
252 $this->setResponseData([ 'upload_id' => $upload->getUniqueId() ]);
253 }
254
255 } else throw new AjaxException("No snapshot id, path of file was provided");
256 }
257
258 /**
259 * @return void
260 * @throws AjaxException
261 * @throws DBException
262 * @throws DestinationException
263 * @throws IOException
264 * @throws InvalidArgumentException
265 * @throws QueueException
266 */
267 private function _queueReindex():void {
268
269 if($this->_getId() == 0) {
270 if(!Factory::getSettingsGeneral()->isJBIntegrationEnabled()) throw new AjaxException("JetBackup Linux integration is disabled");
271 if(!JetBackupLinux::isInstalled()) throw new AjaxException("JetBackup Linux integration is not installed");
272
273 try {
274 JetBackupLinux::checkRequirements();
275 JetBackupLinux::addToQueue();
276 $this->setResponseMessage("Added to reindex queue");
277 } catch (JetBackupLinuxException $e) {
278 throw new AjaxException($e->getMessage());
279 }
280
281 } else {
282 if (!$this->_getId()) throw new AjaxException("No destination id was provided");
283 $destination = new Destination($this->_getId());
284 if (!$destination->getId()) throw new AjaxException("Invalid destination id provided");
285
286 $destination->addToQueue($this->_getMixedSites());
287 if(!$destination->getId()) throw new AjaxException("Invalid destination id provided");
288 $this->setResponseMessage("Destination '" . $destination->getName() . "' add to reindex queue");
289 $this->setResponseData($destination->getDisplay());
290 }
291
292
293 }
294
295 /**
296 * Export to control panel (not supported with legacy backups)
297 * @return void
298 * @throws AjaxException
299 * @throws DBException
300 * @throws IOException
301 * @throws InvalidArgumentException
302 * @throws QueueException
303 */
304 private function _queueExport():void {
305 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
306 $snap = new Snapshot($this->_getId());
307 self::_validateDestinations([$snap->getDestinationId()]);
308 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
309 if ($snap->getEngine() == Engine::ENGINE_SGB) throw new AjaxException("This feature is not supported with legacy SGB backups");
310 if ($snap->getBackupType() != BackupJob::TYPE_ACCOUNT) throw new AjaxException("Can only export account backups");
311 if ($snap->getContains() != BackupJob::BACKUP_ACCOUNT_CONTAINS_FULL) throw new AjaxException("Can only export full backups");
312 $snap->addToExportQueue($this->_getPanelType());
313 $this->setResponseMessage("Added to queue!");
314 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
315 }
316
317
318
319 /**
320 * @return void
321 * @throws AjaxException
322 * @throws DBException
323 * @throws IOException
324 * @throws InvalidArgumentException
325 * @throws QueueException
326 */
327 private function _queueDownload():void {
328 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
329 $snap = new Snapshot($this->_getId());
330 self::_validateDestinations([$snap->getDestinationId()]);
331 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
332 if ($snap->getBackupType() != BackupJob::TYPE_ACCOUNT) throw new AjaxException("Can only download account backups");
333
334 $totalDownloads = sizeof(Download::query()->getQuery()->fetch());
335 $allowedDownloads = Factory::getSettingsMaintenance()->getDownloadLimit();
336 if ($allowedDownloads > 0 && $totalDownloads >= $allowedDownloads) throw new AjaxException("Download limit of $allowedDownloads reached. Please clear an existing download before starting a new one.");
337
338 $snap->addToDownloadQueue();
339 $this->setResponseMessage("Added to queue!");
340 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
341 }
342
343 /**
344 * @return void
345 * @throws AjaxException
346 * @throws DBException
347 * @throws IOException
348 * @throws InvalidArgumentException
349 * @throws QueueException
350 */
351 private function _queueDownloadBackupLog():void {
352 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
353 $snap = new Snapshot($this->_getId());
354 self::_validateDestinations([$snap->getDestinationId()]);
355 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
356
357 $snap->addToDownloadLogQueue();
358 $this->setResponseMessage("Added to queue!");
359 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
360 }
361
362 /**
363 * @return void
364 * @throws AjaxException
365 * @throws DBException
366 * @throws IOException
367 * @throws InvalidArgumentException
368 * @throws QueueException
369 */
370 private function _queueExtract():void {
371 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
372 $snap = new Snapshot($this->_getId());
373 self::_validateDestinations([$snap->getDestinationId()]);
374 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
375 if ($snap->getBackupType() != BackupJob::TYPE_ACCOUNT) throw new AjaxException("Can only extract account backups");
376
377 $snap->addToExtractQueue();
378 $this->setResponseMessage("Added to queue!");
379 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
380 }
381 }
382