backup
4 years ago
database
7 years ago
exception
9 years ago
extension
8 years ago
log
4 years ago
notice
5 years ago
restore
4 years ago
schedule
4 years ago
storage
3 years ago
widget
8 years ago
SGBoot.php
4 years ago
SGConfig.php
4 years ago
SGPing.php
4 years ago
functions.php
3 years ago
SGBoot.php
325 lines
| 1 | <?php |
| 2 | |
| 3 | //check PHP version |
| 4 | if (version_compare(PHP_VERSION, '5.3.3', '<')) { |
| 5 | die('PHP >=5.3.3 version required.'); |
| 6 | } |
| 7 | |
| 8 | require_once SG_EXCEPTION_PATH . 'SGException.php'; |
| 9 | require_once SG_CORE_PATH . 'functions.php'; |
| 10 | backupGuardIncludeFile(SG_CORE_PATH . 'functions.silver.php'); |
| 11 | backupGuardIncludeFile(SG_CORE_PATH . 'functions.gold.php'); |
| 12 | backupGuardIncludeFile(SG_CORE_PATH . 'functions.platinum.php'); |
| 13 | require_once SG_CORE_PATH . 'SGPing.php'; |
| 14 | require_once SG_DATABASE_PATH . 'SGDatabase.php'; |
| 15 | require_once SG_CORE_PATH . 'SGConfig.php'; |
| 16 | require_once SG_NOTICE_PATH . 'SGNotice.php'; |
| 17 | require_once SG_NOTICE_PATH . 'SGNoticeHandler.php'; |
| 18 | backupGuardIncludeFile(SG_BACKUP_PATH . 'SGBackupSchedule.php'); |
| 19 | backupGuardIncludeFile(SG_EXTENSION_PATH . 'SGExtension.php'); |
| 20 | |
| 21 | class SGBoot |
| 22 | { |
| 23 | public static $executionTimeLimit = 0; |
| 24 | public static $memoryLimit = 0; |
| 25 | |
| 26 | public static function init() |
| 27 | { |
| 28 | //get current execution time limit |
| 29 | self::$executionTimeLimit = ini_get('max_execution_time'); |
| 30 | |
| 31 | //get current memory limit |
| 32 | self::$memoryLimit = ini_get('memory_limit'); |
| 33 | |
| 34 | //remove execution time limit |
| 35 | @ini_set('max_execution_time', 0); |
| 36 | |
| 37 | //change initial memory limit |
| 38 | @ini_set('memory_limit', '512M'); |
| 39 | |
| 40 | //don't let server to abort scripts |
| 41 | @ignore_user_abort(true); |
| 42 | |
| 43 | //load all config variables from database |
| 44 | SGConfig::getAll(); |
| 45 | |
| 46 | // TODO: remove |
| 47 | backupGuardMigrateDownloadMode(); |
| 48 | |
| 49 | try { |
| 50 | //check minimum requirements |
| 51 | self::checkMinimumRequirements(); |
| 52 | |
| 53 | //prepare directory for backups |
| 54 | self::prepare(); |
| 55 | } catch (SGException $exception) { |
| 56 | die($exception); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | public static function didInstallForFirstTime() |
| 61 | { |
| 62 | self::setPluginInstallUpdateDate(); |
| 63 | } |
| 64 | |
| 65 | public static function didUpdatePluginVersion() |
| 66 | { |
| 67 | self::setPluginInstallUpdateDate(); |
| 68 | } |
| 69 | |
| 70 | public static function setPluginInstallUpdateDate() |
| 71 | { |
| 72 | SGConfig::set('SG_PLUGIN_INSTALL_UPDATE_DATE', time()); |
| 73 | } |
| 74 | |
| 75 | private static function installConfigTable($sgdb) |
| 76 | { |
| 77 | $dbEngine = backupGuardGetDatabaseEngine(); |
| 78 | $downloadMode = backupGuardCheckDownloadMode(); |
| 79 | //create config table |
| 80 | $res = $sgdb->query( |
| 81 | 'CREATE TABLE IF NOT EXISTS `' . SG_CONFIG_TABLE_NAME . '` ( |
| 82 | `ckey` varchar(100) NOT NULL, |
| 83 | `cvalue` text NOT NULL, |
| 84 | PRIMARY KEY (`ckey`) |
| 85 | ) ENGINE=' . $dbEngine . ' DEFAULT CHARSET=utf8;' |
| 86 | ); |
| 87 | if ($res === false) { |
| 88 | return false; |
| 89 | } |
| 90 | |
| 91 | //delete all content from config table (just in case if wasn't dropped) |
| 92 | $sgdb->query('DELETE FROM `' . SG_CONFIG_TABLE_NAME . '`;'); |
| 93 | |
| 94 | //populate config table |
| 95 | $res = $sgdb->query( |
| 96 | "INSERT INTO `" . SG_CONFIG_TABLE_NAME . "` VALUES |
| 97 | ('SG_BACKUP_GUARD_VERSION','" . SG_BACKUP_GUARD_VERSION . "'), |
| 98 | ('SG_BACKUP_WITH_RELOADINGS', '1'), |
| 99 | ('SG_BACKUP_SYNCHRONOUS_STORAGE_UPLOAD','1'), |
| 100 | ('SG_NOTIFICATIONS_ENABLED','0'), |
| 101 | ('SG_SHOW_STATISTICS_WIDGET','1'), |
| 102 | ('SG_BACKUP_SEND_USAGE_STATUS','0'), |
| 103 | ('SG_NOTIFICATIONS_EMAIL_ADDRESS',''), |
| 104 | ('SG_STORAGE_BACKUPS_FOLDER_NAME','sg_backups'), |
| 105 | ('SG_DOWNLOAD_MODE'," . $downloadMode . ");" |
| 106 | ); |
| 107 | if ($res === false) { |
| 108 | return false; |
| 109 | } |
| 110 | |
| 111 | return true; |
| 112 | } |
| 113 | |
| 114 | private static function installScheduleTable($sgdb) |
| 115 | { |
| 116 | $dbEngine = backupGuardGetDatabaseEngine(); |
| 117 | |
| 118 | //create schedule table |
| 119 | $res = $sgdb->query( |
| 120 | 'CREATE TABLE IF NOT EXISTS `' . SG_SCHEDULE_TABLE_NAME . '` ( |
| 121 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, |
| 122 | `label` varchar(255) NOT NULL, |
| 123 | `status` tinyint(3) unsigned NOT NULL, |
| 124 | `schedule_options` varchar(255) NOT NULL, |
| 125 | `backup_options` text NOT NULL, |
| 126 | PRIMARY KEY (`id`) |
| 127 | ) ENGINE=' . $dbEngine . ' DEFAULT CHARSET=utf8;' |
| 128 | ); |
| 129 | if ($res === false) { |
| 130 | return false; |
| 131 | } |
| 132 | |
| 133 | return true; |
| 134 | } |
| 135 | |
| 136 | private static function installActionTable($sgdb) |
| 137 | { |
| 138 | $dbEngine = backupGuardGetDatabaseEngine(); |
| 139 | |
| 140 | //create action table |
| 141 | $res = $sgdb->query( |
| 142 | "CREATE TABLE IF NOT EXISTS `" . SG_ACTION_TABLE_NAME . "` ( |
| 143 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, |
| 144 | `name` varchar(255) NOT NULL, |
| 145 | `type` tinyint(3) unsigned NOT NULL, |
| 146 | `subtype` tinyint(3) unsigned NOT NULL DEFAULT '0', |
| 147 | `status` tinyint(3) unsigned NOT NULL, |
| 148 | `progress` tinyint(3) unsigned NOT NULL DEFAULT '0', |
| 149 | `start_date` datetime NOT NULL, |
| 150 | `update_date` datetime DEFAULT NULL, |
| 151 | `options` text NOT NULL, |
| 152 | PRIMARY KEY (`id`) |
| 153 | ) ENGINE=" . $dbEngine . " DEFAULT CHARSET=utf8;" |
| 154 | ); |
| 155 | if ($res === false) { |
| 156 | return false; |
| 157 | } |
| 158 | |
| 159 | return true; |
| 160 | } |
| 161 | |
| 162 | public static function install() |
| 163 | { |
| 164 | $sgdb = SGDatabase::getInstance(); |
| 165 | |
| 166 | try { |
| 167 | if (!self::installConfigTable($sgdb)) { |
| 168 | throw new SGExceptionDatabaseError('Could not install config table'); |
| 169 | } |
| 170 | |
| 171 | if (!self::installScheduleTable($sgdb)) { |
| 172 | throw new SGExceptionDatabaseError('Could not install schedule table'); |
| 173 | } |
| 174 | |
| 175 | if (!self::installActionTable($sgdb)) { |
| 176 | throw new SGExceptionDatabaseError('Could not install action table'); |
| 177 | } |
| 178 | |
| 179 | self::installReviewSettings(); |
| 180 | self::checkliteSpeedHosting(); |
| 181 | } catch (SGException $exception) { |
| 182 | die($exception); |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | private static function installReviewSettings() |
| 187 | { |
| 188 | $usageDays = SGConfig::get('usageDays'); |
| 189 | if (!$usageDays) { |
| 190 | SGConfig::set('usageDays', 0); |
| 191 | |
| 192 | $timeDate = new \DateTime('now'); |
| 193 | $installTime = strtotime($timeDate->format('Y-m-d H:i:s')); |
| 194 | SGConfig::set('installDate', $installTime); |
| 195 | $timeDate->modify('+' . SG_BACKUP_REVIEW_PERIOD . ' day'); |
| 196 | |
| 197 | $timeNow = strtotime($timeDate->format('Y-m-d H:i:s')); |
| 198 | SGConfig::set('openNextTime', $timeNow); |
| 199 | } |
| 200 | $backupCountReview = SGConfig::get('backupReviewCount'); |
| 201 | if (!$backupCountReview) { |
| 202 | SGConfig::set('backupReviewCount', SG_BACKUP_REVIEW_BACKUP_COUNT); |
| 203 | } |
| 204 | |
| 205 | $restoreReviewCount = SGConfig::get('restoreReviewCount'); |
| 206 | if (!$restoreReviewCount) { |
| 207 | SGConfig::set('restoreReviewCount', SG_BACKUP_REVIEW_RESTORE_COUNT); |
| 208 | } |
| 209 | |
| 210 | // TODO: remove and check banners logic |
| 211 | SGConfig::set('closeReviewBanner', 1); |
| 212 | } |
| 213 | |
| 214 | private static function checkliteSpeedHosting($delete = false) |
| 215 | { |
| 216 | if ($delete) { |
| 217 | removeLiteSpeedHtaccessModule(); |
| 218 | } else { |
| 219 | addLiteSpeedHtaccessModule(); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | private static function cleanupSchedules() |
| 224 | { |
| 225 | $schedules = SGBackupSchedule::getAllSchedules(); |
| 226 | foreach ($schedules as $schedule) { |
| 227 | SGBackupSchedule::remove($schedule['id']); |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | public static function uninstall($deleteBackups = false) |
| 232 | { |
| 233 | try { |
| 234 | @unlink(SG_PING_FILE_PATH); |
| 235 | |
| 236 | if (self::isFeatureAvailable('SCHEDULE')) { |
| 237 | self::cleanupSchedules(); |
| 238 | } |
| 239 | |
| 240 | $sgdb = SGDatabase::getInstance(); |
| 241 | |
| 242 | //drop config table |
| 243 | $res = $sgdb->query('DROP TABLE IF EXISTS `' . SG_CONFIG_TABLE_NAME . '`;'); |
| 244 | if ($res === false) { |
| 245 | throw new SGExceptionDatabaseError('Could not execute query'); |
| 246 | } |
| 247 | |
| 248 | //drop schedule table |
| 249 | $res = $sgdb->query('DROP TABLE IF EXISTS `' . SG_SCHEDULE_TABLE_NAME . '`;'); |
| 250 | if ($res === false) { |
| 251 | throw new SGExceptionDatabaseError('Could not execute query'); |
| 252 | } |
| 253 | |
| 254 | //drop action table |
| 255 | $res = $sgdb->query('DROP TABLE IF EXISTS `' . SG_ACTION_TABLE_NAME . '`;'); |
| 256 | if ($res === false) { |
| 257 | throw new SGExceptionDatabaseError('Could not execute query'); |
| 258 | } |
| 259 | |
| 260 | self::checkliteSpeedHosting(true); |
| 261 | |
| 262 | //delete directory of backups |
| 263 | if ($deleteBackups) { |
| 264 | $backupPath = SGConfig::get('SG_BACKUP_DIRECTORY'); |
| 265 | backupGuardDeleteDirectory($backupPath); |
| 266 | } |
| 267 | } catch (SGException $exception) { |
| 268 | die($exception); |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | public static function checkRequirement($requirement) |
| 273 | { |
| 274 | if ($requirement == 'ftp' && !extension_loaded('ftp')) { |
| 275 | throw new SGExceptionNotFound('FTP extension is not loaded.'); |
| 276 | } else if ($requirement == 'curl' && !function_exists('curl_version')) { |
| 277 | throw new SGExceptionNotFound('cURL extension is not loaded.'); |
| 278 | } else if ($requirement == 'intSize' && PHP_INT_SIZE < 8) { |
| 279 | throw new SGExceptionIO("BackupGuard uses 64-bit integers, but it looks like we're running on a version of PHP that doesn't support 64-bit integers (PHP_INT_MAX=" . ((string) PHP_INT_MAX) . ")"); |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | public static function isFeatureAvailable($feature) |
| 284 | { |
| 285 | return ((int) SGConfig::get('SG_FEATURE_' . strtoupper($feature)) === 1 ? true : false); |
| 286 | } |
| 287 | |
| 288 | private static function prepare() |
| 289 | { |
| 290 | $backupPath = SGConfig::get('SG_BACKUP_DIRECTORY'); |
| 291 | |
| 292 | //create directory for backups |
| 293 | if (!is_dir($backupPath)) { |
| 294 | if (!@mkdir($backupPath)) { |
| 295 | throw new SGExceptionMethodNotAllowed('Cannot create folder: ' . $backupPath); |
| 296 | } |
| 297 | |
| 298 | if (!@file_put_contents($backupPath . '.htaccess', 'deny from all')) { |
| 299 | throw new SGExceptionMethodNotAllowed('Cannot create htaccess file'); |
| 300 | } |
| 301 | |
| 302 | if (!@file_put_contents($backupPath . 'index.php', "<?php\n// Silence is golden")) { |
| 303 | throw new SGExceptionMethodNotAllowed('Cannot create index file'); |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | //check permissions of backups directory |
| 308 | if (!is_writable($backupPath)) { |
| 309 | throw new SGExceptionForbidden('Permission denied. Directory is not writable: ' . $backupPath); |
| 310 | } |
| 311 | |
| 312 | //prepare notices |
| 313 | $noticeHandler = new SGNoticeHandler(); |
| 314 | $noticeHandler->run(); |
| 315 | } |
| 316 | |
| 317 | private static function checkMinimumRequirements() |
| 318 | { |
| 319 | //check ZLib library |
| 320 | if (!function_exists('gzdeflate')) { |
| 321 | throw new SGExceptionNotFound('ZLib extension is not loaded.'); |
| 322 | } |
| 323 | } |
| 324 | } |
| 325 |