banner
11 months ago
bodies
11 months ago
check
11 months ago
cli
11 months ago
cron
11 months ago
dashboard
11 months ago
database
11 months ago
external
11 months ago
extracter
11 months ago
htaccess
11 months ago
notices
11 months ago
progress
11 months ago
scanner
11 months ago
staging
11 months ago
traits
11 months ago
uploader
11 months ago
zipper
11 months ago
.htaccess
11 months ago
activation.php
11 months ago
ajax.php
11 months ago
ajax_offline.php
11 months ago
analyst.php
11 months ago
backup-process.php
11 months ago
class-backup-method-mananger.php
11 months ago
cli-handler.php
11 months ago
compatibility.php
11 months ago
config.php
11 months ago
constants.php
11 months ago
initializer.php
11 months ago
logger.php
11 months ago
offline.php
11 months ago
ajax.php
4440 lines
| 1 | <?php |
| 2 | |
| 3 | // Namespace |
| 4 | namespace BMI\Plugin; |
| 5 | |
| 6 | // Exit on direct access |
| 7 | if (!defined('ABSPATH')) exit; |
| 8 | |
| 9 | // Uses |
| 10 | use BMI\Plugin\Backup_Migration_Plugin as BMP; |
| 11 | use BMI\Plugin\BMI_Logger as Logger; |
| 12 | use BMI\Plugin\Checker\BMI_Checker as Checker; |
| 13 | use BMI\Plugin\Checker\System_Info as SI; |
| 14 | use BMI\Plugin\CRON\BMI_Crons as Crons; |
| 15 | use BMI\Plugin\Dashboard as Dashboard; |
| 16 | use BMI\Plugin\Extracter\BMI_Extracter as Extracter; |
| 17 | use BMI\Plugin\Progress\BMI_MigrationProgress as MigrationProgress; |
| 18 | use BMI\Plugin\Progress\BMI_ZipProgress as Progress; |
| 19 | use BMI\Plugin\Progress\BMI_StagingProgress as StagingProgress; |
| 20 | use BMI\Plugin\Scanner\BMI_BackupsScanner as Backups; |
| 21 | use BMI\Plugin\Scanner\BMI_FileScanner as Scanner; |
| 22 | use BMI\Plugin\Zipper\BMI_Zipper as Zipper; |
| 23 | use BMI\Plugin\PHPCLI\Checker as PHPCLICheck; |
| 24 | use BMI\Plugin\External\BMI_External_Storage as ExternalStorage; |
| 25 | use BMI\Plugin\External\BMI_External_Storage_Premium as ExternalStoragePremium; |
| 26 | use BMI\Plugin\Staging\BMI_Staging_TasteWP as StagingTasteWP; |
| 27 | use BMI\Plugin\Staging\BMI_StagingLocal as StagingLocal; |
| 28 | use BMI\Plugin\Heart\BMI_Backup_Heart as Bypasser; |
| 29 | use BMI\Plugin\Staging\BMI_Staging as Staging; |
| 30 | use BMI\Plugin\Checker\Compatibility as Compatibility; |
| 31 | use BMI\Plugin\External\BMI_External_BackupBliss as BackupBliss; |
| 32 | use BMI\Plugin\External\BMI_External_SFTP as SFTP; |
| 33 | |
| 34 | /** |
| 35 | * Ajax Handler for BMI |
| 36 | */ |
| 37 | class BMI_Ajax { |
| 38 | |
| 39 | public $post; |
| 40 | public $zip_progress; |
| 41 | public $migration_progress; |
| 42 | public $lock_cli; |
| 43 | public $lastCurlCode; |
| 44 | |
| 45 | public $total_size_for_backup = 0; |
| 46 | public $total_size_for_backup_in_mb = 0; |
| 47 | public $total_excluded_size_for_backup = 0; |
| 48 | |
| 49 | public function __construct($initializedWithCLI = false) { |
| 50 | |
| 51 | // Initialize CRON if wasn't done earlier |
| 52 | $this->shareDomainForAutoCron(); |
| 53 | |
| 54 | // Return if it's not post |
| 55 | if (empty($_POST)) { |
| 56 | $this->post = ['f' => 'unknown_method']; |
| 57 | return; |
| 58 | } |
| 59 | |
| 60 | // Sanitize User Input |
| 61 | $this->post = BMP::sanitize($_POST); |
| 62 | |
| 63 | if (!isset($this->post['f'])) { |
| 64 | if (is_object($this->post) || is_array($this->post)) $this->post['f'] = 'unknown_method'; |
| 65 | else $this->post = ['f' => 'unknown_method']; |
| 66 | } |
| 67 | |
| 68 | // Check nonce for non PHP CLI usage (ignore while self requested via previously verified nonce to PHP CLI) |
| 69 | if (check_ajax_referer('backup-migration-ajax', 'nonce', false) === false && $initializedWithCLI === false) { |
| 70 | return wp_send_json_error(['reason' => 'not authorized request']); |
| 71 | } |
| 72 | |
| 73 | // Log Handler Call (Verbose) |
| 74 | Logger::debug(__("Running POST Function: ", 'backup-backup') . $this->post['f']); |
| 75 | |
| 76 | // Create backup folder |
| 77 | if (!file_exists(BMI_BACKUPS)) { |
| 78 | mkdir(BMI_BACKUPS, 0755, true); |
| 79 | } |
| 80 | |
| 81 | // Create background logs file |
| 82 | $backgroundLogsPath = BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'background-errors.log'; |
| 83 | if (!file_exists($backgroundLogsPath)) { |
| 84 | @touch($backgroundLogsPath); |
| 85 | } |
| 86 | |
| 87 | if (!isset($this->post['f'])) { |
| 88 | return; |
| 89 | } |
| 90 | |
| 91 | // Handle User Request If Known And Sanitize Response |
| 92 | if ($this->post['f'] == 'scan-directory') { |
| 93 | BMP::res($this->dirSize()); |
| 94 | } elseif ($this->post['f'] == 'create-backup') { |
| 95 | BMP::res($this->prepareAndMakeBackup()); |
| 96 | } elseif ($this->post['f'] == 'reset-latest') { |
| 97 | BMP::res($this->resetLatestLogs()); |
| 98 | } elseif ($this->post['f'] == 'get-current-backups') { |
| 99 | BMP::res($this->getBackupsList()); |
| 100 | } elseif ($this->post['f'] == 'restore-backup') { |
| 101 | BMP::res($this->restoreBackup()); |
| 102 | } elseif ($this->post['f'] == 'is-running-backup') { |
| 103 | BMP::res($this->isRunningBackup()); |
| 104 | } elseif ($this->post['f'] == 'stop-backup') { |
| 105 | BMP::res($this->stopBackup()); |
| 106 | } elseif ($this->post['f'] == 'download-backup') { |
| 107 | BMP::res($this->handleQuickMigration()); |
| 108 | } elseif ($this->post['f'] == 'migration-locked') { |
| 109 | BMP::res($this->isMigrationLocked()); |
| 110 | } elseif ($this->post['f'] == 'upload-backup') { |
| 111 | BMP::res($this->handleChunkUpload()); |
| 112 | } elseif ($this->post['f'] == 'delete-backup') { |
| 113 | BMP::res($this->removeBackupFile()); |
| 114 | } elseif ($this->post['f'] == 'save-storage') { |
| 115 | BMP::res($this->saveStorageConfig()); |
| 116 | } elseif ($this->post['f'] == 'save-file-config') { |
| 117 | BMP::res($this->saveFilesConfig()); |
| 118 | } elseif ($this->post['f'] == 'save-other-options') { |
| 119 | BMP::res($this->saveOtherOptions()); |
| 120 | } elseif ($this->post['f'] == 'store-config') { |
| 121 | BMP::res($this->saveStorageTypeConfig()); |
| 122 | } elseif ($this->post['f'] == 'unlock-backup') { |
| 123 | BMP::res($this->toggleBackupLock(true)); |
| 124 | } elseif ($this->post['f'] == 'lock-backup') { |
| 125 | BMP::res($this->toggleBackupLock(false)); |
| 126 | } elseif ($this->post['f'] == 'get-dynamic-names') { |
| 127 | BMP::res($this->getDynamicNames()); |
| 128 | } elseif ($this->post['f'] == 'reset-configuration') { |
| 129 | BMP::res($this->resetConfiguration()); |
| 130 | } elseif ($this->post['f'] == 'get-site-data') { |
| 131 | BMP::res($this->getSiteData()); |
| 132 | } elseif ($this->post['f'] == 'send-test-mail') { |
| 133 | BMP::res($this->sendTestMail()); |
| 134 | } elseif ($this->post['f'] == 'calculate-cron') { |
| 135 | BMP::res($this->calculateCron()); |
| 136 | } elseif ($this->post['f'] == 'dismiss-error-notice') { |
| 137 | BMP::res($this->dismissErrorNotice()); |
| 138 | } elseif ($this->post['f'] == 'fix_uname_issues') { |
| 139 | BMP::res($this->fixUnameFunction()); |
| 140 | } elseif ($this->post['f'] == 'revert_uname_issues') { |
| 141 | BMP::res($this->revertUnameProcess()); |
| 142 | } elseif ($this->post['f'] == 'continue_restore_process') { |
| 143 | BMP::res($this->continueRestoreProcess()); |
| 144 | } elseif ($this->post['f'] == 'htaccess-litespeed') { |
| 145 | BMP::res($this->fixLitespeed()); |
| 146 | } elseif ($this->post['f'] == 'force-backup-to-stop') { |
| 147 | BMP::res($this->forceBackupToStop()); |
| 148 | } elseif ($this->post['f'] == 'force-restore-to-stop') { |
| 149 | BMP::res($this->forceRestoreToStop()); |
| 150 | } elseif ($this->post['f'] == 'staging-local-name') { |
| 151 | BMP::res($this->checkStagingLocalName()); |
| 152 | } elseif ($this->post['f'] == 'staging-start-local-creation') { |
| 153 | BMP::res($this->startLocalStagingCreation()); |
| 154 | } elseif ($this->post['f'] == 'staging-local-creation-process') { |
| 155 | BMP::res($this->localStagingCreationProcess()); |
| 156 | } elseif ($this->post['f'] == 'staging-tastewp-creation-process') { |
| 157 | BMP::res($this->tastewpStagingCreation()); |
| 158 | } elseif ($this->post['f'] == 'staging-rename-display') { |
| 159 | BMP::res($this->stagingRename()); |
| 160 | } elseif ($this->post['f'] == 'staging-prepare-login') { |
| 161 | BMP::res($this->stagingPrepareLogin()); |
| 162 | } elseif ($this->post['f'] == 'staging-delete-permanently') { |
| 163 | BMP::res($this->stagingDelete()); |
| 164 | } elseif ($this->post['f'] == 'staging-get-updated-list') { |
| 165 | BMP::res($this->stagingSitesGetList()); |
| 166 | } elseif ($this->post['f'] == 'send-troubleshooting-logs') { |
| 167 | BMP::res($this->sendTroubleshootingDetails()); |
| 168 | } elseif ($this->post['f'] == 'log-sharing-details') { |
| 169 | BMP::res($this->logSharing()); |
| 170 | } elseif ($this->post['f'] == 'get-latest-backup') { |
| 171 | BMP::res($this->getLatestBackupFile()); |
| 172 | } elseif ($this->post['f'] == 'front-end-ajax-error') { |
| 173 | BMP::res($this->frontEndAjaxError()); |
| 174 | } elseif ($this->post['f'] == 'backup-browser-method') { |
| 175 | BMP::res($this->backupBrowserMethodHandler()); |
| 176 | } elseif ($this->post['f'] == 'debugging') { |
| 177 | BMP::res($this->debugging()); |
| 178 | } elseif ($this->post['f'] == 'check-disk-space') { |
| 179 | BMP::res($this->checkDiskSpace()); |
| 180 | } elseif ($this->post['f'] == 'check-comptability') { |
| 181 | BMP::res($this->checkCompatibility()); |
| 182 | } elseif ($this->post['f'] == 'clean-up-after-error'){ |
| 183 | BMP::res($this->cleanUpAfterError()); |
| 184 | } elseif (substr($this->post['f'], 0, 3) === "bb-") { |
| 185 | require_once BMI_INCLUDES . '/external/backupbliss.php'; |
| 186 | $backupBliss = new BackupBliss(); |
| 187 | BMP::res($backupBliss->process(substr($this->post['f'], 3), $this->post)); |
| 188 | } elseif ($this->post['f'] == 'check-not-uploaded-backups') { |
| 189 | do_action('bmi_ajax_offline', $this->post); |
| 190 | } elseif($this->post['f'] == 'download-cloud-backup') { |
| 191 | if (isset($this->post['storage']) && $this->post['storage'] == 'backupbliss') |
| 192 | BMP::res($this->downloadCloudBackup()); |
| 193 | //Forward it to premium plugin for other cloud downloads |
| 194 | elseif (has_action('bmi_premium_ajax')) { |
| 195 | do_action('bmi_premium_ajax', $this->post); |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | |
| 200 | //If none of the action matches it executes premium ajax if it exists |
| 201 | elseif (has_action('bmi_premium_ajax')) { |
| 202 | do_action('bmi_premium_ajax', $this->post); |
| 203 | } |
| 204 | |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * shareDomainForAutoCron - Allows our API to keep scheduled backups on time |
| 209 | * |
| 210 | * @return json rtoken |
| 211 | */ |
| 212 | private function shareDomainForAutoCron() |
| 213 | { |
| 214 | |
| 215 | $cron_shared = get_option('bmi_cron_new_domain_done', false); |
| 216 | if ($cron_shared) return 0; |
| 217 | |
| 218 | $baseurl = home_url(); |
| 219 | if (substr($baseurl, 0, 4) != 'http') { |
| 220 | if (is_ssl()) $baseurl = 'https://' . home_url(); |
| 221 | else $baseurl = 'http://' . home_url(); |
| 222 | } |
| 223 | |
| 224 | $url = 'https://authentication.backupbliss.com/v1/crons/connect'; |
| 225 | $response = wp_remote_post($url, array( |
| 226 | 'method' => 'POST', |
| 227 | 'timeout' => 15, |
| 228 | 'redirection' => 2, |
| 229 | 'httpversion' => '1.0', |
| 230 | 'blocking' => true, |
| 231 | 'body' => array('site' => $baseurl) |
| 232 | )); |
| 233 | |
| 234 | if (!is_wp_error($response)) { |
| 235 | $response = json_decode($response['body'], true); |
| 236 | if (isset($response['status']) && $response['status'] === 'success') { |
| 237 | update_option('bmi_cron_new_domain_done', true); |
| 238 | } |
| 239 | |
| 240 | return 0; |
| 241 | } |
| 242 | |
| 243 | return 0; |
| 244 | } |
| 245 | |
| 246 | /** |
| 247 | * randomString - Generates "random" string |
| 248 | * |
| 249 | * @return string "random" |
| 250 | */ |
| 251 | private function randomString($length = 64) |
| 252 | { |
| 253 | |
| 254 | $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
| 255 | $str = ""; |
| 256 | |
| 257 | for ($i = 0; $i < $length; ++$i) { |
| 258 | |
| 259 | $str .= $chars[mt_rand(0, strlen($chars) - 1)]; |
| 260 | } |
| 261 | |
| 262 | return $str; |
| 263 | } |
| 264 | |
| 265 | /** |
| 266 | * downloadCloudBackup - Downloads Cloud Backup to Local Storage |
| 267 | * |
| 268 | * @return json status |
| 269 | */ |
| 270 | private function downloadCloudBackup() |
| 271 | { |
| 272 | |
| 273 | $secret = false; |
| 274 | if (isset($this->post['secret'])) $secret = $this->post['secret']; |
| 275 | |
| 276 | $lock = BMI_BACKUPS . '/.migration_lock'; |
| 277 | if (file_exists($lock) && (time() - filemtime($lock)) < 1) { |
| 278 | $lockContent = file_get_contents($lock); |
| 279 | if ($lockContent !== $secret) { |
| 280 | return ['status' => 'msg', 'why' => __('Download process is currently running, please wait till it complete.', 'backup-backup'), 'level' => 'warning']; |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | require_once BMI_INCLUDES . '/progress/migration.php'; |
| 285 | |
| 286 | $step = intval($this->post['step']); |
| 287 | $storage = $this->post['storage']; |
| 288 | $startRestoreProcess = isset($this->post['startRestoreProcess']) ? $this->post['startRestoreProcess'] : 'true'; |
| 289 | |
| 290 | $clearFile = ($step === 0) ? false : true; |
| 291 | $migration = new MigrationProgress($clearFile); |
| 292 | $migration->start(); |
| 293 | |
| 294 | if ($storage == 'backupbliss') { |
| 295 | |
| 296 | require_once BMI_INCLUDES . '/external/backupbliss.php'; |
| 297 | $backupbliss = new BackupBliss(); |
| 298 | |
| 299 | $backupDetails = false; |
| 300 | $fileId = $this->post['fileId']; |
| 301 | |
| 302 | if ($step === 0 || (!isset($this->post['size']) || $this->post['size'] == false || !is_numeric($this->post['size']))) { |
| 303 | |
| 304 | $migration->log((__('Backup & Migration version: ', 'backup-backup') . BMI_VERSION)); |
| 305 | $migration->log(__('Creating lock file', 'backup-backup')); |
| 306 | $secret = $this->randomString(); |
| 307 | file_put_contents($lock, $secret); |
| 308 | |
| 309 | $migration->log('Download intialized', 'INFO'); |
| 310 | $migration->log('Getting backup details from BackupBliss...', 'STEP'); |
| 311 | $backupDetails = $backupbliss->getFileDetailByName($fileId); |
| 312 | |
| 313 | if (!$backupDetails) { |
| 314 | |
| 315 | $migration->log("Couldn't fetch backup details from cloud.", 'ERROR'); |
| 316 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 317 | if (file_exists($lock)) @unlink($lock); |
| 318 | |
| 319 | $migration->log('#002', 'END-CODE'); |
| 320 | $migration->end(); |
| 321 | |
| 322 | return ['status' => 'error']; |
| 323 | } |
| 324 | |
| 325 | $size = intval($backupDetails['size']); |
| 326 | $originalFilename = $backupDetails['name']; |
| 327 | |
| 328 | $migration->log('Backup details received!', 'SUCCESS'); |
| 329 | $migration->log('Backup original name: ' . $originalFilename, 'INFO'); |
| 330 | $migration->log('Starting download process...', 'STEP'); |
| 331 | |
| 332 | $availableMemory = BMP::getAvailableMemoryInBytes(); |
| 333 | $bytesPerRequest = intval($availableMemory / 4); |
| 334 | |
| 335 | $migration->log('Single batch will use up to: ' . $bytesPerRequest . ' bytes (~' . intval($bytesPerRequest / 1024 / 1024 / 2) . ' MBs)', 'INFO'); |
| 336 | |
| 337 | $fileIterator = 2; |
| 338 | $originalFilenameInfo = pathinfo($originalFilename); |
| 339 | $extension = $originalFilenameInfo['extension']; |
| 340 | $originalFilename = $originalFilenameInfo['filename']; |
| 341 | if ($originalFilenameInfo['extension'] == 'gz') { |
| 342 | $originalFilename = pathinfo($originalFilename, PATHINFO_FILENAME); |
| 343 | $extension = 'tar.gz'; |
| 344 | } |
| 345 | |
| 346 | $backupDestinationPath = BMI_BACKUPS . DIRECTORY_SEPARATOR . $originalFilename . '.' . $extension; |
| 347 | $finalName = $originalFilename . '.' . $extension; |
| 348 | |
| 349 | while (file_exists($backupDestinationPath)) { |
| 350 | $backupDestinationPath = BMI_BACKUPS . DIRECTORY_SEPARATOR . $originalFilename . '-' . $fileIterator . '.' . $extension; |
| 351 | $finalName = $originalFilename . '-' . $fileIterator . '.' . $extension; |
| 352 | $fileIterator++; |
| 353 | } |
| 354 | |
| 355 | $originalFilename = $finalName; |
| 356 | |
| 357 | $backupDestinationPath .= '.crdownload'; |
| 358 | |
| 359 | } else { |
| 360 | |
| 361 | $size = intval($this->post['size']); |
| 362 | $originalFilename = $this->post['filename']; |
| 363 | $backupDestinationPath = $this->post['writepath']; |
| 364 | $bytesPerRequest = intval($this->post['chunksize']); |
| 365 | } |
| 366 | |
| 367 | $md5 = $this->post['md5']; |
| 368 | |
| 369 | $totalBatches = ceil($size / (256 * 1024 * 4 * intval($bytesPerRequest / 1024 / 1024 / 2))); |
| 370 | |
| 371 | if ($totalBatches <= $step) { |
| 372 | |
| 373 | $migration->log('Download process finished!', 'SUCCESS'); |
| 374 | $migration->log('Verifying MD5 checksum of downloaded file...', 'STEP'); |
| 375 | |
| 376 | rename($backupDestinationPath, str_replace('.crdownload', '', $backupDestinationPath)); |
| 377 | $backupDestinationPath = str_replace('.crdownload', '', $backupDestinationPath); |
| 378 | |
| 379 | |
| 380 | $local_md5 = hash_file('md5', $backupDestinationPath); |
| 381 | if (file_exists($backupDestinationPath) && $local_md5 == $md5) { |
| 382 | |
| 383 | $migration->log('Downloaded MD5: ' . $local_md5, 'INFO'); |
| 384 | $migration->log('Expected MD5: ' . $md5, 'INFO'); |
| 385 | $migration->log('File MD5 checksum is correct!', 'SUCCESS'); |
| 386 | } else { |
| 387 | |
| 388 | $migration->log('File MD5 checksum is NOT correct!', 'ERROR'); |
| 389 | $migration->log('Downloaded MD5: ' . $local_md5, 'ERROR'); |
| 390 | $migration->log('Expected MD5: ' . $md5, 'ERROR'); |
| 391 | $migration->log('Downloaded file path: ' . $backupDestinationPath, 'ERROR'); |
| 392 | $migration->log('File exist?: ' . (file_exists($backupDestinationPath) ? "Yes" : "No?"), 'ERROR'); |
| 393 | $migration->log('For security reasons, I will remove the file and stop the process...', 'ERROR'); |
| 394 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 395 | if (file_exists($lock)) @unlink($lock); |
| 396 | |
| 397 | $migration->log('#002', 'END-CODE'); |
| 398 | $migration->end(); |
| 399 | |
| 400 | if (file_exists($backupDestinationPath)) @unlink($backupDestinationPath); |
| 401 | return ['status' => 'error']; |
| 402 | } |
| 403 | |
| 404 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 405 | if (file_exists($lock)) @unlink($lock); |
| 406 | if ($startRestoreProcess == 'true') { |
| 407 | $migration->log('Requesting restoration process...', 'STEP'); |
| 408 | |
| 409 | $migration->log('#205', 'END-CODE'); |
| 410 | } else { |
| 411 | $migration->log('Download process finished!', 'SUCCESS'); |
| 412 | $migration->log('#206', 'END-CODE'); |
| 413 | } |
| 414 | $migration->progress(100); |
| 415 | $migration->end(); |
| 416 | |
| 417 | return ['status' => 'success', 'finished' => 'true', 'filename' => $originalFilename]; |
| 418 | } else { |
| 419 | |
| 420 | $chunkSize = 256 * 1024 * 4 * intval($bytesPerRequest / 1024 / 1024 / 2); |
| 421 | $startRange = ($step * $chunkSize); |
| 422 | if ($step !== 0) $startRange = $startRange + 1; |
| 423 | $endRange = (($step + 1) * $chunkSize); |
| 424 | if ($endRange > $size) $endRange = $size; |
| 425 | $percentage = intval(($endRange / $size) * 100); |
| 426 | |
| 427 | $data = $backupbliss->getFile($fileId, $startRange, $endRange); |
| 428 | |
| 429 | if (!$data["file_detail"] || !$data["file_data"]) { |
| 430 | |
| 431 | $migration->log("Couldn't fetch backup file from cloud.", 'ERROR'); |
| 432 | $migration->log('For security reasons, I will remove the file (if exist) and stop the process...', 'ERROR'); |
| 433 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 434 | if (file_exists($lock)) @unlink($lock); |
| 435 | |
| 436 | $migration->log('#002', 'END-CODE'); |
| 437 | $migration->end(); |
| 438 | |
| 439 | if (file_exists($backupDestinationPath)) @unlink($backupDestinationPath); |
| 440 | return ['status' => 'error']; |
| 441 | } |
| 442 | |
| 443 | if ((is_dir(dirname($backupDestinationPath)) && file_exists($backupDestinationPath)) || $step === 0) { |
| 444 | |
| 445 | $backupFile = fopen($backupDestinationPath, 'ab'); |
| 446 | fwrite($backupFile, $data['file_data']); |
| 447 | fclose($backupFile); |
| 448 | } else { |
| 449 | |
| 450 | $migration->log('File is not writable or directory does not exist.', 'ERROR'); |
| 451 | $migration->log('File: ' . basename($backupDestinationPath), 'ERROR'); |
| 452 | $migration->log('Dirname: ' . dirname($backupDestinationPath), 'ERROR'); |
| 453 | $migration->log('For security reasons, I will remove the file and stop the process...', 'ERROR'); |
| 454 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 455 | if (file_exists($lock)) @unlink($lock); |
| 456 | |
| 457 | $migration->log('#002', 'END-CODE'); |
| 458 | $migration->end(); |
| 459 | |
| 460 | if (file_exists($backupDestinationPath)) @unlink($backupDestinationPath); |
| 461 | return ['status' => 'error']; |
| 462 | } |
| 463 | |
| 464 | $migration->log('Download progress (' . ($step + 1) . '/' . $totalBatches . '): ' . $endRange . '/' . $size . ' (' . $percentage . '%)', 'INFO'); |
| 465 | $migration->progress($percentage); |
| 466 | $migration->end(); |
| 467 | |
| 468 | return [ |
| 469 | 'status' => 'success', |
| 470 | 'size' => $size, |
| 471 | 'md5' => $md5, |
| 472 | 'finished' => 'false', |
| 473 | 'originalFilename' => $originalFilename, |
| 474 | 'writepath' => $backupDestinationPath, |
| 475 | 'chunksize' => $bytesPerRequest, |
| 476 | 'secret' => $secret |
| 477 | ]; |
| 478 | } |
| 479 | } |
| 480 | |
| 481 | if (file_exists($lock)) @unlink($lock); |
| 482 | return ['status' => 'error']; |
| 483 | } |
| 484 | |
| 485 | public function siteURL() { |
| 486 | $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; |
| 487 | $domainName = $_SERVER['HTTP_HOST']; |
| 488 | |
| 489 | return $protocol . $domainName; |
| 490 | } |
| 491 | |
| 492 | public function checkIfPHPCliExist(&$logger) { |
| 493 | |
| 494 | $shouldContinue = apply_filters('bmi_cli_enabled', true); |
| 495 | if ($shouldContinue === false) { |
| 496 | $logger->log(__('PHP CLI is disabled manually, plugin will omit all PHP CLI steps.', 'backup-backup'), 'warn'); |
| 497 | return false; |
| 498 | } |
| 499 | |
| 500 | |
| 501 | if (defined('BMI_CLI_ENABLED')) { |
| 502 | $cliEnabled = apply_filters('bmi_cli_enabled', BMI_CLI_ENABLED); |
| 503 | if ($cliEnabled === false) { |
| 504 | $logger->log(__('PHP CLI is disabled manually, plugin will omit all PHP CLI steps.', 'backup-backup'), 'warn'); |
| 505 | return false; |
| 506 | } |
| 507 | } |
| 508 | |
| 509 | $logger->log(__('Looking for PHP CLI executable file.', 'backup-backup'), 'step'); |
| 510 | require_once BMI_INCLUDES . '/cli/php_cli_finder.php'; |
| 511 | $checker = new PHPCLICheck(); |
| 512 | $result = $checker->findPHP(); |
| 513 | |
| 514 | if ($result === false) { |
| 515 | |
| 516 | if (!defined('BMI_CLI_ENABLED')) define('BMI_CLI_ENABLED', false); |
| 517 | if (!defined('BMI_CLI_EXECUTABLE')) define('BMI_CLI_EXECUTABLE', false); |
| 518 | if ($checker->ini_disabled === true) { |
| 519 | $logger->log(__('PHP CLI is disabled in your php.ini file, the process may be unstable.', 'backup-backup'), 'warn'); |
| 520 | } else { |
| 521 | $logger->log(__('Could not find proper PHP CLI executable, this process may be unstable.', 'backup-backup'), 'warn'); |
| 522 | } |
| 523 | |
| 524 | return false; |
| 525 | |
| 526 | } else { |
| 527 | |
| 528 | if (!defined('BMI_CLI_ENABLED')) define('BMI_CLI_ENABLED', apply_filters('bmi_cli_enabled', true)); |
| 529 | if (!defined('BMI_CLI_EXECUTABLE')) define('BMI_CLI_EXECUTABLE', $result['executable']); |
| 530 | |
| 531 | $logger->log(__('PHP CLI Filename: ', 'backup-backup') . basename($result['executable']), 'info'); |
| 532 | $logger->log(__('PHP CLI Version: ', 'backup-backup') . $result['version'] . ' ' . $result['brand'], 'info'); |
| 533 | $logger->log(__('PHP CLI Memory limit: ', 'backup-backup') . $result['memory'], 'info'); |
| 534 | $logger->log(__('PHP CLI Execution limit: ', 'backup-backup') . $result['max_exec'], 'info'); |
| 535 | $logger->log(__('We properly detected PHP CLI executable file.', 'backup-backup'), 'success'); |
| 536 | |
| 537 | return $result; |
| 538 | |
| 539 | } |
| 540 | |
| 541 | } |
| 542 | |
| 543 | public function getDatabaseSize() { |
| 544 | |
| 545 | global $wpdb; |
| 546 | $prefix = $wpdb->prefix; |
| 547 | |
| 548 | $sql = "SELECT SUM(DATA_LENGTH + INDEX_LENGTH) AS `bytes` FROM information_schema.TABLES WHERE TABLE_SCHEMA = %s;"; |
| 549 | $sql = $wpdb->prepare($sql, array(DB_NAME)); |
| 550 | |
| 551 | $result = $wpdb->get_results($sql); |
| 552 | return intval($result[0]->bytes); |
| 553 | |
| 554 | } |
| 555 | |
| 556 | public function dirSize() { |
| 557 | |
| 558 | // Folder |
| 559 | $f = $this->post['folder']; |
| 560 | |
| 561 | // Bytes |
| 562 | $bytes = 0; |
| 563 | $excludedBytes = 0; |
| 564 | |
| 565 | $emptyVar = [ 'this_is_empty_array' ]; |
| 566 | $allowed = [ 'plugins', 'uploads', 'themes', 'contents_others', 'wordpress' ]; |
| 567 | |
| 568 | if (in_array($f, $allowed)) { |
| 569 | |
| 570 | // Get list of staging sites for exclusion rules |
| 571 | require_once BMI_INCLUDES . '/staging/controller.php'; |
| 572 | $staging = new Staging('..ajax..'); |
| 573 | $stagingSites = $staging->getStagingSites(true); |
| 574 | |
| 575 | $files = $this->scanFilesForBackup($emptyVar, $stagingSites, $f); |
| 576 | $files = $this->parseFilesForBackup($files, $emptyVar, false, true); |
| 577 | |
| 578 | $bytes = $this->total_size_for_backup; |
| 579 | $excludedBytes = $this->total_excluded_size_for_backup; |
| 580 | set_transient('bmi_latest_size_' . $f, $bytes); |
| 581 | } elseif ($f == 'database') { |
| 582 | |
| 583 | $bytes = $this->getDatabaseSize(); |
| 584 | set_transient('bmi_latest_size_' . $f, $bytes); |
| 585 | } |
| 586 | |
| 587 | return [ 'bytes' => $bytes, 'excluded' => $excludedBytes, 'readable' => BMP::humanSize($bytes) ]; |
| 588 | |
| 589 | } |
| 590 | |
| 591 | public function backupErrorHandler() { |
| 592 | set_error_handler(function ($errno, $errstr, $errfile, $errline) { |
| 593 | |
| 594 | if (BMI_DEBUG) { |
| 595 | error_log('BMI DEBUG ENABLED, HERE IS THE COMPLETE REPORT (ERROR HANDLER #1):'); |
| 596 | error_log(print_r($errno, true)); |
| 597 | error_log(print_r($errstr, true)); |
| 598 | error_log(print_r($errfile, true)); |
| 599 | error_log(print_r($errline, true)); |
| 600 | } |
| 601 | |
| 602 | if (strpos($errstr, 'deprecated') !== false) return; |
| 603 | if (strpos($errstr, 'php_uname') !== false) return; |
| 604 | if (strpos($errfile, 'backup-backup') === false && strpos($errfile, 'backup-migration') === false && $errno != E_ERROR) return; |
| 605 | |
| 606 | if ($errno != E_ERROR && $errno != E_CORE_ERROR && $errno != E_COMPILE_ERROR && $errno != E_USER_ERROR && $errno != E_RECOVERABLE_ERROR) { |
| 607 | |
| 608 | if (strpos($errfile, 'backup-backup') === false && strpos($errfile, 'backup-migration') === false) return; |
| 609 | Logger::error(__('There was an error before request shutdown (but it was not logged to restore log)', 'backup-backup')); |
| 610 | Logger::error(__('Error message: ', 'backup-backup') . $errstr); |
| 611 | Logger::error(__('Error file/line: ', 'backup-backup') . $errfile . '|' . $errline); |
| 612 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#01' . '|' . $errno); |
| 613 | return; |
| 614 | |
| 615 | } |
| 616 | if (strpos($errfile, 'backup-backup') === false) { |
| 617 | Logger::error(__("Restore process was not aborted because this error is not related to Backup Migration.", 'backup-backup')); |
| 618 | $this->zip_progress->log(__("There was an error not related to Backup Migration Plugin.", 'backup-backup'), 'warn'); |
| 619 | $this->zip_progress->log(__("Message: ", 'backup-backup') . $errstr, 'warn'); |
| 620 | $this->zip_progress->log(__("Backup will not be aborted because of this.", 'backup-backup'), 'warn'); |
| 621 | return; |
| 622 | } |
| 623 | if (strpos($errstr, 'unlink(') !== false) { |
| 624 | Logger::error(__("Restore process was not aborted due to this error.", 'backup-backup')); |
| 625 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#02' . '|' . $errno); |
| 626 | Logger::error($errstr); |
| 627 | return; |
| 628 | } |
| 629 | if (strpos($errfile, 'pclzip') !== false) { |
| 630 | Logger::error(__("Restore process was not aborted due to this error.", 'backup-backup')); |
| 631 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#03' . '|' . $errno); |
| 632 | Logger::error($errstr); |
| 633 | return; |
| 634 | } |
| 635 | if (strpos($errstr, 'rename(') !== false) { |
| 636 | Logger::error(__("Restore process was not aborted due to this error.", 'backup-backup')); |
| 637 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#04' . '|' . $errno); |
| 638 | Logger::error($errstr); |
| 639 | $this->zip_progress->log(__("Cannot move: ", 'backup-backup') . $errstr, 'warn'); |
| 640 | return; |
| 641 | } |
| 642 | |
| 643 | $this->zip_progress->log(__("There was an error during backup:", 'backup-backup'), 'error'); |
| 644 | $this->zip_progress->log(__("Message: ", 'backup-backup') . $errstr, 'error'); |
| 645 | $this->zip_progress->log(__("File/line: ", 'backup-backup') . $errfile . '|' . $errline, 'error'); |
| 646 | $this->zip_progress->log(__('Unfortunately we had to remove the backup (if partly created).', 'backup-backup'), 'error'); |
| 647 | |
| 648 | $backup = $GLOBALS['bmi_current_backup_name']; |
| 649 | $backup_path = BMI_BACKUPS . DIRECTORY_SEPARATOR . $backup; |
| 650 | if (file_exists($backup_path)) @unlink($backup_path); |
| 651 | if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running'); |
| 652 | if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.abort')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.abort'); |
| 653 | |
| 654 | $this->zip_progress->log(__("Aborting backup...", 'backup-backup'), 'step'); |
| 655 | $this->zip_progress->log(__("#002", 'backup-backup'), 'end-code'); |
| 656 | $this->zip_progress->end(); |
| 657 | |
| 658 | $GLOBALS['bmi_error_handled'] = true; |
| 659 | BMP::res(['status' => 'error', 'error' => $errstr]); |
| 660 | exit; |
| 661 | |
| 662 | }, E_ALL); |
| 663 | } |
| 664 | |
| 665 | public function migrationErrorHandler() { |
| 666 | set_exception_handler(function ($exception) { |
| 667 | if (BMI_DEBUG) { |
| 668 | error_log('BMI DEBUG ENABLED, HERE IS THE COMPLETE REPORT (EXCEPTION HANDLER #1):'); |
| 669 | error_log(print_r($exception, true)); |
| 670 | } |
| 671 | |
| 672 | $this->migration_progress->log(__("Restore exception: ", 'backup-backup') . $exception->getMessage(), 'warn'); |
| 673 | Logger::log(__("Restore exception: ", 'backup-backup') . $exception->getMessage()); |
| 674 | }); |
| 675 | } |
| 676 | |
| 677 | public function migrationExceptionHandler() { |
| 678 | set_error_handler(function ($errno, $errstr, $errfile, $errline) { |
| 679 | |
| 680 | if (BMI_DEBUG) { |
| 681 | error_log('BMI DEBUG ENABLED, HERE IS THE COMPLETE REPORT (ERROR HANDLER #2):'); |
| 682 | error_log(print_r($errno, true)); |
| 683 | error_log(print_r($errstr, true)); |
| 684 | error_log(print_r($errfile, true)); |
| 685 | error_log(print_r($errline, true)); |
| 686 | } |
| 687 | |
| 688 | if (strpos($errstr, 'deprecated') !== false) return; |
| 689 | if (strpos($errstr, 'php_uname') !== false) return; |
| 690 | if (strpos($errfile, 'backup-backup') === false && strpos($errfile, 'backup-migration' && $errno != E_ERROR) === false) return; |
| 691 | |
| 692 | if ($errno == E_NOTICE) return; |
| 693 | if ($errno != E_ERROR && $errno != E_CORE_ERROR && $errno != E_COMPILE_ERROR && $errno != E_USER_ERROR && $errno != E_RECOVERABLE_ERROR) { |
| 694 | if (strpos($errfile, 'backup-backup') === false && strpos($errfile, 'backup-migration') === false) return; |
| 695 | Logger::error(__('There was an error before request shutdown (but it was not logged to restore log)', 'backup-backup')); |
| 696 | Logger::error(__('Error message: ', 'backup-backup') . $errstr); |
| 697 | Logger::error(__('Error file/line: ', 'backup-backup') . $errfile . '|' . $errline); |
| 698 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#05' . '|' . $errno); |
| 699 | return; |
| 700 | } |
| 701 | |
| 702 | Logger::error(__("There was an error/warning during restore process:", 'backup-backup')); |
| 703 | Logger::error(__("Message: ", 'backup-backup') . $errstr); |
| 704 | Logger::error(__("File/line: ", 'backup-backup') . $errfile . '|' . $errline); |
| 705 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#06' . '|' . $errno); |
| 706 | |
| 707 | if (strpos($errfile, 'backup-backup') === false) { |
| 708 | Logger::error(__("Restore process was not aborted because this error is not related to Backup Migration.", 'backup-backup')); |
| 709 | $this->migration_progress->log(__("There was an error not related to Backup Migration Plugin.", 'backup-backup'), 'warn'); |
| 710 | $this->migration_progress->log(__("Message: ", 'backup-backup') . $errstr, 'warn'); |
| 711 | $this->migration_progress->log(__("Backup will not be aborted because of this.", 'backup-backup'), 'warn'); |
| 712 | return; |
| 713 | } |
| 714 | if (strpos($errstr, 'unlink(') !== false) { |
| 715 | Logger::error(__("Restore process was not aborted due to this error.", 'backup-backup')); |
| 716 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#07' . '|' . $errno); |
| 717 | Logger::error($errstr); |
| 718 | return; |
| 719 | } |
| 720 | if (strpos($errfile, 'pclzip') !== false) { |
| 721 | Logger::error(__("Restore process was not aborted due to this error.", 'backup-backup')); |
| 722 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#08' . '|' . $errno); |
| 723 | Logger::error($errstr); |
| 724 | return; |
| 725 | } |
| 726 | if (strpos($errstr, 'rename(') !== false) { |
| 727 | Logger::error(__("Restore process was not aborted due to this error.", 'backup-backup')); |
| 728 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#09' . '|' . $errno); |
| 729 | Logger::error($errstr); |
| 730 | $this->migration_progress->log(__("Cannot move: ", 'backup-backup') . $errstr, 'warn'); |
| 731 | return; |
| 732 | } |
| 733 | |
| 734 | $this->migration_progress->log(__("There was an error during restore process:", 'backup-backup'), 'error'); |
| 735 | $this->migration_progress->log(__("Message: ", 'backup-backup') . $errstr, 'error'); |
| 736 | $this->migration_progress->log(__("File/line: ", 'backup-backup') . $errfile . '|' . $errline, 'error'); |
| 737 | |
| 738 | if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock'); |
| 739 | |
| 740 | $this->migration_progress->log(__("Aborting restore process...", 'backup-backup'), 'step'); |
| 741 | |
| 742 | if (isset($GLOBALS['bmi_current_tmp_restore']) && !empty($GLOBALS['bmi_current_tmp_restore'])) { |
| 743 | |
| 744 | $this->migration_progress->log(__("Cleaning up exported files...", 'backup-backup'), 'step'); |
| 745 | |
| 746 | $tmp_unique = $GLOBALS['bmi_current_tmp_restore_unique']; |
| 747 | $dir = $GLOBALS['bmi_current_tmp_restore']; |
| 748 | $it = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); |
| 749 | $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); |
| 750 | |
| 751 | $this->migration_progress->log(__('Removing ', 'backup-backup') . iterator_count($files) . __(' files', 'backup-backup'), 'INFO'); |
| 752 | foreach ($files as $file) { |
| 753 | if ($file->isDir()) { |
| 754 | @rmdir($file->getRealPath()); |
| 755 | } else { |
| 756 | @unlink($file->getRealPath()); |
| 757 | } |
| 758 | } |
| 759 | |
| 760 | @rmdir($dir); |
| 761 | |
| 762 | $config_file = untrailingslashit(ABSPATH) . DIRECTORY_SEPARATOR . 'wp-config.' . $tmp_unique . '.php'; |
| 763 | if (file_exists($config_file)) @unlink($config_file); |
| 764 | |
| 765 | } |
| 766 | |
| 767 | $this->migration_progress->log(__("#002", 'backup-backup'), 'end-code'); |
| 768 | $this->migration_progress->end(); |
| 769 | |
| 770 | $GLOBALS['bmi_error_handled'] = true; |
| 771 | BMP::res(['status' => 'error', 'error' => $errstr]); |
| 772 | exit; |
| 773 | |
| 774 | }, E_ALL); |
| 775 | } |
| 776 | |
| 777 | public function backupExceptionHandler() { |
| 778 | set_exception_handler(function ($exception) { |
| 779 | if (BMI_DEBUG) { |
| 780 | error_log('BMI DEBUG ENABLED, HERE IS THE COMPLETE REPORT (EXCEPTION HANDLER #2):'); |
| 781 | error_log(print_r($exception, true)); |
| 782 | } |
| 783 | |
| 784 | $this->zip_progress->log(__("Exception: ", 'backup-backup') . $exception->getMessage(), 'warn'); |
| 785 | Logger::log(__("Exception: ", 'backup-backup') . $exception->getMessage()); |
| 786 | }); |
| 787 | } |
| 788 | |
| 789 | public function resetLatestLogs() { |
| 790 | |
| 791 | // Restore htaccess |
| 792 | BMP::revertLitespeed(); |
| 793 | BMP::fixLitespeed(); |
| 794 | |
| 795 | // Check time if not bugged |
| 796 | if (file_exists(BMI_BACKUPS . '/.running') && (time() - filemtime(BMI_BACKUPS . '/.running')) > 65) { |
| 797 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 798 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 799 | } |
| 800 | |
| 801 | // Check if backup is not in progress |
| 802 | if (file_exists(BMI_BACKUPS . '/.running')) { |
| 803 | return ['status' => 'msg', 'why' => __('Backup process already running, please wait till it complete.', 'backup-backup'), 'level' => 'warning']; |
| 804 | } |
| 805 | |
| 806 | // Remove too large logs |
| 807 | $completeLogsPath = BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'complete_logs.log'; |
| 808 | if (file_exists($completeLogsPath) && (filesize($completeLogsPath) / 1024 / 1024) >= 3) { |
| 809 | @unlink($completeLogsPath); |
| 810 | } |
| 811 | |
| 812 | $backgroundLogsPath = BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'background-errors.log'; |
| 813 | if (file_exists($backgroundLogsPath) && (filesize($backgroundLogsPath) / 1024 / 1024) >= 3) { |
| 814 | @unlink($backgroundLogsPath); |
| 815 | } |
| 816 | |
| 817 | @touch($completeLogsPath); |
| 818 | @touch($backgroundLogsPath); |
| 819 | |
| 820 | // Require logs |
| 821 | require_once BMI_INCLUDES . '/progress/zip.php'; |
| 822 | require_once BMI_INCLUDES . '/progress/migration.php'; |
| 823 | require_once BMI_INCLUDES . '/progress/staging.php'; |
| 824 | |
| 825 | // Write initial |
| 826 | $zip_progress = new Progress('', 0); |
| 827 | $zip_progress->start(); |
| 828 | $zip_progress->log(__("Initializing backup...", 'backup-backup'), 'step'); |
| 829 | $zip_progress->progress('0/100'); |
| 830 | $zip_progress->end(); |
| 831 | |
| 832 | // Write initial |
| 833 | $migration = new MigrationProgress(false); |
| 834 | $migration->start(); |
| 835 | $migration->log(__('Initializing restore process', 'backup-backup'), 'STEP'); |
| 836 | $migration->progress('0'); |
| 837 | $migration->end(); |
| 838 | |
| 839 | // Write initial |
| 840 | $staging = new StagingProgress(false); |
| 841 | $staging->start(); |
| 842 | $staging->log(__('Preparing creation of staging site...', 'backup-backup'), 'STEP'); |
| 843 | $staging->progress('0'); |
| 844 | $staging->end(); |
| 845 | |
| 846 | // Return done |
| 847 | return ['status' => 'success']; |
| 848 | } |
| 849 | |
| 850 | public function makeBackupName() { |
| 851 | $name = Dashboard\bmi_get_config('BACKUP:NAME'); |
| 852 | |
| 853 | $urlparts = parse_url(home_url()); |
| 854 | $domain = str_replace('.', '-', sanitize_text_field($urlparts['host'])); |
| 855 | |
| 856 | $hash = BMP::randomString(16); |
| 857 | $name = str_replace('%domain', $domain, $name); |
| 858 | $name = str_replace('%hash', $hash, $name); |
| 859 | $name = str_replace('%Y', date('Y'), $name); |
| 860 | $name = str_replace('%M', date('M'), $name); |
| 861 | $name = str_replace('%D', date('D'), $name); |
| 862 | $name = str_replace('%d', date('d'), $name); |
| 863 | $name = str_replace('%j', date('j'), $name); |
| 864 | $name = str_replace('%m', date('m'), $name); |
| 865 | $name = str_replace('%n', date('n'), $name); |
| 866 | $name = str_replace('%Y', date('Y'), $name); |
| 867 | $name = str_replace('%y', date('y'), $name); |
| 868 | $name = str_replace('%a', date('a'), $name); |
| 869 | $name = str_replace('%A', date('A'), $name); |
| 870 | $name = str_replace('%B', date('B'), $name); |
| 871 | $name = str_replace('%g', date('g'), $name); |
| 872 | $name = str_replace('%G', date('G'), $name); |
| 873 | $name = str_replace('%h', date('h'), $name); |
| 874 | $name = str_replace('%H', date('H'), $name); |
| 875 | $name = str_replace('%i', date('i'), $name); |
| 876 | $name = str_replace('%s', date('s'), $name); |
| 877 | $name = str_replace('%s', date('s'), $name); |
| 878 | |
| 879 | $i = 2; |
| 880 | $tmpname = $name; |
| 881 | |
| 882 | while (file_exists($tmpname . '.zip')) { |
| 883 | $tmpname = $name . '_' . $i; |
| 884 | $i++; |
| 885 | } |
| 886 | |
| 887 | $name = $tmpname . '.zip'; |
| 888 | |
| 889 | if (has_filter('bmip_backup_name')) { |
| 890 | $name = apply_filters('bmip_backup_name', $name); |
| 891 | } |
| 892 | |
| 893 | $GLOBALS['bmi_current_backup_name'] = $name; |
| 894 | return $name; |
| 895 | } |
| 896 | |
| 897 | public function fixUnameFunction() { |
| 898 | $file = trailingslashit(ABSPATH) . 'wp-admin/includes/class-pclzip.php'; |
| 899 | $backup = trailingslashit(ABSPATH) . 'wp-admin/includes/class-pclzip-backup.php'; |
| 900 | |
| 901 | // Make backup |
| 902 | if (!file_exists($backup)) { |
| 903 | @copy($file, $backup); |
| 904 | } |
| 905 | |
| 906 | // Replace deprecated php_uname function which is mostly disabled and cause errors |
| 907 | $replace = file_get_contents($file); |
| 908 | $replace = str_replace('php_uname()', '(DIRECTORY_SEPARATOR === "/" ? "linux" : "windows")', $replace); |
| 909 | file_put_contents($file, $replace); |
| 910 | return ['status' => 'success']; |
| 911 | } |
| 912 | |
| 913 | public function revertUnameProcess() { |
| 914 | $file = trailingslashit(ABSPATH) . 'wp-admin/includes/class-pclzip.php'; |
| 915 | $backup = trailingslashit(ABSPATH) . 'wp-admin/includes/class-pclzip-backup.php'; |
| 916 | if (file_exists($backup)) { |
| 917 | if (file_exists($file)) @unlink($file); |
| 918 | @copy($backup, $file); |
| 919 | } |
| 920 | return ['status' => 'success']; |
| 921 | } |
| 922 | |
| 923 | public function isFunctionEnabled($func) { |
| 924 | $disabled = explode(',', ini_get('disable_functions')); |
| 925 | $isDisabled = in_array($func, $disabled); |
| 926 | if (!$isDisabled && function_exists($func)) return true; |
| 927 | else return false; |
| 928 | } |
| 929 | |
| 930 | public function prepareAndMakeBackup($cron = false) { |
| 931 | |
| 932 | global $wp_version; |
| 933 | |
| 934 | $triggerLock = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.last_triggered'; |
| 935 | |
| 936 | if ($this->isFunctionEnabled('ini_set')) { |
| 937 | ini_set('display_errors', 1); |
| 938 | ini_set('error_reporting', E_ALL); |
| 939 | ini_set('log_errors', 1); |
| 940 | ini_set('error_log', BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'complete_logs.log'); |
| 941 | } |
| 942 | |
| 943 | // Double check for .space_check file |
| 944 | if (file_exists(BMI_BACKUPS . '/.space_check')) @unlink(BMI_BACKUPS . '/.space_check'); |
| 945 | |
| 946 | // Require File Scanner |
| 947 | require_once BMI_INCLUDES . '/progress/zip.php'; |
| 948 | require_once BMI_INCLUDES . '/check/checker.php'; |
| 949 | |
| 950 | // CLI Handler |
| 951 | $cliHandler = trailingslashit(sanitize_text_field(BMI_INCLUDES)) . 'cli-handler.php'; |
| 952 | |
| 953 | // Backup name |
| 954 | if (defined('BMI_CLI_ARGUMENT') && !empty(BMI_CLI_ARGUMENT)) { |
| 955 | $name = BMI_CLI_ARGUMENT; |
| 956 | } else { |
| 957 | $name = $this->makeBackupName(); |
| 958 | } |
| 959 | |
| 960 | // Progress & Logs |
| 961 | $cliRunning = (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) ? true : false; |
| 962 | $shouldResetLogs = !$cliRunning; |
| 963 | if (defined('BMI_DOING_SCHEDULED_BACKUP_VIA_CLI')) { |
| 964 | $cron = true; |
| 965 | $shouldResetLogs = true; |
| 966 | } |
| 967 | |
| 968 | $clearEndCodes = false; |
| 969 | if (isset($this->post['preserveLogs']) && ($this->post['preserveLogs'] == 'true' || $this->post['preserveLogs'] === true)) { |
| 970 | $shouldResetLogs = false; |
| 971 | $clearEndCodes = true; |
| 972 | } |
| 973 | |
| 974 | $zip_progress = new Progress($name, 100, 0, $cron, $shouldResetLogs, $clearEndCodes); |
| 975 | $zip_progress->start(); |
| 976 | |
| 977 | // PHP CLI Check |
| 978 | $isCLI = false; |
| 979 | $cli_lock = BMI_BACKUPS . '/.backup_lock_cli'; |
| 980 | $cli_lock_end = BMI_BACKUPS . '/.backup_lock_cli_end'; |
| 981 | $cli_failed_lock = BMI_BACKUPS . '/.backup_lock_cli_failed'; |
| 982 | |
| 983 | if (!defined('BMI_USING_CLI_FUNCTIONALITY') || BMI_USING_CLI_FUNCTIONALITY === false) { |
| 984 | |
| 985 | $cli_result = $this->checkIfPHPCliExist($zip_progress); |
| 986 | $functionNormal = apply_filters('bmi_function_normal', BMI_FUNCTION_NORMAL); |
| 987 | if ($cli_result !== false && $functionNormal === true) { |
| 988 | |
| 989 | $res = null; |
| 990 | if (defined('BMI_DOING_SCHEDULED_BACKUP')) { |
| 991 | @exec(BMI_CLI_EXECUTABLE . ' -f "' . $cliHandler . '" bmi_backup_cron ' . $name . ' > /dev/null &', $res); |
| 992 | } else { |
| 993 | @exec(BMI_CLI_EXECUTABLE . ' -f "' . $cliHandler . '" bmi_backup ' . $name . ' > /dev/null &', $res); |
| 994 | } |
| 995 | $res = implode("\n", $res); |
| 996 | |
| 997 | sleep(3); |
| 998 | |
| 999 | if (file_exists($cli_lock_end) && (time() - filemtime($cli_lock_end)) < 10) { |
| 1000 | |
| 1001 | if (file_exists($cli_lock_end)) @unlink($cli_lock_end); |
| 1002 | if (file_exists($triggerLock)) @unlink($triggerLock); |
| 1003 | return ['status' => 'success', 'filename' => $name]; |
| 1004 | exit; |
| 1005 | |
| 1006 | } |
| 1007 | |
| 1008 | if (!file_exists($cli_lock) || (time() - filemtime($cli_lock)) > 10) { |
| 1009 | |
| 1010 | if (!file_exists(BMI_BACKUPS . '/.abort') || (time() - filemtime(BMI_BACKUPS . '/.abort')) > 10) { |
| 1011 | |
| 1012 | $zip_progress->log(__("Something went wrong in PHP CLI process, backup will be continued with legacy methods.", 'backup-backup'), 'warn'); |
| 1013 | if (file_exists($cli_lock)) @unlink($cli_lock); |
| 1014 | define('BMI_CLI_FAILED', true); |
| 1015 | touch($cli_failed_lock); |
| 1016 | |
| 1017 | } else { |
| 1018 | |
| 1019 | $zip_progress->log(__("Backup will not be continued due to manual abort by user.", 'backup-backup'), 'warn'); |
| 1020 | if (file_exists($cli_lock)) @unlink($cli_lock); |
| 1021 | if (file_exists($triggerLock)) @unlink($triggerLock); |
| 1022 | return ['status' => 'msg', 'why' => __('Backup process aborted.', 'backup-backup'), 'level' => 'info']; |
| 1023 | |
| 1024 | } |
| 1025 | |
| 1026 | } else { |
| 1027 | |
| 1028 | return ['status' => 'background', 'filename' => $name]; |
| 1029 | |
| 1030 | } |
| 1031 | |
| 1032 | } else { |
| 1033 | |
| 1034 | if ($functionNormal !== true) { |
| 1035 | $zip_progress->log(__("PHP CLI will not run due to user settings in plugin other options.", 'backup-backup'), 'warn'); |
| 1036 | } else { |
| 1037 | $zip_progress->log(__("PHP CLI file cannot be executed due to unknown reason.", 'backup-backup'), 'warn'); |
| 1038 | } |
| 1039 | |
| 1040 | } |
| 1041 | |
| 1042 | } else { |
| 1043 | |
| 1044 | if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) { |
| 1045 | |
| 1046 | if (file_exists($cli_failed_lock) && (time() - filemtime($cli_failed_lock)) < 10) { |
| 1047 | exit; |
| 1048 | } |
| 1049 | |
| 1050 | $isCLI = true; |
| 1051 | $zip_progress->log(__("Backup via PHP CLI initialized successfully.", 'backup-backup'), 'success'); |
| 1052 | touch($cli_lock); |
| 1053 | |
| 1054 | } |
| 1055 | |
| 1056 | } |
| 1057 | |
| 1058 | // Just in case (e.g. syntax error, we can close the file correctly) |
| 1059 | $GLOBALS['bmi_backup_progress'] = $zip_progress; |
| 1060 | |
| 1061 | // Logs |
| 1062 | $zip_progress->log(__("Initializing backup...", 'backup-backup'), 'step'); |
| 1063 | $zip_progress->log((__("Backup & Migration version: ", 'backup-backup') . BMI_VERSION), 'info'); |
| 1064 | $zip_progress->log(__("Site which will be backed up: ", 'backup-backup') . site_url(), 'info'); |
| 1065 | $zip_progress->log(__("PHP Version: ", 'backup-backup') . PHP_VERSION, 'info'); |
| 1066 | $zip_progress->log(__("WP Version: ", 'backup-backup') . $wp_version, 'info'); |
| 1067 | $zip_progress->log(__("MySQL Version: ", 'backup-backup') . $GLOBALS['wpdb']->db_version(), 'info'); |
| 1068 | $maxAllowedPackets = $GLOBALS['wpdb']->get_results("SHOW VARIABLES LIKE 'max_allowed_packet';"); |
| 1069 | if (sizeof($maxAllowedPackets) > 0) { |
| 1070 | $zip_progress->log(__("MySQL Max Length: ", 'backup-backup') . $maxAllowedPackets[0]->Value, 'info'); |
| 1071 | } else { |
| 1072 | $zip_progress->log(__("MySQL Max Length: ", 'backup-backup') . 'Unknown', 'info'); |
| 1073 | } |
| 1074 | if (isset($_SERVER['SERVER_SOFTWARE']) && !empty($_SERVER['SERVER_SOFTWARE'])) { |
| 1075 | $zip_progress->log(__("Web server: ", 'backup-backup') . $_SERVER['SERVER_SOFTWARE'], 'info'); |
| 1076 | } else { |
| 1077 | $zip_progress->log(__("Web server: Not available", 'backup-backup'), 'info'); |
| 1078 | } |
| 1079 | $zip_progress->log(__("Max execution time (in seconds): ", 'backup-backup') . @ini_get('max_execution_time'), 'info'); |
| 1080 | |
| 1081 | $zip_progress->log(__("Memory limit (server): ", 'backup-backup') . @ini_get('memory_limit'), 'info'); |
| 1082 | if (defined('WP_MEMORY_LIMIT')) { |
| 1083 | $zip_progress->log(__("Memory limit (wp-config): ", 'backup-backup') . WP_MEMORY_LIMIT, 'info'); |
| 1084 | } |
| 1085 | if (defined('WP_MAX_MEMORY_LIMIT')) { |
| 1086 | $zip_progress->log(__("Memory limit (wp-config admin): ", 'backup-backup') . WP_MAX_MEMORY_LIMIT, 'info'); |
| 1087 | } |
| 1088 | |
| 1089 | if (defined('BMI_DB_MAX_ROWS_PER_QUERY')) { |
| 1090 | $zip_progress->log(__('Max rows per query (this site): ', 'backup-backup') . BMI_DB_MAX_ROWS_PER_QUERY, 'info'); |
| 1091 | } |
| 1092 | |
| 1093 | $zip_progress->log(__("Checking if backup dir is writable...", 'backup-backup'), 'info'); |
| 1094 | |
| 1095 | if (defined('BMI_DOING_SCHEDULED_BACKUP')) { |
| 1096 | $zip_progress->log(__("This process was initialized due to scheduled backup configuration...", 'backup-backup'), 'info'); |
| 1097 | $zip_progress->log(__("Backup will be unlocked by default as it is not manual backup...", 'backup-backup'), 'info'); |
| 1098 | $zip_progress->log('This log is triggered by SCHEDULED BACKUP and its part of automatic backup creation', 'verbose'); |
| 1099 | } |
| 1100 | |
| 1101 | if (defined('BMI_BACKUP_PRO')) { |
| 1102 | if (BMI_BACKUP_PRO == 1) { |
| 1103 | $zip_progress->log(__("Premium plugin is enabled and activated", 'backup-backup'), 'info'); |
| 1104 | } else { |
| 1105 | $zip_progress->log(__("Premium version is enabled but not active, using free plugin.", 'backup-backup'), 'warn'); |
| 1106 | } |
| 1107 | } |
| 1108 | |
| 1109 | // Error handler |
| 1110 | $zip_progress->log(__("Initializing custom error handler", 'backup-backup'), 'info'); |
| 1111 | $this->zip_progress = &$zip_progress; |
| 1112 | $this->backupErrorHandler(); |
| 1113 | $this->backupExceptionHandler(); |
| 1114 | |
| 1115 | // Checker |
| 1116 | $checker = new Checker($zip_progress); |
| 1117 | |
| 1118 | if (!is_writable(dirname(BMI_BACKUPS))) { |
| 1119 | |
| 1120 | // Abort backup |
| 1121 | $zip_progress->log(__("Backup directory is not writable...", 'backup-backup'), 'error'); |
| 1122 | $zip_progress->log(__("Path: ", 'backup-backup') . BMI_BACKUPS, 'error'); |
| 1123 | |
| 1124 | // Close backup |
| 1125 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1126 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1127 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1128 | |
| 1129 | // Log and close log |
| 1130 | $zip_progress->log('#002', 'END-CODE'); |
| 1131 | $zip_progress->end(); |
| 1132 | |
| 1133 | if ($isCLI === true) touch($cli_lock_end); |
| 1134 | $this->actionsAfterProcess(); |
| 1135 | |
| 1136 | // Return error |
| 1137 | if (file_exists($triggerLock)) @unlink($triggerLock); |
| 1138 | if ($cron == true) return ['status' => 'success']; |
| 1139 | else return ['status' => 'error']; |
| 1140 | } else { |
| 1141 | $zip_progress->log(__("Yup it is writable...", 'backup-backup'), 'success'); |
| 1142 | } |
| 1143 | |
| 1144 | if (!file_exists(BMI_BACKUPS)) @mkdir(BMI_BACKUPS, true); |
| 1145 | |
| 1146 | // Get list of staging sites for exclusion rules |
| 1147 | require_once BMI_INCLUDES . '/staging/controller.php'; |
| 1148 | $staging = new Staging('..ajax..'); |
| 1149 | $stagingSites = $staging->getStagingSites(true); |
| 1150 | |
| 1151 | // Get file names (huge list mostly) |
| 1152 | if (has_filter('bmip_backup_files')) { |
| 1153 | $files = apply_filters('bmip_backup_files', []); |
| 1154 | } else if ($fgwp = Dashboard\bmi_get_config('BACKUP:FILES') == 'true') { |
| 1155 | $zip_progress->log(__("Scanning files...", 'backup-backup'), 'step'); |
| 1156 | $files = $this->scanFilesForBackup($zip_progress, $stagingSites); |
| 1157 | $files = $this->parseFilesForBackup($files, $zip_progress, $cron); |
| 1158 | } else { |
| 1159 | $zip_progress->log(__("Omitting files (due to settings)...", 'backup-backup'), 'warn'); |
| 1160 | $files = []; |
| 1161 | } |
| 1162 | |
| 1163 | $zip_progress->log(str_replace('%s', $this->total_excluded_size_for_backup, __("Total size of excluded files: %s bytes", 'backup-backup')), 'info'); |
| 1164 | $zip_progress->log("Total size of excluded files (bytes): " . $this->total_excluded_size_for_backup, 'verbose'); |
| 1165 | |
| 1166 | // Check if there is enough space |
| 1167 | $bytes = intval($this->total_size_for_backup * 1.4); |
| 1168 | update_option('bmi_required_space', $bytes); |
| 1169 | $zip_progress->log(__("Checking free space, reserving...", 'backup-backup'), 'step'); |
| 1170 | if ($this->total_size_for_backup_in_mb >= BMI_REV * 1000 && get_option('bmip_last', false) != '1') { |
| 1171 | |
| 1172 | // Abort backup |
| 1173 | $zip_progress->log(__("Aborting backup...", 'backup-backup'), 'step'); |
| 1174 | $zip_progress->log(str_replace('%s', BMI_REV, __("Site weights more than %s GB.", 'backup-backup')), 'error'); |
| 1175 | if (isset($this->post['f'])) { |
| 1176 | $zip_progress->log('Function: ' . print_r($this->post['f'], true), 'verbose'); |
| 1177 | } |
| 1178 | |
| 1179 | if (isset($_SERVER)) { |
| 1180 | $zip_progress->log('REQUEST_URI: ' . $_SERVER['REQUEST_URI'], 'verbose'); |
| 1181 | $zip_progress->log('REQUEST_METHOD: ' . $_SERVER['REQUEST_METHOD'], 'verbose'); |
| 1182 | } |
| 1183 | |
| 1184 | if (!empty($this->post)) { |
| 1185 | $zip_progress->log(print_r($this->post, true), 'verbose'); |
| 1186 | } |
| 1187 | |
| 1188 | // Close backup |
| 1189 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1190 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1191 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1192 | |
| 1193 | // Log and close log |
| 1194 | $zip_progress->log('#100', 'END-CODE'); |
| 1195 | $zip_progress->end(); |
| 1196 | |
| 1197 | if ($isCLI === true) touch($cli_lock_end); |
| 1198 | $this->actionsAfterProcess(); |
| 1199 | |
| 1200 | // Return error |
| 1201 | if (file_exists($triggerLock)) @unlink($triggerLock); |
| 1202 | return ['status' => 'error', 'bfs' => true]; |
| 1203 | } |
| 1204 | |
| 1205 | $isSpaceCheckDisabled = Dashboard\bmi_get_config('OTHER:BACKUP:SPACE:CHECKING'); |
| 1206 | |
| 1207 | if ($isSpaceCheckDisabled) { |
| 1208 | |
| 1209 | $zip_progress->log(__("Free space checking is disabled by user in settings...", 'backup-backup'), 'warn'); |
| 1210 | $zip_progress->log(__("Backup will continue, trusting there is enough space...", 'backup-backup'), 'warn'); |
| 1211 | |
| 1212 | } else { |
| 1213 | |
| 1214 | if (!$checker->check_free_space($bytes)) { |
| 1215 | |
| 1216 | // Abort backup |
| 1217 | $zip_progress->log(__("Aborting backup...", 'backup-backup'), 'step'); |
| 1218 | $zip_progress->log(__("There is no space for that backup, checked: ", 'backup-backup') . ($bytes) . __(" bytes", 'backup-backup'), 'error'); |
| 1219 | $zip_progress->log('not_enough_space', 'verbose'); |
| 1220 | |
| 1221 | // Close backup |
| 1222 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1223 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1224 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1225 | |
| 1226 | // Log and close log |
| 1227 | $zip_progress->log('#002', 'END-CODE'); |
| 1228 | $zip_progress->end(); |
| 1229 | |
| 1230 | if ($isCLI === true) touch($cli_lock_end); |
| 1231 | $this->actionsAfterProcess(); |
| 1232 | |
| 1233 | // Return error |
| 1234 | if (file_exists($triggerLock)) @unlink($triggerLock); |
| 1235 | if ($cron == true) return ['status' => 'msg', 'why' => __('There is not enough space for backup, please free up ' . $bytes / 1024 / 1024 . ' MB of space.', 'backup-backup')]; |
| 1236 | else return ['status' => 'error']; |
| 1237 | } else { |
| 1238 | $zip_progress->log(__("Confirmed, there is more than enough space, checked: ", 'backup-backup') . ($bytes) . __(" bytes", 'backup-backup'), 'success'); |
| 1239 | $zip_progress->bytes = $this->total_size_for_backup; |
| 1240 | } |
| 1241 | |
| 1242 | } |
| 1243 | |
| 1244 | if (Dashboard\bmi_get_config('BACKUP:DATABASE') != 'true') { |
| 1245 | |
| 1246 | // $zip_progress->log(__("Database won't be backed-up due to user settings, omitting...", 'backup-backup'), 'info'); |
| 1247 | // Commented as message will be shown in database backup module |
| 1248 | |
| 1249 | } |
| 1250 | |
| 1251 | // Log and set files length |
| 1252 | $zip_progress->log(__("Scanning done - found ", 'backup-backup') . sizeof($files) . __(" files...", 'backup-backup'), 'info'); |
| 1253 | $zip_progress->files = sizeof($files); |
| 1254 | |
| 1255 | // Make Backup |
| 1256 | $zip_progress->log(__("Backup initialized...", 'backup-backup'), 'success'); |
| 1257 | $zip_progress->log(__("Initializing archiving system...", 'backup-backup'), 'step'); |
| 1258 | |
| 1259 | $resultCreateBackup = $this->createBackup($files, ABSPATH, $name, $zip_progress, $cron, $isCLI); |
| 1260 | do_action('bmp_created_backup',$resultCreateBackup); |
| 1261 | return $resultCreateBackup; |
| 1262 | |
| 1263 | $bckpres = $this->createBackup($files, ABSPATH, $name, $zip_progress, $cron, $isCLI); |
| 1264 | if (file_exists($triggerLock)) @unlink($triggerLock); |
| 1265 | if ($cron == true) return ['status' => 'success']; |
| 1266 | else return $bckpres; |
| 1267 | } |
| 1268 | |
| 1269 | public function fixLitespeed() { |
| 1270 | BMP::fixLitespeed(); |
| 1271 | |
| 1272 | return ['status' => 'success']; |
| 1273 | } |
| 1274 | |
| 1275 | public function revertLitespeed() { |
| 1276 | BMP::revertLitespeed(); |
| 1277 | |
| 1278 | return ['status' => 'success']; |
| 1279 | } |
| 1280 | |
| 1281 | public function createBackup($files, $base, $name, &$zip_progress, $cron = false, $isCLI = false) { |
| 1282 | |
| 1283 | // Require File Zipper |
| 1284 | require_once BMI_INCLUDES . '/zipper/zipping.php'; |
| 1285 | |
| 1286 | // CLI locks |
| 1287 | $cli_lock = BMI_BACKUPS . '/.backup_lock_cli'; |
| 1288 | $cli_lock_end = BMI_BACKUPS . '/.backup_lock_cli_end'; |
| 1289 | $cli_failed_lock = BMI_BACKUPS . '/.backup_lock_cli_failed'; |
| 1290 | |
| 1291 | // Backup name |
| 1292 | $backup_path = BMI_BACKUPS . '/' . $name; |
| 1293 | |
| 1294 | // Check time if not bugged |
| 1295 | if (file_exists(BMI_BACKUPS . '/.running') && (time() - filemtime(BMI_BACKUPS . '/.running')) > 65) { |
| 1296 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1297 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1298 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1299 | if ($isCLI === true && file_exists($cli_lock_end)) @unlink($cli_lock_end); |
| 1300 | } |
| 1301 | |
| 1302 | if ($isCLI === true) { |
| 1303 | if (file_exists($cli_failed_lock) && (time() - filemtime($cli_failed_lock)) < 10) { |
| 1304 | exit; |
| 1305 | } |
| 1306 | } |
| 1307 | |
| 1308 | // Mark as in progress |
| 1309 | if (!file_exists(BMI_BACKUPS . '/.running')) { |
| 1310 | touch(BMI_BACKUPS . '/.running'); |
| 1311 | file_put_contents(BMI_BACKUPS . '/.running', $name); |
| 1312 | if ($isCLI === true) touch($cli_lock); |
| 1313 | } else { |
| 1314 | return ['status' => 'msg', 'why' => __('Backup process already running, please wait till it complete.', 'backup-backup'), 'level' => 'warning']; |
| 1315 | } |
| 1316 | |
| 1317 | // Initialized |
| 1318 | $zip_progress->log(__("Archive system initialized...", 'backup-backup'), 'success'); |
| 1319 | |
| 1320 | // Make ZIP |
| 1321 | $zipper = new Zipper(); |
| 1322 | $zippy = $zipper->makeZIP($files, $backup_path, $name, $zip_progress, $cron); |
| 1323 | if (!$zippy) { |
| 1324 | |
| 1325 | // Make sure it's open |
| 1326 | $zip_progress->start(); |
| 1327 | |
| 1328 | // Abort backup |
| 1329 | $zip_progress->log(__("Aborting backup...", 'backup-backup'), 'step'); |
| 1330 | |
| 1331 | // Close backup |
| 1332 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1333 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1334 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1335 | |
| 1336 | // Log and close log |
| 1337 | $zip_progress->log('#002', 'END-CODE'); |
| 1338 | $zip_progress->end(); |
| 1339 | |
| 1340 | if ($isCLI === true) touch($cli_lock_end); |
| 1341 | |
| 1342 | // Return error |
| 1343 | if (file_exists($backup_path)) @unlink($backup_path); |
| 1344 | |
| 1345 | $this->actionsAfterProcess(); |
| 1346 | return ['status' => 'error']; |
| 1347 | } |
| 1348 | |
| 1349 | if (isset($zippy['status']) && $zippy['status'] == 'background') { |
| 1350 | return; |
| 1351 | } |
| 1352 | |
| 1353 | // Backup aborted |
| 1354 | if (file_exists(BMI_BACKUPS . '/.abort')) { |
| 1355 | |
| 1356 | // Make sure it's open |
| 1357 | $zip_progress->start(); |
| 1358 | |
| 1359 | if (file_exists($backup_path)) @unlink($backup_path); |
| 1360 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1361 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1362 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1363 | |
| 1364 | // Log and close log |
| 1365 | $zip_progress->log(__("Backup process aborted.", 'backup-backup'), 'warn'); |
| 1366 | $zip_progress->log('#002', 'END-CODE'); |
| 1367 | $zip_progress->end(); |
| 1368 | |
| 1369 | if ($isCLI === true) touch($cli_lock_end); |
| 1370 | Logger::log(__("Backup process aborted.", 'backup-backup')); |
| 1371 | |
| 1372 | $this->actionsAfterProcess(); |
| 1373 | return ['status' => 'msg', 'why' => __('Backup process aborted.', 'backup-backup'), 'level' => 'info']; |
| 1374 | } |
| 1375 | |
| 1376 | if (!file_exists($backup_path) && !$cron) { |
| 1377 | |
| 1378 | // Make sure it's open |
| 1379 | $zip_progress->start(); |
| 1380 | |
| 1381 | // Abort backup |
| 1382 | $zip_progress->log(__("Aborting backup...", 'backup-backup'), 'step'); |
| 1383 | $zip_progress->log(__("There is no backup file...", 'backup-backup'), 'error'); |
| 1384 | $zip_progress->log(__("We could not find backup file when it already should be here.", 'backup-backup'), 'error'); |
| 1385 | $zip_progress->log(__("This error may be related to missing space. (filled during backup)", 'backup-backup'), 'error'); |
| 1386 | $zip_progress->log(__("Path: ", 'backup-backup') . $backup_path, 'error'); |
| 1387 | |
| 1388 | // Close backup |
| 1389 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1390 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1391 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1392 | |
| 1393 | // Log and close log |
| 1394 | $zip_progress->log('#002', 'END-CODE'); |
| 1395 | $zip_progress->end(); |
| 1396 | |
| 1397 | if ($isCLI === true) touch($cli_lock_end); |
| 1398 | $this->actionsAfterProcess(); |
| 1399 | |
| 1400 | // Return error |
| 1401 | if ($cron == true) return ['status' => 'success']; |
| 1402 | else return ['status' => 'error']; |
| 1403 | } |
| 1404 | |
| 1405 | // End zip log |
| 1406 | $zip_progress->log(__("New backup created and its name is: ", 'backup-backup') . $name, 'success'); |
| 1407 | $zip_progress->log('#001', 'END-CODE'); |
| 1408 | $zip_progress->end(); |
| 1409 | |
| 1410 | if ($isCLI === true) touch($cli_lock_end); |
| 1411 | |
| 1412 | // Unlink progress |
| 1413 | if (file_exists(BMI_BACKUPS . '/.running')) @unlink(BMI_BACKUPS . '/.running'); |
| 1414 | if (file_exists(BMI_BACKUPS . '/.abort')) @unlink(BMI_BACKUPS . '/.abort'); |
| 1415 | if ($isCLI === true && file_exists($cli_lock)) @unlink($cli_lock); |
| 1416 | |
| 1417 | // Return |
| 1418 | Logger::log(__("New backup created and its name is: ", 'backup-backup') . $name); |
| 1419 | |
| 1420 | $GLOBALS['bmi_error_handled'] = true; |
| 1421 | |
| 1422 | $this->actionsAfterProcess(true); |
| 1423 | return ['status' => 'success', 'filename' => $name, 'root' => plugin_dir_url(BMI_ROOT_FILE)]; |
| 1424 | |
| 1425 | } |
| 1426 | |
| 1427 | public function continueRestoreProcess() { |
| 1428 | |
| 1429 | // BMI_RESTORE_SECRET |
| 1430 | |
| 1431 | } |
| 1432 | |
| 1433 | public function getBackupsList() { |
| 1434 | |
| 1435 | // Require File Scanner |
| 1436 | require_once BMI_INCLUDES . '/scanner/backups.php'; |
| 1437 | |
| 1438 | // Get backups |
| 1439 | $backups = new Backups(); |
| 1440 | $manifests = $backups->getAvailableBackups(); |
| 1441 | |
| 1442 | // Return files |
| 1443 | return ['status' => 'success', 'backups' => $manifests]; |
| 1444 | } |
| 1445 | |
| 1446 | public function sendTestMail() { |
| 1447 | |
| 1448 | $email = Dashboard\bmi_get_config('OTHER:EMAIL') != false ? Dashboard\bmi_get_config('OTHER:EMAIL') : get_bloginfo('admin_email'); |
| 1449 | $subject = __('Backup Migration – Example email', 'backup-backup'); |
| 1450 | $message = __('This is a test email sent by the Backup Migration plugin via Troubleshooting options!', 'backup-backup'); |
| 1451 | |
| 1452 | try { |
| 1453 | |
| 1454 | if (wp_mail($email, $subject, $message)) return [ 'status' => 'success' ]; |
| 1455 | else return ['status' => 'error']; |
| 1456 | |
| 1457 | } catch (\Exception $e) { |
| 1458 | |
| 1459 | return ['status' => 'error']; |
| 1460 | |
| 1461 | } catch (\Throwable $e) { |
| 1462 | |
| 1463 | return ['status' => 'error']; |
| 1464 | |
| 1465 | } |
| 1466 | |
| 1467 | } |
| 1468 | |
| 1469 | public function restoreBackup() { |
| 1470 | |
| 1471 | global $wp_version; |
| 1472 | |
| 1473 | if ($this->isFunctionEnabled('ini_set')) { |
| 1474 | ini_set('display_errors', 1); |
| 1475 | ini_set('error_reporting', E_ALL); |
| 1476 | ini_set('log_errors', 1); |
| 1477 | ini_set('error_log', BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'complete_logs.log'); |
| 1478 | } |
| 1479 | |
| 1480 | |
| 1481 | // Double check for .space_check file |
| 1482 | if (file_exists(BMI_BACKUPS . '/.space_check')) @unlink(BMI_BACKUPS . '/.space_check'); |
| 1483 | |
| 1484 | // Require File Scanner |
| 1485 | require_once BMI_INCLUDES . '/zipper/zipping.php'; |
| 1486 | require_once BMI_INCLUDES . '/extracter/extract.php'; |
| 1487 | require_once BMI_INCLUDES . '/progress/migration.php'; |
| 1488 | require_once BMI_INCLUDES . '/check/checker.php'; |
| 1489 | |
| 1490 | // Make AutoLogin possible |
| 1491 | $ip = '127.0.0.1'; |
| 1492 | if (isset($_SERVER['HTTP_CLIENT_IP'])) { |
| 1493 | $ip = $_SERVER['HTTP_CLIENT_IP']; |
| 1494 | } else { |
| 1495 | if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { |
| 1496 | $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; |
| 1497 | } |
| 1498 | if ($ip === false) { |
| 1499 | if (isset($_SERVER['REMOTE_ADDR'])) $ip = $_SERVER['REMOTE_ADDR']; |
| 1500 | } |
| 1501 | } |
| 1502 | $autoLoginMD = time() . '_' . $ip . '_' . '4u70L051n'; |
| 1503 | |
| 1504 | // Progress & lock file |
| 1505 | $lock = BMI_BACKUPS . '/.migration_lock'; |
| 1506 | $lock_cli = BMI_BACKUPS . '/.migration_lock_cli'; |
| 1507 | $autologin_file = BMI_BACKUPS . '/.autologin'; |
| 1508 | $lock_cli_end = BMI_BACKUPS . '/.migration_lock_ended'; |
| 1509 | $progress = BMI_BACKUPS . '/latest_migration_progress.log'; |
| 1510 | $cli_last_download = BMI_BACKUPS . '/.cli_download_last'; |
| 1511 | |
| 1512 | $ignoreRunCheck = ((isset($this->post['ignoreRunning']) && $this->post['ignoreRunning'] == 'true') ? true : false); |
| 1513 | $isCLIRunning = (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) ? true : false; |
| 1514 | if ($isCLIRunning) $ignoreRunCheck = false; |
| 1515 | |
| 1516 | if (file_exists($lock) && (time() - filemtime($lock)) < 65 && !$ignoreRunCheck) { |
| 1517 | return ['status' => 'msg', 'why' => __('The restore process is currently running, please wait till it end or once the lock file expire.', 'backup-backup'), 'level' => 'warning']; |
| 1518 | } |
| 1519 | |
| 1520 | // Check if download was via CLI |
| 1521 | if ($this->post['file'] == '.cli_download' && file_exists($cli_last_download)) { |
| 1522 | $this->post['file'] = file_get_contents($cli_last_download); |
| 1523 | if (file_exists($cli_last_download)) @unlink($cli_last_download); |
| 1524 | } |
| 1525 | |
| 1526 | // Logs |
| 1527 | $migration = new MigrationProgress($this->post['remote']); |
| 1528 | $migration->start(); |
| 1529 | |
| 1530 | if ($ignoreRunCheck) { |
| 1531 | |
| 1532 | $migration->mute(); |
| 1533 | |
| 1534 | } |
| 1535 | |
| 1536 | // Check PHP CLI |
| 1537 | if ((!defined('BMI_USING_CLI_FUNCTIONALITY') || BMI_USING_CLI_FUNCTIONALITY === false) && (!defined('BMI_CLI_REQUEST') || BMI_CLI_REQUEST === false)) { |
| 1538 | |
| 1539 | $cli_result = $this->checkIfPHPCliExist($migration); |
| 1540 | |
| 1541 | if ($cli_result !== false) { |
| 1542 | |
| 1543 | $cliHandler = trailingslashit(sanitize_text_field(BMI_INCLUDES)) . 'cli-handler.php'; |
| 1544 | $backupName = esc_attr($this->post['file']); |
| 1545 | $remoteType = 'false'; |
| 1546 | if ($this->post['remote'] == 'true' || $this->post['remote'] === true) $remoteType = 'true'; |
| 1547 | if (file_exists($lock_cli_end)) @unlink($lock_cli_end); |
| 1548 | |
| 1549 | $res = null; |
| 1550 | @exec(BMI_CLI_EXECUTABLE . ' -f "' . $cliHandler . '" bmi_restore ' . $backupName . ' ' . $remoteType . ' > /dev/null &', $res); |
| 1551 | $res = implode("\n", $res); |
| 1552 | |
| 1553 | sleep(3); |
| 1554 | |
| 1555 | if (file_exists($lock_cli_end) && (time() - filemtime($lock_cli_end)) < 10) { |
| 1556 | |
| 1557 | // Put autologin |
| 1558 | file_put_contents($autologin_file, $autoLoginMD); |
| 1559 | touch($autologin_file); |
| 1560 | |
| 1561 | return ['status' => 'cli', 'login' => explode('_', $autoLoginMD)[0], 'url' => site_url()]; |
| 1562 | exit; |
| 1563 | |
| 1564 | } |
| 1565 | |
| 1566 | if (!file_exists($lock_cli) || (time() - filemtime($lock_cli)) > 10) { |
| 1567 | |
| 1568 | $progressFile = null; |
| 1569 | $migration->log(__('No response from PHP CLI - plugin will try to recover the migration with traditional restore.', 'backup-backup'), 'warn'); |
| 1570 | if (file_exists($lock_cli)) @unlink($lock_cli); |
| 1571 | |
| 1572 | } else { |
| 1573 | |
| 1574 | $progressFile = null; |
| 1575 | |
| 1576 | // $migration->log(__('PHP CLI responded with correct code - we will continue via PHP CLI.', 'backup-backup'), 'info'); |
| 1577 | // $migration->end(); |
| 1578 | |
| 1579 | // Put autologin |
| 1580 | file_put_contents($autologin_file, $autoLoginMD); |
| 1581 | touch($autologin_file); |
| 1582 | |
| 1583 | return ['status' => 'cli', 'login' => explode('_', $autoLoginMD)[0], 'url' => site_url()]; |
| 1584 | exit; |
| 1585 | |
| 1586 | } |
| 1587 | |
| 1588 | } else { |
| 1589 | |
| 1590 | if (file_exists($lock_cli)) @unlink($lock_cli); |
| 1591 | |
| 1592 | } |
| 1593 | |
| 1594 | } else { |
| 1595 | |
| 1596 | if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) { |
| 1597 | $migration->log(__('PHP CLI: Restore process initialized, restoring...', 'backup-backup'), 'success'); |
| 1598 | touch($lock_cli); |
| 1599 | } else { |
| 1600 | $migration->log(__('Restore process initialized, restoring (non-cli mode)...', 'backup-backup'), 'success'); |
| 1601 | } |
| 1602 | |
| 1603 | } |
| 1604 | |
| 1605 | // Just in case (e.g. syntax error, we can close the file correctly) |
| 1606 | $GLOBALS['bmi_migration_progress'] = $migration; |
| 1607 | |
| 1608 | // Checker |
| 1609 | $checker = new Checker($migration); |
| 1610 | $zipper = new Zipper(); |
| 1611 | |
| 1612 | // Handle remote |
| 1613 | if ($this->post['file']) { |
| 1614 | $migration->log(__('Restore process responded', 'backup-backup'), 'SUCCESS'); |
| 1615 | } |
| 1616 | |
| 1617 | // Make lock file |
| 1618 | $migration->log(__('Locking migration process', 'backup-backup'), 'SUCCESS'); |
| 1619 | touch($lock); |
| 1620 | |
| 1621 | // Initializing |
| 1622 | $migration->log(__('Initializing restore process', 'backup-backup'), 'STEP'); |
| 1623 | $migration->log((__("Backup & Migration version: ", 'backup-backup') . BMI_VERSION), 'info'); |
| 1624 | |
| 1625 | // Error handler |
| 1626 | $migration->log(__("Initializing custom error handler", 'backup-backup'), 'info'); |
| 1627 | |
| 1628 | // Error handler |
| 1629 | $this->migration_progress = &$migration; |
| 1630 | $this->migrationErrorHandler(); |
| 1631 | $this->migrationExceptionHandler(); |
| 1632 | |
| 1633 | $homeURL = site_url(); |
| 1634 | if (strlen($homeURL) <= 8) $homeURL = home_url(); |
| 1635 | if (defined('WP_SITEURL') && strlen(WP_SITEURL) > 8) $homeURL = WP_SITEURL; |
| 1636 | |
| 1637 | $migration->log(__("Site which will be restored: ", 'backup-backup') . $homeURL, 'info'); |
| 1638 | $migration->log(__("PHP Version: ", 'backup-backup') . PHP_VERSION, 'info'); |
| 1639 | $migration->log(__("WP Version: ", 'backup-backup') . $wp_version, 'info'); |
| 1640 | $migration->log(__("MySQL Version: ", 'backup-backup') . $GLOBALS['wpdb']->db_version(), 'info'); |
| 1641 | $maxAllowedPackets = $GLOBALS['wpdb']->get_results("SHOW VARIABLES LIKE 'max_allowed_packet';"); |
| 1642 | if (sizeof($maxAllowedPackets) > 0) { |
| 1643 | $migration->log(__("MySQL Max Length: ", 'backup-backup') . $maxAllowedPackets[0]->Value, 'info'); |
| 1644 | } else { |
| 1645 | $migration->log(__("MySQL Max Length: ", 'backup-backup') . 'Unknown', 'info'); |
| 1646 | } |
| 1647 | if (isset($_SERVER['SERVER_SOFTWARE']) && !defined('BMI_USING_CLI_FUNCTIONALITY')) { |
| 1648 | $migration->log(__("Web server: ", 'backup-backup') . $_SERVER['SERVER_SOFTWARE'], 'info'); |
| 1649 | } else { |
| 1650 | $migration->log(__("Web server: Not available", 'backup-backup'), 'info'); |
| 1651 | } |
| 1652 | $migration->log(__("Max execution time (in seconds): ", 'backup-backup') . @ini_get('max_execution_time'), 'info'); |
| 1653 | |
| 1654 | $migration->log(__("Memory limit (server): ", 'backup-backup') . @ini_get('memory_limit'), 'info'); |
| 1655 | if (defined('WP_MEMORY_LIMIT')) { |
| 1656 | $migration->log(__("Memory limit (wp-config): ", 'backup-backup') . WP_MEMORY_LIMIT, 'info'); |
| 1657 | } |
| 1658 | if (defined('WP_MAX_MEMORY_LIMIT')) { |
| 1659 | $migration->log(__("Memory limit (wp-config admin): ", 'backup-backup') . WP_MAX_MEMORY_LIMIT, 'info'); |
| 1660 | } |
| 1661 | |
| 1662 | if (defined('BMI_BACKUP_PRO')) { |
| 1663 | if (BMI_BACKUP_PRO == 1) { |
| 1664 | $migration->log(__("Premium plugin is enabled and activated", 'backup-backup'), 'info'); |
| 1665 | } else { |
| 1666 | $migration->log(__("Premium version is enabled but not active, using free plugin.", 'backup-backup'), 'warn'); |
| 1667 | } |
| 1668 | } |
| 1669 | |
| 1670 | $migration->log(__("Restore process initialized successfully.", 'backup-backup'), 'success'); |
| 1671 | |
| 1672 | // Check file size |
| 1673 | $zippath = BMP::fixSlashes(BMI_BACKUPS) . DIRECTORY_SEPARATOR . $this->post['file']; |
| 1674 | if (!$ignoreRunCheck) { |
| 1675 | |
| 1676 | $manifest = $zipper->getZipFileContent($zippath, 'bmi_backup_manifest.json'); |
| 1677 | $migration->log(__('Free space checking...', 'backup-backup'), 'STEP'); |
| 1678 | $migration->log(__('Checking if there is enough amount of free space', 'backup-backup'), 'INFO'); |
| 1679 | |
| 1680 | $isSpaceCheckDisabled = Dashboard\bmi_get_config('OTHER:BACKUP:SPACE:CHECKING'); |
| 1681 | |
| 1682 | if ($isSpaceCheckDisabled) { |
| 1683 | $migration->log(__("Free space checking is disabled by user in settings...", 'backup-backup'), 'warn'); |
| 1684 | $migration->log(__("Restore will continue, trusting there is enough space...", 'backup-backup'), 'warn'); |
| 1685 | } else { |
| 1686 | if ($manifest) { |
| 1687 | if (isset($manifest->bytes) && $manifest->bytes) { |
| 1688 | $bytes = intval($manifest->bytes * 1.4); |
| 1689 | update_option('bmi_required_space', $bytes); |
| 1690 | if (file_exists(BMI_TMP . DIRECTORY_SEPARATOR . 'restore_parts.json')) { |
| 1691 | $restoreParts = json_decode(file_get_contents(BMI_TMP . DIRECTORY_SEPARATOR . 'restore_parts.json')); |
| 1692 | if (isset($restoreParts->size) && $restoreParts->size && $restoreParts->backupName == $this->post['file']) { |
| 1693 | $bytes = intval($restoreParts->size * 1.4); |
| 1694 | } |
| 1695 | } |
| 1696 | if (!$checker->check_free_space($bytes)) { |
| 1697 | $migration->log(__('Cannot start migration process', 'backup-backup'), 'ERROR'); |
| 1698 | $migration->log(__('Error: There is not enough space on the server, checked: ' . ($bytes) . ' bytes.', 'backup-backup'), 'ERROR'); |
| 1699 | $migration->log("not_enough_space", 'verbose'); |
| 1700 | $migration->log(__('Aborting...', 'backup-backup'), 'ERROR'); |
| 1701 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 1702 | |
| 1703 | if (file_exists($lock)) @unlink($lock); |
| 1704 | $migration->log('#004', 'END-CODE'); |
| 1705 | $migration->end(); |
| 1706 | |
| 1707 | if ($isCLIRunning == true) touch($lock_cli_end); |
| 1708 | $this->actionsAfterProcess(false, 'migration'); |
| 1709 | |
| 1710 | return ['status' => 'error']; |
| 1711 | } else { |
| 1712 | $migration->log(__('Confirmed, there is enough space on the device, checked: ' . ($bytes) . ' bytes.', 'backup-backup'), 'SUCCESS'); |
| 1713 | } |
| 1714 | } |
| 1715 | } else { |
| 1716 | $migration->log(__('Cannot start migration process', 'backup-backup'), 'ERROR'); |
| 1717 | $migration->log(__('Error: File may not exist, check file name and if it still exist', 'backup-backup'), 'ERROR'); |
| 1718 | $migration->log(__('Error: Could not find manifest in backup, file may be broken', 'backup-backup'), 'ERROR'); |
| 1719 | $migration->log(__('Error: Btw. because of this I also cannot check free space', 'backup-backup'), 'ERROR'); |
| 1720 | $migration->log(__('Used path: ', 'backup-backup') . $zippath, 'ERROR'); |
| 1721 | $migration->log(__('Aborting...', 'backup-backup'), 'ERROR'); |
| 1722 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 1723 | |
| 1724 | if (file_exists($lock)) @unlink($lock); |
| 1725 | $migration->log('#003', 'END-CODE'); |
| 1726 | $migration->end(); |
| 1727 | |
| 1728 | if ($isCLIRunning == true) touch($lock_cli_end); |
| 1729 | $this->actionsAfterProcess(false, 'migration'); |
| 1730 | |
| 1731 | return ['status' => 'error']; |
| 1732 | } |
| 1733 | } |
| 1734 | |
| 1735 | } |
| 1736 | |
| 1737 | if ($ignoreRunCheck) { |
| 1738 | |
| 1739 | $migration->unmute(); |
| 1740 | |
| 1741 | } |
| 1742 | |
| 1743 | // New extracter |
| 1744 | $theTmpName = ((isset($this->post['tmpname'])) ? $this->post['tmpname'] : false); |
| 1745 | $options = ((isset($this->post['options'])) ? $this->post['options'] : []); |
| 1746 | $extracter = new Extracter($this->post['file'], $migration, $theTmpName, $isCLIRunning, $options); |
| 1747 | |
| 1748 | // Extract |
| 1749 | $theSecret = ((isset($this->post['secret'])) ? $this->post['secret'] : null); |
| 1750 | $isFine = $extracter->extractTo($theSecret); |
| 1751 | if (!$isFine) { |
| 1752 | $migration->log(__('Aborting...', 'backup-backup'), 'ERROR'); |
| 1753 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 1754 | |
| 1755 | if (file_exists($lock)) @unlink($lock); |
| 1756 | $migration->log('#002', 'END-CODE'); |
| 1757 | $migration->end(); |
| 1758 | |
| 1759 | if ($isCLIRunning == true) touch($lock_cli_end); |
| 1760 | $this->actionsAfterProcess(false, 'migration'); |
| 1761 | |
| 1762 | return ['status' => 'error']; |
| 1763 | } |
| 1764 | |
| 1765 | $migration->progress('100'); |
| 1766 | $migration->log(__('Restore process completed', 'backup-backup'), 'SUCCESS'); |
| 1767 | $migration->log(__('Finalizing restored files', 'backup-backup'), 'STEP'); |
| 1768 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 1769 | if (file_exists($lock)) @unlink($lock); |
| 1770 | |
| 1771 | $migration->log('#001', 'END-CODE'); |
| 1772 | $migration->end(); |
| 1773 | |
| 1774 | if ($isCLIRunning == true) touch($lock_cli_end); |
| 1775 | |
| 1776 | // Put autologin |
| 1777 | file_put_contents($autologin_file, $autoLoginMD); |
| 1778 | touch($autologin_file); |
| 1779 | |
| 1780 | $this->actionsAfterProcess(true, 'migration'); |
| 1781 | return ['status' => 'success', 'login' => explode('_', $autoLoginMD)[0], 'url' => site_url()]; |
| 1782 | } |
| 1783 | |
| 1784 | public function isRunningBackup() { |
| 1785 | $this->lock_cli = BMI_BACKUPS . '/.backup_cli_lock'; |
| 1786 | |
| 1787 | // Ongoing processes |
| 1788 | $ongoing = get_option('bmip_to_be_uploaded', [ |
| 1789 | 'current_upload' => [], |
| 1790 | 'queue' => [], |
| 1791 | 'failed' => [] |
| 1792 | ]); |
| 1793 | |
| 1794 | // Backup CLI running |
| 1795 | if (file_exists($this->lock_cli) && (time() - filemtime($this->lock_cli)) <= 3600) { |
| 1796 | return ['status' => 'msg', 'why' => __('Backup process already running, please wait till it complete.', 'backup-backup'), 'level' => 'warning', 'ongoing' => $ongoing]; |
| 1797 | } |
| 1798 | |
| 1799 | if (file_exists(BMI_BACKUPS . '/.running') && (time() - filemtime(BMI_BACKUPS . '/.running')) <= 65) { |
| 1800 | return ['status' => 'msg', 'why' => __('Backup process already running, please wait till it complete.', 'backup-backup'), 'level' => 'warning', 'ongoing' => $ongoing]; |
| 1801 | } else { |
| 1802 | return ['status' => 'success', 'ongoing' => $ongoing]; |
| 1803 | } |
| 1804 | } |
| 1805 | |
| 1806 | public function stopBackup() { |
| 1807 | if (!file_exists(BMI_BACKUPS . '/.running')) { |
| 1808 | return ['status' => 'msg', 'why' => __('Backup process completed or is not running.', 'backup-backup'), 'level' => 'info']; |
| 1809 | } else { |
| 1810 | if (!file_exists(BMI_BACKUPS . '/.abort')) { |
| 1811 | touch(BMI_BACKUPS . '/.abort'); |
| 1812 | } |
| 1813 | |
| 1814 | return ['status' => 'success']; |
| 1815 | } |
| 1816 | } |
| 1817 | |
| 1818 | public function isMigrationLocked() { |
| 1819 | $lock = BMI_BACKUPS . '/.migration_lock'; |
| 1820 | $lock_cli = BMI_BACKUPS . '/.migration_lock_cli'; |
| 1821 | $lock_cli_end = BMI_BACKUPS . '/.migration_lock_ended'; |
| 1822 | |
| 1823 | if ((file_exists($lock) && (time() - filemtime($lock)) < 65) || (file_exists($lock_cli) && (time() - filemtime($lock_cli)) < 7200)) { |
| 1824 | |
| 1825 | return ['status' => 'msg', 'why' => __('Restore process is currently running, please wait till it complete.', 'backup-backup'), 'level' => 'warning']; |
| 1826 | |
| 1827 | } else { |
| 1828 | |
| 1829 | require_once BMI_INCLUDES . '/progress/migration.php'; |
| 1830 | $progress = BMI_BACKUPS . '/latest_migration_progress.log'; |
| 1831 | $shouldClearLogs = true; |
| 1832 | |
| 1833 | if (isset($this->post['clearLogs']) && $this->post['clearLogs'] == 'false') { |
| 1834 | $shouldClearLogs = false; |
| 1835 | } |
| 1836 | |
| 1837 | if ($shouldClearLogs === true) { |
| 1838 | if (file_exists($lock_cli_end) && (time() - filemtime($lock_cli_end)) > 10) { |
| 1839 | |
| 1840 | $migration = new MigrationProgress(); |
| 1841 | $migration->start(); |
| 1842 | $migration->log(__('Initializing restore process...', 'backup-backup'), 'STEP'); |
| 1843 | $migration->end(); |
| 1844 | |
| 1845 | file_put_contents($progress, '0'); |
| 1846 | |
| 1847 | } |
| 1848 | } |
| 1849 | |
| 1850 | return ['status' => 'success']; |
| 1851 | |
| 1852 | } |
| 1853 | } |
| 1854 | |
| 1855 | public function downloadFile($url, $dest, $progress, $lock, &$logger) { |
| 1856 | $current_percentage = 0; |
| 1857 | $previous_logged = 0; |
| 1858 | $fp = fopen($dest, 'w+'); |
| 1859 | |
| 1860 | $progressfile = $progress; |
| 1861 | $lockfile = $lock; |
| 1862 | |
| 1863 | $ch = curl_init(rawurldecode($url)); |
| 1864 | curl_setopt($ch, CURLOPT_TIMEOUT, 0); |
| 1865 | |
| 1866 | curl_setopt($ch, CURLOPT_FILE, $fp); |
| 1867 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); |
| 1868 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); |
| 1869 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); |
| 1870 | |
| 1871 | curl_setopt($ch, CURLOPT_NOPROGRESS, false); |
| 1872 | curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function ($resource, $download_size, $downloaded) use (&$current_percentage, &$lockfile, &$progressfile, &$logger, &$previous_logged) { |
| 1873 | if ($download_size > 0) { |
| 1874 | $new_percentage = intval(($downloaded / $download_size) * 100); |
| 1875 | |
| 1876 | if (intval($current_percentage) != intval($new_percentage)) { |
| 1877 | $logger->progress($new_percentage); |
| 1878 | |
| 1879 | if ($current_percentage == 0 || ($new_percentage % 5 == 0) || $new_percentage > 99) { |
| 1880 | $logger->log(sprintf(__('Download progress: %s/%s MB (%s%%)', 'backup-backup'), round($downloaded / 1024 / 1024), round($download_size / 1024 / 1024), $new_percentage), 'INFO'); |
| 1881 | $previous_logged = $new_percentage; |
| 1882 | } |
| 1883 | |
| 1884 | $current_percentage = $new_percentage; |
| 1885 | } |
| 1886 | } |
| 1887 | }); |
| 1888 | |
| 1889 | curl_exec($ch); |
| 1890 | $this->lastCurlCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
| 1891 | |
| 1892 | $error_msg = false; |
| 1893 | if (curl_errno($ch)) { |
| 1894 | $error_msg = curl_error($ch); |
| 1895 | $curl_errno = curl_errno($ch); |
| 1896 | $fileSize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); |
| 1897 | |
| 1898 | if ($curl_errno == CURLE_WRITE_ERROR || $curl_errno == CURLE_ABORTED_BY_CALLBACK) { |
| 1899 | $requiredSpace = $fileSize * 1.1; // Add 10% buffer |
| 1900 | update_option('bmi_required_space', $requiredSpace); |
| 1901 | $logger->log('not_enough_space', 'verbose'); |
| 1902 | } |
| 1903 | } |
| 1904 | |
| 1905 | curl_close($ch); |
| 1906 | fclose($fp); |
| 1907 | |
| 1908 | if ($error_msg) { |
| 1909 | return $error_msg; |
| 1910 | } else { |
| 1911 | return false; |
| 1912 | } |
| 1913 | } |
| 1914 | |
| 1915 | public function handleQuickMigration() { |
| 1916 | $lock = BMI_BACKUPS . '/.migration_lock'; |
| 1917 | if (file_exists($lock) && (time() - filemtime($lock)) < 65) { |
| 1918 | return ['status' => 'msg', 'why' => __('Download process is currently running, please wait till it complete.', 'backup-backup'), 'level' => 'warning']; |
| 1919 | } |
| 1920 | |
| 1921 | require_once BMI_INCLUDES . '/progress/migration.php'; |
| 1922 | require_once BMI_INCLUDES . '/zipper/zipping.php'; |
| 1923 | |
| 1924 | $migration = new MigrationProgress(true); |
| 1925 | $migration->start(); |
| 1926 | |
| 1927 | $tmp_name = 'backup_' . time() . '.zip.part'; |
| 1928 | |
| 1929 | // Missing URL parameter |
| 1930 | if (!isset($this->post['url'])) { |
| 1931 | wp_send_json_error(); |
| 1932 | } |
| 1933 | |
| 1934 | if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true && defined('BMI_CLI_ARGUMENT')) { |
| 1935 | |
| 1936 | $url = BMI_CLI_ARGUMENT; |
| 1937 | |
| 1938 | } else { |
| 1939 | |
| 1940 | $url = $this->post['url']; |
| 1941 | $startRestoreProcess = isset($this->post['startRestoreProcess']) ? $this->post['startRestoreProcess'] : 'true'; |
| 1942 | |
| 1943 | $url = trim(rawurlencode(sanitize_url($url, ['http', 'https']))); // or esc_attr but rawurlencode should be fine |
| 1944 | |
| 1945 | // Just why not { |
| 1946 | $url = str_replace(' ', '', $url); |
| 1947 | $url = str_replace('$', '%24', $url); |
| 1948 | $url = str_replace('`', '%60', $url); |
| 1949 | $url = str_replace('"', '%22', $url); |
| 1950 | $url = str_replace('\\', '%5C', $url); |
| 1951 | $url = str_replace('&', '&', $url); |
| 1952 | // } |
| 1953 | |
| 1954 | } |
| 1955 | |
| 1956 | $dest = BMI_BACKUPS . '/' . $tmp_name; |
| 1957 | $progress = BMI_BACKUPS . '/latest_migration_progress.log'; |
| 1958 | $cli_lock = BMI_BACKUPS . '/.cli_download_lock'; |
| 1959 | |
| 1960 | if (!defined('BMI_USING_CLI_FUNCTIONALITY') || BMI_USING_CLI_FUNCTIONALITY === false) { |
| 1961 | |
| 1962 | $cli_result = $this->checkIfPHPCliExist($migration); |
| 1963 | if ($cli_result !== false) { |
| 1964 | |
| 1965 | $cliHandler = trailingslashit(sanitize_text_field(BMI_INCLUDES)) . 'cli-handler.php'; |
| 1966 | |
| 1967 | $res = null; |
| 1968 | @exec(BMI_CLI_EXECUTABLE . ' -f "' . $cliHandler . '" bmi_quick_migration "' . $url . '" > /dev/null &', $res); |
| 1969 | $res = implode("\n", $res); |
| 1970 | |
| 1971 | sleep(2); |
| 1972 | if (file_exists($cli_lock) && (time() - filemtime($cli_lock)) < 10) { |
| 1973 | |
| 1974 | if (file_exists($cli_lock)) @unlink($cli_lock); |
| 1975 | return [ 'status' => 'cli_download' ]; |
| 1976 | exit; |
| 1977 | |
| 1978 | } |
| 1979 | |
| 1980 | } |
| 1981 | |
| 1982 | } else { |
| 1983 | |
| 1984 | $migration->log(__('Downloading via PHP CLI', 'backup-backup')); |
| 1985 | touch($cli_lock); |
| 1986 | |
| 1987 | } |
| 1988 | |
| 1989 | $migration->log((__("Backup & Migration version: ", 'backup-backup') . BMI_VERSION)); |
| 1990 | $migration->log(__('Creating lock file', 'backup-backup')); |
| 1991 | file_put_contents($lock, ''); |
| 1992 | $migration->log(__('Initializing download process', 'backup-backup'), 'STEP'); |
| 1993 | $downstart = microtime(true); |
| 1994 | $migration->log(__('Downloading initialized', 'backup-backup'), 'SUCCESS'); |
| 1995 | $migration->log(__('Downloading remote file...', 'backup-backup'), 'STEP'); |
| 1996 | $migration->log(__('Used URL: ', 'backup-backup') . rawurldecode($url), 'INFO'); |
| 1997 | $fileError = $this->downloadFile($url, $dest, $progress, $lock, $migration); |
| 1998 | $migration->log(__('Unlocking migration', 'backup-backup'), 'INFO'); |
| 1999 | if (file_exists($lock)) @unlink($lock); |
| 2000 | |
| 2001 | if ($fileError) { |
| 2002 | $migration->log(__('Removing downloaded file', 'backup-backup'), 'INFO'); |
| 2003 | if (file_exists($dest)) @unlink($dest); |
| 2004 | $migration->log(__('Download error', 'backup-backup'), 'ERROR'); |
| 2005 | |
| 2006 | if (strpos($fileError, 'Failed writing body') !== false) { |
| 2007 | $migration->log(__('Error: There is not enough space on the server', 'backup-backup'), 'ERROR'); |
| 2008 | $migration->log("not_enough_space", 'verbose'); |
| 2009 | } else { |
| 2010 | $migration->log(__('Error', 'backup-backup') . ': ' . $fileError, 'ERROR'); |
| 2011 | } |
| 2012 | |
| 2013 | $migration->log('#002', 'END-CODE'); |
| 2014 | return ['status' => 'error']; |
| 2015 | } else { |
| 2016 | $migration->log(__('Download completed (took: ', 'backup-backup') . (microtime(true) - $downstart) . 's)', 'SUCCESS'); |
| 2017 | $migration->log(__('Looking for backup manifest', 'backup-backup'), 'STEP'); |
| 2018 | $zipper = new Zipper(); |
| 2019 | $content = $zipper->getZipFileContent($dest, 'bmi_backup_manifest.json'); |
| 2020 | if ($content) { |
| 2021 | try { |
| 2022 | $i = 1; |
| 2023 | $name = $content->name; |
| 2024 | $prepared_name = $name; |
| 2025 | $migration->log(__('Manifest found remote name: ', 'backup-backup') . $name, 'SUCCESS'); |
| 2026 | |
| 2027 | while (file_exists(BMI_BACKUPS . '/' . $prepared_name)) { |
| 2028 | $prepared_name = substr($name, 0, -4) . '_' . $i . '.zip'; |
| 2029 | $i++; |
| 2030 | } |
| 2031 | |
| 2032 | rename($dest, BMI_BACKUPS . '/' . $prepared_name); |
| 2033 | $migration->log(__('Requesting restore process', 'backup-backup'), 'STEP'); |
| 2034 | $migration->progress(0); |
| 2035 | file_put_contents(BMI_BACKUPS . '/' . '.cli_download_last', $prepared_name); |
| 2036 | if ($startRestoreProcess == 'true'){ |
| 2037 | $migration->log('#205', 'END-CODE'); |
| 2038 | } else { |
| 2039 | $migration->log('#206', 'END-CODE'); |
| 2040 | } |
| 2041 | |
| 2042 | if (defined('BMI_USING_CLI_FUNCTIONALITY')) { |
| 2043 | $this->post['file'] = '.cli_download'; |
| 2044 | $this->post['remote'] = true; |
| 2045 | return $this->restoreBackup(); |
| 2046 | } else { |
| 2047 | return ['status' => 'success', 'name' => $prepared_name]; |
| 2048 | } |
| 2049 | } catch (\Exception $e) { |
| 2050 | $migration->log(__('Error: ', 'backup-backup') . $e, 'ERROR'); |
| 2051 | $migration->log(__('Removing downloaded file', 'backup-backup'), 'ERROR'); |
| 2052 | if (file_exists($dest)) @unlink($dest); |
| 2053 | |
| 2054 | $migration->log('#002', 'END-CODE'); |
| 2055 | return ['status' => 'error']; |
| 2056 | } catch (\Throwable $e) { |
| 2057 | $migration->log(__('Error: ', 'backup-backup') . $e, 'ERROR'); |
| 2058 | $migration->log(__('Removing downloaded file', 'backup-backup'), 'ERROR'); |
| 2059 | if (file_exists($dest)) @unlink($dest); |
| 2060 | |
| 2061 | $migration->log('#002', 'END-CODE'); |
| 2062 | return ['status' => 'error']; |
| 2063 | |
| 2064 | } |
| 2065 | |
| 2066 | } else { |
| 2067 | |
| 2068 | // $migration->log(__('Error during manifest check: ', 'backup-backup') . print_r($content, true), 'ERROR'); |
| 2069 | if ($this->lastCurlCode == '403') { |
| 2070 | $migration->log(__('Backup is not available to download (Error 403).', 'backup-backup'), 'ERROR'); |
| 2071 | $migration->log(__('It is restricted by remote server configuration.', 'backup-backup'), 'ERROR'); |
| 2072 | } elseif ($this->lastCurlCode == '423') { |
| 2073 | $migration->log(__('Backup is locked on remote site, please unlock remote downloading.', 'backup-backup'), 'ERROR'); |
| 2074 | $migration->log(__('You can find the setting in "Where shall the backup(s) be stored?" section.', 'backup-backup'), 'ERROR'); |
| 2075 | } elseif ($this->lastCurlCode == '200' || $this->lastCurlCode == '404') { |
| 2076 | $migration->log(__('Backup does not exist under provided URL.', 'backup-backup'), 'ERROR'); |
| 2077 | $migration->log(__('Please confirm that you can download the backup file via provided URL.', 'backup-backup'), 'ERROR'); |
| 2078 | $migration->log(__('...or the manifest file does not exist in the backup.', 'backup-backup'), 'ERROR'); |
| 2079 | $migration->log(__('Missing manifest means that the backup is probably invalid.', 'backup-backup'), 'ERROR'); |
| 2080 | } else { |
| 2081 | $migration->log(__('Manifest file does not exist', 'backup-backup'), 'ERROR'); |
| 2082 | $migration->log(__('Downloaded backup may be incomplete (missing manifest)', 'backup-backup'), 'ERROR'); |
| 2083 | $migration->log(__('...or provided URL is not a direct download of ZIP file.', 'backup-backup'), 'ERROR'); |
| 2084 | $migration->log(__('Removing downloaded file', 'backup-backup'), 'ERROR'); |
| 2085 | } |
| 2086 | |
| 2087 | if (file_exists($dest)) @unlink($dest); |
| 2088 | |
| 2089 | $migration->log('#002', 'END-CODE'); |
| 2090 | return ['status' => 'error']; |
| 2091 | |
| 2092 | } |
| 2093 | } |
| 2094 | } |
| 2095 | |
| 2096 | public function handleChunkUpload() { |
| 2097 | require_once BMI_INCLUDES . '/uploader/chunks.php'; |
| 2098 | } |
| 2099 | |
| 2100 | public function removeBackupFile() { |
| 2101 | $files = $this->post['filenames']; |
| 2102 | $deleteCloud = $this->post['deleteCloud'] === 'yes' ? true : false; |
| 2103 | $cloudDetails = $this->post['cloudDetails']; |
| 2104 | |
| 2105 | $md5_file_summary_path = BMI_BACKUPS . DIRECTORY_SEPARATOR. 'md5summary.php'; |
| 2106 | $md5summary = []; |
| 2107 | |
| 2108 | if (file_exists($md5_file_summary_path)) { |
| 2109 | $md5summary = file_get_contents($md5_file_summary_path); |
| 2110 | $md5summary = substr($md5summary, 18, -2); |
| 2111 | if (is_serialized($md5summary)) { |
| 2112 | $md5summary = maybe_unserialize($md5summary); |
| 2113 | } |
| 2114 | } |
| 2115 | |
| 2116 | if ($deleteCloud) { |
| 2117 | //Initialize externall storages for backup deletion action to be initiated |
| 2118 | require_once BMI_INCLUDES . '/external/controller.php'; |
| 2119 | new ExternalStorage(); |
| 2120 | |
| 2121 | if (defined('BMI_BACKUP_PRO') && defined('BMI_PRO_INC')) { |
| 2122 | $proPath = BMI_PRO_INC . 'external/controller.php'; |
| 2123 | if (file_exists($proPath)) { |
| 2124 | require_once $proPath; |
| 2125 | new ExternalStoragePremium(); |
| 2126 | } |
| 2127 | } |
| 2128 | } |
| 2129 | |
| 2130 | try { |
| 2131 | if (is_array($files)) { |
| 2132 | for ($i = 0; $i < sizeof($files); $i++) { |
| 2133 | |
| 2134 | $removeByMD5 = false; |
| 2135 | $file = $files[$i]; |
| 2136 | $file = preg_replace('/\.\./', '', $file); |
| 2137 | |
| 2138 | if (file_exists(BMI_BACKUPS . '/' . $file)) { |
| 2139 | |
| 2140 | if ($deleteCloud) { |
| 2141 | do_action('bmi_premium_remove_backup_file', md5_file(BMI_BACKUPS . '/' . $file)); |
| 2142 | } |
| 2143 | |
| 2144 | unlink(BMI_BACKUPS . '/' . $file); |
| 2145 | |
| 2146 | } else if ($deleteCloud) $removeByMD5 = true; |
| 2147 | |
| 2148 | if (isset($md5summary[$file])) { |
| 2149 | $md5s = $md5summary[$file]; |
| 2150 | |
| 2151 | for ($j = 0; $j < sizeof($md5s); ++$j) { |
| 2152 | $md5_file_path = BMI_BACKUPS . DIRECTORY_SEPARATOR . $md5s[$j] . '.json'; |
| 2153 | if (file_exists($md5_file_path)) { |
| 2154 | if ($deleteCloud) { |
| 2155 | do_action('bmi_premium_remove_backup_json_file', $md5s[$j] . '.json'); |
| 2156 | } |
| 2157 | unlink($md5_file_path); |
| 2158 | } else if ($deleteCloud) $removeByMD5 = true; |
| 2159 | } |
| 2160 | |
| 2161 | unset($md5summary[$file]); |
| 2162 | } |
| 2163 | |
| 2164 | if ($deleteCloud && $removeByMD5) { |
| 2165 | if (isset($cloudDetails[$file])) { |
| 2166 | do_action('bmi_premium_remove_backup_file', $cloudDetails[$file]['md5']); |
| 2167 | do_action('bmi_premium_remove_backup_json_file', $cloudDetails[$file]['md5'] . '.json'); |
| 2168 | } |
| 2169 | } |
| 2170 | |
| 2171 | } |
| 2172 | } |
| 2173 | } catch (\Exception $e) { |
| 2174 | return ['status' => 'error', 'e' => $e]; |
| 2175 | } catch (\Throwable $e) { |
| 2176 | return ['status' => 'error', 'e' => $e]; |
| 2177 | } |
| 2178 | |
| 2179 | $cacheMd5String = "<?php exit; \$x = '" . serialize($md5summary) . "';"; |
| 2180 | file_put_contents($md5_file_summary_path, $cacheMd5String); |
| 2181 | |
| 2182 | return ['status' => 'success']; |
| 2183 | } |
| 2184 | |
| 2185 | public function saveStorageConfig() { |
| 2186 | $dir_path = $this->post['directory']; // STORAGE::LOCAL::PATH |
| 2187 | $accessible = $this->post['access']; // STORAGE::DIRECT::URL |
| 2188 | $gdrivedirname = 'BACKUP_MIGRATION_BACKUPS'; // STORAGE::EXTERNAL::GDRIVE::DIRNAME // $this->post['gdrivedirname'] |
| 2189 | $curr_path = Dashboard\bmi_get_config('STORAGE::LOCAL::PATH'); |
| 2190 | |
| 2191 | $error = 0; |
| 2192 | $created = false; |
| 2193 | |
| 2194 | if (!preg_match("/^[a-zA-Z0-9\_\-\/\.]+$/", $dir_path)) { |
| 2195 | return ['status' => 'msg', 'why' => __('Entered directory/path name does not match allowed characters (Local Storage).', 'backup-backup'), 'level' => 'warning']; |
| 2196 | } |
| 2197 | |
| 2198 | if (!is_string($dir_path) || $dir_path === '' || |
| 2199 | !(preg_match('/^[A-Z]:[\/\\\\]/i', $dir_path) || strpos($dir_path, '/') === 0)) { |
| 2200 | return ['status' => 'msg', 'why' => __('Please enter full path to the directory (Local Storage).', 'backup-backup'), 'level' => 'warning']; |
| 2201 | } |
| 2202 | if (!file_exists($dir_path)) { |
| 2203 | $created = @mkdir($dir_path, 0755, true); |
| 2204 | } |
| 2205 | |
| 2206 | if (defined('BMI_BACKUP_PRO') && BMI_BACKUP_PRO === 1) { |
| 2207 | |
| 2208 | if (isset($this->post['gdrive'])) { |
| 2209 | $gdriveenabled = $this->post['gdrive']; |
| 2210 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::GDRIVE', $gdriveenabled)) { |
| 2211 | $errors++; |
| 2212 | } |
| 2213 | |
| 2214 | if (isset($this->post['gdrivedirname'])) { |
| 2215 | $gdrivedirname = $this->post['gdrivedirname']; |
| 2216 | |
| 2217 | if (!preg_match("/^[a-zA-Z0-9\_\-\.]+$/", $gdrivedirname)) { |
| 2218 | return ['status' => 'msg', 'why' => __('Entered directory name does not match allowed characters (Google Drive).', 'backup-backup'), 'level' => 'warning']; |
| 2219 | } |
| 2220 | |
| 2221 | if (strlen(trim($gdrivedirname)) < 3) { |
| 2222 | return ['status' => 'msg', 'why' => __('Entered directory name is too short, min 3 characters (Google Drive).', 'backup-backup'), 'level' => 'warning']; |
| 2223 | } |
| 2224 | |
| 2225 | if (strlen(trim($gdrivedirname)) > 48) { |
| 2226 | return ['status' => 'msg', 'why' => __('Entered directory name is too long, max 48 characters (Google Drive).', 'backup-backup'), 'level' => 'warning']; |
| 2227 | } |
| 2228 | |
| 2229 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::GDRIVE::DIRNAME', $gdrivedirname)) { |
| 2230 | $errors++; |
| 2231 | } |
| 2232 | } |
| 2233 | } |
| 2234 | |
| 2235 | if (isset($this->post['backupbliss'])) { |
| 2236 | $backupblissenabled = $this->post['backupbliss']; |
| 2237 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::backupbliss', $backupblissenabled)) { |
| 2238 | $errors++; |
| 2239 | } |
| 2240 | } |
| 2241 | |
| 2242 | if (isset($this->post['onedrive'])) { |
| 2243 | $onedriveenabled = $this->post['onedrive']; |
| 2244 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::ONEDRIVE', $onedriveenabled)) { |
| 2245 | $errors++; |
| 2246 | } |
| 2247 | } |
| 2248 | |
| 2249 | if (isset($this->post['sftp'])) { |
| 2250 | $sftpenabled = $this->post['sftp']; |
| 2251 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::SFTP', $sftpenabled)) { |
| 2252 | $errors++; |
| 2253 | } |
| 2254 | |
| 2255 | } |
| 2256 | |
| 2257 | if (isset($this->post['ftp'])) { |
| 2258 | $ftpenabled = $this->post['ftp']; |
| 2259 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::FTP', $ftpenabled)) { |
| 2260 | $errors++; |
| 2261 | } |
| 2262 | |
| 2263 | if ($ftpenabled != "false"){ |
| 2264 | if (isset($this->post['ftphostip'])) { |
| 2265 | $ftpiphost = $this->post['ftphostip']; |
| 2266 | update_option('bmi_pro_ftp_host', $ftpiphost); |
| 2267 | } |
| 2268 | |
| 2269 | if (isset($this->post['ftphostusername'])) { |
| 2270 | $ftpHostUsername = $this->post['ftphostusername']; |
| 2271 | update_option('bmi_pro_ftp_username', $ftpHostUsername); |
| 2272 | } |
| 2273 | |
| 2274 | if (isset($this->post['ftppassword'])) { |
| 2275 | $ftpHostPassword = $this->post['ftppassword']; |
| 2276 | if (!empty($ftpHostPassword) && is_string($ftpHostPassword) && strlen(trim($ftpHostPassword)) > 0) |
| 2277 | update_option('bmi_pro_ftp_password', $ftpHostPassword); |
| 2278 | } |
| 2279 | |
| 2280 | if (isset($this->post['ftpport'])) { |
| 2281 | $ftpHostPort = $this->post['ftpport']; |
| 2282 | update_option('bmi_pro_ftp_port', $ftpHostPort); |
| 2283 | } |
| 2284 | |
| 2285 | if (isset($this->post['ftpdir'])) { |
| 2286 | $ftpHostDir = $this->post['ftpdir']; |
| 2287 | update_option('bmi_pro_ftp_backup_dir', $ftpHostDir); |
| 2288 | } |
| 2289 | } else { |
| 2290 | delete_option('bmi_pro_ftp_host'); |
| 2291 | delete_option('bmi_pro_ftp_username'); |
| 2292 | delete_option('bmi_pro_ftp_password'); |
| 2293 | } |
| 2294 | |
| 2295 | } else { |
| 2296 | delete_option('bmi_pro_ftp_host'); |
| 2297 | delete_option('bmi_pro_ftp_username'); |
| 2298 | delete_option('bmi_pro_ftp_password'); |
| 2299 | } |
| 2300 | |
| 2301 | if (isset($this->post['aws'])) { |
| 2302 | $s3enabled = $this->post['aws']; |
| 2303 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::AWS', $s3enabled)) { |
| 2304 | $errors++; |
| 2305 | } |
| 2306 | } |
| 2307 | |
| 2308 | if (isset($this->post['wasabi'])) { |
| 2309 | $wasabienabled = $this->post['wasabi']; |
| 2310 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::WASABI', $wasabienabled)) { |
| 2311 | $errors++; |
| 2312 | } |
| 2313 | } |
| 2314 | |
| 2315 | if (isset($this->post['dropbox'])) { |
| 2316 | $dropboxenabled = $this->post['dropbox']; |
| 2317 | if (!Dashboard\bmi_set_config('STORAGE::EXTERNAL::DROPBOX', $dropboxenabled)) { |
| 2318 | $errors++; |
| 2319 | } |
| 2320 | |
| 2321 | |
| 2322 | } |
| 2323 | |
| 2324 | } |
| 2325 | |
| 2326 | if (is_writable($dir_path)) { |
| 2327 | if (!Dashboard\bmi_set_config('STORAGE::DIRECT::URL', $accessible)) { |
| 2328 | Logger::error('Backup Storage Direct Url Error'); |
| 2329 | $error++; |
| 2330 | } |
| 2331 | if (!Dashboard\bmi_set_config('STORAGE::LOCAL::PATH', esc_attr($dir_path))) { |
| 2332 | Logger::error('Backup Storage Local Path Error'); |
| 2333 | $error++; |
| 2334 | } else { |
| 2335 | $cur_dir = BMP::fixSlashes($curr_path); |
| 2336 | $new_dir = BMP::fixSlashes($dir_path); |
| 2337 | |
| 2338 | $backups_cur_dir = BMP::fixSlashes($curr_path) . DIRECTORY_SEPARATOR . 'backups'; |
| 2339 | $backups_new_dir = BMP::fixSlashes($dir_path) . DIRECTORY_SEPARATOR . 'backups'; |
| 2340 | |
| 2341 | $staging_cur_dir = BMP::fixSlashes($curr_path) . DIRECTORY_SEPARATOR . 'staging'; |
| 2342 | $staging_new_dir = BMP::fixSlashes($dir_path) . DIRECTORY_SEPARATOR . 'staging'; |
| 2343 | |
| 2344 | $tmp_cur_dir = BMP::fixSlashes($curr_path) . DIRECTORY_SEPARATOR . 'tmp'; |
| 2345 | $tmp_new_dir = BMP::fixSlashes($dir_path) . DIRECTORY_SEPARATOR . 'tmp'; |
| 2346 | |
| 2347 | update_option('BMI::STORAGE::LOCAL::PATH', $new_dir); |
| 2348 | |
| 2349 | if ($cur_dir != $new_dir) { |
| 2350 | |
| 2351 | if (!file_exists($new_dir)) @mkdir($new_dir, 0755, true); |
| 2352 | if (!file_exists($backups_new_dir)) @mkdir($backups_new_dir, 0755, true); |
| 2353 | if (!file_exists($staging_new_dir)) @mkdir($staging_new_dir, 0755, true); |
| 2354 | if (!file_exists($tmp_new_dir)) @mkdir($tmp_new_dir, 0755, true); |
| 2355 | |
| 2356 | $scanned_directory_staging = array_diff(scandir($staging_cur_dir), ['..', '.']); |
| 2357 | foreach ($scanned_directory_staging as $i => $file) { |
| 2358 | if (file_exists($staging_cur_dir . DIRECTORY_SEPARATOR . $file) && !is_dir($staging_cur_dir . DIRECTORY_SEPARATOR . $file)) { |
| 2359 | rename($staging_cur_dir . DIRECTORY_SEPARATOR . $file, $staging_new_dir . DIRECTORY_SEPARATOR . $file); |
| 2360 | } |
| 2361 | } |
| 2362 | |
| 2363 | $scanned_directory_tmp = array_diff(scandir($tmp_cur_dir), ['..', '.']); |
| 2364 | foreach ($scanned_directory_tmp as $i => $file) { |
| 2365 | if (file_exists($tmp_cur_dir . DIRECTORY_SEPARATOR . $file) && !is_dir($tmp_cur_dir . DIRECTORY_SEPARATOR . $file)) { |
| 2366 | rename($tmp_cur_dir . DIRECTORY_SEPARATOR . $file, $tmp_new_dir . DIRECTORY_SEPARATOR . $file); |
| 2367 | } |
| 2368 | } |
| 2369 | |
| 2370 | $scanned_directory_backups = array_diff(scandir($backups_cur_dir), ['..', '.']); |
| 2371 | foreach ($scanned_directory_backups as $i => $file) { |
| 2372 | if (file_exists($backups_cur_dir . DIRECTORY_SEPARATOR . $file) && !is_dir($backups_cur_dir . DIRECTORY_SEPARATOR . $file)) { |
| 2373 | rename($backups_cur_dir . DIRECTORY_SEPARATOR . $file, $backups_new_dir . DIRECTORY_SEPARATOR . $file); |
| 2374 | } |
| 2375 | } |
| 2376 | |
| 2377 | $scanned_directory = array_diff(scandir($cur_dir), ['..', '.']); |
| 2378 | foreach ($scanned_directory as $i => $file) { |
| 2379 | if (file_exists($cur_dir . DIRECTORY_SEPARATOR . $file) && !is_dir($cur_dir . DIRECTORY_SEPARATOR . $file)) { |
| 2380 | rename($cur_dir . DIRECTORY_SEPARATOR . $file, $new_dir . DIRECTORY_SEPARATOR . $file); |
| 2381 | } |
| 2382 | } |
| 2383 | |
| 2384 | if (file_exists($backups_cur_dir . DIRECTORY_SEPARATOR . '.htaccess')) @unlink($backups_cur_dir . DIRECTORY_SEPARATOR . '.htaccess'); |
| 2385 | if (file_exists($backups_cur_dir . DIRECTORY_SEPARATOR . 'index.php')) @unlink($backups_cur_dir . DIRECTORY_SEPARATOR . 'index.php'); |
| 2386 | if (file_exists($backups_cur_dir . DIRECTORY_SEPARATOR . 'index.html')) @unlink($backups_cur_dir . DIRECTORY_SEPARATOR . 'index.html'); |
| 2387 | if (file_exists($backups_cur_dir)) @rmdir($backups_cur_dir); |
| 2388 | |
| 2389 | if (file_exists($staging_cur_dir . DIRECTORY_SEPARATOR . '.htaccess')) @unlink($staging_cur_dir . DIRECTORY_SEPARATOR . '.htaccess'); |
| 2390 | if (file_exists($staging_cur_dir . DIRECTORY_SEPARATOR . 'index.php')) @unlink($staging_cur_dir . DIRECTORY_SEPARATOR . 'index.php'); |
| 2391 | if (file_exists($staging_cur_dir . DIRECTORY_SEPARATOR . 'index.html')) @unlink($staging_cur_dir . DIRECTORY_SEPARATOR . 'index.html'); |
| 2392 | if (file_exists($staging_cur_dir)) @rmdir($staging_cur_dir); |
| 2393 | |
| 2394 | if (file_exists($tmp_cur_dir . DIRECTORY_SEPARATOR . '.htaccess')) @unlink($tmp_cur_dir . DIRECTORY_SEPARATOR . '.htaccess'); |
| 2395 | if (file_exists($tmp_cur_dir . DIRECTORY_SEPARATOR . 'index.php')) @unlink($tmp_cur_dir . DIRECTORY_SEPARATOR . 'index.php'); |
| 2396 | if (file_exists($tmp_cur_dir . DIRECTORY_SEPARATOR . 'index.html')) @unlink($tmp_cur_dir . DIRECTORY_SEPARATOR . 'index.html'); |
| 2397 | if (file_exists($tmp_cur_dir)) @rmdir($tmp_cur_dir); |
| 2398 | |
| 2399 | if (file_exists($cur_dir . DIRECTORY_SEPARATOR . 'complete_logs.log')) @unlink($cur_dir . DIRECTORY_SEPARATOR . 'complete_logs.log'); |
| 2400 | if (file_exists($cur_dir)) @rmdir($cur_dir); |
| 2401 | |
| 2402 | if (is_dir($cur_dir) && file_exists($cur_dir)) { |
| 2403 | $left_files = array_diff(scandir($cur_dir), ['..', '.']); |
| 2404 | if (sizeof($left_files) == 0) { |
| 2405 | if (file_exists($cur_dir)) { |
| 2406 | @rmdir($cur_dir); |
| 2407 | } |
| 2408 | } |
| 2409 | } |
| 2410 | |
| 2411 | } |
| 2412 | } |
| 2413 | } else { |
| 2414 | if ($created === true) { |
| 2415 | if (file_exists($dir_path)) @unlink($dir_path); |
| 2416 | } |
| 2417 | |
| 2418 | return ['status' => 'msg', 'why' => __('Entered path is not writable, cannot be used.', 'backup-backup'), 'level' => 'warning']; |
| 2419 | } |
| 2420 | |
| 2421 | return ['status' => 'success', 'errors' => $error]; |
| 2422 | } |
| 2423 | |
| 2424 | public function saveOtherOptions() { |
| 2425 | |
| 2426 | // Errors |
| 2427 | $invalid_email = __('Provided email addess is not valid.', 'backup-backup'); |
| 2428 | $title_long = __('Your email title is too long, please change the title (max 64 chars).', 'backup-backup'); |
| 2429 | $title_short = __('Your email title is too short, please use longer one (at least 3 chars).', 'backup-backup'); |
| 2430 | $title_empty = __('Title field is required, please fill it.', 'backup-backup'); |
| 2431 | $email_empty = __('Email field cannot be empty, please fill it.', 'backup-backup'); |
| 2432 | $cli_no_exist = __('Path to executable that you provided for PHP CLI does not exist.', 'backup-backup'); |
| 2433 | $db_query_too_low = __('The value for query amount cannot be smaller than 15.', 'backup-backup'); |
| 2434 | $db_query_too_much = __('The value for query amount cannot be larger than 15000.', 'backup-backup'); |
| 2435 | $db_sr_max_too_low = __('The value for search replace max page cannot be smaller than 10.', 'backup-backup'); |
| 2436 | $db_sr_max_too_much = __('The value for search replace max page cannot be larger than 30000.', 'backup-backup'); |
| 2437 | $fl_ex_max_too_low = __('The value for extraction limit cannot be smaller than 50.', 'backup-backup'); |
| 2438 | $fl_ex_max_too_much = __('The value for extraction limit cannot be larger than 20000.', 'backup-backup'); |
| 2439 | |
| 2440 | $email = sanitize_email(trim($this->post['email'])); // OTHER:EMAIL |
| 2441 | $email_title = sanitize_text_field(trim($this->post['email_title'])); // OTHER:EMAIL:TITLE |
| 2442 | $schedule_issues = $this->post['schedule_issues'] === 'true' ? true : false; // OTHER:EMAIL:NOTIS |
| 2443 | $experiment_timeout = $this->post['experiment_timeout'] === 'true' ? true : false; // OTHER:EXPERIMENT:TIMEOUT |
| 2444 | $experiment_timeout_hard = $this->post['experimental_hard_timeout'] === 'true' ? true : false; // OTHER:EXPERIMENT:TIMEOUT:HARD |
| 2445 | $php_cli_manual_path = isset($this->post['php_cli_manual_path']) ? trim($this->post['php_cli_manual_path']) : ''; // OTHER:CLI:PATH |
| 2446 | $php_cli_disable_others = $this->post['php_cli_disable_others'] === 'true' ? true : false; // OTHER:CLI:DISABLE |
| 2447 | $normal_timeout = $this->post['normal_timeout'] === 'true' ? true : false; // OTHER:USE:TIMEOUT:NORMAL |
| 2448 | $insecure_download = $this->post['download_technique'] === 'true' ? true : false; // OTHER:DOWNLOAD:DIRECT |
| 2449 | $db_query_size = isset($this->post['db_queries_amount']) ? trim($this->post['db_queries_amount']) : '2000'; // OTHER:DB:QUERIES |
| 2450 | $db_search_replace_max = isset($this->post['db_search_replace_max']) ? trim($this->post['db_search_replace_max']) : '300'; // OTHER:DB:SEARCHREPLACE:MAX |
| 2451 | $file_limit_extraction_max = isset($this->post['file_limit_extraction_max']) ? trim($this->post['file_limit_extraction_max']) : 'auto'; // OTHER:FILE:EXTRACT:MAX |
| 2452 | $db_restore_splitting = $this->post['bmi-restore-splitting'] === 'true' ? true : false; // OTHER:RESTORE:SPLITTING |
| 2453 | $db_restore_v3_engine = $this->post['bmi-db-v3-restore-engine'] === 'true' ? true : false; // OTHER:RESTORE:DB:V3 |
| 2454 | |
| 2455 | $no_assets_b4_restore = $this->post['remove-assets-before-restore'] === 'true' ? true : false; // OTHER:RESTORE:BEFORE:CLEANUP |
| 2456 | $single_file_db_force = $this->post['bmi-db-single-file-backup'] === 'true' ? true : false; // OTHER:BACKUP:DB:SINGLE:FILE |
| 2457 | $db_batching_backup = $this->post['bmi-db-batching-backup'] === 'true' ? true : false; // OTHER:BACKUP:DB:BATCHING |
| 2458 | |
| 2459 | $bmi_disable_space_check = $this->post['bmi-disable-space-check-function'] === 'true' ? true : false; // OTHER:BACKUP:SPACE:CHECKING |
| 2460 | |
| 2461 | $uninstall_config = $this->post['uninstall_config'] === 'true' ? true : false; // OTHER:UNINSTALL:CONFIGS |
| 2462 | $uninstall_backups = $this->post['uninstall_backups'] === 'true' ? true : false; // OTHER:UNINSTALL:BACKUPS |
| 2463 | |
| 2464 | if ($experiment_timeout_hard === true) { |
| 2465 | $experiment_timeout = false; |
| 2466 | } |
| 2467 | |
| 2468 | if ($normal_timeout === true) { |
| 2469 | $experiment_timeout = false; |
| 2470 | $experiment_timeout_hard = false; |
| 2471 | } |
| 2472 | |
| 2473 | if (!is_numeric($db_query_size) || empty($db_query_size)) { |
| 2474 | $db_query_size = "2000"; |
| 2475 | } |
| 2476 | |
| 2477 | if (!is_numeric($file_limit_extraction_max) || empty($file_limit_extraction_max)) { |
| 2478 | $file_limit_extraction_max = "auto"; |
| 2479 | } |
| 2480 | |
| 2481 | if (!is_numeric($db_search_replace_max) || empty($db_search_replace_max)) { |
| 2482 | $db_search_replace_max = "300"; |
| 2483 | } |
| 2484 | |
| 2485 | if (strlen($email) <= 0) { |
| 2486 | return ['status' => 'msg', 'why' => $email_empty, 'level' => 'warning']; |
| 2487 | } |
| 2488 | if (strlen($email_title) <= 0) { |
| 2489 | return ['status' => 'msg', 'why' => $title_empty, 'level' => 'warning']; |
| 2490 | } |
| 2491 | if (strlen($email_title) > 64) { |
| 2492 | return ['status' => 'msg', 'why' => $title_long, 'level' => 'warning']; |
| 2493 | } |
| 2494 | if (strlen($email_title) < 3) { |
| 2495 | return ['status' => 'msg', 'why' => $title_short, 'level' => 'warning']; |
| 2496 | } |
| 2497 | if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { |
| 2498 | return ['status' => 'msg', 'why' => $invalid_email, 'level' => 'warning']; |
| 2499 | } |
| 2500 | if ($php_cli_manual_path != '' && !file_exists($php_cli_manual_path)) { |
| 2501 | return ['status' => 'msg', 'why' => $cli_no_exist, 'level' => 'warning']; |
| 2502 | } |
| 2503 | if (intval($db_query_size) > 15000) { |
| 2504 | return ['status' => 'msg', 'why' => $db_query_too_much, 'level' => 'warning']; |
| 2505 | } |
| 2506 | if (intval($db_query_size) < 15) { |
| 2507 | return ['status' => 'msg', 'why' => $db_query_too_low, 'level' => 'warning']; |
| 2508 | } |
| 2509 | if (intval($db_search_replace_max) > 30000) { |
| 2510 | return ['status' => 'msg', 'why' => $db_sr_max_too_much, 'level' => 'warning']; |
| 2511 | } |
| 2512 | if (intval($db_search_replace_max) < 10) { |
| 2513 | return ['status' => 'msg', 'why' => $db_sr_max_too_low, 'level' => 'warning']; |
| 2514 | } |
| 2515 | if ($file_limit_extraction_max != 'auto' && intval($file_limit_extraction_max) > 20000) { |
| 2516 | return ['status' => 'msg', 'why' => $fl_ex_max_too_much, 'level' => 'warning']; |
| 2517 | } |
| 2518 | if ($file_limit_extraction_max != 'auto' && intval($file_limit_extraction_max) < 50) { |
| 2519 | return ['status' => 'msg', 'why' => $fl_ex_max_too_low, 'level' => 'warning']; |
| 2520 | } |
| 2521 | |
| 2522 | $error = 0; |
| 2523 | if (!Dashboard\bmi_set_config('OTHER:EMAIL', $email)) { |
| 2524 | Logger::error('Backup Other Email Error'); |
| 2525 | $error++; |
| 2526 | } |
| 2527 | if (!Dashboard\bmi_set_config('OTHER:EMAIL:TITLE', $email_title)) { |
| 2528 | Logger::error('Backup Other Email Title Error'); |
| 2529 | $error++; |
| 2530 | } |
| 2531 | if (!Dashboard\bmi_set_config('OTHER:EMAIL:NOTIS', $schedule_issues)) { |
| 2532 | Logger::error('Backup Other Email Notis Error'); |
| 2533 | $error++; |
| 2534 | } |
| 2535 | if (!Dashboard\bmi_set_config('OTHER:CLI:PATH', $php_cli_manual_path)) { |
| 2536 | Logger::error('Backup Other CLI Path Error'); |
| 2537 | $error++; |
| 2538 | } |
| 2539 | if (!Dashboard\bmi_set_config('OTHER:CLI:DISABLE', $php_cli_disable_others)) { |
| 2540 | Logger::error('Backup Other CLI Disable Error'); |
| 2541 | $error++; |
| 2542 | } |
| 2543 | if (!Dashboard\bmi_set_config('OTHER:EXPERIMENT:TIMEOUT', $experiment_timeout)) { |
| 2544 | Logger::error('Backup Other Experiment Timeout Error'); |
| 2545 | $error++; |
| 2546 | } |
| 2547 | if (!Dashboard\bmi_set_config('OTHER:EXPERIMENT:TIMEOUT:HARD', $experiment_timeout_hard)) { |
| 2548 | Logger::error('Backup Other Experiment Timeout Hard Error'); |
| 2549 | $error++; |
| 2550 | } |
| 2551 | if (!Dashboard\bmi_set_config('OTHER:USE:TIMEOUT:NORMAL', $normal_timeout)) { |
| 2552 | Logger::error('Backup Other Experiment Timeout Normal Error'); |
| 2553 | $error++; |
| 2554 | } |
| 2555 | if (!Dashboard\bmi_set_config('OTHER:RESTORE:DB:V3', $db_restore_v3_engine)) { |
| 2556 | Logger::error('Backup Other Restore DB V3 Error'); |
| 2557 | $error++; |
| 2558 | } |
| 2559 | if (!Dashboard\bmi_set_config('OTHER:DB:QUERIES', $db_query_size)) { |
| 2560 | Logger::error('Backup Other DB Queries Error'); |
| 2561 | $error++; |
| 2562 | } |
| 2563 | if (!Dashboard\bmi_set_config('OTHER:DB:SEARCHREPLACE:MAX', $db_search_replace_max)) { |
| 2564 | Logger::error('Backup Other DB Queries Error'); |
| 2565 | $error++; |
| 2566 | } |
| 2567 | if (!Dashboard\bmi_set_config('OTHER:FILE:EXTRACT:MAX', $file_limit_extraction_max)) { |
| 2568 | Logger::error('Backup Other File Extract Max Error'); |
| 2569 | $error++; |
| 2570 | } |
| 2571 | if (!Dashboard\bmi_set_config('OTHER:DOWNLOAD:DIRECT', $insecure_download)) { |
| 2572 | Logger::error('Backup Other Download Direct Error'); |
| 2573 | $error++; |
| 2574 | } |
| 2575 | if (!Dashboard\bmi_set_config('OTHER:UNINSTALL:CONFIGS', $uninstall_config)) { |
| 2576 | Logger::error('Backup Other Uninstall Configs Error'); |
| 2577 | $error++; |
| 2578 | } |
| 2579 | if (!Dashboard\bmi_set_config('OTHER:UNINSTALL:BACKUPS', $uninstall_backups)) { |
| 2580 | Logger::error('Backup Other Uninstall Backups Error'); |
| 2581 | $error++; |
| 2582 | } |
| 2583 | if (!Dashboard\bmi_set_config('OTHER:RESTORE:SPLITTING', $db_restore_splitting)) { |
| 2584 | Logger::error('Backup Other Restore Splitting Error'); |
| 2585 | $error++; |
| 2586 | } |
| 2587 | if (!Dashboard\bmi_set_config('OTHER:BACKUP:DB:SINGLE:FILE', $single_file_db_force)) { |
| 2588 | Logger::error('Backup Other Backup DB Single File Error'); |
| 2589 | $error++; |
| 2590 | } |
| 2591 | if (!Dashboard\bmi_set_config('OTHER:BACKUP:DB:BATCHING', $db_batching_backup)) { |
| 2592 | Logger::error('Backup Other Backup DB Batching Error'); |
| 2593 | $error++; |
| 2594 | } |
| 2595 | if (!Dashboard\bmi_set_config('OTHER:BACKUP:SPACE:CHECKING', $bmi_disable_space_check)) { |
| 2596 | Logger::error('Backup Other Backup Space Checking Error'); |
| 2597 | $error++; |
| 2598 | } |
| 2599 | if (!Dashboard\bmi_set_config('OTHER:RESTORE:BEFORE:CLEANUP', $no_assets_b4_restore)) { |
| 2600 | Logger::error('Backup Other Restore Before Cleanup Error'); |
| 2601 | $error++; |
| 2602 | } |
| 2603 | |
| 2604 | if (has_action('bmi_premium_other_options')) { |
| 2605 | do_action('bmi_premium_other_options', $this->post); |
| 2606 | } |
| 2607 | |
| 2608 | return ['status' => 'success', 'errors' => $error]; |
| 2609 | } |
| 2610 | |
| 2611 | public function saveStorageTypeConfig() { |
| 2612 | |
| 2613 | // Errors |
| 2614 | $name_empty = __('Name is required, please fill the input.', 'backup-backup'); |
| 2615 | $name_long = __('Your name is too long, please change the name.', 'backup-backup'); |
| 2616 | $name_short = __('Your name is too short, please create longer one.', 'backup-backup'); |
| 2617 | $name_space = __('Please, do not use spaces in file name.', 'backup-backup'); |
| 2618 | $name_forbidden = __('Your name contains character(s) that are not allowed in file names: ', 'backup-backup'); |
| 2619 | |
| 2620 | $forbidden_chars = ['/', '\\', '<', '>', ':', '"', "'", '|', '?', '*', '.', ';', '@', '!', '~', '`', ',', '#', '$', '&', '=', '+']; |
| 2621 | $name = trim($this->post['name']); // BACKUP:NAME |
| 2622 | $extensionType = trim($this->post['extension']); // BACKUP:EXTENSION:TYPE |
| 2623 | |
| 2624 | if (strlen($name) == 0) { |
| 2625 | return ['status' => 'msg', 'why' => $name_empty, 'level' => 'warning']; |
| 2626 | } |
| 2627 | if (strlen($name) > 40) { |
| 2628 | return ['status' => 'msg', 'why' => $name_long, 'level' => 'warning']; |
| 2629 | } |
| 2630 | if (strlen($name) < 3) { |
| 2631 | return ['status' => 'msg', 'why' => $name_short, 'level' => 'warning']; |
| 2632 | } |
| 2633 | if (strpos($name, ' ') !== false) { |
| 2634 | return ['status' => 'msg', 'why' => $name_space, 'level' => 'warning']; |
| 2635 | } |
| 2636 | |
| 2637 | if (defined('BMI_BACKUP_PRO') && BMI_BACKUP_PRO == 1) { |
| 2638 | if (!in_array($extensionType, ['.zip', '.tar.gz', '.tar'])) { |
| 2639 | return ['status' => 'msg', 'why' => $name_space, 'level' => 'warning']; |
| 2640 | } |
| 2641 | } |
| 2642 | |
| 2643 | for ($i = 0; $i < sizeof($forbidden_chars); ++$i) { |
| 2644 | $char = $forbidden_chars[$i]; |
| 2645 | if (strpos($name, $char) !== false) { |
| 2646 | return ['status' => 'msg', 'why' => $name_forbidden . $char, 'level' => 'warning']; |
| 2647 | } |
| 2648 | } |
| 2649 | |
| 2650 | $error = 0; |
| 2651 | if (!Dashboard\bmi_set_config('BACKUP:NAME', $name)) { |
| 2652 | Logger::error('Backup Name Error'); |
| 2653 | $error++; |
| 2654 | } |
| 2655 | |
| 2656 | if (defined('BMI_BACKUP_PRO') && BMI_BACKUP_PRO == 1) { |
| 2657 | if (!Dashboard\bmi_set_config('BACKUP:EXTENSION:TYPE', $extensionType)) { |
| 2658 | Logger::error('Backup Extension Type Error'); |
| 2659 | $error++; |
| 2660 | } |
| 2661 | } |
| 2662 | |
| 2663 | return ['status' => 'success', 'errors' => $error]; |
| 2664 | } |
| 2665 | |
| 2666 | public function saveFilesConfig() { |
| 2667 | $db_group = $this->post['database_group']; // BACKUP:DATABASE |
| 2668 | $files_group = $this->post['files_group']; // BACKUP:FILES |
| 2669 | |
| 2670 | $fgp = $this->post['files-group-plugins']; // BACKUP:FILES::PLUGINS |
| 2671 | $fgu = $this->post['files-group-uploads']; // BACKUP:FILES::UPLOADS |
| 2672 | $fgt = $this->post['files-group-themes']; // BACKUP:FILES::THEMES |
| 2673 | $fgoc = $this->post['files-group-other-contents']; // BACKUP:FILES::OTHERS |
| 2674 | $fgwp = $this->post['files-group-wp-install']; // BACKUP:FILES::WP |
| 2675 | |
| 2676 | $file_filters = $this->post['files_by_filters']; // BACKUP:FILES::FILTER |
| 2677 | $ffs = $this->post['ex_b_fs']; // BACKUP:FILES::FILTER:SIZE |
| 2678 | $ffsizemax = $this->post['BFFSIN']; // BACKUP:FILES::FILTER:SIZE:IN |
| 2679 | $ffn = $this->post['ex_b_names']; // BACKUP:FILES::FILTER:NAMES |
| 2680 | $ffp = $this->post['ex_b_fpaths']; // BACKUP:FILES::FILTER:FPATHS |
| 2681 | $ffd = $this->post['ex_b_dpaths']; // BACKUP:FILES::FILTER:DPATHS |
| 2682 | |
| 2683 | $dbeg = $this->post['db-exclude-tables-group']; // BACKUP:DATABASE:EXCLUDE |
| 2684 | $dbet = $this->post['db-excluded-tables']; // BACKUP:DATABASE:EXCLUDE:LIST |
| 2685 | |
| 2686 | $existant = []; |
| 2687 | $parsed = []; |
| 2688 | $ffnames = $this->post['dynamic-names']; // BACKUP:FILES::FILTER:NAMES:IN |
| 2689 | $ffpnames = array_unique($this->post['dynamic-fpaths-names']); // BACKUP:FILES::FILTER:FPATHS:IN |
| 2690 | $ffdnames = array_unique($this->post['dynamic-dpaths-names']); // BACKUP:FILES::FILTER:DPATHS:IN |
| 2691 | |
| 2692 | if (is_array($dbet) || is_object($dbet)) { |
| 2693 | if (sizeof($dbet) == 1 && $dbet[0] == 'empty') { |
| 2694 | $dbet = []; |
| 2695 | } |
| 2696 | } |
| 2697 | |
| 2698 | if ($dbeg === 'true' || $dbeg === true) $dbeg = true; |
| 2699 | else $dbeg = false; |
| 2700 | |
| 2701 | $max = sizeof($ffpnames); |
| 2702 | for ($i = 0; $i < $max; ++$i) { |
| 2703 | if (!is_string($ffpnames[$i]) || trim(strlen($ffpnames[$i])) <= 1) { |
| 2704 | array_splice($ffpnames, $i, 1); |
| 2705 | $i--; |
| 2706 | $max--; |
| 2707 | } |
| 2708 | } |
| 2709 | |
| 2710 | $max = sizeof($ffdnames); |
| 2711 | for ($i = 0; $i < $max; ++$i) { |
| 2712 | if (!is_string($ffdnames[$i]) || trim(strlen($ffdnames[$i])) <= 1) { |
| 2713 | array_splice($ffdnames, $i, 1); |
| 2714 | $i--; |
| 2715 | $max--; |
| 2716 | } |
| 2717 | } |
| 2718 | |
| 2719 | for ($i = 0; $i < sizeof($ffnames); ++$i) { |
| 2720 | $row = $ffnames[$i]; |
| 2721 | $txt = array_key_exists('txt', $row) ? "" . $row['txt'] . "" : false; |
| 2722 | $pos = array_key_exists('pos', $row) ? $row['pos'] : false; |
| 2723 | $whr = array_key_exists('whr', $row) ? $row['whr'] : false; |
| 2724 | |
| 2725 | if ($txt === false || $pos === false || $whr === false) { |
| 2726 | continue; |
| 2727 | } |
| 2728 | if (trim(strlen($txt)) <= 0) { |
| 2729 | continue; |
| 2730 | } |
| 2731 | if (!in_array($pos, ["1", "2", "3"])) { |
| 2732 | continue; |
| 2733 | } |
| 2734 | if (!in_array($whr, ["1", "2"])) { |
| 2735 | continue; |
| 2736 | } |
| 2737 | if (in_array($txt . $pos . $whr, $existant)) { |
| 2738 | continue; |
| 2739 | } else { |
| 2740 | $existant[] = $txt . $pos . $whr; |
| 2741 | } |
| 2742 | |
| 2743 | $parsed[] = ['txt' => $txt, 'pos' => $pos, 'whr' => $whr]; |
| 2744 | } |
| 2745 | |
| 2746 | if ($ffs == 'true' && !is_numeric($ffsizemax)) { |
| 2747 | return ['status' => 'msg', 'why' => __('Entred file size limit, is not correct number.', 'backup-backup'), 'level' => 'warning']; |
| 2748 | } |
| 2749 | |
| 2750 | $error = 0; |
| 2751 | if (!Dashboard\bmi_set_config('BACKUP:DATABASE', $db_group)) { |
| 2752 | Logger::error('Backup Database Error'); |
| 2753 | $error++; |
| 2754 | } |
| 2755 | if (!Dashboard\bmi_set_config('BACKUP:FILES', $files_group)) { |
| 2756 | Logger::error('Backup Files Error'); |
| 2757 | $error++; |
| 2758 | } |
| 2759 | |
| 2760 | if (!Dashboard\bmi_set_config('BACKUP:FILES::PLUGINS', $fgp)) { |
| 2761 | Logger::error('Backup Files Plugins Error'); |
| 2762 | $error++; |
| 2763 | } |
| 2764 | if (!Dashboard\bmi_set_config('BACKUP:FILES::UPLOADS', $fgu)) { |
| 2765 | Logger::error('Backup Files Uploads Error'); |
| 2766 | $error++; |
| 2767 | } |
| 2768 | if (!Dashboard\bmi_set_config('BACKUP:FILES::THEMES', $fgt)) { |
| 2769 | Logger::error('Backup Files Themes Error'); |
| 2770 | $error++; |
| 2771 | } |
| 2772 | if (!Dashboard\bmi_set_config('BACKUP:FILES::OTHERS', $fgoc)) { |
| 2773 | Logger::error('Backup Files Others Error'); |
| 2774 | $error++; |
| 2775 | } |
| 2776 | if (!Dashboard\bmi_set_config('BACKUP:FILES::WP', $fgwp)) { |
| 2777 | Logger::error('Backup Files WP Error'); |
| 2778 | $error++; |
| 2779 | } |
| 2780 | |
| 2781 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER', $file_filters)) { |
| 2782 | Logger::error('Backup Files Filter Error'); |
| 2783 | $error++; |
| 2784 | } |
| 2785 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:SIZE', $ffs)) { |
| 2786 | Logger::error('Backup Files Filter Size Error'); |
| 2787 | $error++; |
| 2788 | } |
| 2789 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:NAMES', $ffn)) { |
| 2790 | Logger::error('Backup Files Names Error'); |
| 2791 | $error++; |
| 2792 | } |
| 2793 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:FPATHS', $ffp)) { |
| 2794 | Logger::error('Backup Files Fpaths Error'); |
| 2795 | $error++; |
| 2796 | } |
| 2797 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:DPATHS', $ffd)) { |
| 2798 | Logger::error('Backup Files Dpaths Error'); |
| 2799 | $error++; |
| 2800 | } |
| 2801 | |
| 2802 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:SIZE:IN', $ffsizemax)) { |
| 2803 | Logger::error('Backup Files Filter Size In Error'); |
| 2804 | $error++; |
| 2805 | } |
| 2806 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:NAMES:IN', $parsed)) { |
| 2807 | Logger::error('Backup Files Filter Names In Error'); |
| 2808 | $error++; |
| 2809 | } |
| 2810 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:FPATHS:IN', $ffpnames)) { |
| 2811 | Logger::error('Backup Files Filter Fpaths In Error'); |
| 2812 | $error++; |
| 2813 | } |
| 2814 | if (!Dashboard\bmi_set_config('BACKUP:FILES::FILTER:DPATHS:IN', $ffdnames)) { |
| 2815 | Logger::error('Backup Files Filter Dpaths In Error'); |
| 2816 | $error++; |
| 2817 | } |
| 2818 | |
| 2819 | if (defined('BMI_BACKUP_PRO') && BMI_BACKUP_PRO == 1) { |
| 2820 | if (!Dashboard\bmi_set_config('BACKUP:DATABASE:EXCLUDE', $dbeg)) { |
| 2821 | Logger::error('Backup Files Filter Database Exclude Error'); |
| 2822 | $error++; |
| 2823 | } |
| 2824 | if (!Dashboard\bmi_set_config('BACKUP:DATABASE:EXCLUDE:LIST', $dbet)) { |
| 2825 | Logger::error('Backup Files Filter Database Exclude List Error'); |
| 2826 | $error++; |
| 2827 | } |
| 2828 | } |
| 2829 | |
| 2830 | if (has_action('bmip_smart_exclusion_options')){ |
| 2831 | do_action('bmip_smart_exclusion_options', $this->post); |
| 2832 | } |
| 2833 | |
| 2834 | // return array('status' => 'msg', 'why' => __('Entred path is not writable or does not exist.', 'backup-backup'), 'level' => 'warning'); |
| 2835 | |
| 2836 | return ['status' => 'success', 'errors' => $error]; |
| 2837 | } |
| 2838 | |
| 2839 | public function scanFilesForBackup(&$progress, $stgSites = [], $fileCalcType = false) { |
| 2840 | require_once BMI_INCLUDES . '/scanner/files.php'; |
| 2841 | |
| 2842 | $stagingSites = []; |
| 2843 | |
| 2844 | // Get all directory names of staging sites |
| 2845 | foreach ($stgSites as $index => $site) { |
| 2846 | |
| 2847 | // Convert every directory to their location path |
| 2848 | $stagingSites[] = '***ABSPATH***/' . $site['name']; |
| 2849 | |
| 2850 | } |
| 2851 | |
| 2852 | // Use filters? |
| 2853 | $is = Dashboard\bmi_get_config('BACKUP:FILES::FILTER') === 'true' ? true : false; |
| 2854 | |
| 2855 | // Get settings form config |
| 2856 | $fgp = Dashboard\bmi_get_config('BACKUP:FILES::PLUGINS'); |
| 2857 | $fgt = Dashboard\bmi_get_config('BACKUP:FILES::THEMES'); |
| 2858 | $fgu = Dashboard\bmi_get_config('BACKUP:FILES::UPLOADS'); |
| 2859 | $fgoc = Dashboard\bmi_get_config('BACKUP:FILES::OTHERS'); |
| 2860 | $fgwp = Dashboard\bmi_get_config('BACKUP:FILES::WP'); |
| 2861 | $dpathsis = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:DPATHS') === 'true' ? true : false; |
| 2862 | $dpaths = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:DPATHS:IN'); |
| 2863 | $dynamesis = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:NAMES') === 'true' ? true : false; |
| 2864 | $dynames = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:NAMES:IN'); |
| 2865 | $dynparsed = []; |
| 2866 | |
| 2867 | $isSmartExclusion =defined("BMI_BACKUP_PRO") && BMI_BACKUP_PRO && Dashboard\bmi_get_config('SMART:EXCLUSION:ENABLED') == 'true' ? true : false; |
| 2868 | $isCacheExcluded = $isSmartExclusion && (Dashboard\bmi_get_config('SMART:EXCLUSION:CACHE') == 'true' ? true : false); |
| 2869 | $isDeactivePluginsExcluded = $isSmartExclusion && (Dashboard\bmi_get_config('SMART:EXCLUSION:DPLUGINS') == 'true' ? true : false); |
| 2870 | $isNotUsedThemesExcluded = $isSmartExclusion && (Dashboard\bmi_get_config('SMART:EXCLUSION:NUTHEMES') == 'true' ? true : false); |
| 2871 | $isDebugLogsExcluded = $isSmartExclusion && (Dashboard\bmi_get_config('SMART:EXCLUSION:DLOGS') == 'true' ? true : false); |
| 2872 | $isPostRevisionsExcluded = $isSmartExclusion &&(Dashboard\bmi_get_config('SMART:EXCLUSION:PREVISIONS') == 'true' ? true : false); |
| 2873 | |
| 2874 | |
| 2875 | if ($fileCalcType != false) { |
| 2876 | $fgp = ($fileCalcType == 'plugins') ? true : false; |
| 2877 | $fgt = ($fileCalcType == 'themes') ? true : false; |
| 2878 | $fgu = ($fileCalcType == 'uploads') ? true : false; |
| 2879 | $fgoc = ($fileCalcType == 'contents_others') ? true : false; |
| 2880 | $fgwp = ($fileCalcType == 'wordpress') ? true : false; |
| 2881 | } |
| 2882 | |
| 2883 | // Filter dynames to for smaller size |
| 2884 | if ($is && $dynamesis) { |
| 2885 | for ($i = 0; $i < sizeof($dynames); ++$i) { |
| 2886 | $s = $dynames[$i]; |
| 2887 | if ($s->whr == '2') { |
| 2888 | $dynparsed[] = ['s' => $s->txt, 'w' => $s->pos, 'z' => strlen($s->txt)]; |
| 2889 | } |
| 2890 | } |
| 2891 | } |
| 2892 | |
| 2893 | // Set exclusion rules |
| 2894 | $ignored_folders_default = []; |
| 2895 | if ($is && $dynamesis) { |
| 2896 | BMP::merge_arrays($ignored_folders_default, $dynparsed); |
| 2897 | } |
| 2898 | $ignored_folders = $ignored_folders_default; |
| 2899 | $ignored_paths_default = [BMI_CONFIG_DIR, BMI_BACKUPS, BMI_ROOT_DIR]; |
| 2900 | $ignored_paths_default[] = "***ABSPATH***/wp-content/ai1wm-backups"; |
| 2901 | $ignored_paths_default[] = "***ABSPATH***/wp-content/ai1wm-backups-old"; |
| 2902 | $ignored_paths_default[] = "***ABSPATH***/wp-content/mwp-download"; |
| 2903 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/wp-clone"; |
| 2904 | $ignored_paths_default[] = "***ABSPATH***/wp-content/updraft"; |
| 2905 | $ignored_paths_default[] = "***ABSPATH***/wp-content/ebwp-backups"; |
| 2906 | $ignored_paths_default[] = "***ABSPATH***/wp-content/cache/seraphinite-accelerator"; |
| 2907 | $ignored_paths_default[] = "***ABSPATH***/wp-content/backups-dup-pro"; |
| 2908 | $ignored_paths_default[] = "***ABSPATH***/wp-content/wpvividbackups"; |
| 2909 | $ignored_paths_default[] = "***ABSPATH***/wp-content/backup-guard"; |
| 2910 | $ignored_paths_default[] = "***ABSPATH***/wp-content/backuply"; |
| 2911 | $ignored_paths_default[] = "***ABSPATH***/wp-content/backups-dup-lite"; |
| 2912 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/backupbuddy_backups"; |
| 2913 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/wp-file-manager-pro"; |
| 2914 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/wp-file-manager"; |
| 2915 | $ignored_paths_default[] = "***ABSPATH***/wp-content/plugins/akeebabackupwp"; |
| 2916 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/jetbackup"; |
| 2917 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/backup-guard"; |
| 2918 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/wp-migrate-db"; |
| 2919 | |
| 2920 | $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/wp-staging"; |
| 2921 | |
| 2922 | if ($isSmartExclusion && ($fileCalcType == false || $fileCalcType == 'database')) { |
| 2923 | if ($isCacheExcluded) { |
| 2924 | $ignored_paths_default = apply_filters('bmip_smart_exclusion_cache', $ignored_paths_default); |
| 2925 | } |
| 2926 | if ($isDeactivePluginsExcluded) { |
| 2927 | $ignored_paths_default = apply_filters('bmip_smart_exclusion_deactive_plugins', $ignored_paths_default); |
| 2928 | } |
| 2929 | if ($isNotUsedThemesExcluded) { |
| 2930 | $ignored_paths_default = apply_filters('bmip_smart_exclusion_not_used_themes', $ignored_paths_default); |
| 2931 | } |
| 2932 | } |
| 2933 | |
| 2934 | // Exclude cache directory permanently as it's just cache |
| 2935 | // $ignored_paths_default[] = "***ABSPATH***/wp-content/cache"; |
| 2936 | // $ignored_paths_default[] = "***ABSPATH***/wp-content/cache_bak"; |
| 2937 | // $ignored_paths_default[] = "***ABSPATH***/wp-content/uploads/cache"; |
| 2938 | |
| 2939 | // Add staging sites to permanent exclusion rules |
| 2940 | for ($i = 0; $i < sizeof($stagingSites); ++$i) { |
| 2941 | $ignored_paths_default[] = $stagingSites[$i]; |
| 2942 | } |
| 2943 | |
| 2944 | if (defined('BMI_PRO_ROOT_DIR')) $ignored_paths_default[] = BMI_PRO_ROOT_DIR; |
| 2945 | if ($is && $dpathsis) { |
| 2946 | BMP::merge_arrays($ignored_paths_default, $dpaths); |
| 2947 | } |
| 2948 | $ignored_paths = $ignored_paths_default; |
| 2949 | |
| 2950 | // Fix slashes for current system (directories) |
| 2951 | for ($i = 0; $i < sizeof($ignored_paths); ++$i) { |
| 2952 | $ignored_paths[$i] = str_replace('***ABSPATH***', untrailingslashit(ABSPATH), $ignored_paths[$i]); |
| 2953 | $ignored_paths[$i] = BMP::fixSlashes($ignored_paths[$i]); |
| 2954 | } |
| 2955 | |
| 2956 | // WordPress Paths |
| 2957 | $plugins_path = BMP::fixSlashes(WP_PLUGIN_DIR); |
| 2958 | $themes_path = BMP::fixSlashes(dirname(get_template_directory())); |
| 2959 | $uploads_path = BMP::fixSlashes(wp_upload_dir()['basedir']); |
| 2960 | $wp_contents = BMP::fixSlashes(WP_CONTENT_DIR); |
| 2961 | $wp_install = BMP::fixSlashes(ABSPATH); |
| 2962 | |
| 2963 | // Getting plugins |
| 2964 | $sfgp = Scanner::equalFolderByPath($wp_install, $plugins_path, $ignored_folders); |
| 2965 | if ($fgp == 'true' && !$sfgp) { |
| 2966 | $plugins_path_files = Scanner::scanFilesGetNamesWithIgnoreFBC($plugins_path, $ignored_folders, $ignored_paths); |
| 2967 | } |
| 2968 | |
| 2969 | // Getting themes |
| 2970 | $sfgt = Scanner::equalFolderByPath($wp_install, $themes_path, $ignored_folders); |
| 2971 | if ($fgt == 'true' && !$sfgt) { |
| 2972 | $themes_path_files = Scanner::scanFilesGetNamesWithIgnoreFBC($themes_path, $ignored_folders, $ignored_paths); |
| 2973 | } |
| 2974 | |
| 2975 | // Getting uploads |
| 2976 | $sfgu = Scanner::equalFolderByPath($wp_install, $uploads_path, $ignored_folders); |
| 2977 | if ($fgu == 'true' && !$sfgu) { |
| 2978 | $uploads_path_files = Scanner::scanFilesGetNamesWithIgnoreFBC($uploads_path, $ignored_folders, $ignored_paths); |
| 2979 | } |
| 2980 | |
| 2981 | // Ignore above paths |
| 2982 | $sfgoc = Scanner::equalFolderByPath($wp_install, $wp_contents, $ignored_folders); |
| 2983 | if ($fgoc == 'true' && !$sfgoc) { |
| 2984 | |
| 2985 | // Ignore common folders (already scanned) |
| 2986 | $content_folders = [$plugins_path, $themes_path, $uploads_path]; |
| 2987 | BMP::merge_arrays($content_folders, $ignored_paths); |
| 2988 | |
| 2989 | // Getting other contents |
| 2990 | $wp_contents_files = Scanner::scanFilesGetNamesWithIgnoreFBC($wp_contents, $ignored_folders, $content_folders); |
| 2991 | } |
| 2992 | |
| 2993 | // Ignore contents path |
| 2994 | if ($fgwp == 'true') { |
| 2995 | |
| 2996 | // Ignore contents file |
| 2997 | $ignored_paths[] = $wp_contents; |
| 2998 | |
| 2999 | // Getting WP Installation |
| 3000 | $wp_install_files = Scanner::scanFilesGetNamesWithIgnoreFBC($wp_install, $ignored_folders, $ignored_paths); |
| 3001 | } |
| 3002 | |
| 3003 | // Concat all file paths |
| 3004 | $all_files = []; |
| 3005 | if ($fgp == 'true' && !$sfgp) { |
| 3006 | BMP::merge_arrays($all_files, $plugins_path_files); |
| 3007 | unset($plugins_path_files); |
| 3008 | } |
| 3009 | |
| 3010 | if ($fgt == 'true' && !$sfgt) { |
| 3011 | BMP::merge_arrays($all_files, $themes_path_files); |
| 3012 | unset($themes_path_files); |
| 3013 | } |
| 3014 | |
| 3015 | if ($fgu == 'true' && !$sfgu) { |
| 3016 | BMP::merge_arrays($all_files, $uploads_path_files); |
| 3017 | unset($uploads_path_files); |
| 3018 | } |
| 3019 | |
| 3020 | if ($fgoc == 'true' && !$sfgoc) { |
| 3021 | BMP::merge_arrays($all_files, $wp_contents_files); |
| 3022 | unset($wp_contents_files); |
| 3023 | } |
| 3024 | |
| 3025 | if ($fgwp == 'true') { |
| 3026 | BMP::merge_arrays($all_files, $wp_install_files); |
| 3027 | unset($wp_install_files); |
| 3028 | } |
| 3029 | |
| 3030 | return $all_files; |
| 3031 | } |
| 3032 | |
| 3033 | public function parseFilesForBackup(&$files, &$progress, $cron = false, $dirCalc = false) { |
| 3034 | |
| 3035 | $is = Dashboard\bmi_get_config('BACKUP:FILES::FILTER') === 'true' ? true : false; |
| 3036 | $acis = (Dashboard\bmi_get_config('BACKUP:FILES::FILTER:FPATHS') === 'true' && $is) ? true : false; |
| 3037 | $ac = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:FPATHS:IN'); |
| 3038 | |
| 3039 | $abis = (Dashboard\bmi_get_config('BACKUP:FILES::FILTER:NAMES') === 'true' && $is) ? true : false; |
| 3040 | $ab = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:NAMES:IN'); |
| 3041 | $abres = []; |
| 3042 | $acres = new \stdClass(); |
| 3043 | |
| 3044 | $isSmartExclusion = defined("BMI_BACKUP_PRO") && BMI_BACKUP_PRO && Dashboard\bmi_get_config('SMART:EXCLUSION:ENABLED') == 'true' ? true : false; |
| 3045 | $isDebugLogsExcluded = $isSmartExclusion && (Dashboard\bmi_get_config('SMART:EXCLUSION:DLOGS') == 'true' ? true : false); |
| 3046 | |
| 3047 | // Local list of permanently blocked files |
| 3048 | if ($acis == false) { |
| 3049 | $acis = true; |
| 3050 | $ac = [ |
| 3051 | '***ABSPATH***/wp-content/uploads/wpforms/.htaccess.cpmh3129', // Binary broken file of wpforms |
| 3052 | '***ABSPATH***/wp-content/uploads/gravity_forms/.htaccess.cpmh3129', // Binary broken file of wpforms |
| 3053 | '***ABSPATH***/.htaccess.cpmh3129', // Binary broken file of wpforms |
| 3054 | '***ABSPATH***/logs/traffic.html/.md5sums', // Binary broken file of wpforms |
| 3055 | '***ABSPATH***/wp-config.php', // Exclude wp-config.php permanently |
| 3056 | '***ABSPATH***/wp-content/backup-migration-config.php' // Exclude BMI CONFIG hardly |
| 3057 | ]; |
| 3058 | } else { |
| 3059 | $ac[] = '***ABSPATH***/wp-content/uploads/wpforms/.htaccess.cpmh3129'; // Binary broken file of wpforms |
| 3060 | $ac[] = '***ABSPATH***/wp-content/uploads/gravity_forms/.htaccess.cpmh3129'; // Binary broken file of wpforms |
| 3061 | $ac[] = '***ABSPATH***/.htaccess.cpmh3129'; // Binary broken file of wpforms |
| 3062 | $ac[] = '***ABSPATH***/logs/traffic.html/.md5sums'; // Binary broken file of wpforms |
| 3063 | $ac[] = '***ABSPATH***/wp-config.php'; // Exclude wp-config.php permanently |
| 3064 | $ac[] = '***ABSPATH***/wp-content/backup-migration-config.php'; // Exclude BMI CONFIG hardly |
| 3065 | } |
| 3066 | |
| 3067 | if ($isDebugLogsExcluded) { |
| 3068 | $ac = apply_filters('bmip_smart_exclusion_debug_logs', $ac); |
| 3069 | } |
| 3070 | |
| 3071 | $temp_is = false; |
| 3072 | if ($is == false) { |
| 3073 | $temp_is = true; |
| 3074 | } |
| 3075 | |
| 3076 | if (($is && $acis) || $temp_is) { |
| 3077 | foreach ($ac as $key => $value) { |
| 3078 | $value = str_replace('***ABSPATH***', untrailingslashit(ABSPATH), $value); |
| 3079 | $value = BMP::fixSlashes($value); |
| 3080 | $acres->{$value} = 1; |
| 3081 | } |
| 3082 | } |
| 3083 | |
| 3084 | if ($is && $abis) { |
| 3085 | for ($i = 0; $i < sizeof($ab); ++$i) { |
| 3086 | $s = $ab[$i]; |
| 3087 | if ($s->whr == '1') { |
| 3088 | $abres[] = ['s' => $s->txt, 'w' => $s->pos, 'z' => strlen($s->txt)]; |
| 3089 | } |
| 3090 | } |
| 3091 | } |
| 3092 | |
| 3093 | $limitcrl = 64; |
| 3094 | $cliEnabled = false; |
| 3095 | if (defined('BMI_CLI_ENABLED')) $cliEnabled = apply_filters('bmi_cli_enabled', BMI_CLI_ENABLED); |
| 3096 | if ($dirCalc && $cliEnabled && !defined('BMI_CLI_FAILED')) $limitcrl = 128; |
| 3097 | $first_big = false; |
| 3098 | $sizemax = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:SIZE:IN'); |
| 3099 | $usesize = (Dashboard\bmi_get_config('BACKUP:FILES::FILTER:SIZE') === 'true' && $is) ? true : false; |
| 3100 | if (!is_numeric($sizemax)) { |
| 3101 | $usesize = false; |
| 3102 | $sizemax = 99999; |
| 3103 | } else { |
| 3104 | $sizemax = intval($sizemax); |
| 3105 | } |
| 3106 | |
| 3107 | // If legacy === false it will use background process to bypass the timeout |
| 3108 | if ($dirCalc) { |
| 3109 | $legacy = true; |
| 3110 | } else { |
| 3111 | $legacyVersion = apply_filters('bmi_legacy_version', BMI_LEGACY_VERSION); |
| 3112 | $legacyHardVersion = apply_filters('bmi_legacy_hard_version', BMI_LEGACY_HARD_VERSION); |
| 3113 | $functionNormal = apply_filters('bmi_function_normal', BMI_FUNCTION_NORMAL); |
| 3114 | if (!defined('BMI_LEGACY_VERSION')) $legacy = true; |
| 3115 | else $legacy = $legacyVersion; |
| 3116 | if ($legacy && defined('BMI_LEGACY_HARD_VERSION') && !$legacyHardVersion) $legacy = $legacyHardVersion; |
| 3117 | $cliEnabled = false; |
| 3118 | if (defined('BMI_CLI_ENABLED')) $cliEnabled = apply_filters('bmi_cli_enabled', BMI_CLI_ENABLED); |
| 3119 | if (defined('BMI_FUNCTION_NORMAL') && $cliEnabled === true && $functionNormal === true && !defined('BMI_CLI_FAILED')) $legacy = false; |
| 3120 | } |
| 3121 | |
| 3122 | $total_size = 0; |
| 3123 | $excludedBytes = 0; |
| 3124 | $max = $sizemax * (1024 * 1024); |
| 3125 | $maxfor = sizeof($files); |
| 3126 | |
| 3127 | // Non-legacy variables |
| 3128 | if ($legacy === false) { |
| 3129 | $Hx = trailingslashit(WP_CONTENT_DIR); |
| 3130 | $Hz = trailingslashit(ABSPATH); |
| 3131 | $Hxs = strlen($Hx); |
| 3132 | $Hzs = strlen($Hz); |
| 3133 | } |
| 3134 | |
| 3135 | // Sort it by size |
| 3136 | if ($legacy === false) { |
| 3137 | usort($files, function ($a, $b) { |
| 3138 | $a = explode(',', $a); |
| 3139 | $last = sizeof($a) - 1; |
| 3140 | $sizea = intval($a[$last]); |
| 3141 | |
| 3142 | $b = explode(',', $b); |
| 3143 | $last = sizeof($b) - 1; |
| 3144 | $sizeb = intval($b[$last]); |
| 3145 | |
| 3146 | if ($sizea == $sizeb) return 0; |
| 3147 | if ($sizea < $sizeb) return -1; |
| 3148 | else return 1; |
| 3149 | }); |
| 3150 | } |
| 3151 | |
| 3152 | // Process due to rules |
| 3153 | for ($i = 0; $i < $maxfor; ++$i) { |
| 3154 | |
| 3155 | // Remove size from path and get the size |
| 3156 | $files[$i] = explode(',', $files[$i]); |
| 3157 | $last = sizeof($files[$i]) - 1; |
| 3158 | $size = intval($files[$i][$last]); |
| 3159 | unset($files[$i][$last]); |
| 3160 | $files[$i] = implode(',', $files[$i]); |
| 3161 | |
| 3162 | if ($usesize && Scanner::fileTooLarge($size, $max)) { |
| 3163 | if (!$dirCalc) $progress->log(__("Removing file from backup (too large) ", 'backup-backup') . $files[$i] . ' (' . number_format(($size / 1024 / 1024), 2) . ' MB)', 'WARN'); |
| 3164 | array_splice($files, $i, 1); |
| 3165 | $maxfor--; |
| 3166 | $i--; |
| 3167 | |
| 3168 | $excludedBytes += $size; |
| 3169 | continue; |
| 3170 | } |
| 3171 | |
| 3172 | if ($abis && Scanner::equalFolder(basename($files[$i]), $abres)) { |
| 3173 | if (!$dirCalc) $progress->log(__("Removing file from backup (due to exclude rules): ", 'backup-backup') . $files[$i], 'WARN'); |
| 3174 | array_splice($files, $i, 1); |
| 3175 | $maxfor--; |
| 3176 | $i--; |
| 3177 | |
| 3178 | $excludedBytes += $size; |
| 3179 | continue; |
| 3180 | } |
| 3181 | |
| 3182 | if ($acis && property_exists($acres, $files[$i])) { |
| 3183 | if (!$dirCalc) $progress->log(__("Removing file from backup (due to path rules): ", 'backup-backup') . $files[$i], 'WARN'); |
| 3184 | array_splice($files, $i, 1); |
| 3185 | $maxfor--; |
| 3186 | $i--; |
| 3187 | |
| 3188 | $excludedBytes += $size; |
| 3189 | continue; |
| 3190 | } |
| 3191 | |
| 3192 | // if ($size === 0) { |
| 3193 | // array_splice($files, $i, 1); |
| 3194 | // $maxfor--; |
| 3195 | // $i--; |
| 3196 | |
| 3197 | // $excludedBytes += $size; |
| 3198 | // continue; |
| 3199 | // } |
| 3200 | |
| 3201 | if (strpos($files[$i], 'bmi-pclzip-') !== false || strpos($files[$i], 'backup-migration') !== false) { |
| 3202 | array_splice($files, $i, 1); |
| 3203 | $maxfor--; |
| 3204 | $i--; |
| 3205 | |
| 3206 | $excludedBytes += $size; |
| 3207 | continue; |
| 3208 | } |
| 3209 | |
| 3210 | if ($size > ($limitcrl * (1024 * 1024))) { |
| 3211 | if ($first_big === false) $first_big = $i; |
| 3212 | if (!$dirCalc) $progress->log(__("This file is quite big consider to exclude it, if backup fails: ", 'backup-backup') . $files[$i] . ' (' . BMP::humanSize($size) . ')', 'WARN'); |
| 3213 | } |
| 3214 | |
| 3215 | $functionNormal = apply_filters('bmi_function_normal', BMI_FUNCTION_NORMAL); |
| 3216 | $cliEnabled = apply_filters('bmi_cli_enabled', defined('BMI_CLI_ENABLED') ? BMI_CLI_ENABLED : false); |
| 3217 | if (($legacy === false && ($functionNormal === false || ($functionNormal === true && $cliEnabled === true))) && (!defined('BMI_USING_CLI_FUNCTIONALITY') || BMI_USING_CLI_FUNCTIONALITY === false)) { |
| 3218 | $fx = strpos($files[$i], $Hx); |
| 3219 | $fz = strpos($files[$i], $Hz); |
| 3220 | |
| 3221 | if ($fx !== false) $files[$i] = substr_replace($files[$i], '@1@', $fx, $Hxs); |
| 3222 | else if ($fz !== false) $files[$i] = substr_replace($files[$i], '@2@', $fz, $Hzs); |
| 3223 | |
| 3224 | $files[$i] .= ',' . $size; |
| 3225 | } |
| 3226 | $total_size += $size; |
| 3227 | } |
| 3228 | |
| 3229 | if ($legacy === false && (!defined('BMI_USING_CLI_FUNCTIONALITY') || BMI_USING_CLI_FUNCTIONALITY === false)) { |
| 3230 | $list_file = BMI_TMP . DIRECTORY_SEPARATOR . 'files_latest.list'; |
| 3231 | if (file_exists($list_file)) @unlink($list_file); |
| 3232 | $files_list = fopen($list_file, 'a'); |
| 3233 | if ($first_big === false) fwrite($files_list, sizeof($files) . "_-1\r\n"); |
| 3234 | else fwrite($files_list, sizeof($files) . '_' . $first_big . "\r\n"); |
| 3235 | for ($i = 0; $i < sizeof($files); ++$i) { |
| 3236 | fwrite($files_list, $files[$i] . "\r\n"); |
| 3237 | } |
| 3238 | fclose($files_list); |
| 3239 | $this->first_big = $first_big; |
| 3240 | } |
| 3241 | |
| 3242 | $this->total_excluded_size_for_backup = $excludedBytes; |
| 3243 | $this->total_size_for_backup = $total_size; |
| 3244 | $this->total_size_for_backup_in_mb = ($total_size / 1024 / 1024); |
| 3245 | |
| 3246 | return $files; |
| 3247 | } |
| 3248 | |
| 3249 | public function toggleBackupLock($unlock = false) { |
| 3250 | |
| 3251 | // Require lib |
| 3252 | require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'zipper' . DIRECTORY_SEPARATOR . 'zipping.php'; |
| 3253 | |
| 3254 | // Backup name |
| 3255 | $filename = $this->post['filename']; |
| 3256 | |
| 3257 | // Init Zipper |
| 3258 | $zipper = new Zipper(); |
| 3259 | |
| 3260 | // Path to Backup |
| 3261 | $path = BMI_BACKUPS . DIRECTORY_SEPARATOR . $filename; |
| 3262 | $path_dir = BMP::fixSlashes(dirname($path)); |
| 3263 | |
| 3264 | // Check if file exists |
| 3265 | if (!file_exists($path)) { |
| 3266 | return ['status' => 'fail']; |
| 3267 | } |
| 3268 | |
| 3269 | // Check if directory is correct |
| 3270 | if ($path_dir != BMP::fixSlashes(BMI_BACKUPS)) { |
| 3271 | return ['status' => 'fail']; |
| 3272 | } |
| 3273 | |
| 3274 | // Toggle the lock |
| 3275 | $status = $zipper->lock_zip($path, $unlock); |
| 3276 | |
| 3277 | // Return the status |
| 3278 | return ['status' => ($status ? 'success' : 'fail')]; |
| 3279 | } |
| 3280 | |
| 3281 | public function getDynamicNames() { |
| 3282 | $data = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:NAMES:IN'); |
| 3283 | $fpdata = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:FPATHS:IN'); |
| 3284 | $fddata = Dashboard\bmi_get_config('BACKUP:FILES::FILTER:DPATHS:IN'); |
| 3285 | |
| 3286 | for ($i = 0; $i < sizeof($fpdata); ++$i) { |
| 3287 | $fpdata[$i] = BMP::fixSlashes($fpdata[$i]); |
| 3288 | } |
| 3289 | |
| 3290 | for ($i = 0; $i < sizeof($fddata); ++$i) { |
| 3291 | $fddata[$i] = BMP::fixSlashes($fddata[$i]); |
| 3292 | } |
| 3293 | |
| 3294 | return [ |
| 3295 | 'status' => 'success', |
| 3296 | 'dynamic-fpaths-names' => $fpdata, |
| 3297 | 'dynamic-dpaths-names' => $fddata, |
| 3298 | 'data' => $data |
| 3299 | ]; |
| 3300 | } |
| 3301 | |
| 3302 | public function resetConfiguration() { |
| 3303 | |
| 3304 | if (file_exists(BMI_CONFIG_PATH)) { |
| 3305 | @unlink(BMI_CONFIG_PATH); |
| 3306 | } |
| 3307 | |
| 3308 | delete_option('bmi_hotfixes'); |
| 3309 | delete_option('bmip_to_be_uploaded'); |
| 3310 | delete_option('bmi_pro_gd_client_id'); |
| 3311 | delete_option('bmi_pro_gd_token'); |
| 3312 | delete_option('bmi_pro_cron_domain_done'); |
| 3313 | delete_option('BMI::STORAGE::LOCAL::PATH'); |
| 3314 | |
| 3315 | // update_option('BMI_LOGS_SHARING_IS_ALLOWED', 'unknown'); |
| 3316 | |
| 3317 | return ['status' => 'success']; |
| 3318 | |
| 3319 | } |
| 3320 | |
| 3321 | public function getSiteData() { |
| 3322 | require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'check' . DIRECTORY_SEPARATOR . 'system_info.php'; |
| 3323 | $bmi = new SI(); |
| 3324 | $bmi = $bmi->to_array(); |
| 3325 | |
| 3326 | return ['status' => 'success', 'data' => $bmi]; |
| 3327 | } |
| 3328 | |
| 3329 | public function calculateCron() { |
| 3330 | require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'cron' . DIRECTORY_SEPARATOR . 'handler.php'; |
| 3331 | |
| 3332 | $minutes = []; |
| 3333 | $keeps = []; |
| 3334 | $days = []; |
| 3335 | $weeks = []; |
| 3336 | $hours = []; |
| 3337 | |
| 3338 | for ($i = 1; $i <= 28; ++$i) { |
| 3339 | $days[] = substr('0' . $i, -2); |
| 3340 | } |
| 3341 | for ($i = 1; $i <= 7; ++$i) { |
| 3342 | $weeks[] = $i . ''; |
| 3343 | } |
| 3344 | for ($i = 0; $i <= 23; ++$i) { |
| 3345 | $hours[] = substr('0' . $i, -2); |
| 3346 | } |
| 3347 | for ($i = 0; $i <= 55; $i += 5) { |
| 3348 | $minutes[] = substr('0' . $i, -2); |
| 3349 | } |
| 3350 | for ($i = 1; $i <= 20; ++$i) { |
| 3351 | $keeps[] = $i . ''; |
| 3352 | } |
| 3353 | |
| 3354 | $errors = 0; |
| 3355 | if (in_array($this->post['type'], ['month', 'week', 'day'])) { |
| 3356 | if (!Dashboard\bmi_set_config('CRON:TYPE', $this->post['type'])) { |
| 3357 | $errors++; |
| 3358 | } |
| 3359 | } |
| 3360 | if (in_array($this->post['day'], $days)) { |
| 3361 | if (!Dashboard\bmi_set_config('CRON:DAY', $this->post['day'])) { |
| 3362 | $errors++; |
| 3363 | } |
| 3364 | } |
| 3365 | if (in_array($this->post['week'], $weeks)) { |
| 3366 | if (!Dashboard\bmi_set_config('CRON:WEEK', $this->post['week'])) { |
| 3367 | $errors++; |
| 3368 | } |
| 3369 | } |
| 3370 | if (in_array($this->post['hour'], $hours)) { |
| 3371 | if (!Dashboard\bmi_set_config('CRON:HOUR', $this->post['hour'])) { |
| 3372 | $errors++; |
| 3373 | } |
| 3374 | } |
| 3375 | if (in_array($this->post['minute'], $minutes)) { |
| 3376 | if (!Dashboard\bmi_set_config('CRON:MINUTE', $this->post['minute'])) { |
| 3377 | $errors++; |
| 3378 | } |
| 3379 | } |
| 3380 | if (in_array($this->post['keep'], $keeps)) { |
| 3381 | if (!Dashboard\bmi_set_config('CRON:KEEP', $this->post['keep'])) { |
| 3382 | $errors++; |
| 3383 | } |
| 3384 | } |
| 3385 | |
| 3386 | if ($this->post['enabled'] === 'true') { |
| 3387 | $this->post['enabled'] = true; |
| 3388 | } else { |
| 3389 | $this->post['enabled'] = false; |
| 3390 | } |
| 3391 | |
| 3392 | if (!Dashboard\bmi_set_config('CRON:ENABLED', $this->post['enabled'])) { |
| 3393 | $errors++; |
| 3394 | } |
| 3395 | |
| 3396 | if ($errors === 0) { |
| 3397 | $time = Crons::calculate_date([ |
| 3398 | 'type' => $this->post['type'], |
| 3399 | 'week' => $this->post['week'], |
| 3400 | 'day' => $this->post['day'], |
| 3401 | 'hour' => $this->post['hour'], |
| 3402 | 'minute' => $this->post['minute'] |
| 3403 | ], time()); |
| 3404 | |
| 3405 | $file = BMI_TMP . DIRECTORY_SEPARATOR . '.plan'; |
| 3406 | if (file_exists($file)) { |
| 3407 | $earlier = intval(file_get_contents($file)); |
| 3408 | } else { |
| 3409 | $earlier = 0; |
| 3410 | } |
| 3411 | |
| 3412 | if (!wp_next_scheduled('bmi_do_backup_right_now') || $earlier === 0 || (abs($time - $earlier) >= 15)) { |
| 3413 | wp_clear_scheduled_hook('bmi_do_backup_right_now'); |
| 3414 | if ($this->post['enabled'] === true) { |
| 3415 | wp_schedule_single_event($time, 'bmi_do_backup_right_now'); |
| 3416 | file_put_contents($file, $time); |
| 3417 | } |
| 3418 | } |
| 3419 | |
| 3420 | return [ |
| 3421 | 'status' => 'success', |
| 3422 | 'data' => date('Y-m-d H:i:s', $time), |
| 3423 | 'currdata' => date('Y-m-d H:i:s') |
| 3424 | ]; |
| 3425 | } else { |
| 3426 | return ['status' => 'error']; |
| 3427 | } |
| 3428 | } |
| 3429 | |
| 3430 | public function dismissErrorNotice() { |
| 3431 | $optionId = isset($this->post['option_id']) ? $this->post['option_id'] : ''; |
| 3432 | if (in_array($optionId, ['backupbliss-issues', 'backupbliss-dismiss-upload-issue'])) |
| 3433 | { |
| 3434 | require_once BMI_INCLUDES . '/external/backupbliss.php'; |
| 3435 | $backupbliss = new BackupBliss(); |
| 3436 | } |
| 3437 | |
| 3438 | switch ($optionId) { |
| 3439 | case 'email-issues': |
| 3440 | delete_option('bmi_display_email_issues'); |
| 3441 | break; |
| 3442 | case 'before-update-issues': |
| 3443 | delete_option('bmi_display_before_update_backup_issues'); |
| 3444 | break; |
| 3445 | case 'aws-issues': |
| 3446 | update_option('bmip_aws_dismiss_issue', true); |
| 3447 | break; |
| 3448 | case 'wasabi-issues': |
| 3449 | update_option('bmip_wasabi_dismiss_issue', true); |
| 3450 | break; |
| 3451 | case 'sftp-issues': |
| 3452 | update_option('bmip_sftp_dismiss_issue', true); |
| 3453 | break; |
| 3454 | case 'gdrive-issues': |
| 3455 | delete_transient('bmip_gd_issue'); |
| 3456 | break; |
| 3457 | case 'backupbliss-issues': |
| 3458 | $backupbliss->removeNotice("invalid_key"); |
| 3459 | $backupbliss->removeNotice("invalid_permission"); |
| 3460 | if ($backupbliss->getNotice("storage_warn")) |
| 3461 | $backupbliss->hideNotice("storage_warn", 60 * 60); |
| 3462 | if ($backupbliss->getNotice("upload_issue")) |
| 3463 | $backupbliss->hideNotice("upload_issue", 60); //Hide only for a minute |
| 3464 | break; |
| 3465 | case 'backupbliss-dismiss-upload-issue': |
| 3466 | $backupbliss->hideFailureWarnNotice(14 * 24 * 60 * 60); //14 days |
| 3467 | break; |
| 3468 | case 'security-plugin-warning': |
| 3469 | update_option('bmi_security_warning_dismiss', true); |
| 3470 | default: |
| 3471 | break; |
| 3472 | } |
| 3473 | } |
| 3474 | |
| 3475 | // recursive removal |
| 3476 | private function rrmdir($dir) { |
| 3477 | |
| 3478 | if (is_dir($dir)) { |
| 3479 | |
| 3480 | $objects = scandir($dir); |
| 3481 | foreach ($objects as $object) { |
| 3482 | |
| 3483 | if ($object != "." && $object != "..") { |
| 3484 | |
| 3485 | if (is_dir($dir . DIRECTORY_SEPARATOR . $object) && !is_link($dir . DIRECTORY_SEPARATOR . $object)) { |
| 3486 | |
| 3487 | $this->rrmdir($dir . DIRECTORY_SEPARATOR . $object); |
| 3488 | |
| 3489 | } else { |
| 3490 | |
| 3491 | @unlink($dir . DIRECTORY_SEPARATOR . $object); |
| 3492 | |
| 3493 | } |
| 3494 | |
| 3495 | } |
| 3496 | |
| 3497 | } |
| 3498 | |
| 3499 | @rmdir($dir); |
| 3500 | |
| 3501 | } else { |
| 3502 | |
| 3503 | if (file_exists($dir) && is_file($dir)) { |
| 3504 | |
| 3505 | @unlink($dir); |
| 3506 | |
| 3507 | } |
| 3508 | |
| 3509 | } |
| 3510 | |
| 3511 | } |
| 3512 | |
| 3513 | public function forceBackupToStop() { |
| 3514 | |
| 3515 | $filesToBeRemoved = []; |
| 3516 | |
| 3517 | $tmp_dir = BMI_ROOT_DIR . DIRECTORY_SEPARATOR . 'tmp'; |
| 3518 | if (!is_dir($tmp_dir)) @mkdir($tmp_dir, 0755, true); |
| 3519 | |
| 3520 | foreach (scandir($tmp_dir) as $filename) { |
| 3521 | |
| 3522 | if (in_array($filename, ['.', '..'])) continue; |
| 3523 | $path = BMI_ROOT_DIR . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . $filename; |
| 3524 | $filesToBeRemoved[] = $path; |
| 3525 | |
| 3526 | } |
| 3527 | |
| 3528 | $allowedFiles = ['wp-config.php', '.htaccess', '.litespeed', '.default.json', 'driveKeys.php', 'dropboxKeys.php', '.autologin.php', '.migrationFinished', 'onedriveKeys.php', 'awsKeys.php', 'wasabiKeys.php', 'backupblissKeys.php', 'sftpKeys.php']; |
| 3529 | foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . '.*') as $filename) { |
| 3530 | |
| 3531 | $basename = basename($filename); |
| 3532 | |
| 3533 | if (in_array($basename, ['.', '..'])) continue; |
| 3534 | if (is_file($filename) && !in_array($basename, $allowedFiles)) { |
| 3535 | $filesToBeRemoved[] = $filename; |
| 3536 | } |
| 3537 | |
| 3538 | } |
| 3539 | |
| 3540 | foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . 'BMI-*', GLOB_ONLYDIR) as $filename) { |
| 3541 | |
| 3542 | $basename = basename($filename); |
| 3543 | |
| 3544 | if (in_array($basename, ['.', '..'])) continue; |
| 3545 | if (is_dir($filename) && !in_array($filename, $allowedFiles)) { |
| 3546 | $filesToBeRemoved[] = $filename; |
| 3547 | } |
| 3548 | |
| 3549 | } |
| 3550 | |
| 3551 | foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . 'bg-BMI-*', GLOB_ONLYDIR) as $filename) { |
| 3552 | |
| 3553 | $basename = basename($filename); |
| 3554 | |
| 3555 | if (in_array($basename, ['.', '..'])) continue; |
| 3556 | if (is_dir($filename) && !in_array($filename, $allowedFiles)) { |
| 3557 | $filesToBeRemoved[] = $filename; |
| 3558 | } |
| 3559 | |
| 3560 | } |
| 3561 | |
| 3562 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.backup_cli_lock'; |
| 3563 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.backup_cli_lock_ended'; |
| 3564 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.backup_cli_lock_end'; |
| 3565 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.last_triggered'; |
| 3566 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running'; |
| 3567 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.space_check'; |
| 3568 | $filesToBeRemoved[] = BMI_TMP . DIRECTORY_SEPARATOR . 'db_tables'; |
| 3569 | $filesToBeRemoved[] = BMI_TMP . DIRECTORY_SEPARATOR . 'bmi_backup_manifest.json'; |
| 3570 | $filesToBeRemoved[] = BMI_TMP . DIRECTORY_SEPARATOR . 'files_latest.list'; |
| 3571 | $filesToBeRemoved[] = BMI_TMP . DIRECTORY_SEPARATOR . 'currentBackupConfig.php'; |
| 3572 | |
| 3573 | if (is_array($filesToBeRemoved) || is_object($filesToBeRemoved)) { |
| 3574 | foreach ((array) $filesToBeRemoved as $file) { |
| 3575 | $this->rrmdir($file); |
| 3576 | } |
| 3577 | } |
| 3578 | |
| 3579 | return ['status' => 'success']; |
| 3580 | |
| 3581 | } |
| 3582 | |
| 3583 | public function forceRestoreToStop() { |
| 3584 | |
| 3585 | $filesToBeRemoved = []; |
| 3586 | |
| 3587 | $themedir = get_theme_root(); |
| 3588 | $tempTheme = $themedir . DIRECTORY_SEPARATOR . 'backup_migration_restoration_in_progress'; |
| 3589 | $filesToBeRemoved[] = $tempTheme; |
| 3590 | |
| 3591 | $tmpDirectory = BMI_ROOT_DIR . DIRECTORY_SEPARATOR . 'tmp'; |
| 3592 | if (!is_dir($tmpDirectory)) @mkdir($tmpDirectory, 0755, true); |
| 3593 | |
| 3594 | foreach (scandir($tmpDirectory) as $filename) { |
| 3595 | |
| 3596 | if (in_array($filename, ['.', '..'])) continue; |
| 3597 | $path = BMI_ROOT_DIR . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . $filename; |
| 3598 | $filesToBeRemoved[] = $path; |
| 3599 | |
| 3600 | } |
| 3601 | |
| 3602 | foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . 'backup-migration_??????????') as $filename) { |
| 3603 | |
| 3604 | $basename = basename($filename); |
| 3605 | |
| 3606 | if (is_dir($filename) && !in_array($basename, ['.', '..'])) { |
| 3607 | $filesToBeRemoved[] = $filename; |
| 3608 | } |
| 3609 | |
| 3610 | } |
| 3611 | |
| 3612 | $allowedFiles = ['wp-config.php', '.htaccess', '.litespeed', '.default.json', 'driveKeys.php', 'dropboxKeys.php', '.autologin.php', '.migrationFinished', 'onedriveKeys.php','awsKeys.php', 'wasabiKeys.php', 'backupblissKeys.php', 'sftpKeys.php']; |
| 3613 | foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . '.*') as $filename) { |
| 3614 | |
| 3615 | $basename = basename($filename); |
| 3616 | |
| 3617 | if (in_array($basename, ['.', '..'])) continue; |
| 3618 | if (is_file($filename) && !in_array($basename, $allowedFiles)) { |
| 3619 | $filesToBeRemoved[] = $filename; |
| 3620 | } |
| 3621 | |
| 3622 | } |
| 3623 | |
| 3624 | foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . 'restore_scan_*') as $filename) { |
| 3625 | |
| 3626 | $basename = basename($filename); |
| 3627 | |
| 3628 | if (in_array($basename, ['.', '..'])) continue; |
| 3629 | if (is_file($filename) && !in_array($basename, $allowedFiles)) { |
| 3630 | $filesToBeRemoved[] = $filename; |
| 3631 | } |
| 3632 | |
| 3633 | } |
| 3634 | |
| 3635 | foreach (glob(untrailingslashit(ABSPATH) . DIRECTORY_SEPARATOR . 'wp-config.??????????.php') as $filename) { |
| 3636 | |
| 3637 | $basename = basename($filename); |
| 3638 | |
| 3639 | if (in_array($basename, ['.', '..'])) continue; |
| 3640 | if (is_file($filename) && !in_array($filename, $allowedFiles)) { |
| 3641 | $filesToBeRemoved[] = $filename; |
| 3642 | } |
| 3643 | |
| 3644 | } |
| 3645 | |
| 3646 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock'; |
| 3647 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock_cli'; |
| 3648 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock_cli_end'; |
| 3649 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock_ended'; |
| 3650 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.cli_download_last'; |
| 3651 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running'; |
| 3652 | $filesToBeRemoved[] = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.space_check'; |
| 3653 | $filesToBeRemoved[] = BMI_TMP . DIRECTORY_SEPARATOR . '.restore_secret'; |
| 3654 | $filesToBeRemoved[] = BMI_TMP . DIRECTORY_SEPARATOR . '.table_map'; |
| 3655 | |
| 3656 | if (is_array($filesToBeRemoved) || is_object($filesToBeRemoved)) { |
| 3657 | foreach ((array) $filesToBeRemoved as $file) { |
| 3658 | $this->rrmdir($file); |
| 3659 | } |
| 3660 | } |
| 3661 | |
| 3662 | return ['status' => 'success']; |
| 3663 | |
| 3664 | } |
| 3665 | |
| 3666 | public function sendTroubleshootingDetails($send_type = 'manual', $triggeredBy = false, $blocking = true) { |
| 3667 | |
| 3668 | global $table_prefix; |
| 3669 | |
| 3670 | require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'check' . DIRECTORY_SEPARATOR . 'system_info.php'; |
| 3671 | $bmiSiteData = new SI(); |
| 3672 | $bmiSiteData = $bmiSiteData->to_array(); |
| 3673 | $bmiSiteData['database_size'] = $this->getDatabaseSize(); |
| 3674 | $bmiSiteData['database_size_mb'] = BMP::humanSize($bmiSiteData['database_size']); |
| 3675 | $bmiSiteData['xhria'] = get_option('z__bmi_xhria', 'none'); |
| 3676 | $bmiSiteData['current_table_prefix'] = $table_prefix; |
| 3677 | |
| 3678 | $wpconfigPath = ABSPATH . DIRECTORY_SEPARATOR . 'wp-config.php'; |
| 3679 | if (file_exists($wpconfigPath)) { |
| 3680 | $bmiSiteData['is_wp_config_writable'] = is_writable($wpconfigPath) ? "yes" : "no"; |
| 3681 | } else { |
| 3682 | $bmiSiteData['is_wp_config_writable'] = "file_does_not_exist?"; |
| 3683 | } |
| 3684 | |
| 3685 | $latestBackupLogs = 'does_not_exist'; |
| 3686 | $latestBackupProgress = 'does_not_exist'; |
| 3687 | $latestRestorationLogs = 'does_not_exist'; |
| 3688 | $latestRestorationProgress = 'does_not_exist'; |
| 3689 | $latestStagingLogs = 'does_not_exist'; |
| 3690 | $latestStagingProgress = 'does_not_exist'; |
| 3691 | $currentPluginConfig = 'does_not_exist'; |
| 3692 | $pluginGlobalLogs = 'does_not_exist'; |
| 3693 | $backgroundErrors = 'does_not_exist'; |
| 3694 | |
| 3695 | if (file_exists(BMI_BACKUPS . '/latest.log')) { |
| 3696 | $latestBackupLogs = file_get_contents(BMI_BACKUPS . '/latest.log'); |
| 3697 | } |
| 3698 | |
| 3699 | if (file_exists(BMI_BACKUPS . '/latest_progress.log')) { |
| 3700 | $latestBackupProgress = file_get_contents(BMI_BACKUPS . '/latest_progress.log'); |
| 3701 | } |
| 3702 | |
| 3703 | if (file_exists(BMI_BACKUPS . '/latest_migration.log')) { |
| 3704 | $latestRestorationLogs = file_get_contents(BMI_BACKUPS . '/latest_migration.log'); |
| 3705 | } |
| 3706 | |
| 3707 | if (file_exists(BMI_BACKUPS . '/latest_migration_progress.log')) { |
| 3708 | $latestRestorationProgress = file_get_contents(BMI_BACKUPS . '/latest_migration_progress.log'); |
| 3709 | } |
| 3710 | |
| 3711 | if (file_exists(BMI_STAGING . '/latest_staging.log')) { |
| 3712 | $latestStagingLogs = file_get_contents(BMI_STAGING . '/latest_staging.log'); |
| 3713 | } |
| 3714 | |
| 3715 | if (file_exists(BMI_STAGING . '/latest_staging_progress.log')) { |
| 3716 | $latestStagingProgress = file_get_contents(BMI_STAGING . '/latest_staging_progress.log'); |
| 3717 | } |
| 3718 | |
| 3719 | if (file_exists(BMI_CONFIG_PATH)) { |
| 3720 | $currentPluginConfig = substr(file_get_contents(BMI_CONFIG_PATH), 8); |
| 3721 | } |
| 3722 | |
| 3723 | $completeLogsPath = BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'complete_logs.log'; |
| 3724 | if (file_exists($completeLogsPath)) { |
| 3725 | if ((filesize($completeLogsPath) / 1024 / 1024) <= 4) { |
| 3726 | $pluginGlobalLogs = file_get_contents($completeLogsPath); |
| 3727 | } else { |
| 3728 | $fp = fopen($completeLogsPath, 'rb'); |
| 3729 | if ($fp) { |
| 3730 | $seekPos = max(0, $fileSize - (4 * 1024 * 1024)); |
| 3731 | fseek($fp, $seekPos, SEEK_SET); |
| 3732 | $pluginGlobalLogs = fread($fp, 4 * 1024 * 1024); |
| 3733 | fclose($fp); |
| 3734 | file_put_contents($completeLogsPath, $pluginGlobalLogs); // Save the last 4MB |
| 3735 | } else { |
| 3736 | $pluginGlobalLogs = 'could_not_open_file'; |
| 3737 | } |
| 3738 | } |
| 3739 | } |
| 3740 | |
| 3741 | $backgroundLogsPath = BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'background-errors.log'; |
| 3742 | if (file_exists($backgroundLogsPath)) { |
| 3743 | if ((filesize($backgroundLogsPath) / 1024 / 1024) <= 4) { |
| 3744 | $backgroundErrors = file_get_contents($backgroundLogsPath); |
| 3745 | } else { |
| 3746 | @unlink($backgroundLogsPath); |
| 3747 | @touch($backgroundLogsPath); |
| 3748 | $backgroundErrors = 'file_too_large'; |
| 3749 | } |
| 3750 | } |
| 3751 | |
| 3752 | $ifCLI = false; |
| 3753 | if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) { |
| 3754 | $ifCLI = true; |
| 3755 | } |
| 3756 | |
| 3757 | $logsSourceFrontEnd = 'manual'; |
| 3758 | if ($triggeredBy != false) { |
| 3759 | $logsSourceFrontEnd = $triggeredBy; |
| 3760 | } |
| 3761 | if (isset($this->post['source']) && in_array($this->post['source'], ['backup', 'migration', 'staging'])) { |
| 3762 | $logsSourceFrontEnd = $this->post['source']; |
| 3763 | } |
| 3764 | |
| 3765 | $latestBackupLogs = preg_replace('/\:\ ((.*)\.zip)/', ': *****.zip', $latestBackupLogs); |
| 3766 | $latestRestorationLogs = preg_replace('/backup\-id\=(.*)\.zip/', 'backup-id=[***redacted***].zip', $latestRestorationLogs); |
| 3767 | $latestStagingLogs = preg_replace('/\:\ ((.*)\.zip)/', ': *****.zip', $latestStagingLogs); |
| 3768 | |
| 3769 | $currentPluginConfig = json_decode($currentPluginConfig); |
| 3770 | unset($currentPluginConfig->{"OTHER:EMAIL"}); |
| 3771 | $currentPluginConfig = json_encode($currentPluginConfig); |
| 3772 | |
| 3773 | $url = 'https://' . BMI_API_BACKUPBLISS_PUSH . '/v1' . '/push'; |
| 3774 | $data = array( |
| 3775 | 'method' => 'POST', |
| 3776 | 'timeout' => 15, |
| 3777 | 'blocking' => $blocking, |
| 3778 | 'sslverify' => false, |
| 3779 | 'send_type' => $send_type, |
| 3780 | 'body' => array( |
| 3781 | 'admin_url' => admin_url(), |
| 3782 | 'home_url' => home_url(), |
| 3783 | 'site_url' => get_site_url(), |
| 3784 | 'is_multisite' => is_multisite() ? "yes" : "no", |
| 3785 | 'is_abspath_writable' => is_writable(ABSPATH) ? "yes" : "no", |
| 3786 | 'site_information' => $bmiSiteData, |
| 3787 | 'latest_backup_logs' => $latestBackupLogs, |
| 3788 | 'latest_backup_progress' => $latestBackupProgress, |
| 3789 | 'latest_restoration_logs' => $latestRestorationLogs, |
| 3790 | 'latest_restoration_progress' => $latestRestorationProgress, |
| 3791 | 'latest_staging_logs' => $latestStagingLogs, |
| 3792 | 'latest_staging_progress' => $latestStagingProgress, |
| 3793 | 'current_plugin_config' => $currentPluginConfig, |
| 3794 | 'plugin_global_logs' => $pluginGlobalLogs, |
| 3795 | 'background_errors' => $backgroundErrors, |
| 3796 | 'triggered_by' => $logsSourceFrontEnd, |
| 3797 | 'is_defined' => defined('BMI_BACKUP_PRO') ? 'yes' : 'no', |
| 3798 | 'is_cli' => $ifCLI |
| 3799 | ) |
| 3800 | ); |
| 3801 | |
| 3802 | $disabled_functions = explode(',', ini_get('disable_functions')); |
| 3803 | $vA = !in_array('curl_exec', $disabled_functions); |
| 3804 | $vB = !in_array('curl_init', $disabled_functions); |
| 3805 | $vC = !in_array('http_build_query', $disabled_functions); |
| 3806 | $vD = !in_array('stream_context_create', $disabled_functions); |
| 3807 | $vE = !in_array('file_get_contents', $disabled_functions); |
| 3808 | $vF = false; |
| 3809 | $response = false; |
| 3810 | |
| 3811 | if (function_exists('curl_version') && function_exists('curl_exec') && function_exists('curl_init') && $vA && $vB) { |
| 3812 | |
| 3813 | $response = wp_remote_post($url, $data); |
| 3814 | |
| 3815 | } else { |
| 3816 | |
| 3817 | if (ini_get('allow_url_fopen') == true && $vC && $vD && $vE) { |
| 3818 | |
| 3819 | $vF = true; |
| 3820 | $postdata = http_build_query($data['body']); |
| 3821 | |
| 3822 | $opts = [ |
| 3823 | 'ssl' => [ 'verify_peer_name' => false, 'verify_peer' => false ], |
| 3824 | 'http' => [ |
| 3825 | 'method' => 'POST', |
| 3826 | 'header' => 'Content-type: application/x-www-form-urlencoded', |
| 3827 | 'content' => $postdata |
| 3828 | ] |
| 3829 | ]; |
| 3830 | |
| 3831 | $context = stream_context_create($opts); |
| 3832 | $result = file_get_contents($url, false, $context); |
| 3833 | |
| 3834 | $response = [ 'body' => $result ]; |
| 3835 | |
| 3836 | } |
| 3837 | |
| 3838 | } |
| 3839 | |
| 3840 | if ($response === false || is_wp_error($response)) { |
| 3841 | $error_message = $response->get_error_message(); |
| 3842 | Logger::error($error_message, 'backup-backup'); |
| 3843 | return ['status' => 'fail']; |
| 3844 | } else { |
| 3845 | try { |
| 3846 | $body = json_decode($response['body']); |
| 3847 | if (isset($body->code)) { |
| 3848 | return ['status' => 'success', 'code' => sanitize_text_field($body->code)]; |
| 3849 | } else { |
| 3850 | return ['status' => 'fail']; |
| 3851 | } |
| 3852 | } catch (\Exception $e) { |
| 3853 | Logger::error(print_r($e, true), 'backup-backup'); |
| 3854 | return ['status' => 'fail']; |
| 3855 | } catch (\Throwable $t) { |
| 3856 | Logger::error(print_r($t, true), 'backup-backup'); |
| 3857 | return ['status' => 'fail']; |
| 3858 | } |
| 3859 | } |
| 3860 | |
| 3861 | } |
| 3862 | |
| 3863 | public function actionsAfterProcess($success = false, $triggeredBy = 'backup') { |
| 3864 | |
| 3865 | $afterMigrationLock = BMI_TMP . DIRECTORY_SEPARATOR . '.migrationFinished'; |
| 3866 | if ($success) { |
| 3867 | |
| 3868 | file_put_contents($afterMigrationLock, ''); |
| 3869 | Logger::log("Process (" . $triggeredBy . ") finished successfully via ajax.php"); |
| 3870 | |
| 3871 | } else { |
| 3872 | |
| 3873 | Logger::log("Process (" . $triggeredBy . ") finished with errors via ajax.php"); |
| 3874 | if (file_exists($afterMigrationLock)) @unlink($afterMigrationLock); |
| 3875 | |
| 3876 | } |
| 3877 | |
| 3878 | if (file_exists(BMI_TMP . DIRECTORY_SEPARATOR . 'restore_parts.json')) @unlink(BMI_TMP . DIRECTORY_SEPARATOR . 'restore_parts.json'); |
| 3879 | |
| 3880 | |
| 3881 | if (has_action('bmi_premium_after_process') || (defined('BACKUP_TRIGGERED_BY_URL') && BACKUP_TRIGGERED_BY_URL === true)){ |
| 3882 | do_action('bmi_premium_after_process', $success, $triggeredBy, defined('BACKUP_TRIGGERED_BY_URL') && BACKUP_TRIGGERED_BY_URL === true); |
| 3883 | } |
| 3884 | |
| 3885 | BMP::handle_after_cron(); |
| 3886 | |
| 3887 | return null; |
| 3888 | |
| 3889 | // REMOVED CODE: |
| 3890 | // $canShare = BMP::canShareLogsOrShouldAsk(); |
| 3891 | // if ($canShare === 'allowed') { |
| 3892 | // |
| 3893 | // $send_type = 'error'; |
| 3894 | // if ($success) $send_type = 'success'; |
| 3895 | // $this->sendTroubleshootingDetails($send_type, $triggeredBy, false); |
| 3896 | // |
| 3897 | // } |
| 3898 | |
| 3899 | } |
| 3900 | |
| 3901 | public function logSharing() { |
| 3902 | |
| 3903 | $type = $this->post['question']; |
| 3904 | |
| 3905 | if ($type == 'set_yes') { |
| 3906 | |
| 3907 | // $isOk = Dashboard\bmi_set_config('LOGS::SHARING', 'yes'); |
| 3908 | // update_option('BMI_LOGS_SHARING_IS_ALLOWED', 'yes'); |
| 3909 | return ['status' => 'success']; |
| 3910 | |
| 3911 | } else if ($type == 'set_no') { |
| 3912 | |
| 3913 | // $isOk = Dashboard\bmi_set_config('LOGS::SHARING', 'no'); |
| 3914 | // update_option('BMI_LOGS_SHARING_IS_ALLOWED', 'no'); |
| 3915 | return ['status' => 'success']; |
| 3916 | |
| 3917 | } else if ($type == 'is_allowed') { |
| 3918 | |
| 3919 | // $canShare = BMP::canShareLogsOrShouldAsk(); |
| 3920 | // return ['status' => 'success', 'result' => $canShare]; |
| 3921 | return ['status' => 'success', 'result' => 'not-allowed']; |
| 3922 | |
| 3923 | } else { |
| 3924 | |
| 3925 | return ['status' => 'fail']; |
| 3926 | |
| 3927 | } |
| 3928 | |
| 3929 | } |
| 3930 | |
| 3931 | public function getLatestBackupFile() { |
| 3932 | |
| 3933 | $dir = BMI_BACKUPS; |
| 3934 | $backupdir = array_diff(scandir($dir), ['..', '.']); |
| 3935 | $backups = []; |
| 3936 | foreach ($backupdir as $index => $name) { |
| 3937 | |
| 3938 | $ext = pathinfo($dir . DIRECTORY_SEPARATOR . $name, PATHINFO_EXTENSION); |
| 3939 | |
| 3940 | if (in_array($ext, ['zip', 'tar', 'gz'])) { |
| 3941 | $backups[] = [ |
| 3942 | 'cdate' => filemtime($dir . DIRECTORY_SEPARATOR . $name), |
| 3943 | 'name' => $name |
| 3944 | ]; |
| 3945 | } |
| 3946 | |
| 3947 | } |
| 3948 | |
| 3949 | usort($backups, function ($a, $b) { |
| 3950 | if (intval($a['cdate']) < intval($b['cdate'])) return 1; |
| 3951 | else return -1; |
| 3952 | }); |
| 3953 | |
| 3954 | $backups = array_values($backups); |
| 3955 | |
| 3956 | if (sizeof($backups) > 0) { |
| 3957 | return $backups[0]['name']; |
| 3958 | } else { |
| 3959 | return '---'; |
| 3960 | } |
| 3961 | |
| 3962 | } |
| 3963 | |
| 3964 | /** |
| 3965 | * isStagingSiteCreationOngoing - Checks if the process is ongoing or not |
| 3966 | * |
| 3967 | * @return {bool} true if the process is running false if its not |
| 3968 | */ |
| 3969 | public function isStagingSiteCreationOngoing() { |
| 3970 | |
| 3971 | $staging_lock = BMI_STAGING . '/.staging_lock'; |
| 3972 | if (file_exists($staging_lock) && (time() - filemtime($staging_lock)) <= 15) { |
| 3973 | return true; |
| 3974 | } else { |
| 3975 | return false; |
| 3976 | } |
| 3977 | |
| 3978 | } |
| 3979 | |
| 3980 | /** |
| 3981 | * checkStagingLocalName - Verifies name of staging site and checks if it's not currently running |
| 3982 | * Can be called for verification pre start or during start on initial request |
| 3983 | * |
| 3984 | * @param {string} $name = false name of staging site if called without ajax |
| 3985 | * @return {array} with status/fail/progress data |
| 3986 | */ |
| 3987 | public function checkStagingLocalName($name = false) { |
| 3988 | |
| 3989 | if ($name == false && isset($this->post['name'])) { |
| 3990 | $name = $this->post['name']; |
| 3991 | } |
| 3992 | |
| 3993 | $ongoing = __('Staging site creation is already ongoing, please wait and try again.', 'backup-backup'); |
| 3994 | $empty = __('You have to provide some staging site name before process.', 'backup-backup'); |
| 3995 | $toolong = __('Staging site name cannot be longer than 24 characters.', 'backup-backup'); |
| 3996 | $invalid = __('Provided name contains prohibited characters.', 'backup-backup'); |
| 3997 | $blacklisted = __('This name is not allowed to be used, please pick different one.', 'backup-backup'); |
| 3998 | $exist = __('Seems like directory or staging site with that name already exist, pick different one.', 'backup-backup'); |
| 3999 | $dashes = __('Name cannot start or end with dash or underscore.', 'backup-backup'); |
| 4000 | |
| 4001 | if ($this->isStagingSiteCreationOngoing()) { |
| 4002 | return ['status' => 'fail', 'message' => $ongoing]; |
| 4003 | } |
| 4004 | |
| 4005 | if (strlen($name) <= 0) { |
| 4006 | return ['status' => 'fail', 'message' => $empty]; |
| 4007 | } |
| 4008 | |
| 4009 | if (!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) { |
| 4010 | return ['status' => 'fail', 'message' => $invalid]; |
| 4011 | } |
| 4012 | |
| 4013 | if (strlen($name) >= 24) { |
| 4014 | return ['status' => 'fail', 'message' => $toolong]; |
| 4015 | } |
| 4016 | |
| 4017 | if (in_array($name[0], ['_', '-']) || in_array($name[strlen($name) - 1], ['_', '-'])) { |
| 4018 | return ['status' => 'fail', 'message' => $dashes]; |
| 4019 | } |
| 4020 | |
| 4021 | $bannedNames = [ |
| 4022 | 'wp-content', |
| 4023 | 'wp-admin', |
| 4024 | 'wp-includes', |
| 4025 | 'content', |
| 4026 | 'admin', |
| 4027 | 'includes', |
| 4028 | 'tmp', |
| 4029 | '.well-known', |
| 4030 | 'download', |
| 4031 | 'downloads', |
| 4032 | 'google', |
| 4033 | 'temporary' |
| 4034 | ]; |
| 4035 | |
| 4036 | if (strpos($name, '.') !== false) { |
| 4037 | return ['status' => 'fail', 'message' => $blacklisted]; |
| 4038 | } |
| 4039 | |
| 4040 | if (in_array($name, $bannedNames)) { |
| 4041 | return ['status' => 'fail', 'message' => $blacklisted]; |
| 4042 | } |
| 4043 | |
| 4044 | $path = trailingslashit(ABSPATH) . $name; |
| 4045 | if (file_exists($path) || is_dir($path)) { |
| 4046 | return ['status' => 'fail', 'message' => $exist]; |
| 4047 | } |
| 4048 | |
| 4049 | return ['status' => 'success']; |
| 4050 | |
| 4051 | } |
| 4052 | |
| 4053 | /** |
| 4054 | * startLocalStagingCreation - Initials creation of staging site process |
| 4055 | * |
| 4056 | * @return {array} with status/fail/progress data |
| 4057 | */ |
| 4058 | public function startLocalStagingCreation() { |
| 4059 | |
| 4060 | // Verification of state |
| 4061 | $name = $this->post['name']; |
| 4062 | $verification = $this->checkStagingLocalName($name); |
| 4063 | $staging_lock = BMI_STAGING . '/.staging_lock'; |
| 4064 | |
| 4065 | // Fail in case of wrong data or state |
| 4066 | if (isset($verification['status']) && $verification['status'] != 'success') { |
| 4067 | return $verification; |
| 4068 | } |
| 4069 | |
| 4070 | // Update lock file to prevent double processes |
| 4071 | touch($staging_lock); |
| 4072 | |
| 4073 | // Include local staging site controller |
| 4074 | require_once BMI_INCLUDES . '/staging/local.php'; |
| 4075 | $staging = new StagingLocal($name, true); |
| 4076 | |
| 4077 | // Append the return if staging process requires more batches |
| 4078 | if ($staging->continue == true) return $staging->continuationData; |
| 4079 | |
| 4080 | return [ 'status' => 'continue', 'data' => [ 'name' => $name ] ]; |
| 4081 | |
| 4082 | } |
| 4083 | |
| 4084 | /** |
| 4085 | * stagingSitesGetList - Returns staging sites list |
| 4086 | * |
| 4087 | * @return {array} with staging sites data |
| 4088 | */ |
| 4089 | public function stagingSitesGetList() { |
| 4090 | |
| 4091 | // Include local staging site controller |
| 4092 | require_once BMI_INCLUDES . '/staging/controller.php'; |
| 4093 | $staging = new Staging('..ajax..'); |
| 4094 | $sites = $staging->getStagingSites(); |
| 4095 | |
| 4096 | return [ 'status' => 'success', 'sites' => $sites ]; |
| 4097 | |
| 4098 | } |
| 4099 | |
| 4100 | /** |
| 4101 | * stagingRename - Renames display name |
| 4102 | * |
| 4103 | * @return {array} status |
| 4104 | */ |
| 4105 | public function stagingRename() { |
| 4106 | |
| 4107 | $name = $this->post['name']; |
| 4108 | $newName = $this->post['new']; |
| 4109 | |
| 4110 | // Include local staging site controller |
| 4111 | require_once BMI_INCLUDES . '/staging/controller.php'; |
| 4112 | $staging = new Staging('..ajax..'); |
| 4113 | return $staging->rename($name, $newName); |
| 4114 | |
| 4115 | } |
| 4116 | |
| 4117 | /** |
| 4118 | * stagingPrepareLogin - Prepares login script |
| 4119 | * |
| 4120 | * @return {array} login credentials |
| 4121 | */ |
| 4122 | public function stagingPrepareLogin() { |
| 4123 | |
| 4124 | $name = $this->post['name']; |
| 4125 | |
| 4126 | // Include local staging site controller |
| 4127 | require_once BMI_INCLUDES . '/staging/controller.php'; |
| 4128 | $staging = new Staging('..ajax..'); |
| 4129 | return $staging->prepareLogin($name); |
| 4130 | |
| 4131 | } |
| 4132 | |
| 4133 | /** |
| 4134 | * Handles secure backup via browser method |
| 4135 | */ |
| 4136 | public function backupBrowserMethodHandler() { |
| 4137 | |
| 4138 | try { |
| 4139 | |
| 4140 | // Load bypasser |
| 4141 | require_once BMI_INCLUDES . '/backup-process.php'; |
| 4142 | $request = new Bypasser(false, BMI_CONFIG_DIR, trailingslashit(WP_CONTENT_DIR), BMI_BACKUPS, trailingslashit(ABSPATH), plugin_dir_path(BMI_ROOT_FILE)); |
| 4143 | |
| 4144 | // Handle request |
| 4145 | $request->handle_batch(); |
| 4146 | $request->shutdown(); |
| 4147 | return; |
| 4148 | |
| 4149 | } catch (\Exception $e) { |
| 4150 | |
| 4151 | error_log('There was an error with Backup Migration plugin: ' . $e->getMessage()); |
| 4152 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#01' . '|' . $e->getMessage()); |
| 4153 | error_log(strval($e)); |
| 4154 | |
| 4155 | } catch (\Throwable $t) { |
| 4156 | |
| 4157 | error_log('There was an error with Backup Migration plugin: ' . $t->getMessage()); |
| 4158 | Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#01' . '|' . $t->getMessage()); |
| 4159 | error_log(strval($t)); |
| 4160 | |
| 4161 | } |
| 4162 | |
| 4163 | return [ 'status' => 'error' ]; |
| 4164 | |
| 4165 | } |
| 4166 | |
| 4167 | /** |
| 4168 | * Handles ajax error on browser side, keep alive timeout etc. |
| 4169 | * |
| 4170 | * @return array static success |
| 4171 | */ |
| 4172 | public function frontEndAjaxError() { |
| 4173 | |
| 4174 | if ($this->post['call'] == 'create-backup') { |
| 4175 | require_once BMI_INCLUDES . '/progress/zip.php'; |
| 4176 | $logger = new Progress('', 0, 0, false, false); |
| 4177 | } else if (in_array($this->post['call'], ['restore-backup', 'download-backup', 'continue_restore_process'])) { |
| 4178 | require_once BMI_INCLUDES . '/progress/migration.php'; |
| 4179 | $logger = new MigrationProgress(true); |
| 4180 | } else if (in_array($this->post['call'], ['staging-start-local-creation', 'staging-local-creation-process', 'staging-tastewp-creation-process'])) { |
| 4181 | require_once BMI_INCLUDES . '/progress/staging.php'; |
| 4182 | $logger = new StagingProgress(true); |
| 4183 | } |
| 4184 | |
| 4185 | if (isset($this->post['error'])) { |
| 4186 | |
| 4187 | Logger::error('Front End Ajax Error START'); |
| 4188 | if (isset($logger)) $logger->log('Front End Ajax Error START', 'verbose'); |
| 4189 | |
| 4190 | if (is_array($this->post['error'])) { |
| 4191 | |
| 4192 | $errors = $this->post['error']; |
| 4193 | foreach ($errors as $k => $val) { |
| 4194 | $error = sanitize_text_field(print_r($val, true)); |
| 4195 | Logger::error($k . ' = ' . $error); |
| 4196 | if (isset($logger)) $logger->log($k . ' = ' . $error, 'verbose'); |
| 4197 | } |
| 4198 | |
| 4199 | } else { |
| 4200 | |
| 4201 | $theError = sanitize_text_field(print_r($this->post->error, true)); |
| 4202 | Logger::error('Front End Ajax Error: ' . $theError); |
| 4203 | if (isset($logger)) $logger->log($theError, 'verbose'); |
| 4204 | |
| 4205 | } |
| 4206 | |
| 4207 | Logger::error('Front End Ajax Error END'); |
| 4208 | if (isset($logger)) $logger->log('Front End Ajax Error END', 'verbose'); |
| 4209 | |
| 4210 | } else { |
| 4211 | |
| 4212 | Logger::error('Front End Ajax Error was called, but no error included.'); |
| 4213 | |
| 4214 | } |
| 4215 | |
| 4216 | if (isset($logger)) { |
| 4217 | $logger->log(__('Browser-side error detected, the process will try to restart with alternative methods, otherwise it will throw error window.', 'backup-backup'), 'error'); |
| 4218 | $logger->log('Browser-side error detected, the process will try to restart with alternative methods, otherwise it will throw error window.', 'verbose'); |
| 4219 | } |
| 4220 | |
| 4221 | return [ 'status' => 'success' ]; |
| 4222 | |
| 4223 | } |
| 4224 | |
| 4225 | /** |
| 4226 | * stagingDelete - Removes the staging site |
| 4227 | * |
| 4228 | * @return {array} status |
| 4229 | */ |
| 4230 | public function stagingDelete() { |
| 4231 | |
| 4232 | $name = $this->post['name']; |
| 4233 | |
| 4234 | // Include local staging site controller |
| 4235 | require_once BMI_INCLUDES . '/staging/controller.php'; |
| 4236 | $staging = new Staging('..ajax..'); |
| 4237 | return $staging->delete($name); |
| 4238 | |
| 4239 | } |
| 4240 | |
| 4241 | /** |
| 4242 | * localStagingCreationProcess - Method that can continue batching of Staging process |
| 4243 | * |
| 4244 | * @return {array} data that should be send back to this function as POST |
| 4245 | */ |
| 4246 | public function localStagingCreationProcess() { |
| 4247 | |
| 4248 | // Get $name and declare lock file |
| 4249 | $name = $this->post['name']; |
| 4250 | $staging_lock = BMI_STAGING . '/.staging_lock'; |
| 4251 | |
| 4252 | // Update lock file to prevent double processes |
| 4253 | touch($staging_lock); |
| 4254 | |
| 4255 | // Include local staging site controller |
| 4256 | require_once BMI_INCLUDES . '/staging/local.php'; |
| 4257 | $staging = new StagingLocal($name); |
| 4258 | |
| 4259 | // Process handler |
| 4260 | if (isset($this->post['delete'])) { |
| 4261 | $staging->requestDelete(); |
| 4262 | } else $staging->continueProcess(); |
| 4263 | |
| 4264 | // Append the return if staging process requires more batches |
| 4265 | if ($staging->continue == true) return $staging->continuationData; |
| 4266 | |
| 4267 | // Send success if nothing went wrong which finishes the process |
| 4268 | if (file_exists($staging_lock)) @unlink($staging_lock); |
| 4269 | return ['status' => 'error']; |
| 4270 | |
| 4271 | } |
| 4272 | |
| 4273 | /** |
| 4274 | * tastewpStagingCreation - Initializes and declares staging site will |
| 4275 | * |
| 4276 | * @return {array} batching status |
| 4277 | */ |
| 4278 | public function tastewpStagingCreation() { |
| 4279 | |
| 4280 | // Get $name and declare lock file |
| 4281 | $name = $this->post['name']; |
| 4282 | $backupName = isset($this->post['backupName']) ? $this->post['backupName'] : false; |
| 4283 | $initialize = isset($this->post['initialize']) ? $this->post['initialize'] : false; |
| 4284 | $staging_lock = BMI_STAGING . '/.staging_lock'; |
| 4285 | |
| 4286 | // Fix var type |
| 4287 | if ($initialize === true || $initialize == 'true') $initialize = true; |
| 4288 | else $initialize = false; |
| 4289 | |
| 4290 | // Update lock file to prevent double processes |
| 4291 | touch($staging_lock); |
| 4292 | |
| 4293 | // Include TasteWP staging site controller |
| 4294 | require_once BMI_INCLUDES . '/staging/tastewp.php'; |
| 4295 | |
| 4296 | // Process handler |
| 4297 | if (isset($this->post['delete'])) { |
| 4298 | $delete = true; |
| 4299 | } else $delete = false; |
| 4300 | |
| 4301 | // Make first handshake with TasteWP |
| 4302 | $staging = new StagingTasteWP($name, $initialize, $backupName, $delete); |
| 4303 | |
| 4304 | // Append the return if staging process requires more batches |
| 4305 | if ($staging->continue == true) return $staging->continuationData; |
| 4306 | |
| 4307 | // Send success if nothing went wrong which finishes the process |
| 4308 | if (file_exists($staging_lock)) @unlink($staging_lock); |
| 4309 | return ['status' => 'error']; |
| 4310 | |
| 4311 | } |
| 4312 | |
| 4313 | public function debugging() { |
| 4314 | |
| 4315 | require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'scanner' . DIRECTORY_SEPARATOR . 'backups.php'; |
| 4316 | $backups = new Backups(); |
| 4317 | $availableBackups = $backups->getAvailableBackups(); |
| 4318 | $list = $availableBackups['local']; |
| 4319 | |
| 4320 | // $cron_list = []; |
| 4321 | // $cron_dates = []; |
| 4322 | // foreach ($list as $key => $value) { |
| 4323 | // if ($list[$key][6] == true) { |
| 4324 | // if ($list[$key][5] == 'unlocked') { |
| 4325 | // $cron_list[$list[$key][1]] = $list[$key][0]; |
| 4326 | // $cron_dates[] = $list[$key][1]; |
| 4327 | // } |
| 4328 | // } |
| 4329 | // } |
| 4330 | |
| 4331 | // usort($cron_dates, function ($a, $b) { |
| 4332 | // return (strtotime($a) < strtotime($b)) ? -1 : 1; |
| 4333 | // }); |
| 4334 | |
| 4335 | // $cron_dates = array_slice($cron_dates, 0, -(intval(Dashboard\bmi_get_config('CRON:KEEP')))); |
| 4336 | // foreach ($cron_dates as $key => $value) { |
| 4337 | // $name = $cron_list[$cron_dates[$key]]; |
| 4338 | // $name = explode('#%&', $name)[1]; |
| 4339 | // Logger::log(__("Removing backup due to keep rules: ", 'backup-backup') . $name); |
| 4340 | // @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . $name); |
| 4341 | // } |
| 4342 | |
| 4343 | if (isset($availableBackups['external']['gdrive'])) { |
| 4344 | $sortedMD5s = []; |
| 4345 | $gdrive = $availableBackups['external']['gdrive']; |
| 4346 | foreach ($gdrive as $md5 => $data) { |
| 4347 | if ($gdrive[$md5][6] == true && $gdrive[$md5][5] == 'unlocked') { |
| 4348 | $sortedMD5s[] = [$gdrive[$md5][1], $md5]; |
| 4349 | } |
| 4350 | } |
| 4351 | |
| 4352 | usort($sortedMD5s, function ($a, $b) { |
| 4353 | return (strtotime($a[0]) < strtotime($b[0])) ? -1 : 1; |
| 4354 | }); |
| 4355 | |
| 4356 | $gdrive_md5s = array_slice($sortedMD5s, 0, -(intval(Dashboard\bmi_get_config('CRON:KEEP')))); |
| 4357 | foreach ($sortedMD5s as $index => $data) { |
| 4358 | $md5 = $data[1]; |
| 4359 | |
| 4360 | } |
| 4361 | } |
| 4362 | |
| 4363 | return ['availableBackups' => $availableBackups, '$gdrive' => $sortedMD5s]; |
| 4364 | |
| 4365 | } |
| 4366 | |
| 4367 | public function checkCompatibility() { |
| 4368 | |
| 4369 | $for = isset($this->post['for']) ? $this->post['for'] : 'backup'; |
| 4370 | |
| 4371 | require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'check' . DIRECTORY_SEPARATOR . 'compatibility.php'; |
| 4372 | $compatibility = new Compatibility($for); |
| 4373 | $errors = $compatibility->check(); |
| 4374 | return ['status' => 'success', 'data' => $errors]; |
| 4375 | } |
| 4376 | |
| 4377 | public function checkDiskSpace(){ |
| 4378 | $file = BMI_BACKUPS . '/' . '.space_check'; |
| 4379 | |
| 4380 | $backupSize = BMP::getRecentSize() * 1.4; |
| 4381 | |
| 4382 | try { |
| 4383 | $size = $backupSize; |
| 4384 | $fh = fopen($file, 'w'); |
| 4385 | while($size > 0){ |
| 4386 | $chunk = 1024; |
| 4387 | fputs($fh, str_pad('', min($chunk, $size))); |
| 4388 | $size -= $chunk; |
| 4389 | } |
| 4390 | fclose($fh); |
| 4391 | |
| 4392 | $fs = filesize($file); |
| 4393 | @unlink($file); |
| 4394 | |
| 4395 | return ['status' => 'enough-space']; |
| 4396 | |
| 4397 | |
| 4398 | } catch (\Exception $e) { |
| 4399 | if (file_exists($file)){ |
| 4400 | $fileSize = filesize($file); |
| 4401 | unlink($file); |
| 4402 | |
| 4403 | return ['status' => 'not-enough-space', 'data' => ['available' => BMP::humanSize(intval($fileSize)), 'required' => BMP::humanSize(intval($backupSize))]]; |
| 4404 | } |
| 4405 | |
| 4406 | } catch (\Throwable $e) { |
| 4407 | if (file_exists($file)){ |
| 4408 | $fileSize = filesize($file); |
| 4409 | unlink($file); |
| 4410 | return ['status' => 'not-enough-space', 'data' => ['available' => BMP::humanSize(intval($fileSize)), 'required' => BMP::humanSize(intval($backupSize))]]; |
| 4411 | } |
| 4412 | |
| 4413 | } |
| 4414 | } |
| 4415 | |
| 4416 | public function cleanUpAfterError() { |
| 4417 | $runningFile = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running'; |
| 4418 | $spaceCheckFile = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.space_check'; |
| 4419 | |
| 4420 | if (file_exists($runningFile)){ |
| 4421 | $backupName = file_get_contents($runningFile); |
| 4422 | if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupName)){ |
| 4423 | $partialBackup = glob(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupName . '.??????'); |
| 4424 | if (is_array($partialBackup) && !empty($partialBackup)){ |
| 4425 | foreach ($partialBackup as $file){ |
| 4426 | @unlink($file); |
| 4427 | } |
| 4428 | } |
| 4429 | @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupName); |
| 4430 | } |
| 4431 | @unlink($runningFile); |
| 4432 | } |
| 4433 | |
| 4434 | if (file_exists($spaceCheckFile)){ |
| 4435 | @unlink($spaceCheckFile); |
| 4436 | } |
| 4437 | } |
| 4438 | |
| 4439 | } |
| 4440 |