PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / trunk
JetBackup – Backup, Restore & Migrate vtrunk
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 / SGB / Migration.php
backup / src / JetBackup / SGB Last commit date
.htaccess 1 year ago Extractor.php 1 year ago Migration.php 10 months ago index.html 1 year ago web.config 1 year ago
Migration.php
580 lines
1 <?php
2
3 namespace JetBackup\SGB;
4
5 if (!defined( '__JETBACKUP__')) die('Direct access is not allowed');
6
7 use Exception;
8 use JetBackup\Alert\Alert;
9 use JetBackup\BackupJob\BackupJob;
10 use JetBackup\Destination\Destination;
11 use JetBackup\Destination\ScanDirIterator;
12 use JetBackup\Destination\Vendors\Box\Box;
13 use JetBackup\Destination\Vendors\DropBox\DropBox;
14 use JetBackup\Destination\Vendors\FTP\FTP;
15 use JetBackup\Destination\Vendors\GoogleDrive\GoogleDrive;
16 use JetBackup\Destination\Vendors\OneDrive\Client\Client;
17 use JetBackup\Destination\Vendors\OneDrive\OneDrive;
18 use JetBackup\Destination\Vendors\pCloud\pCloud;
19 use JetBackup\Destination\Vendors\S3\S3;
20 use JetBackup\Destination\Vendors\SFTP\SFTP;
21 use JetBackup\Exception\DBException;
22 use JetBackup\Exception\DestinationException;
23 use JetBackup\Exception\IOException;
24 use JetBackup\Exception\IOVanishedException;
25 use JetBackup\Exception\QueueException;
26 use JetBackup\Exception\SGBMigrationException;
27 use JetBackup\Factory;
28 use JetBackup\JetBackup;
29 use JetBackup\License\License;
30 use JetBackup\Schedule\Schedule;
31 use JetBackup\Schedule\ScheduleItem;
32 use JetBackup\Wordpress\MySQL;
33 use JetBackup\Wordpress\Wordpress;
34 use phpseclib3\Crypt\AES;
35 use SleekDB\Exceptions\InvalidArgumentException;
36 use stdClass;
37
38 class Migration {
39
40 const BG_SCHEDULE_INTERVAL_HOURLY = 0;
41 const BG_SCHEDULE_INTERVAL_DAILY = 1;
42 const BG_SCHEDULE_INTERVAL_WEEKLY = 2;
43 const BG_SCHEDULE_INTERVAL_MONTHLY = 3;
44
45 const BG_FIRST_DAY_OF_MONTH = 1;
46 const BG_MIDDLE_OF_MONTH = 2;
47 const BG_LAST_DAY_OF_MONTH = 3;
48
49
50 const SG_STORAGE_FTP = 1;
51 const SG_STORAGE_DROPBOX = 2;
52 const SG_STORAGE_GOOGLE_DRIVE = 3;
53 const SG_STORAGE_AMAZON = 4;
54 const SG_STORAGE_ONE_DRIVE = 5;
55 const SG_STORAGE_P_CLOUD = 7;
56 const SG_STORAGE_BOX = 8;
57
58 const SG_CONFIG = 'sg_config';
59 const SG_PRO_NAMES = [ 'backup-guard-gold', 'backup-guard-platinum', 'backup-guard-silver'];
60
61 private MySQL $_db;
62 private string $_prefix;
63 private array $_settings = [];
64 private array $_destinations = [];
65 /** @var Schedule[] */
66 private array $_schedules = [];
67
68
69 // Mapping V2 day intervals to corresponding V3 schedule days
70 private array $bgDayIntervalMap = [
71 self::BG_FIRST_DAY_OF_MONTH => 1,
72 self::BG_MIDDLE_OF_MONTH => 14,
73 self::BG_LAST_DAY_OF_MONTH => 28
74 ];
75
76 /**
77 *
78 */
79 public function __construct() {
80 $this->_db = new MySQL();
81 $this->_prefix = $this->_db->getPrefix();
82 }
83
84 /**
85 * @return void
86 * @throws DBException
87 * @throws IOException
88 * @throws QueueException
89 * @throws \SleekDB\Exceptions\IOException
90 * @throws InvalidArgumentException
91 */
92 public function migrate():void {
93
94 $settings = Factory::getConfig();
95 if($settings->isSGBLegacyConverted()) return;
96
97
98
99 try {
100
101 $this->_migrateLegacyPluginDirectory();
102
103 if(in_array($this->_prefix . self::SG_CONFIG, $this->_db->listTables())) {
104 $this->_migrateConfig();
105 $this->_migrateDestinations();
106 $this->_migrateSchedules();
107 $this->_migrateBackupJob();
108 $this->_migrateBackups();
109 $this->_addReindexDestinations();
110 }
111
112 } catch(Exception $e) {
113 // We are stopping after one try or else it will flood the system
114 Alert::add("Migration failed", "The migration for version 3.x has been failed with the following error: " . $e->getMessage(), Alert::LEVEL_CRITICAL);
115 }
116
117 $settings->setSGBLegacyConverted(true);
118 $settings->save();
119 }
120
121 private function _addReindexDestinations():void {
122 $list = Destination::query()->getQuery()->fetch();
123
124 foreach($list as $destination_details) {
125 $destination = new Destination($destination_details[JetBackup::ID_FIELD]);
126 $destination->addToQueue();
127 }
128 }
129
130 private static function _decrypt($encrypted, $key) {
131 if (strlen($encrypted) < 16)
132 throw new \Exception("Invalid encrypted data: Insufficient length.");
133
134 $iv = substr($encrypted, 0, 16);
135 $data = substr($encrypted, 32);
136
137 $cipher = new AES('cbc');
138 $cipher->setKeyLength(256);
139 $cipher->setKey(hex2bin(hash('sha256', $key)));
140 $cipher->setIV($iv);
141
142 try {
143 $decrypted = $cipher->decrypt($data);
144 } catch (\Exception $e) {
145 throw new \Exception("Decryption failed: Invalid key or corrupted data.");
146 }
147 return $decrypted;
148 }
149
150 /**
151 * @return array
152 * @throws DBException
153 */
154 private function _getSettings():array {
155
156 if(!$this->_settings) {
157 $sql = "SELECT *
158 FROM `$this->_prefix" . self::SG_CONFIG . "`
159 WHERE ckey LIKE '%%SG_%%'";
160 $results = $this->_db->query($sql);
161
162 if (empty($results)) return [];
163 foreach($results as $data) $this->_settings[$data->ckey] = $data->cvalue;
164 }
165
166 return $this->_settings;
167 }
168
169 /**
170 * @return void
171 */
172 private function _migrateLegacyPluginDirectory():void {
173
174 $plugins_path = Factory::getWPHelper()->getWordPressHomedir() . Wordpress::WP_CONTENT . JetBackup::SEP . Wordpress::WP_PLUGINS;
175
176 foreach(self::SG_PRO_NAMES as $name) {
177 $name_path = $plugins_path . JetBackup::SEP . $name . JetBackup::SEP . 'backup-guard-pro.php';
178 if (!file_exists($name_path)) continue;
179
180 rename($name_path, $name_path . '_disabled');
181
182 $legacy_cron_path = $plugins_path . JetBackup::SEP . $name . JetBackup::SEP . 'public' . JetBackup::SEP . 'cron';
183 $new_cron_path = $plugins_path . JetBackup::SEP . JetBackup::PLUGIN_NAME . JetBackup::SEP . 'public' . JetBackup::SEP . 'cron';
184
185 if (!file_exists($legacy_cron_path) || !file_exists($new_cron_path) || is_link($legacy_cron_path)) continue;
186
187 rename($legacy_cron_path, $legacy_cron_path . '_disabled');
188 if (function_exists('symlink')) {
189 symlink($new_cron_path, $legacy_cron_path);
190 Alert::add('Legacy Plugin Found', 'Legacy JetBackup found, data imported and converted', Alert::LEVEL_INFORMATION);
191 } else {
192 Alert::add('Legacy Plugin Convert Error', "Failed created symlink from $legacy_cron_path to $new_cron_path", Alert::LEVEL_CRITICAL);
193 }
194
195
196 }
197 }
198
199 /**
200 * @return void
201 * @throws DestinationException
202 * @throws DBException
203 * @throws Exception
204 */
205 private function _migrateDestinations():void {
206
207 $config = $this->_getSettings();
208 $legacy_chunk_size = $config['SG_BACKUP_CLOUD_UPLOAD_CHUNK_SIZE'] ?? 1;
209
210 // Create S3 destination
211 if (isset($config['SG_AMAZON_KEY']) && $config['SG_AMAZON_KEY'] != '') {
212
213 $region = $config['SG_AMAZON_BUCKET_REGION'];
214 if(preg_match('/s3\.([a-z0-9-]+)\.amazonaws\.com/', $region, $matches)) $region = $matches[1];
215
216 $destination = new Destination();
217 $destination->setName('S3 Legacy Converted');
218 $destination->setDefault(false);
219 $destination->setType(S3::TYPE);
220 $destination->setPath('/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'));
221 $destination->setChunkSize(max($legacy_chunk_size, 5));
222 $destination->setNotes('Legacy Converted');
223 $destination->setOptions((object) [
224 'access_key' => $config['SG_AMAZON_KEY'],
225 'secret_key' => $config['SG_AMAZON_SECRET_KEY'],
226 'region' => $region,
227 'bucket' => $config['SG_AMAZON_BUCKET'],
228 'endpoint' => 's3.{region}.amazonaws.com',
229 'verifyssl' => false,
230 'retries' => 5,
231 'extrafields' => new stdClass(),
232 'keepalive_timeout' => 60,
233 'keepalive_requests' => 100,
234 ]);
235 $destination->save();
236
237 $this->_destinations[self::SG_STORAGE_AMAZON] = $destination->getId();
238 }
239
240 // Create FTP destination
241 if (isset($config['SG_STORAGE_FTP_CONNECTED']) && $config['SG_STORAGE_FTP_CONNECTED'] == 1 && isset($config['SG_STORAGE_CONNECTION_METHOD']) && $config['SG_STORAGE_CONNECTION_METHOD'] == 'ftp') {
242
243 $destination = new Destination();
244 $destination->setName('FTP Legacy Converted');
245 $destination->setDefault(false);
246 $destination->setType(FTP::TYPE);
247 $destination->setPath('./' . trim(trim($config['SG_FTP_ROOT_FOLDER'], '/.') . '/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'), '/'));
248 $destination->setChunkSize($legacy_chunk_size);
249 $destination->setNotes('Legacy Converted');
250 $destination->setOptions((object) [
251 'server' => $config['SG_FTP_HOST'],
252 'port' => $config['SG_FTP_PORT'],
253 'username' => $config['SG_FTP_USER'],
254 'password' => self::_decrypt(base64_decode($config['SG_FTP_PASSWORD']),NONCE_SALT) ?? 'dummy_password',
255 'timeout' => 60,
256 'retries' => 5,
257 'ssl' => false,
258 'ignore_self_signed' => false,
259 'passive_mode' => $config['SG_FTP_PASSIVE_MODE'],
260 ]);
261 $destination->save();
262
263 $this->_destinations[self::SG_STORAGE_FTP] = $destination->getId();
264 }
265
266 // Create DropBox destination
267 if (isset($config['SG_DROPBOX_REFRESH_TOKEN']) && $config['SG_DROPBOX_REFRESH_TOKEN'] != '') {
268
269 $destination = new Destination();
270 $destination->setName('DropBox Legacy Converted');
271 $destination->setDefault(false);
272 $destination->setType(DropBox::TYPE);
273 $destination->setPath('/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'));
274 $destination->setChunkSize($legacy_chunk_size);
275 $destination->setNotes('Legacy Converted');
276 $destination->setOptions((object) [
277 'retries' => 5,
278 'access_token' => $config['SG_DROPBOX_ACCESS_TOKEN'] ?? 'dummy',
279 'refresh_token' => $config['SG_DROPBOX_REFRESH_TOKEN'],
280 'token_fetch_time' => time(),
281 'access_token_expiry' => 253386463868,
282
283 // This is for legacy migration only
284 'client_id' => 'backup-guard',
285 'client_secret' => 's8crjkls7f9wqtd',
286 ]);
287 $destination->save();
288
289 $this->_destinations[self::SG_STORAGE_DROPBOX] = $destination->getId();
290 }
291
292 // Create Box destination
293 if (isset($config['SG_BOX_REFRESH_TOKEN']) && $config['SG_BOX_REFRESH_TOKEN'] != '') {
294
295 $destination = new Destination();
296 $destination->setName('Box Legacy Converted');
297 $destination->setDefault(false);
298 $destination->setType(Box::TYPE);
299 $destination->setPath('/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'));
300 $destination->setChunkSize(max($legacy_chunk_size, 20));
301 $destination->setNotes('Legacy Converted');
302 $destination->setOptions((object) [
303 'retries' => 5,
304 'token' => 'dummy',
305 'refresh_token' => $config['SG_BOX_REFRESH_TOKEN'],
306 'token_expires' => 0,
307 ]);
308 $destination->save();
309
310 $this->_destinations[self::SG_STORAGE_BOX] = $destination->getId();
311 }
312
313 // Create pCloud destination
314 if (isset($config['SG_P_CLOUD_ACCESS_TOKEN']) && $config['SG_P_CLOUD_ACCESS_TOKEN'] != '') {
315
316 $destination = new Destination();
317 $destination->setName('pCloud Legacy Converted');
318 $destination->setDefault(false);
319 $destination->setType(pCloud::TYPE);
320 $destination->setPath('/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'));
321 $destination->setChunkSize($legacy_chunk_size);
322 $destination->setNotes('Legacy Converted');
323 $destination->setOptions((object) [
324 'retries' => 5,
325 'token' => $config['SG_P_CLOUD_ACCESS_TOKEN'],
326 'api_url' => isset($config['SG_P_CLOUD_LOCATION_ID']) && $config['SG_P_CLOUD_LOCATION_ID'] == 2 ? 'eapi.pcloud.com' : 'api.pcloud.com',
327 ]);
328 $destination->save();
329
330 $this->_destinations[self::SG_STORAGE_P_CLOUD] = $destination->getId();
331 }
332
333 // Create OneDrive destination
334 if (isset($config['SG_ONE_DRIVE_REFRESH_TOKEN']) && $config['SG_ONE_DRIVE_REFRESH_TOKEN'] != '') {
335
336 $destination = new Destination();
337 $destination->setName('OneDrive Legacy Converted');
338 $destination->setDefault(false);
339 $destination->setType(OneDrive::TYPE);
340 $destination->setPath('/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'));
341 $destination->setChunkSize($legacy_chunk_size);
342 $destination->setNotes('Legacy Converted');
343 $destination->setOptions((object) [
344 'retries' => 5,
345 'http_version' => Client::HTTP_VERSION_DEFAULT,
346 'access_token' => 'dummy',
347 'refresh_token' => $config['SG_ONE_DRIVE_REFRESH_TOKEN'],
348 'token_fetch_time' => 0,
349 'access_token_expiry' => 0,
350
351 // This is for legacy migration only
352 'client_id' => '00652d36-9155-48cb-aac9-c31579261ba6',
353 'client_secret' => 'I.K8Q~qOAMv1LLVMcK_pJpPQQPuekhUtp12Jqa7.',
354 ]);
355 $destination->save();
356
357 $this->_destinations[self::SG_STORAGE_ONE_DRIVE] = $destination->getId();
358 }
359
360 // Create SFTP destination
361 if(isset($config['SG_STORAGE_FTP_CONNECTED']) && $config['SG_STORAGE_FTP_CONNECTED'] == 1 && isset($config['SG_STORAGE_CONNECTION_METHOD']) && $config['SG_STORAGE_CONNECTION_METHOD'] == 'sftp') {
362
363 $destination = new Destination();
364 $destination->setName('SFTP Legacy Converted');
365 $destination->setDefault(false);
366 $destination->setType(SFTP::TYPE);
367 $destination->setPath('./' . trim(trim($config['SG_FTP_ROOT_FOLDER'], '/.') . '/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'), '/'));
368 $destination->setChunkSize($legacy_chunk_size);
369 $destination->setNotes('Legacy Converted');
370 $destination->setOptions((object) [
371 'host' => $config['SG_FTP_HOST'],
372 'port' => $config['SG_FTP_PORT'],
373 'username' => $config['SG_FTP_USER'],
374 'password' => self::_decrypt(base64_decode($config['SG_FTP_PASSWORD']),NONCE_SALT) ?? 'dummy_password',
375 'timeout' => 60,
376 'retries' => 5,
377 'privatekey' => '',
378 'passphrase' => '',
379 ]);
380 $destination->save();
381
382 $this->_destinations[self::SG_STORAGE_FTP] = $destination->getId();
383 }
384
385 // Create googleDrive destination
386 if(isset($config['SG_GOOGLE_DRIVE_REFRESH_TOKEN']) && $config['SG_GOOGLE_DRIVE_REFRESH_TOKEN'] != '') {
387
388 $destination = new Destination();
389 $destination->setName('GoogleDrive Legacy Converted');
390 $destination->setDefault(false);
391 $destination->setType(GoogleDrive::TYPE);
392 $destination->setPath('/' . trim($config['SG_STORAGE_BACKUPS_FOLDER_NAME'], '/.'));
393 $destination->setChunkSize($legacy_chunk_size);
394 $destination->setNotes('Legacy Converted');
395 $destination->setOptions((object) [
396 'retries' => 5,
397 'token' => json_encode([ 'created' => 0, 'expires_in' => 0 ]),
398 'refresh_token' => $config['SG_GOOGLE_DRIVE_REFRESH_TOKEN'],
399
400 // This is for legacy migration only
401 'client_id' => '1030123017859-vfdlqkjhiuuu5n36pbov93v9ruo6jpj5.apps.googleusercontent.com',
402 'client_secret' => 'oUcZwC17q5ZSbYahnQkGYpyH',
403 ]);
404 $destination->save();
405
406 $this->_destinations[self::SG_STORAGE_GOOGLE_DRIVE] = $destination->getId();
407 }
408 }
409
410 /**
411 * @return void
412 * @throws SGBMigrationException
413 */
414 private function _migrateSchedules():void {
415
416 try {
417 $sql = "SELECT *
418 FROM `{$this->_prefix}sg_schedule`";
419 if (!($results = $this->_db->query($sql))) return;
420
421 foreach($results as $res) {
422
423 $options = json_decode($res->schedule_options);
424
425 $schedule = new Schedule();
426 $schedule->setName('Legacy_converted_' . $res->label);
427
428 switch ($options->interval) {
429 case self::BG_SCHEDULE_INTERVAL_HOURLY:
430 $schedule->setType(Schedule::TYPE_HOURLY);
431 $schedule->setIntervals(1);
432 break;
433
434 case self::BG_SCHEDULE_INTERVAL_DAILY:
435 $schedule->setType(Schedule::TYPE_DAILY);
436 $schedule->setIntervals([1]);
437 break;
438
439 case self::BG_SCHEDULE_INTERVAL_WEEKLY:
440 $schedule->setType(Schedule::TYPE_WEEKLY);
441 $schedule->setIntervals(!empty($options->dayOfInterval) ? $options->dayOfInterval : 1);
442 break;
443
444 case self::BG_SCHEDULE_INTERVAL_MONTHLY:
445 $schedule->setType(Schedule::TYPE_MONTHLY);
446 $schedule->setIntervals([$this->bgDayIntervalMap[!empty($options->dayOfInterval) ? $options->dayOfInterval : 1]]);
447 break;
448 }
449
450 $schedule->setHidden(false);
451 $schedule->setDefault(false);
452 $schedule->save();
453
454 $this->_schedules[] = $schedule;
455 }
456
457
458 } catch(Exception $e) {
459 throw new SGBMigrationException($e->getMessage(), $e->getCode());
460 }
461 }
462
463 /**
464 * @throws IOVanishedException
465 */
466 private function _migrateBackups():void {
467
468
469 $legacy_upload_folder = Factory::getWPHelper()->getWordPressHomedir() . Factory::getWPHelper()->getUploadDir() . JetBackup::SEP . 'jetbackup';
470 if(!file_exists($legacy_upload_folder)) return;
471
472 $scan = new ScanDirIterator($legacy_upload_folder);
473
474 while($file = $scan->next()) {
475 $path = $file->getFullPath();
476 if(!str_ends_with($path, BackupJob::SNAPSHOT_SGBP_SUFFIX)) continue;
477 $target = Factory::getLocations()->getBackupsDir() . JetBackup::SEP . basename($path);
478 rename($path, $target);
479 chmod($target, 0600);
480 }
481 }
482
483 /**
484 * @return void
485 * @throws SGBMigrationException
486 */
487 private function _migrateBackupJob():void {
488
489 try {
490 $sql = "SELECT *
491 FROM `{$this->_prefix}sg_schedule`";
492 $results = $this->_db->query($sql);
493 if(!$results) return;
494
495 $config = $this->_getSettings();
496
497 foreach ($results as $res) {
498 $schedule_options = json_decode($res->schedule_options);
499 $backup_options = json_decode($res->backup_options);
500
501 $contains = 0;
502 if ($backup_options->SG_ACTION_BACKUP_DATABASE_AVAILABLE) $contains |= BackupJob::BACKUP_ACCOUNT_CONTAINS_DATABASE;
503 if ($backup_options->SG_ACTION_BACKUP_FILES_AVAILABLE) $contains |= BackupJob::BACKUP_ACCOUNT_CONTAINS_HOMEDIR;
504
505 $destinations = [];
506 if($backup_options->SG_BACKUP_UPLOAD_TO_STORAGES) {
507 $legacy_storage = explode(',', $backup_options->SG_BACKUP_UPLOAD_TO_STORAGES);
508 foreach($legacy_storage as $storage) {
509 if(!isset($this->_destinations[$storage])) continue;
510 $destinations[] = $this->_destinations[$storage];
511 }
512 }
513
514 if(!sizeof($destinations)) {
515 $destination = Destination::createDefaultDestination();
516 $destinations[] = $destination->getId();
517 }
518
519 $schedule = $this->_schedules[0] ?? Schedule::getDefaultConfigSchedule();
520
521 $schedule_item = new ScheduleItem();
522 $schedule_item->setId($schedule->getId());
523 $schedule_item->setType($schedule->getType());
524 $schedule_item->setRetain(isset($config['SG_AMOUNT_OF_BACKUPS_TO_KEEP']) ? (int) $config['SG_AMOUNT_OF_BACKUPS_TO_KEEP'] : 30);
525
526 $job = new BackupJob();
527 $job->setName('Legacy Job');
528 $job->setType(BackupJob::TYPE_ACCOUNT);
529 $job->setContains($contains);
530 $job->setEnabled(true);
531 $job->setHidden(false);
532 $job->setDefault(false);
533 $job->setScheduleTime(!empty($schedule_options->intervalHour) ? $schedule_options->intervalHour.':00' : 1 . ':00');
534 $job->setDestinations($destinations);
535 $job->setSchedules([$schedule_item]);
536 $job->setExcludeDatabases(isset($config['SG_TABLES_TO_EXCLUDE']) ? explode(',', $config['SG_TABLES_TO_EXCLUDE']) : []);
537 $job->setExcludes(isset($config['SG_PATHS_TO_EXCLUDE']) ? explode(',', $config['SG_PATHS_TO_EXCLUDE']) : []);
538 $job->save();
539 }
540
541 } catch (Exception $e) {
542 throw new SGBMigrationException($e->getMessage(), $e->getCode());
543 }
544 }
545
546 /**
547 * @return void
548 * @throws DBException
549 * @throws IOException
550 */
551 private function _migrateConfig():void {
552
553 $settings = $this->_getSettings();
554 foreach ($settings as $key=>$value) if(trim($value) == '') unset($settings[$key]);
555
556 $config = Factory::getConfig();
557 $general = Factory::getSettingsGeneral();
558 $notifications = Factory::getSettingsNotifications();
559
560 if(isset($settings['SG_TIMEZONE'])) $general->setTimeZone($settings['SG_TIMEZONE']);
561 if(isset($settings['SG_PHP_CLI_LOCATION'])) $general->setPHPCLILocation($settings['SG_PHP_CLI_LOCATION']);
562
563 if(!License::isValid()) {
564 if(isset($settings['SG_LICENSE_KEY'])) $config->setLicenseKey($settings['SG_LICENSE_KEY']);
565 if(isset($settings['SG_LOCAL_KEY'])) $config->setLicenseLocalKey($settings['SG_LOCAL_KEY']);
566 if(isset($settings['SG_LOCAL_KEY_LAST_CHECK_TS'])) $config->setLicenseLastCheck((int) $settings['SG_LOCAL_KEY_LAST_CHECK_TS']);
567 if(isset($settings['SG_LOCAL_KEY_NEXT_CHECK_TS'])) $config->setLicenseNextCheck((int) $settings['SG_LOCAL_KEY_NEXT_CHECK_TS']);
568 }
569
570 if(isset($settings['SG_BACKUP_CURRENT_KEY'])) $config->setCronToken($settings['SG_BACKUP_CURRENT_KEY']);
571 if(isset($settings['SG_NOTIFICATIONS_ENABLED'])) $notifications->setEmailsEnabled(!!$settings['SG_NOTIFICATIONS_ENABLED']);
572
573 $config->save();
574 $general->save();
575 $notifications->save();
576 }
577 }
578
579
580