PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.22.4
JetBackup – Backup, Restore & Migrate v3.1.22.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 1 year ago AbortQueueItem.php 1 year ago AddToQueue.php 3 months ago ClearAlerts.php 1 year ago ClearCompletedQueueItems.php 1 year ago CreateSupportUser.php 1 year ago DeleteBackupJob.php 1 year ago DeleteDestination.php 1 year ago DeleteDownload.php 1 year ago DeleteSchedule.php 1 year ago DeleteSnapshot.php 1 year ago DestinationSetExportConfig.php 1 year ago DuplicateBackupJob.php 1 year ago EditBackupNotes.php 1 year ago EnableBackupJob.php 1 year ago EnableDestination.php 1 year ago ExecuteCron.php 1 year ago FileManager.php 10 months ago GetBackup.php 1 year ago GetBackupJob.php 1 year ago GetDashboard.php 1 year ago GetDatabaseTables.php 1 year ago GetDestination.php 1 year ago GetLog.php 1 year ago GetQRCode.php 1 year ago GetQueueItem.php 1 year ago GetSchedule.php 1 year ago GetSettingsAutomation.php 1 year ago GetSettingsGeneral.php 1 year ago GetSettingsIntegrations.php 1 year ago GetSettingsLogging.php 1 year ago GetSettingsMaintenance.php 1 year ago GetSettingsNotifications.php 1 year ago GetSettingsPerformance.php 1 year ago GetSettingsRestore.php 1 year ago GetSettingsSecurity.php 1 year ago GetSettingsUpdates.php 1 year ago GetSystemInfo.php 11 months ago ListAlerts.php 1 year ago ListBackupJobs.php 1 year ago ListBackups.php 1 year ago ListDatabaseTables.php 1 year ago ListDestinations.php 1 year ago ListDownloads.php 1 year ago ListQueueItems.php 4 months ago ListSchedules.php 1 year ago LockSnapshot.php 1 year ago ManageBackupJob.php 1 year ago ManageDestination.php 1 year ago ManageSchedule.php 3 months ago ManageSettingsAutomation.php 10 months ago ManageSettingsGeneral.php 4 months ago ManageSettingsIntegrations.php 1 year ago ManageSettingsLogging.php 1 year ago ManageSettingsMaintenance.php 1 year ago ManageSettingsNotifications.php 1 year ago ManageSettingsPerformance.php 1 year ago ManageSettingsRestore.php 1 year ago ManageSettingsSecurity.php 1 week ago ManageSettingsUpdates.php 1 year ago ManageShowcase.php 1 year ago PanelPreload.php 1 year ago SendTestEmail.php 1 year ago StartOverQueueItem.php 1 year ago ValidateDestination.php 1 year ago ValidateMFA.php 1 year ago index.html 1 year ago web.config 1 year ago
AddToQueue.php
398 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 // Import the backup file and save it to the database for potential retry
214 $crossDomain = Factory::getSettingsRestore()->isRestoreAllowCrossDomain();
215 $snap = Snapshot::importFromPath($this->_snapshotPath(), $crossDomain);
216 $snap->addToRestoreQueue($options, $excluded_files, $included_files, $exclude_db, $include_db);
217 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
218 $this->setResponseMessage("Added to queue!");
219 } elseif($this->_getFileName()) {
220
221 $tmp_name = isset($_FILES['file']['tmp_name']) ? Wordpress::sanitizeTextField($_FILES['file']['tmp_name']) : null;
222 if(!$tmp_name)
223 throw new AjaxException("No upload file was provided");
224
225 $upload = new Upload();
226
227 if(!$this->_getFileUploadId()) {
228 if(!$this->_getFileSize()) throw new AjaxException("No upload file size was provided");
229
230 if(
231 $this->_getFileName() != basename($this->_getFileName()) ||
232 $this->_getFileName() == "." ||
233 $this->_getFileName() == ".."
234 ) throw new AjaxException("Invalid filename: ". $this->_getFileName());
235
236 $upload->setFilename($this->_getFileName());
237 $upload->setSize($this->_getFileSize());
238 $upload->setCreated(time());
239 $upload->save();
240 } else {
241 $upload->loadByUploadId($this->_getFileUploadId());
242 if(!$upload->getId()) throw new AjaxException("Invalid upload id was provided");
243 }
244
245 try {
246 $upload->writeChunk($tmp_name);
247 } catch(IOException $e) {
248 throw new AjaxException("Failed writing chunk to upload file. Error: %s", [$e->getMessage()]);
249 }
250
251 if($upload->isCompleted()) {
252
253 $fileLocation = $upload->getFileLocation();
254
255 if (!( Archive::isTar($fileLocation) || Archive::isGzCompressed($fileLocation) ) ) {
256 Util::rm(dirname($fileLocation));
257 throw new AjaxException("Invalid backup file provided. Only .tar or .tar.gz files are allowed.");
258 }
259
260 // Import the backup file and save it to the database for potential retry
261 $crossDomain = Factory::getSettingsRestore()->isRestoreAllowCrossDomain();
262 $snap = Snapshot::importFromPath($fileLocation, $crossDomain);
263 $snap->addToRestoreQueue($options, $excluded_files, $included_files, $exclude_db, $include_db);
264 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
265 $this->setResponseMessage("Added to queue!");
266 } else {
267 $this->setResponseMessage("Waiting for next file chunk");
268 $this->setResponseData([ 'upload_id' => $upload->getUniqueId() ]);
269 }
270
271 } else throw new AjaxException("No snapshot id, path of file was provided");
272 }
273
274 /**
275 * @return void
276 * @throws AjaxException
277 * @throws DBException
278 * @throws DestinationException
279 * @throws IOException
280 * @throws InvalidArgumentException
281 * @throws QueueException
282 */
283 private function _queueReindex():void {
284
285 if($this->_getId() == 0) {
286 if(!Factory::getSettingsGeneral()->isJBIntegrationEnabled()) throw new AjaxException("JetBackup Linux integration is disabled");
287 if(!JetBackupLinux::isInstalled()) throw new AjaxException("JetBackup Linux integration is not installed");
288
289 try {
290 JetBackupLinux::checkRequirements();
291 JetBackupLinux::addToQueue();
292 $this->setResponseMessage("Added to reindex queue");
293 } catch (JetBackupLinuxException $e) {
294 throw new AjaxException($e->getMessage());
295 }
296
297 } else {
298 if (!$this->_getId()) throw new AjaxException("No destination id was provided");
299 $destination = new Destination($this->_getId());
300 if (!$destination->getId()) throw new AjaxException("Invalid destination id provided");
301
302 $destination->addToQueue($this->_getMixedSites());
303 if(!$destination->getId()) throw new AjaxException("Invalid destination id provided");
304 $this->setResponseMessage("Destination '" . $destination->getName() . "' add to reindex queue");
305 $this->setResponseData($destination->getDisplay());
306 }
307
308
309 }
310
311 /**
312 * Export to control panel (not supported with legacy backups)
313 * @return void
314 * @throws AjaxException
315 * @throws DBException
316 * @throws IOException
317 * @throws InvalidArgumentException
318 * @throws QueueException
319 */
320 private function _queueExport():void {
321 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
322 $snap = new Snapshot($this->_getId());
323 self::_validateDestinations([$snap->getDestinationId()]);
324 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
325 if ($snap->getEngine() == Engine::ENGINE_SGB) throw new AjaxException("This feature is not supported with legacy SGB backups");
326 if ($snap->getBackupType() != BackupJob::TYPE_ACCOUNT) throw new AjaxException("Can only export account backups");
327 if ($snap->getContains() != BackupJob::BACKUP_ACCOUNT_CONTAINS_FULL) throw new AjaxException("Can only export full backups");
328 $snap->addToExportQueue($this->_getPanelType());
329 $this->setResponseMessage("Added to queue!");
330 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
331 }
332
333
334
335 /**
336 * @return void
337 * @throws AjaxException
338 * @throws DBException
339 * @throws IOException
340 * @throws InvalidArgumentException
341 * @throws QueueException
342 */
343 private function _queueDownload():void {
344 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
345 $snap = new Snapshot($this->_getId());
346 self::_validateDestinations([$snap->getDestinationId()]);
347 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
348 if ($snap->getBackupType() != BackupJob::TYPE_ACCOUNT) throw new AjaxException("Can only download account backups");
349
350 $totalDownloads = sizeof(Download::query()->getQuery()->fetch());
351 $allowedDownloads = Factory::getSettingsMaintenance()->getDownloadLimit();
352 if ($allowedDownloads > 0 && $totalDownloads >= $allowedDownloads) throw new AjaxException("Download limit of $allowedDownloads reached. Please clear an existing download before starting a new one.");
353
354 $snap->addToDownloadQueue();
355 $this->setResponseMessage("Added to queue!");
356 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
357 }
358
359 /**
360 * @return void
361 * @throws AjaxException
362 * @throws DBException
363 * @throws IOException
364 * @throws InvalidArgumentException
365 * @throws QueueException
366 */
367 private function _queueDownloadBackupLog():void {
368 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
369 $snap = new Snapshot($this->_getId());
370 self::_validateDestinations([$snap->getDestinationId()]);
371 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
372
373 $snap->addToDownloadLogQueue();
374 $this->setResponseMessage("Added to queue!");
375 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
376 }
377
378 /**
379 * @return void
380 * @throws AjaxException
381 * @throws DBException
382 * @throws IOException
383 * @throws InvalidArgumentException
384 * @throws QueueException
385 */
386 private function _queueExtract():void {
387 if (!$this->_getId()) throw new AjaxException("No snapshot id was provided");
388 $snap = new Snapshot($this->_getId());
389 self::_validateDestinations([$snap->getDestinationId()]);
390 if (!$snap->getId()) throw new AjaxException("Invalid snapshot id provided");
391 if ($snap->getBackupType() != BackupJob::TYPE_ACCOUNT) throw new AjaxException("Can only extract account backups");
392
393 $snap->addToExtractQueue();
394 $this->setResponseMessage("Added to queue!");
395 $this->setResponseData($this->isCLI() ? $snap->getDisplayCLI() : $snap->getDisplay());
396 }
397 }
398