Orderadmin/card/feature/class-versions.php000064400000003152147577722710013710 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Versions * * @since 1.11.0 */ class Versions extends \Boldgrid\Library\Library\Ui\Feature { /** * */ public function init() { $data = wp_get_update_data(); $has_updates = ! empty( $data['counts']['plugins'] ) || ! empty( $data['counts']['themes'] ) || ! empty( $data['counts']['wordpress'] ); $this->icon = ''; $this->title = esc_html__( 'WordPress, Plugins, & Theme Version', 'boldgrid-backup' ); if ( $has_updates ) { $this->content = '

' . wp_kses( sprintf( // translators: 1 A description of what updates are available (such as plugins, themes, or core). __( 'The following updates are available: %1$s', 'boldgrid-backup' ), $data['title'] ), [] ) . '

'; $this->content .= '

' . wp_kses( sprintf( // translators: 1 An opening anchor tag to the update-core.php page, 2 its closing tag. __( 'Not everything is up to date. %1$sFix this%2$s.', 'boldgrid-backup' ), '', '' ), [ 'a' => [ 'href' => [], ], ] ) . '

'; } else { $this->content = '

' . esc_html__( 'Everything is up to date!', 'boldgrid-backup' ) . '

'; } } } admin/card/feature/class-timely-auto-updates.php000064400000003411147577722710015752 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Timely_Auto_Updates. * * This class is responsible for rendering the, "Timely Auto Updates" feature on the BoldGrid. * Backup Dashboard. * * @since 1.14.0 */ class Timely_Auto_Updates extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.14.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $this->icon = ''; $this->title = __( 'Timely Auto Updates', 'boldgrid-backup' ); // Determine whether or not this feature is enabled. $auto_update_settings = $core->settings->get_setting( 'auto_update' ); $is_enabled = ! empty( $auto_update_settings['timely-updates-enabled'] ); if ( $is_enabled ) { $this->content = '

' . esc_html__( 'Timely Auto Updates are enabled!', 'boldgrid-backup' ) . '

'; } else { $this->content = '

' . esc_html__( 'By setting up Timely Auto Updates, you can have more control over when new updates are installed by WordPress.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . wp_kses( sprintf( // translators: 1 Opening anchor tag to "Auto Updates" settings page, 2 its closing tag. __( 'Timely Auto Updates are not enabled. %1$sFix this%2$s.', 'boldgrid-backup' ), '', '' ), [ 'a' => [ 'href' => [] ] ] ) . '

'; } } } admin/card/feature/class-speed-coach.php000064400000001550147577722710014213 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Speed_Coach * * @since 1.11.0 */ class Speed_Coach extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $this->icon = ''; $this->title = esc_html__( 'Speed Coach', 'boldgrid-backup' ); $this->content = '

' . esc_html__( 'A faster website means happier visitors and higher rankings on the search engines. Simply type in your website’s URL and receive detailed advice on making your site lightning fast.', 'boldgrid-backup' ) . '

'; } } admin/card/feature/class-sign-up.php000064400000002113147577722710013416 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Sign_Up * * @since 1.11.0 */ class Sign_Up extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $new_key_url = \Boldgrid\Library\Library\Key\PostNewKey::getCentralUrl( admin_url( 'admin.php?page=boldgrid-backup-dashboard' ) ); $this->icon = ''; $this->content = '

' . esc_html__( 'There’s more waiting for you in BoldGrid Central. Download the full-featured community versions of ALL our plugins for FREE. It’s just a click away.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . __( 'Sign Up for Free!', 'boldgrid-backup' ) . '

'; } } admin/card/feature/class-scheduled-backups.php000064400000005471147577722710015434 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Scheduled_Backups * * This class is responsible for displaying the scheduled backups feature on this plugin's dashboard. * * @since 1.11.0 */ class Scheduled_Backups extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $this->icon = ''; $this->title = esc_html__( 'Scheduled Backups', 'boldgrid-backup' ); $cron = new \Boldgrid\Backup\Admin\Cron(); $backup_entry = $cron->get_entry( 'backup' ); /* * If a user does not have backups scheduled, suggest they schedule them. * * As of 1.11.4, in addition to checking if a schedule is saved in the settings, we also ensure * that the backup cron can be found. We need to check for the scenario in which the user has * manually deleted the cron entry yet the settings say backups are scheduled. * * In some cases where the settings say backups are scheduled but the cron doesn't actually * exist, false positives may be given or errors triggered. We may want to explore the idea * of showing an admin notice. For now, if this scenario exists, the dashboard will tell the * user to schedule backups, and resaving the settings will resave the cron entry. */ if ( $core->settings->has_scheduled_backups() && $backup_entry->is_set() ) { $next_runtime = $backup_entry->get_next_runtime(); $this->content = '

' . wp_kses( sprintf( // Translators: 1 An opening span tag, 2 the date of the next backup, 3 its closing span tag. __( 'Next backup in: %1$s%2$s%3$s', 'boldgrid-backup' ), '', human_time_diff( time(), $next_runtime ), '' ), [ 'span' => [ 'class' => [], 'title' => [], ], ] ) . '

'; } else { $this->content = '

' . esc_html__( 'It\'s easy to forget to make a backup. Schedule automatic backups so they\'re made for you.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . wp_kses( sprintf( // translators: 1 An opening anchor tag to the settings page, 2 its closing tag. __( 'Scheduled Backups not configured. %1$sFix this%2$s.', 'boldgrid-backup' ), '', '' ), [ 'a' => [ 'href' => [], ], ] ) . '

'; } } } admin/card/feature/class-remote-storage.php000064400000003475147577722710015005 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Remote_Storage * * @since 1.11.0 */ class Remote_Storage extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $this->icon = ''; $this->title = esc_html__( 'Remote Storage', 'boldgrid-backup' ); if ( $core->settings->has_remote_configured() ) { $storage_locations = $core->remote->get_enabled( 'title' ); $this->content = '

' . wp_kses( sprintf( // translators: 1 An opening span tag, A list of remote backup storage locations (csv), its closing span tag. __( 'Backups saved to: %1$s%2$s%3$s', 'boldgrid-bakcup' ), '', esc_html( implode( ', ', $storage_locations ) ), '' ), [ 'span' => [ 'class' => [], ], ] ) . '

'; } else { $this->content = '

' . esc_html__( 'Don\'t put all of your eggs in one basket! Store your backups remotely.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . wp_kses( sprintf( // translators: 1 An opening anchor tag to the Remote Storage settings, 2 its closing anchor tag. __( 'Remote Storage is not configured. %1$sFix this%2$s', 'boldgrid-backup' ), '', '' ), [ 'a' => [ 'href' => [] ] ] ) . '

'; } } } admin/card/feature/class-more-central.php000064400000002217147577722710014431 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: More_Central * * @since 1.11.0 */ class More_Central extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $get_premium_url = $core->go_pro->get_premium_url( 'bgbkup-dashboard' ); $this->icon = ''; $this->title = esc_html__( 'More BoldGrid Central Features', 'boldgrid-backup' ); $this->content = '

' . esc_html__( 'Unlock more features within BoldGrid Central, including Cloud WordPress Advanced Controls and Automated Website Speed Tests.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . __( 'Get Premium', 'boldgrid-backup' ) . '

'; } } admin/card/feature/class-more-boldgrid.php000064400000001543147577722710014570 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: More_Boldgrid * * @since 1.11.0 */ class More_Boldgrid extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $this->icon = ''; $this->title = esc_html__( 'More Premium BoldGrid Plugins', 'boldgrid-backup' ); $this->content = '

' . esc_html__( 'Gain access to all BoldGrid premium plugins and services. This includes Post and Page Builder Premium, which offers premium Blocks and native sliders.', 'boldgrid-backup' ) . '

'; } } admin/card/feature/class-more-backup.php000064400000002404147577722710014244 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: More_Backup * * @since 1.11.0 */ class More_Backup extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $this->icon = ''; $this->title = sprintf( // translators: 1: Plugin title. esc_html__( 'More %1$s Features', 'boldgrid-backup' ), BOLDGRID_BACKUP_TITLE ); $this->content = '

' . wp_kses( sprintf( // translators: 1 A span displaying the Google Drive logo, 2 a span displaying the Amazon S3 logo. esc_html__( '%3$s can store backups on %1$s and %2$s, restore individual files with just a click, and more!', 'boldgrid-backup' ), '', '', BOLDGRID_BACKUP_TITLE . ' Premium' ), [ 'span' => [ 'class' => [], 'title' => [], ], ] ) . '

'; } } admin/card/feature/class-database-encryption.php000064400000002506147577722710015776 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Database_Encryption * * @since 1.13.0 */ class Database_Encryption extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.13.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $this->icon = ''; $this->title = esc_html__( 'Database Encryption', 'boldgrid-backup' ); $this->content = '

' . esc_html__( 'Secure your sensitive data with Database Encryption.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . wp_kses( sprintf( // translators: 1 An opening anchor tag to the Remote Storage settings, 2 its closing anchor tag. __( 'Database Encryption is not configured. %1$sFix this%2$s', 'boldgrid-backup' ), '', '' ), [ 'a' => [ 'href' => [] ] ] ) . '

'; } } admin/card/feature/class-cloud-wordpress.php000064400000001522147577722710015173 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Cloud_WordPress * * @since 1.11.0 */ class Cloud_Wordpress extends \Boldgrid\Library\Library\Ui\Feature { //phpcs:ignore /** * Init. * * @since 1.11.0 */ public function init() { $this->icon = ''; $this->title = __( 'Cloud WordPress', 'boldgrid-backup' ); $this->content = '

' . __( 'Create a fully functional free WordPress demo in just a few clicks. Easily design, build, test and share your WordPress website with clients or teams.', 'boldgrid-backup' ) . '

'; } } admin/card/feature/class-central.php000064400000002241147577722710013466 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Central * * This class is responsible for initializing a BoldGrid Central "feature" for use within a card. * * @since 1.11.0 */ class Central extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $reseller = new \Boldgrid\Library\Library\Reseller(); $this->icon = ''; $this->title = esc_html__( 'BoldGrid Central', 'boldgrid-backup' ); $this->content = '

' . esc_html__( 'Manage your account, Run Automated Website Speed Tests, and more within BoldGrid Central.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . esc_html__( 'BoldGrid Central Login', 'boldgrid-backup' ) . '

'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar } } admin/card/feature/class-auto-update-backup.php000064400000003341147577722710015533 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Auto_Update_Backup * * This class is responsible for rendering the, "Auto Backup Before Updates" feature on the BoldGrid * Backup Dashboard. * * @since 1.11.0 */ class Auto_Update_Backup extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $this->icon = ''; $this->title = __( 'Auto Backup Before Updates', 'boldgrid-backup' ); // Determine whether or not this feature is enabled. $setting_value = $core->settings->get_setting( 'auto_backup' ); $is_enabled = ! empty( $setting_value ); if ( $is_enabled ) { $this->content = '

' . esc_html__( 'Auto Backup Before Updates is enabled!', 'boldgrid-backup' ) . '

'; } else { $this->content = '

' . esc_html__( 'When Auto Backup is enabled, we will backup your site before any auto-updates occur.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . wp_kses( sprintf( // translators: 1 Opening anchor tag to "Auto Updates" settings page, 2 its closing tag. __( 'Auto Backup Before Updates is not enabled. %1$sFix this%2$s.', 'boldgrid-backup' ), '', '' ), [ 'a' => [ 'href' => [] ] ] ) . '

'; } } } admin/card/feature/class-auto-rollback.php000064400000003040147577722710014573 0ustar00 */ namespace Boldgrid\Backup\Admin\Card\Feature; /** * Class: Auto_Rollback * * This class is responsible for rendering the "Auto Rollback" feature on this plugin's dashboard. * * @since 1.11.0 */ class Auto_Rollback extends \Boldgrid\Library\Library\Ui\Feature { /** * Init. * * @since 1.11.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $this->icon = ''; $this->title = __( 'Auto Rollback', 'boldgrid-backup' ); if ( $core->auto_rollback->is_enabled() ) { $this->content = '

' . esc_html__( 'Auto Rollback is enabled!', 'boldgrid-backup' ) . '

'; } else { $this->content = '

' . esc_html__( 'With Auto Rollback, we can help fix your site if anything goes wrong while performing updates.', 'boldgrid-backup' ) . '

'; $this->content .= '

' . wp_kses( sprintf( // translators: 1 An opening anchor tag to the "Auto Updates" settings page, 2 its closing tag. __( 'Auto Rollback is not enabled. %1$sFix this%2$s.', 'boldgrid-backup' ), '', '' ), [ 'a' => [ 'href' => [] ] ] ) . '

'; } } } admin/card/class-updates.php000064400000002272147577722710012054 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Updates * * This class is responsible for rendering the "Update Management" card on this plugin's dashboard. * * @since 1.11.0 */ class Updates extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.11.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $this->id = 'bgbkup_updates'; $this->title = esc_html__( 'Update Management', 'boldgrid-backup' ); $this->subTitle = esc_html__( 'Keep everything tidy and up to date.', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar $this->icon = ''; $this->features = [ new Feature\Versions(), new Feature\Auto_Rollback(), new Feature\Auto_Update_Backup(), ]; if ( $core->config->get_is_premium() ) { $this->features[] = new Feature\Timely_Auto_Updates(); } } } admin/card/class-timely-auto-updates.php000064400000002255147577722710014324 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Timely Auto Updates * * This class is responsible for rendering the "Timely Auto Updates" card on this plugin's Premium Features page. * * @since 1.14.0 */ class Timely_Auto_Updates extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.14.0 */ public function init() { $this->id = 'bgbkup_timely_auto_updates'; $this->title = esc_html__( 'Timely Auto Updates', 'boldgrid-backup' ); $this->footer = '

' . esc_html__( 'Gives you more control over when new updates are installed by WordPress\' Automatic Updates.', 'boldgrid-backup' ) . '

'; $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/timely-auto-updates/' ); $this->links = ' ' . esc_html__( 'Setup Guide', 'boldgrid-backup' ) . ' '; $this->icon = ''; } } admin/card/class-premium.php000064400000003750147577722710012067 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Premium * * This class is responsible for rendering the "Premium" card on this plugin's dashboard. * * @since 1.11.0 */ class Premium extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.11.0 */ public function init() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $api_key = apply_filters( 'Boldgrid\Library\License\getApiKey', '' ); // phpcs:ignore $this->id = 'bgbkup_get_premium'; $this->icon = ''; $features = []; if ( empty( $api_key ) ) { $this->title = esc_html__( 'BoldGrid Central', 'boldgrid-backup' ); $this->subTitle = esc_html__( 'All the tools and services you need to succeed.', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar $this->features = [ new Feature\Cloud_Wordpress(), new Feature\Speed_Coach(), new Feature\Sign_Up(), ]; } elseif ( ! $core->config->get_is_premium() ) { $this->title = esc_html__( 'Enjoying your free account?', 'boldgrid-backup' ); $this->subTitle = esc_html__( 'We hope so. There\'s more available by upgrading now!', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar $this->features = [ new Feature\More_Backup(), new Feature\More_Boldgrid(), new Feature\More_Central(), ]; } else { $this->title = esc_html__( 'BoldGrid Premium', 'boldgrid-backup' ); $this->subTitle = esc_html__( 'Thank you for running BoldGrid Premium!', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar $this->features = [ new Feature\Central(), ]; } } } admin/card/class-plugin-editor-tools.php000064400000003153147577722710014326 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Plugin_Editor_Tools. * * This class is responsible for rendering the "Plugin Editor Tools". * card on this plugin's Premium Features Page. * * @since 1.13.0 */ class Plugin_Editor_Tools extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_plugin_editor_tools'; $this->title = esc_html__( 'Plugin Editor Tools', 'boldgrid-backup' ); $this->icon = ''; $this->footer = '

' . esc_html__( 'When using the WordPress Plugin Editor, Total Upkeep Premium will save a copy of the file in case you need to undo any changes.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/plugin-editor-backup/?source=plugin-editor-tools'; $video = 'https://www.youtube.com/embed/Nb0AFEXpE00?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; } } admin/card/class-one-click-restoration.php000064400000003103147577722710014614 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: One_Click_Restoration. * * This class is responsible for rendering the "One Click Restoration" card. * on this plugin's Premium Features Page. * * @since 1.13.0 */ class One_Click_Restoration extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_one_click_restoration'; $this->title = esc_html__( 'One Click File Restorations', 'boldgrid-backup' ); $this->icon = ''; $this->footer = '

' . esc_html__( 'Restore a single file within the backup browser. Helpful when modifying individual files.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/individual-file-restorations/?source=one-click-restore'; $video = 'https://www.youtube.com/embed/r2VCQ-9fQP8?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; } } admin/card/class-history.php000064400000003033147577722710012104 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: History. * * This class is responsible for rendering the "History" card on this plugin's. * Premium Features Page. * * @since 1.13.0 */ class History extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_history'; $this->title = esc_html__( 'Update History', 'boldgrid-backup' ); $this->icon = ''; $this->footer = '

' . esc_html__( 'View a running log of significant actions to your WordPress site, including which users updated a plugin, theme, or WordPress itself.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/backup-changed-files-history/?source=update-history'; $video = 'https://www.youtube.com/embed/kaeb30pYPYU?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; } } admin/card/class-historical-versions.php000064400000003070147577722710014413 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Historical_Versions. * * This class is responsible for rendering the "Historical Versions" card on this. * plugin's Premium Features Page. * * @since 1.13.0 */ class Historical_Versions extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_historical_versions'; $this->title = esc_html__( 'Historical Versions', 'boldgrid-backup' ); $this->icon = ''; $this->footer = '

' . esc_html__( 'Search through all backup archives for a particular, individual file and restore it.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/restore-historical-files/?source=historical-versions'; $video = 'https://www.youtube.com/embed/wGda86tdScg?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; } } admin/card/class-google-drive.php000064400000003051147577722710012766 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Google Drive. * * This class is responsible for rendering the "Google drive" card on this. * plugin's Premium Features Page. * * @since 1.13.0 */ class Google_Drive extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_google_drive'; $this->title = esc_html__( 'Google Drive', 'boldgrid-backup' ); $this->icon = ''; $this->footer = '

' . esc_html__( 'Keep your backup archives safe and secure with remote, automated backups to Google Drive.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/auto-backup-to-google-drive/?source=google-drive'; $video = 'https://www.youtube.com/embed/p6I_xxo4TLo?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; } } admin/card/class-find-modified-files.php000064400000002122147577722710014177 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Find Modified Files. * * @since 1.13.1 */ class Find_Modified_Files extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.1 */ public function init() { $this->id = 'bgbkup_find_modified_files'; $this->title = esc_html__( 'Find Modified Files', 'boldgrid-backup' ); $this->icon = ''; $this->footer = '

' . esc_html__( 'Search for all files modified within a certain time period. You can also look for other versions of that file within your backups.', 'boldgrid-backup' ) . '

'; $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/additional-tools/' ); $this->links = ' ' . esc_html__( 'Setup Guide' ) . ' '; } } admin/card/class-dream-objects.php000064400000003103147577722710013120 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Dream_Objects. * * This class is responsible for rendering the "Dream Objects" card. * on this plugin's Premium Features Page. * * @since 1.13.0 */ class Dream_Objects extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_dream_objects'; $this->title = esc_html__( 'DreamObjects', 'boldgrid-backup' ); $this->footer = '

' . esc_html__( 'Safely store backups in the cloud via DreamObjects by DreamHost. Compatible with automated backups feature.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/dreamobjects-storage/?source=dreamobjects'; $video = 'https://www.youtube.com/embed/fJXnMq5JYi8?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; $this->icon = ''; } } admin/card/class-database-encryption.php000064400000003106147577722710014340 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Encryption. * * This class is responsible for rendering the "Encryption" card on this plugin's Premium Features page. * * @since 1.13.0 */ class Database_Encryption extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_database_encryption'; $this->title = esc_html__( 'Database Encryption', 'boldgrid-backup' ); $this->footer = '

' . esc_html__( 'Provides another level of protection by preventing unauthorized access to your database backup archives.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/encrypt-database-backups/?source=encrypt-database-backups'; $video = 'https://www.youtube.com/embed/Pwxous6_LKg?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; $this->icon = ''; } } admin/card/class-backups.php000064400000002134147577722710012034 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Backups. * * This class is responsible for rendering the "Backups" card on this plugin's dashboard. * * @since 1.11.0 */ class Backups extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.11.0 */ public function init() { $this->id = 'bgbkup_backups'; $this->title = esc_html__( 'Backups', 'boldgrid-backup' ); $this->subTitle = esc_html__( 'It\'s website insurance. Make sure you have a backup.', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName $this->icon = ''; $this->features = array( new Feature\Scheduled_Backups(), new Feature\Remote_Storage(), ); if ( ! get_option( 'boldgrid_backup_settings' )['encrypt_db'] ) { $this->features[] = new Feature\Database_Encryption(); } } } admin/card/class-amazon-s3.php000064400000003035147577722710012215 0ustar00 */ namespace Boldgrid\Backup\Admin\Card; /** * Class: Amazon_S3. * * This class is responsible for rendering the "Amazon S3" card on this plugin's Premium Features page. * * @since 1.13.0 */ class Amazon_S3 extends \Boldgrid\Library\Library\Ui\Card { /** * Init. * * @since 1.13.0 */ public function init() { $this->id = 'bgbkup_amazon_s3'; $this->title = esc_html__( 'Amazon S3', 'boldgrid-backup' ); $this->footer = '

' . esc_html__( 'Safely store backups in the cloud via Amazon S3. Compatible with automated remote backups feature.', 'boldgrid-backup' ) . '

'; $url = 'https://www.boldgrid.com/support/total-upkeep/backup-wordpress-to-amazon-s3/?source=amazon-s3'; $video = 'https://www.youtube.com/embed/ZN0lab5ndhE?controls=1&autoplay=1&modestbranding=1&width=560&height=315&KeepThis=true&TB_iframe=true'; $this->links = ' ' . esc_html__( 'Learn More' ) . '' . esc_html__( 'Setup Guide' ) . ' '; $this->icon = ''; } } admin/compressor/class-boldgrid-backup-admin-compressor-system-zip-test.php000064400000016706147577722710023311 0ustar00 */ /** * Class: Boldgrid_Backup_Admin_Compressor_System_Zip_Test * * @since 1.13.0 */ class Boldgrid_Backup_Admin_Compressor_System_Zip_Test { /** * An instance of core. * * @since 1.13.0 * @access private * @var Boldgrid_Backup_Admin_Core */ private $core; /** * An error message. * * @since 1.13.0 * @access private * @var string */ private $error; /** * An array of files that will make up the self::filelist_filepath file. * * @since 1.13.0 * @access private * @var array */ private $filelist = []; /** * A filepath to the file containing a list of files we will zip. * * @since 1.13.0 * @access private * @var array */ private $filelist_filepath; /** * An array of files and folders that we will create. * * @since 1.13.0 * @access private * @var array */ private $items; /** * A path to a directory we will be creating, filling with files, and zipping. * * @since 1.13.0 * @access private * @var string */ private $test_dir; /** * A filepath to the zip we will be creating. * * @since 1.13.0 * @access private * @var string */ private $zip_filepath; /** * Constructor. * * @since 1.13.0 * * @param Boldgrid_Backup_Admin_Core $core */ public function __construct( Boldgrid_Backup_Admin_Core $core ) { $this->core = $core; $this->items = [ [ 'type' => 'f', 'name' => 'file.txt', ], [ 'type' => 'd', 'name' => 'folder-empty', ], [ 'type' => 'd', 'name' => 'folder-1', ], [ 'type' => 'f', 'name' => 'folder-1/file-1.txt', ], [ 'type' => 'd', 'name' => 'folder-1/folder-1a', ], [ 'type' => 'd', 'name' => 'folder-1/folder-1a/folder-1a.txt', ], ]; $this->zip_filepath = $this->core->backup_dir->get_path_to( $this->core->test->test_prefix . 'system-zip-test.zip' ); $this->filelist_filepath = $this->core->backup_dir->get_path_to( $this->core->test->test_prefix . 'system-zip-filelist.txt' ); $this->test_dir = $this->core->backup_dir->get_path_to( $this->core->test->test_prefix . 'system-zip-test' ); } /** * Get our error message. * * @since 1.13.0 * * @return string */ public function get_error() { return $this->error; } /** * Create and setup our test directory. * * We will be zipping up this directory. * * @since 1.13.0 * * @return bool True on success. */ private function test_dir_create() { // Create our test directory. if ( ! $this->core->wp_filesystem->mkdir( $this->test_dir ) ) { $this->error = sprintf( // translators: 1 The name of a folder that could not be created. esc_html__( 'Unable to create test directory: %1$s', 'boldgrid-backup' ), $this->test_dir ); return false; } // Create all the files. Abort if one could not be. foreach ( $this->items as $item ) { $created = false; switch ( $item['type'] ) { case 'd': $created = $this->core->wp_filesystem->mkdir( $this->test_dir . DIRECTORY_SEPARATOR . $item['name'] ); break; case 'f': $created = $this->core->wp_filesystem->touch( $this->test_dir . DIRECTORY_SEPARATOR . $item['name'] ); break; } // Add this item to our filelist (a .txt file containing a list of files to backup). $this->filelist[] = $item['name']; // Above if we could not create a file. if ( ! $created ) { $this->error = sprintf( // translators: 1 The name of a file that could not be created. esc_html__( 'Unable to create test file: %1$s', 'boldgrid-backup' ), $item['name'] ); return false; } } // Save the filelist. if ( ! $this->core->wp_filesystem->put_contents( $this->filelist_filepath, implode( PHP_EOL, $this->filelist ) ) ) { $this->error = esc_html__( 'Unable to create filelist.txt', 'boldgrid-backup' ); return false; } return true; } /** * Restore our test directory from zip and make sure everything was restored. * * @since 1.13.0 * * @return bool True on success. */ private function test_dir_restore() { // Delete the folder we zipped and make sure it's gone. if ( ! $this->core->wp_filesystem->delete( $this->test_dir, true ) ) { $this->error = esc_html__( 'Unable to delete test directory.', 'boldgrid-backup' ); return false; } // Create our test directory again. if ( ! $this->core->wp_filesystem->mkdir( $this->test_dir ) ) { $this->error = esc_html__( 'Unable to recreate test directory.', 'boldgrid-backup' ); return false; } // Move our zip file to our test directory. if ( ! $this->core->wp_filesystem->move( $this->zip_filepath, $this->test_dir . DIRECTORY_SEPARATOR . basename( $this->zip_filepath ) ) ) { $this->error = esc_html__( 'Unable to move zip to test directory.', 'boldgrid-backup' ); return false; } // Unzip. $this->core->execute_command( 'cd ' . $this->test_dir . '; unzip ' . basename( $this->zip_filepath ) ); foreach ( $this->items as $item ) { $path = $this->test_dir . DIRECTORY_SEPARATOR . $item['name']; if ( ! $this->core->wp_filesystem->exists( $path ) ) { $this->error = esc_html__( 'Unable to restore all files and folders.', 'boldgrid-backup' ); return false; } } return true; } /** * Zip up our test directory. * * @since 1.13.0 * * @return bool True on success. */ private function test_dir_zip() { // Zip everything up and make sure it worked. $this->core->execute_command( 'cd ' . $this->test_dir . '; zip ' . $this->zip_filepath . ' -@ < ' . $this->filelist_filepath ); if ( ! $this->core->wp_filesystem->exists( $this->zip_filepath ) ) { $this->error = esc_html__( 'Unable to create zip file.', 'boldgrid-backup' ); return false; } return true; } /** * Determine if system_zip is working as expected. * * On average, this takes 0.019 seconds to complete. * * @since 1.13.0 * * @param bool $force Whether to run this test or get results from transient. * @return bool True on success. */ public function run( $force = false ) { // Force a fresh test if we're on the preflight check page. $force = Boldgrid_Backup_Admin_Utility::is_admin_page( 'boldgrid-backup-test' ) ? true : $force; $pass = 1; $transient_key = 'boldgrid_backup_system_zip_test'; $transient_value = get_transient( $transient_key ); if ( ! $force && false !== $transient_value ) { return $transient_value; } // Before and after running the test, delete test files created. $this->core->test->delete_test_files( $this->core->backup_dir->get() ); // This is the beef of the test, where we actually test things. if ( ! $this->core->execute_command( '/usr/bin/zip -v ' ) ) { $this->error = __( '/usr/bin/zip is not available.', 'boldgrid-backup' ); $pass = 0; } elseif ( ! $this->test_dir_create() ) { // Create our test directory. $pass = 0; } elseif ( ! $this->test_dir_zip() ) { // Zip up our test directory. $pass = 0; } elseif ( ! $this->test_dir_restore() ) { // Restore our test directory. $pass = 0; } $this->core->test->delete_test_files( $this->core->backup_dir->get() ); set_transient( $transient_key, $pass, 24 * HOUR_IN_SECONDS ); return ! empty( $pass ); } } admin/compressor/class-boldgrid-backup-admin-compressor-system-zip-temp-folder.php000064400000004715147577722710024545 0ustar00 */ /** * Class: Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder * * @since 1.13.0 */ class Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder { /** * An instance of core. * * @since 1.13.0 * @access private * @var Boldgrid_Backup_Admin_Core */ private $core; /** * The name of the temporary folder where the compression will take place. * * @since 1.13.0 * @access private * @var string */ private static $name = 'system-zip-temp'; /** * Constructor. * * @since 1.13.0 */ public function __construct() { $this->core = apply_filters( 'boldgrid_backup_get_core', null ); } /** * Create the temp folder. * * @since 1.13.0 * * @return bool True on success. */ public function create() { return $this->core->wp_filesystem->mkdir( self::get_path() ); } /** * Delete the temp folder. * * @since 1.13.0 * * @return bool True on success. */ public function delete() { return $this->core->wp_filesystem->rmdir( self::get_path() ); } /** * Determine whether or not the system zip temp folder exists. * * @since 1.13.8 * * @return bool */ public function exists() { $path = self::get_path(); return $this->core->wp_filesystem->exists( $path ); } /** * Return a list of files in the system zip temp folder. * * @since 1.13.8 * * @return array */ public function dirlist() { $dirlist = array(); if ( $this->exists() ) { $path = trailingslashit( self::get_path() ); $dirlist = $this->core->wp_filesystem->dirlist( $path ); $dirlist = empty( $dirlist ) ? array() : $dirlist; /* * When using WP_Filesystem, the key of each array element is the name of the file. For * this method, we prefer the keys to be the full path to the file. */ foreach ( $dirlist as $filename => $data ) { $dirlist[ $path . $filename ] = $data; unset( $dirlist[ $filename ] ); } } return $dirlist; } /** * Get the path to our temp folder. * * @since 1.13.0 * * @return string */ public static function get_path() { $core = apply_filters( 'boldgrid_backup_get_core', null ); return $core->backup_dir->get_path_to( self::$name ); } } admin/compressor/class-boldgrid-backup-admin-compressor-system-zip.php000064400000025207147577722710022330 0ustar00 */ /** * Class: Boldgrid_Backup_Admin_Compressor_System_Zip * * @since 1.13.0 */ class Boldgrid_Backup_Admin_Compressor_System_Zip extends Boldgrid_Backup_Admin_Compressor { /** * An error message. * * If we encounter an error while zipping, the error may be placed here - key phrase "may be placed * here". At the introduction of this class property, it is being used in only one place. The entire * class was not checked and tested to ensure all methods add any errors they run into here. * * @since SINCEVERSION * @access private * @var string */ private $error; /** * An array of files that should be archived. * * @since 1.13.0 * @access private * @var array { * An array of files. * * @type string 0 Path. Example: ""/home/user/public_html/readme.html". * @type string 1 basename. Example: "readme.html". * @type int 2 File size (in bytes). Example: "7413". * @type string 3 File type. Examples: "d", "f". * } */ private $filelist = []; /** * The filepath to our text file holding list of files to archive. * * @since 1.13.0 * @access private * @var string */ private $filelist_path; /** * The filepath to the zip file. * * @since 1.13.0 * @access PRIVATE * @var string */ private $filepath; /** * The temporary folder used when saving a zip file. * * @since 1.13.0 * @access private * @var Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder */ private $temp_folder; /** * Key. * * @since 1.13.0 * @access protected * @var string */ protected $key = 'system_zip'; /** * Total Size Archived. * * @since 1.14.0 * @var int */ public $total_size_archived; /** * Default Compression Level. * * @since 1.14.0 * @var string */ public $default_compression_level = '6'; /** * Constructor. * * @since 1.13.0 */ public function __construct() { $core = apply_filters( 'boldgrid_backup_get_core', null ); parent::__construct( $core ); $this->temp_folder = new Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder(); } /** * Archive files. * * @since 1.5.1 * * @see Boldgrid_Backup_Admin_Filelist::get_total_size() * * @param array $filelist { * File details. * * @type string 0 Path. Example: ""/home/user/public_html/readme.html". * @type string 1 basename. Example: "readme.html". * @type int 2 File size (in bytes). Example: "7413". * @type string 3 File type. Examples: "d", "f". * } * @param array $info { * Data about the backup archive we are generating. * * @type string mode backup * @type bool dryrun * @type string compressor php_zip * @type int filesize 0 * @type bool save 1 * @type int total_size 0 * } * @return mixed True on success, an array on failure. This approach has been taken to follow the * standards already set by the pcl-zip and php-zip classes. */ public function archive_files( $filelist, &$info ) { if ( $info['dryrun'] ) { return true; } // Prevent this process from ending; allow the archive to be completed. ignore_user_abort( true ); set_time_limit( 0 ); $this->filelist = $filelist; $this->filepath = $info['filepath']; $this->filelist_create(); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 3 ); $zip_success = $this->zip(); // @todo Simliar to the zip call above which returns a success status, so should zip_sql. $this->zip_sql(); Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'step' ); // Actions to take when we're all done / cleanup. $this->core->wp_filesystem->delete( $this->filelist_path ); return true === $zip_success ? true : array( 'error' => $this->error, ); } /** * Create the file containing a list of files to backup. * * @since 1.13.0 */ private function filelist_create() { $this->core->logger->add( 'Starting to create list of files to include in zip.' ); $this->core->logger->add_memory(); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 2 ); $this->filelist_path = $this->core->backup_dir->get_path_to( 'system_zip_filelist-' . time() . '.txt' ); $this->total_size_archived = 0; // Create the file list. $filelist_array = []; foreach ( $this->filelist as $file ) { $filelist_array[] = str_replace( ABSPATH, '', $file[0] ); $this->total_size_archived += empty( $file[2] ) ? 0 : $file[2]; } // Add some values for "In progress". Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_files_done', count( $this->filelist ) ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived', $this->total_size_archived ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived_size_format', size_format( $this->total_size_archived, 2 ) ); /* * Remove our db_dump_filepath from the list. * * If we add it now, the zip file will include /home/user/boldgrid_backup/db.sql * * We'll add the sql separately in self::zip_sql(). */ if ( ( $key = array_search( $this->core->db_dump_filepath, $filelist_array ) ) !== false ) { // phpcs:ignore unset( $filelist_array[ $key ] ); } $this->core->wp_filesystem->put_contents( $this->filelist_path, implode( PHP_EOL, $filelist_array ) ); $this->core->logger->add( 'Finished creating list of files to include in zip. ' . count( $filelist_array ) . ' files in zip.' ); $this->core->logger->add_memory(); } /** * Run the command to actually zip the files. * * @since 1.13.0 * * @return bool True on success. Do note that $this->close() calls $this->zip_proc(), which will * store any error messages in $this->error. */ private function zip() { $this->core->logger->add( 'Starting to close the zip file.' ); $this->core->logger->add_memory(); $this->temp_folder->create(); $success = $this->close(); $this->temp_folder->delete(); $this->core->logger->add( 'Finished closing the zip file.' ); $this->core->logger->add_memory(); return $success; } /** * Get Filelist Chunks. * * @since 1.14.0 * * @return array Example https://pastebin.com/JsSEzNwA */ public function get_filelist_chunks() { // Chunk size in bytes. $max_chunk_size = 26214400; $size_of_chunk = 0; $filelist_chunks = array( array() ); $chunk_position = 0; foreach ( $this->filelist as $file ) { // Adds file to this chunk. $filelist_chunks[ $chunk_position ][] = $file[1]; // Adds the most recent file's size to chunk size. $size_of_chunk = $size_of_chunk + (int) $file[2]; // If the chunk size is >= the max chunk size, then move to next chunk. if ( $size_of_chunk >= $max_chunk_size ) { $chunk_position++; $size_of_chunk = 0; } } return $filelist_chunks; } /** * Close. * * @since 1.14.0 */ private function close() { $chunks_closed = 0; $filelist_chunks = $this->get_filelist_chunks(); $total_chunks = count( $filelist_chunks ); foreach ( $filelist_chunks as $filelist_chunk ) { $chunk_start_time = microtime( true ); $success = $this->zip_proc( $filelist_chunk ); if ( ! $success ) { return false; } // Process some stats. $chunks_closed++; $percent_complete = round( $chunks_closed / $total_chunks, 2 ); $chunk_end_time = microtime( true ); $close_duration = $chunk_end_time - $chunk_start_time; Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'percent_closed', $percent_complete ); // Add messages to the log. $this->core->logger->add( 'Chunk closed in ' . $close_duration . ' seconds. ' . $percent_complete * 100 . '% complete closing' ); $this->core->logger->add_memory(); } return true; } /** * Get Compression Level. * * @since 1.14.0 * * @return string */ private function get_compression_level() { $compression_level = $this->core->settings->get_setting( 'compression_level' ); return isset( $compression_level ) ? $compression_level : $this->default_compression_level; } /** * Close Zip using proc_open. * * @since 1.14.0 * * @param array $filelist_chunk Array of Files to be added. * @return bool True on success. */ private function zip_proc( $filelist_chunk ) { $has_error = false; $descriptorspec = array( 0 => array( 'pipe', 'r' ), // stdin is a pipe that the child will read from. 1 => array( 'pipe', 'w' ), // stdout is a pipe that the child will write to. /** * Initially we sent errors to /tmp/error-output.txt. This caused warnings when the file * was not writable. For any error messages, see $pipes[2] further down this method. */ 2 => array( 'pipe', 'w' ), ); $cwd = ABSPATH; $compression_level = $this->get_compression_level(); $process = proc_open( //phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.system_calls_proc_open 'zip -' . $compression_level . ' -g -q -@ ' . $this->filepath, $descriptorspec, $pipes, $cwd ); if ( is_resource( $process ) ) { foreach ( $filelist_chunk as $file ) { fwrite( $pipes[0], $file . "\n" ); //phpcs:ignore WordPress.WP.AlternativeFunctions } fclose( $pipes[0] ); //phpcs:ignore WordPress.WP.AlternativeFunctions fclose( $pipes[1] ); //phpcs:ignore WordPress.WP.AlternativeFunctions // Check for any errors. $stderr = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); //phpcs:ignore WordPress.WP.AlternativeFunctions if ( ! empty( $stderr ) ) { $this->error = $stderr; $this->core->logger->add( 'Error zipping files with system zip: ' . $stderr ); $has_error = true; } // It is important that you close any pipes before calling. // proc_close in order to avoid a deadlock. proc_close( $process ); } else { $has_error = true; } return ! $has_error; } /** * Add the .sql file individually. * * @since 1.13.0 * * @see self::filelist_create */ private function zip_sql() { $this->core->logger->add( 'Starting to add db dump to the zip file.' ); $this->core->logger->add_memory(); $dir = pathinfo( $this->core->db_dump_filepath, PATHINFO_DIRNAME ); $compression_level = $this->get_compression_level(); $this->core->execute_command( 'cd ' . $dir . '; zip -' . $compression_level . ' -g -q ' . $this->filepath . ' ' . basename( $this->core->db_dump_filepath ) . ';' ); $this->core->logger->add( 'Finished adding db dump to the zip file.' ); $this->core->logger->add_memory(); } } admin/compressor/class-boldgrid-backup-admin-compressor-php-zip.php000064400000024347147577722710021577 0ustar00 */ /** * Class: Boldgrid_Backup_Admin_Compressor_Php_Zip * * @since 1.5.1 */ class Boldgrid_Backup_Admin_Compressor_Php_Zip extends Boldgrid_Backup_Admin_Compressor { /** * An array of directories we've added to the zip. * * @since 1.6.0 * @access public * @var array */ public $dirs = array(); /** * The status of our test result. * * @since 1.5.1 * @access public * @var mixed|bool|null */ public static $test_result = null; /** * An array of any errors received while testing. * * @since 1.5.1 * @access public * @var array */ public $test_errors = array(); /** * An instance of ZipArchive. * * @since 1.5.1 * @var ZipArchive */ public $zip; /** * Key. * * @since 1.13.0 * @access protected * @var string */ protected $key = 'php_zip'; /** * Add a file's directories to the zip. * * When you add a file, the parent directories are not always explicitly * created. For example, if you add wp-content/themes/pavilion/index.php the * wp-content directory (and so forth) is not explicity added to the zip. * * @since 1.6.0 * * @param string $file A file path. */ public function add_dir( $file ) { $add_directory = ''; $dirs = explode( DIRECTORY_SEPARATOR, dirname( $file ) ); foreach ( $dirs as $key => $dir ) { if ( 0 === $key ) { $add_directory = $dir; } else { $add_directory .= '/' . $dir; } if ( ! in_array( $add_directory, $this->dirs, true ) ) { $this->zip->addEmptyDir( $add_directory ); $this->dirs[] = $add_directory; } } } /** * Archive files. * * @since 1.5.1 * * @see Boldgrid_Backup_Admin_Filelist::get_total_size() * * @param array $filelist { * File details. * * @type string 0 Path. Example: ""/home/user/public_html/readme.html". * @type string 1 basename. Example: "readme.html". * @type int 2 File size (in bytes). Example: "7413". * @type string 3 File type. Examples: "d", "f". * } * @param array $info { * Data about the backup archive we are generating. * * @type string mode backup * @type bool dryrun * @type string compressor php_zip * @type int filesize 0 * @type bool save 1 * @type int total_size 0 * } */ public function archive_files( $filelist, &$info ) { // Init vars used for our "in progress" bar. $number_files_archived = 0; $total_size_archived = 0; $number_files_todo = count( $filelist ); $last_x_files = array(); if ( $info['dryrun'] ) { return true; } // Prevent this process from ending; allow the archive to be completed. ignore_user_abort( true ); set_time_limit( 0 ); $this->zip = new ZipArchive(); $status = $this->zip->open( $info['filepath'], ZipArchive::CREATE ); if ( ! $status ) { return array( 'error' => 'Cannot open ZIP archive file "' . $info['filepath'] . '".', 'error_code' => $status, 'error_message' => Boldgrid_Backup_Admin_Utility::translate_zip_error( $status ), ); } $has_setexternalattributesname = method_exists( $this->zip, 'setExternalAttributesName' ); foreach ( $filelist as $fileinfo ) { $is_dir = ! empty( $fileinfo[3] ) && 'd' === $fileinfo[3]; switch ( $is_dir ) { case true: $this->zip->addEmptyDir( $fileinfo[1] ); break; case false: if ( ! is_readable( $fileinfo[0] ) ) { $info['backup_errors'][] = sprintf( // translators: 1 The path to a file that was unable to be added to the backup. __( 'Permission defined. Unable to add the following file to your backup: %1$s', 'boldgrid-backup' ), $fileinfo[0] ); continue 2; } else { $this->zip->addFile( $fileinfo[0], $fileinfo[1] ); $this->add_dir( $fileinfo[1] ); } break; } /* * ZipArchive::setExternalAttributesName() is avaiable in PHP >= 5.6. * If available, use the method to set the permissions for items in the ZIP archive. * By default, items in a ZIP file are extracted with loose (777/666) modes, which can * cause issues on Linux systems using suEXEX/suPHP or other mechanisms requiring * tighter (755/644; world non-writable permissions) modes on directories and files. */ if ( $has_setexternalattributesname ) { $this->zip->setExternalAttributesName( $is_dir ? $fileinfo[1] . '/' : $fileinfo[1], ZipArchive::OPSYS_UNIX, fileperms( $fileinfo[0] ) << 16 ); } $number_files_archived++; $total_size_archived += empty( $fileinfo[2] ) ? 0 : $fileinfo[2]; /* * If applicable, add this file to the list of files archived that we show the user. * * To give the user a more broad sense of the files being added, our list only contains * every 20th file. * * Our list is only 5 long because we make hook into the heartbeat every 5 seconds to grab * the last 5 files, and we display each file for 1 second. */ if ( 0 === $number_files_archived % 20 ) { $last_x_files[] = $fileinfo[1]; if ( count( $last_x_files ) > 5 ) { array_shift( $last_x_files ); } } /* * Update our "in progress" data. * * To prevent excessive calls to update options, we only update our in progress data every * 100 files. */ $all_files_archived = $number_files_archived >= $number_files_todo; if ( 0 === $number_files_archived % 100 || $all_files_archived ) { Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_files_done', $number_files_archived ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'last_files', $last_x_files ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived', $total_size_archived ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived_size_format', size_format( $total_size_archived, 2 ) ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 2 ); } } $this->core->logger->add( sprintf( 'Total files / size archived: %1$s / %2$s (%3$s)', $number_files_archived, $total_size_archived, size_format( $total_size_archived, 2 ) ) ); /* * We're done archiving all files. * * Empty out the "last files archived" data, and set an appropriate status. */ Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'last_files' ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 3 ); /* * Verify files before write/close. Delete any invalid file indicies in the ZIP index. * * In some scenarios, a file will be added above, but then deleted before the zip->close() * call below. For example, while a backup is in progress, users may be editing pages and * on save, cache files may get deleted. If the cache file was added to the zip above, and then * deleted before the zip->close() below, we're going to have a problem. * * There is one file path outside of ABSPATH; the database dump file. * The full path of each file is determined by checking if it is the dump file or not. * * @todo The user is not notified if a file is removed below. */ for ( $i = 0; $i < $this->zip->numFiles; $i++ ) { $filename = $this->zip->getNameIndex( $i ); $filepath = false !== strpos( $this->core->db_dump_filepath, $filename ) ? $this->core->db_dump_filepath : ABSPATH . $filename; if ( ! $this->core->wp_filesystem->is_readable( $filepath ) ) { $this->zip->deleteIndex( $i ); } } $this->core->logger->add( 'Starting to close the zip file.' ); $this->core->logger->add_memory(); $close = $this->zip->close(); $this->core->logger->add( 'Finished closing the zip file.' ); $this->core->logger->add_memory(); Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'step' ); if ( ! $close ) { return array( 'error' => 'Cannot close ZIP archive file "' . $info['filepath'] . '".', ); } return true; } /** * Determine if ZipArchive is available. * * @since 1.5.2 */ public static function is_extension_available() { return extension_loaded( 'zip' ) && class_exists( 'ZipArchive' ); } /** * Test the functionality of php_zip. * * @since 1.5 * * @return bool */ public function test() { if ( null !== self::$test_result ) { return self::$test_result; } $backup_dir = $this->core->backup_dir->get(); $test_file_contents = sprintf( // translators: 1: Plugin title. __( 'This is a test file from %1$s. You can delete this file.', 'boldgrid-backup' ), BOLDGRID_BACKUP_TITLE ); // translators: 1: A filename. $cannot_open_zip = __( 'Unable to create zip file: %1$s', 'boldgrid-backup' ); // translators: 1: Backup directory path. $cannot_close_zip = __( 'When testing ZipArchive functionality, we are able to create a zip file and add files to it, but we were unable to close the zip file.
Please be sure the following backup directory has modify permissions:
%1$s', 'boldgrid-backup' ); $safe_to_delete = __( 'safe-to-delete', 'boldgrid-backup' ); $test_zip_file = $this->core->test->test_prefix . '-zip'; $test_filename = sprintf( '%1$s%5$s%2$s-%3$s-%4$s', $backup_dir, $test_zip_file, mt_rand(), $safe_to_delete, DIRECTORY_SEPARATOR ); $zip_filepath = $test_filename . '.zip'; $random_filename = $test_filename . '.txt'; $zip = new ZipArchive(); $status = $zip->open( $zip_filepath, ZipArchive::CREATE ); if ( ! $status ) { $this->test_errors[] = sprintf( $cannot_open_zip, $zip_filepath ); self::$test_result = false; return false; } $this->core->wp_filesystem->touch( $random_filename ); $this->core->wp_filesystem->put_contents( $random_filename, $test_file_contents ); $zip->addFile( $random_filename, 'test.txt' ); $zip_closed = @$zip->close(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged $this->core->test->delete_test_files( $backup_dir ); if ( ! $zip_closed ) { $this->test_errors[] = sprintf( $cannot_close_zip, $backup_dir ); self::$test_result = false; return false; } self::$test_result = true; return true; } } admin/compressor/class-boldgrid-backup-admin-compressor-pcl-zip.php000064400000037265147577722710021571 0ustar00 */ /** * Class: Boldgrid_Backup_Admin_Compressor_Pcl_Zip * * @since 1.5.1 */ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Compressor { /** * An array of errors. * * @since 1.6.0 * @access public * @var array */ public $errors = array(); /** * The status of our test result. * * @since 1.5.1 * @access public * @var mixed|bool|null */ public static $test_result = null; /** * An array of any errors received while testing. * * @since 1.5.1 * @access public * @var array */ public $test_errors = array(); /** * Key. * * @since 1.13.0 * @access proteced * @var string */ protected $key = 'pcl_zip'; /** * Constructor. * * @since 1.5.1 * * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object. */ public function __construct( $core ) { if ( ! class_exists( 'PclZip' ) ) { require_once ABSPATH . '/wp-admin/includes/class-pclzip.php'; } parent::__construct( $core ); } /** * Add empty directories to current directory we're browsing. * * This method is used by this->browse, and it's whole reason for existence * is because ZipArchive gives you the ability to simply add a directory to * the archive, but PclZip does not. * * If PclZip archive only includes one file, such as * wp-content/plugins/boldgrid/index.php, we need to "artificially" create * these directories for the zip browser: * # wp-content/ * # wp-content/plugins/ * # wp-content/plugins/boldgrid/ * * @since 1.6.0 * * @param array $list A list of files. * @param array $contents Contents; not used here. * @param array $filenames Filenames. * @param string $in_dir Current directory. * @return array An updated $contents. */ public function browse_add_dirs( $list, $contents, $filenames, $in_dir ) { foreach ( $list as $key => $file ) { // These variables are very similar, both exist for readability. $top_dir = null; $next_dir = null; if ( '.' === $in_dir ) { $top_dir = explode( '/', $file['filename'] ); $top_dir = $top_dir[0]; if ( empty( $top_dir ) || in_array( $top_dir, $filenames, true ) ) { continue; } } else { /* * Determine if file is in directory. * * For example, We want to know if file wp-admin/user/about is * in wp-content/ */ $file_in_dir = 0 === strpos( $file['filename'], $in_dir . '/' ); if ( ! $file_in_dir ) { continue; } /* * Calcular our next directory. * * If we're looking for all folders within wp-content/plugins * and we're given a filename of * wp-content/plugins/boldgrid/index.php, then we can say that * wp-content/plugins/boldgrid exists in wp-content/plugins. */ $next_dir = str_replace( $in_dir . '/', '', $file['filename'] ); $next_dir = explode( '/', $next_dir ); $next_dir = $in_dir . '/' . $next_dir[0]; if ( $next_dir === $file['filename'] || in_array( $next_dir, $filenames, true ) ) { continue; } } $dir = ! empty( $top_dir ) ? $top_dir : $next_dir; $sudo_file = array( 'filename' => $dir, 'folder' => true, ); $contents[] = $sudo_file; $filenames[] = $dir; } return $contents; } /** * Archive files. * * @since 1.5.1 * * @see Boldgrid_Backup_Admin_Filelist::get_total_size() * * @param array $filelist File list. * @param array $info { * An array of data about the backup archive we are generating. * * @type string mode backup * @type bool dryrun * @type string compressor php_zip * @type ing filesize 0 * @type bool save 1 * @type int total_size 0 * } */ public function archive_files( $filelist, &$info ) { if ( $info['dryrun'] ) { return true; } $cwd = $this->wp_filesystem->cwd(); $archive = new PclZip( $info['filepath'] ); if ( 0 === $archive ) { return array( 'error' => sprintf( 'Cannot create ZIP archive file %1$s. %2$s.', $info['filepath'], $archive->errorInfo() ), ); } // Prevent this process from ending; allow the archive to be completed. ignore_user_abort( true ); set_time_limit( 0 ); /* * Create our $new_filelist. * * We can pass $archive->add() an array of files to archive. $filelist * is an array of arrays, so we need to convert to simply an array of * strings (filenames to archive). */ $total_size_archived = 0; $new_filelist = []; foreach ( $filelist as $file ) { // Don't add the database dump at this time, it will be added later. if ( ! empty( $this->core->db_dump_filepath ) && $file[0] === $this->core->db_dump_filepath ) { continue; } $total_size_archived += empty( $file[2] ) ? 0 : $file[2]; $new_filelist[] = $file[0]; } Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 3 ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived', $total_size_archived ); Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived_size_format', size_format( $total_size_archived, 2 ) ); $status = $archive->add( $new_filelist, PCLZIP_OPT_REMOVE_PATH, ABSPATH ); if ( 0 === $status ) { $error_info = $archive->errorInfo(); $custom_error = $this->parse_error_info( $error_info ); if ( false === $custom_error ) { return array( 'error' => sprintf( 'Cannot add files to ZIP archive file: %1$s', $archive->errorInfo() ), ); } else { return array( 'error' => $custom_error, ); } } /* * Add our database dump to the zip. * * The check for ! empty is here because the user may have opted not * to backup their database. */ if ( ! empty( $this->core->db_dump_filepath ) ) { $status = $archive->add( $this->core->db_dump_filepath, PCLZIP_OPT_REMOVE_ALL_PATH ); if ( 0 === $status ) { return array( 'error' => sprintf( 'Cannot add database dump to ZIP archive file: %1$s', $archive->errorInfo() ), ); } } Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'step' ); $this->wp_filesystem->chdir( $cwd ); return true; } /** * Get the contents of a zip file. * * @param string $filepath File path. * @param string $in_dir Current directory. * @return array */ public function browse( $filepath, $in_dir = '.' ) { $in_dir = untrailingslashit( $in_dir ); /* * Keep track of the contents of the directory we're trying to browse. * * This variable is different than the below $filenames variable because * $contents contains an array arrays (info ABOUT each filename) while * $filenames just contains either the file or folder name. */ $contents = array(); /* * Keep track of just file and folder names added to the $contents. For * example: * * [0] wp-content (folder) * [1] wp-content/index.php (file) */ $filenames = array(); $zip = new PclZip( $filepath ); $list = $zip->listContent(); if ( empty( $list ) ) { return $contents; } /* * Each $file is an array. Several example $file's can be seen here: * https://pastebin.com/bjQZYcAt */ foreach ( $list as $key => $file ) { /* * Calculate the parent directory this file / folder belongs to. * * Examples: * * readme.html = . * * wp-admin/press-this.php = wp-admin * * wp-admin/js/user-profile.min.js = wp-admin/js */ $parent_dir = dirname( $file['filename'] ); if ( $parent_dir !== $in_dir ) { continue; } $contents[] = $file; $filenames[] = rtrim( $file['filename'], '/' ); } $contents = $this->browse_add_dirs( $list, $contents, $filenames, $in_dir ); return $contents; } /** * Extract one file from an archive. * * @since 1.5.3 * * @param string $filepath Archive path, such as "/home/user/boldgrid_backup/archive.zip". * @param string $file A file path in the archive file, such as "wp-content/index.php". * @return bool */ public function extract_one( $filepath, $file ) { if ( ! $this->core->archive->is_archive( $filepath ) ) { $this->errors[] = __( 'Not an archive.', 'boldgrid-backup' ); return false; } if ( empty( $file ) ) { $this->errors[] = __( 'Empty file.', 'boldgrid-backup' ); return false; } $file_contents = $this->get_file( $filepath, $file ); if ( empty( $file_contents ) ) { $this->errors[] = __( 'Unable to extract single file from archive.', 'boldgrid-backup' ); return false; } // Make sure the file's dir exists, write the file, and adjust the timestamp. $file_abspath = ABSPATH . $file; wp_mkdir_p( dirname( $file_abspath ) ); $written = $this->core->wp_filesystem->put_contents( $file_abspath, $file_contents[0]['content'] ); if ( ! $written ) { $this->errors[] = __( 'Not written.', 'boldgrid-backup' ); return false; } return $this->core->wp_filesystem->touch( ABSPATH . $file, $file_contents[0]['mtime'] ); } /** * Extract 1 file from a zip archive. * * @since 1.5.3 * * @param string $filepath Archive path, such as "/home/user/boldgrid_backup/archive.zip". * @param string $file A file path in the archive file, such as "wp-content/index.php". * @return mixed False on failure, array on success { * Accessed via $file_contents[0]. * * @type string $filename wp-content/index.php * @type string $stored_filename wp-content/index.php * @type int $size 28 * @type int $compressed_size 30 * @type int $mtime 1505997200 * @type string $comment * @type bool $folder * @type int $index 25054 * @type string $status ok * @type int $crc 4212199498 * @type string $content * } */ public function get_file( $filepath, $file ) { if ( ! $this->core->archive->is_archive( $filepath ) ) { return false; } if ( empty( $file ) ) { return false; } $zip = new PclZip( $filepath ); $list = $zip->listContent(); if ( empty( $list ) ) { return false; } $file_index = false; foreach ( $list as $index => $filedata ) { if ( $file === $filedata['filename'] ) { $file_index = $index; } } /* * We use to check if(! $file_index) however sometimes the file we want * is at the 0 index. */ if ( false === $file_index ) { return false; } $file_contents = $zip->extractByIndex( $file_index, PCLZIP_OPT_EXTRACT_AS_STRING ); /* * Ensure the mtime is UTC. * * mtime can vary based upon how the archive was initially created (php_zip * or pcl_zip). Make sure it is in UTC. */ $this->core->archive->init( $filepath ); $this->core->time->init( $file_contents[0]['mtime'], $this->core->archive->compressor ); $file_contents[0]['mtime'] = $this->core->time->utc_time; return $file_contents; } /** * Get a list of all sql dumps in an archive's root. * * When restoring an archive, this method is helpful in determining which * sql dump to restore. We're expecting only 1 to be found. * * @since 1.5.2 * * @param string $filepath Full path to zip file. * @return array An array of sql dumps found in the root. */ public function get_sqls( $filepath ) { $sqls = array(); $zip = new PclZip( $filepath ); $list = $zip->listContent(); if ( empty( $list ) ) { return $sqls; } foreach ( $list as $key => $file ) { $filename = $file['filename']; // If it's not in the root, skip it. if ( false !== strpos( $filename, '/' ) || false !== strpos( $filename, '\\' ) ) { continue; } // If it's not in this format, skip it - Format: "*.########-######.sql". if ( 1 !== preg_match( '/\.[\d]+-[\d]+\.sql$/', $filename ) ) { continue; } $sqls[] = $filename; } return $sqls; } /** * Parse the error message and take appropriate action. * * @since 1.5.2 * * @param string $error_info Error message. * @return mixed False when no messages should be displayed, String when * returning a message to the user. */ public function parse_error_info( $error_info ) { $parts = explode( '\'', $error_info ); $force_php_zip = false; $messages = array(); // Does not exist [code -4]. if ( ! empty( $parts[2] ) && false !== strpos( $parts[2], 'code -4' ) ) { $path = ABSPATH . $parts[1]; // Check for broken symlink. if ( is_link( $path ) && ! $this->core->wp_filesystem->exists( $path ) ) { $force_php_zip = true; // translators: 1: File path. $messages[] = sprintf( __( 'PclZip encountered the following broken symlink and is unable to create a backup:
%1$s', 'boldgrid-backup' ), $parts[1] ); } } /* * If we have flagged that ZipArchive should be used instead of PclZip, * then update the settings. */ if ( $force_php_zip ) { $php_zip_set = $this->core->compressors->set_php_zip(); if ( $php_zip_set ) { $messages[] = __( 'We have changed your compressor from PclZip to ZipArchive. Please try to create a backup again.' ); } } return empty( $messages ) ? false : implode( '
', $messages ); } /** * Test the functionality of php_zip. * * @since 1.5 * * @param bool $display_errors Display errors; default is TRUE. * @return bool */ public function test( $display_errors = true ) { if ( null !== self::$test_result ) { return self::$test_result; } $backup_dir = $this->core->backup_dir->get(); // Strings to help with creating test files. $test_file_contents = sprintf( // translators: 1: Plugin title. __( 'This is a test file from %1$s. You can delete this file.', 'boldgrid-backup' ), BOLDGRID_BACKUP_TITLE ); $safe_to_delete = __( 'safe-to-delete', 'boldgrid-backup' ); $test_zip_file = $this->core->test->test_prefix . '-zip'; $test_filename = sprintf( '%1$s%5$s%2$s-%3$s-%4$s', $backup_dir, $test_zip_file, mt_rand(), $safe_to_delete, DIRECTORY_SEPARATOR ); $zip_filepath = $test_filename . '.zip'; $random_filename = $test_filename . '.txt'; // translators: 1: File path. $cannot_touch_file = __( 'PclZip test failed. We were unable to create the following test file:
%1$s.
Please ensure your backup directory has read, write, and modify permissions.', 'boldgrid-backup' ); // translators: 1: File path. $cannot_put_contents = __( 'PclZip test failed. We were able to create the following test file, but we were unable to modify it. were unable to modify it:
%1$s
Please ensure your backup directory has read, write, and modify permissions.', 'boldgrid-backup' ); $touched = $this->core->wp_filesystem->touch( $random_filename ); if ( ! $touched ) { $this->test_errors[] = sprintf( $cannot_touch_file, $random_filename ); self::$test_result = false; return false; } $contents_put = $this->core->wp_filesystem->put_contents( $random_filename, $test_file_contents ); if ( ! $contents_put ) { $this->test_errors[] = sprintf( $cannot_put_contents, $random_filename ); self::$test_result = false; return false; } $archive = new PclZip( $zip_filepath ); if ( 0 === $archive ) { $this->test_errors[] = sprintf( 'Cannot create ZIP archive file %1$s. %2$s.', $info['filepath'], $archive->errorInfo() ); } $status = $archive->add( $random_filename ); if ( 0 === $status ) { $this->test_errors[] = sprintf( 'Cannot add files to PclZip archive file: %1$s', $archive->errorInfo() ); } $this->core->test->delete_test_files( $backup_dir ); self::$test_result = true; return true; } } admin/cron/entry/class-wpcron.php000064400000003072147577722710013107 0ustar00 */ namespace Boldgrid\Backup\Admin\Cron\Entry; use Boldgrid\Backup\Admin\Cron\Entry\Entry; use Boldgrid\Backup\Admin\Cron\Entry\Base; /** * Class: Entry * * @since 1.11.0 */ class Wpcron extends Base implements Entry { /** * The hook this wpcron uses. * * @since 1.11.0 * @access private * @var string */ private $hook; /** * Whether or not this wpcron is set / configured within the wpcron system. * * @since 1.11.0 * @access private * @var bool */ private $is_set; /** * Get the next runtime of this wpcron. * * @since 1.11.0 * * @return string Timestamp, the time the scheduled event will next occur (unix timestamp). * False, if the event isn't scheduled. */ public function get_next_runtime() { return wp_next_scheduled( $this->hook ); } /** * Initialize this wpcron entry. * * @since 1.11.0 * * @param string $hook */ public function init_via_search( array $patterns = [] ) { $this->is_set = false; $this->hook = $patterns[0]; $schedule = wp_get_schedule( $this->hook ); if ( ! empty( $schedule ) ) { $this->is_set = true; } } /** * Get whether or not this wpcron entry exists. * * @since 1.11.0 * * @return bool */ public function is_set() { return $this->is_set; } } admin/cron/entry/class-entry.php000064400000000771147577722710012743 0ustar00 */ namespace Boldgrid\Backup\Admin\Cron\Entry; /** * Class: Entry * * @since 1.11.0 */ interface Entry { public function get_next_runtime(); public function init_via_search( array $patterns = [] ); public function is_set(); } admin/cron/entry/class-crontab.php000064400000006332147577722710013231 0ustar00 */ namespace Boldgrid\Backup\Admin\Cron\Entry; use Boldgrid\Backup\Admin\Cron\Entry\Entry; use Boldgrid\Backup\Admin\Cron\Entry\Base; /** * Class: Crontab Entry. * * @since 1.11.0 */ class Crontab extends Base implements Entry { /** * Our cron entry's command. * * Given the following entry: * "* * * * * COMMAND" * * This property is the "COMMAND" part. * * @since 1.11.0 * @access private * @var string */ private $command; /** * Whether or not this cron exists in the crontab. * * @since 1.11.0 * @access private * @var bool */ private $is_set; /** * The cron's entire command. * * Given the following entry: * "* * * * * COMMAND" * * The raw command is the entire string, "* * * * * COMMAND". * * @since 1.11.0 * @access private * @var string */ private $raw_command; /** * The time defined for the cron. * * Given the following entry: * "* * * * * COMMAND" * * The time is the "* * * * *" part. * * @since 1.11.0 * @access private * @var string */ private $time; /** * An instance of Boldgrid\Backup\Admin\Cron\Crontab. * * @since 1.11.0 * @access private * @var Boldgrid\Backup\Admin\Cron\Crontab */ private $engine; /** * */ public function __construct() { $this->engine = new \Boldgrid\Backup\Admin\Cron\Crontab(); } /** * Get our cron's next runtime. * * @since 1.11.0 * * @return string The unix timestamp (UTC) of when this cron will run next. */ public function get_next_runtime() { $core = apply_filters( 'boldgrid_backup_get_core', null ); require_once BOLDGRID_BACKUP_PATH . '/vendor/boldgrid/tdcron/class.tdcron.php'; require_once BOLDGRID_BACKUP_PATH . '/vendor/boldgrid/tdcron/class.tdcron.entry.php'; /* * Get our next runtime. * * Cron jobs are configured to run on the server's timezone, not UTC. Therefore, our next * runtime will be server time. */ $next_runtime = \tdCron::getNextOccurrence( $this->time ); /* * Initialize our time class with our $next_runtime, and specify the time is in the server's * timezone (local). */ $core->time->init( $next_runtime, 'local' ); return $core->time->utc_time; } /** * Init this cron entry. * * @since 1.11.0 * * @return mixed */ public function init_via_search( array $patterns = [] ) { $this->is_set = false; $matched_crons = $this->engine->find_crons( $patterns ); if ( 1 === count( $matched_crons ) ) { $this->raw_command = $matched_crons[0]; $exploded_command = explode( ' ', trim( $this->raw_command ) ); $time = array_slice( $exploded_command, 0, 5 ); $this->time = implode( ' ', $time ); $command = array_splice( $exploded_command, 5 ); $this->command = implode( ' ', $command ); $this->is_set = true; } } /** * Whether or not this cron entry exists in the crontab. * * @since 1.11.0 * * @return bool */ public function is_set() { return $this->is_set; } } admin/cron/entry/class-base.php000064400000001637147577722710012516 0ustar00 */ namespace Boldgrid\Backup\Admin\Cron\Entry; use Boldgrid\Backup\Admin\Cron\Entry\Entry; /** * Class: Entry * * @since 1.11.0 */ class Base implements Entry { /** * Get our cron entry's next runtime. * * @since 1.11.0 * * @return bool */ public function get_next_runtime() { return false; } /** * Initialize our cron entry. * * @since 1.11.0 * * @return bool */ public function init_via_search( array $patterns = [] ) { return false; } /** * Get whether or not our cron entry exists in the cron engine. * * @since 1.11.0 * * @return boolean */ public function is_set() { return false; } } admin/cron/class-crontab.php000064400000005533147577722710012072 0ustar00 */ namespace Boldgrid\Backup\Admin\Cron; /** * Class: Crontab * * @since 1.11.0 */ class Crontab { /** * Boldgrid_Backup_Admin_Core object. * * @since 1.11.1 * @access private * * @var Boldgrid_Backup_Admin_Core */ private $core; /** * Constructor. * * @since 1.11.1 */ public function __construct() { $this->core = apply_filters( 'boldgrid_backup_get_core', null ); } /** * Search for cron entries. * * This method is similar to the Boldgrid_Backup_Admin_Cron::entry_search() method, except it * accepts an array of patterns to search for, rather than just one. * * @since 1.11.0 * * @param array $patterns An array of patterns to search for. All patterns must be found in * order to return a cron entry as a match. * @return array An array of crons. */ public function find_crons( array $patterns = [] ) { $all_crons = $this->core->cron->get_all( false ); $all_crons = false === $all_crons ? array() : $all_crons; $matched_crons = []; foreach ( $all_crons as $cron ) { $all_patterns_found = true; foreach ( $patterns as $pattern ) { if ( false === strpos( $cron, $pattern ) ) { $all_patterns_found = false; } } if ( $all_patterns_found ) { $matched_crons[] = $cron; } } return $matched_crons; } /** * Write to the system crontab. * * The crontab contents will be replaced with the string passed to this method. * * @since 1.11.1 * * @param string $crontab The crontab contents to be written. * @return bool */ public function write_crontab( $crontab ) { $backup_directory = $this->core->backup_dir->get(); if ( ! $this->core->wp_filesystem->is_writable( $backup_directory ) ) { return false; } // Strip extra line breaks. $crontab = str_replace( "\n\n", "\n", $crontab ); // Trim the crontab. $crontab = trim( $crontab ); // Add a line break at the end of the file. $crontab .= "\n"; // Save the temp crontab to file. $temp_crontab_path = $backup_directory . '/crontab.' . microtime( true ) . '.tmp'; // Save a temporary file for crontab. $this->core->wp_filesystem->put_contents( $temp_crontab_path, $crontab, 0600 ); // Check if the defaults file was written. if ( ! $this->core->wp_filesystem->exists( $temp_crontab_path ) ) { return false; } // Write crontab. $command = 'crontab ' . $temp_crontab_path; $this->core->execute_command( $command, $success ); // Remove temp crontab file. $this->core->wp_filesystem->delete( $temp_crontab_path, false, 'f' ); return (bool) $success; } } admin/css/boldgrid-backup-admin-zip-browser.css000064400000001072147577722710015561 0ustar00.listing .dashicons.dashicons-portfolio { color: #c4963d; } .listing .dashicons.dashicons-media-default { color: #0073aa; } .listing a, a.restore-db, a.view-db, a.load-browser, .breadcrumbs a { cursor: pointer; } .breadcrumbs .dashicons.dashicons-admin-home { vertical-align: text-bottom; } .file-actions > td { padding-left:35px; } /* Mimic postbox toggle arrows. These generally are in the last thead th. */ .bulk-action-notice .toggle-indicator { float: right; cursor: pointer; } .bulk-action-notice .toggle-indicator.closed:before { content: "\f140"; }admin/css/boldgrid-backup-admin-test.css000064400000001513147577722710014255 0ustar00.functionality-test-section table { border-collapse: collapse; } .functionality-test-section table tr { border: 1px solid #ddd; } .functionality-test-section table tr td { padding: 5px 10px; vertical-align: top; } .functionality-test-section table tr td h2 { margin-bottom: 5px; margin-top: 30px; } /* The first tr will be the status (pass/fail) */ .functionality-test-section table tr:first-of-type { background: none; border: none; font-weight: bold; } /* Highlight errors and warnings. */ .wp-list-table .error { color: #dc3232; font-weight: bold; } .wp-list-table .warning { color: #ffba00; font-weight: bold; } .wp-list-table .success { color: green; font-weight: bold; } .functionality-test-section tr.heading { border: 0px; background: transparent; } .functionality-test-section pre { white-space: pre-line; }admin/css/boldgrid-backup-admin-settings.css000064400000001506147577722710015140 0ustar00/* If a day of the week checkbox is disabled, modify its hover cursor. */ .schedule-dow input[type='checkbox'][disabled]:hover { cursor: not-allowed; } .form-table tr td p { padding: 5px 0px; margin: 0px; } .bgb-unbold { font-weight: normal; } #auto-recovery-tr { display: none; } /** * Auto Update Styles */ .auto-update-settings.form-table .table-help td, .auto-update-settings.form-table .table-help td p { padding: 0; padding-left: 5px; } .form-table .bglib-divider { border-bottom: 1px solid #e2e4e7; } #section_auto_updates .form-table th { width: auto; } .auto-update-settings.form-table td { padding: 5px 5px; } .auto-update-settings .toggle.right { float: right; } .auto-update-settings input[type="number"] { width: 5em; } .auto-update-settings .help-icon { vertical-align: middle; padding-left: 0.25em; }admin/css/boldgrid-backup-admin-premium.css000064400000003554147577722710014763 0ustar00/** * Style for specific premium feature cards. */ #bgbkup_amazon_s3 .bglib-card-icon { border-top-color: #feb424; } #bgbkup_database_encryption .bglib-card-icon { border-top-color: #aaa; } #bgbkup_dream_objects .bglib-card-icon { border-top-color: #3e95be; } #bgbkup_backups .bglib-card-icon { border-top-color: #0073aa; } #bgbkup_google_drive .bglib-card-icon { border-top-color: #1ba160; } #bgbkup_amazon .bglib-card-icon { border-top-color: #feb424; } #bgbkup_dream_objects .bglib-card-icon { border-top-color: #3e95be; } #bgbkup_history .bglib-card-icon { color: #f04207; border-top-color: #f04207; } #bgbkup_historical_versions .bglib-card-icon { color: #9ebaa0; border-top-color: #9ebaa0; } #bgbkup_plugin_editor_tools .bglib-card-icon { color: #5d824b; border-top-color: #5d824b; } #bgbkup_backups .bglib-card-icon .dashicons { color: #0073aa; } #bgbkup_updates .bglib-card-icon { border-top-color: #aa0073; } #bgbkup_updates .bglib-card-icon .dashicons { color: #aa0073; } #bgbkup_one_click_restoration .bglib-card-icon { color: #c604c6; border-top-color: #c604c6; } #bgbkup_get_premium .bglib-card-icon { border-top-color: #f95b26; } #bgbkup_get_premium .bglib-card-icon .dashicons { color: #f95b26; } /** * Misc. */ /* The get premium button in the top notice. */ .bglib-card { display: flex; flex-direction: column; } .bglib-card-icon { height: 60px; } .bg-box-bottom.premium .button-success { float: none; } .bglib-card-footer { flex-grow: 10; } .bglib-card-links { flex-grow: 1; } .bglib-card-links a { margin: 1em; } .bg-box-title { font-size: 1.25em; font-weight: 600; } .bglib-card-title { height: 2em; } .bglib-card-links span.dashicons { vertical-align: text-top; padding-right: 0.25em; } .bglib-card .bglib-card-links { justify-content: flex-end; } .bglib-smaller .bglib-card-links a.button { margin-right: 10px; }admin/css/boldgrid-backup-admin-new-thickbox-style.css000064400000001066147577722710017041 0ustar00/** * Thickbox styles. * * Thickbox appears when user clicks "View details" for a backup. These styles * make the standard thickbox look more like the modal of a plugin's * "View details" link. */ body #TB_window, #TB_window #TB_title { background-color: rgba(0, 0, 0, 0); border: 0px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } #TB_closeAjaxWindow #TB_closeWindowButton { right: -29px; top: 30px; } #TB_closeAjaxWindow .tb-close-icon:before { font: normal 30px/30px dashicons; color: #eee; } #TB_ajaxContent { background: #fff; }admin/css/boldgrid-backup-admin-home.css000064400000000520147577722710014223 0ustar00#upload-archive-section .spinner { display: none; float: none !important; } .upload-plugin .help { background: none; padding-top: 0px; padding-bottom: 0px; border: 0px; } /* Disable floating of mine count so help section displays nicely. */ .subsubsub { float: none; } .page-title-actions { display: inline-block; } admin/css/boldgrid-backup-admin-hide-all.css000064400000001005147577722710014751 0ustar00/** * Hide all but content. * * This set of styles hides everything on the page except for what the plugin * displays. This helps make the page look better in an iframe / modal. */ .boldgrid-backup-in-progress, .update-nag, #adminmenumain, [id$="-tgmpa"], #wpadminbar, #wpfooter { display: none; } #wpwrap { position: absolute; top: 0px; left: 0px; } #wpwrap #wpcontent { margin: 0px; !important; padding-left: 10px; !important; padding-right: 10px; !important; } #wpbody-content { padding-bottom: 0px; } admin/css/boldgrid-backup-admin-ftp-settings.css000064400000000141147577722710015721 0ustar00table [type="text"], table [type="password"] { width: 100%; } [type="number"] { width: 75px; }admin/css/boldgrid-backup-admin-folder-exclude.css000064400000003570147577722710016205 0ustar00/** * This section contains code for the "Exclude Folder" interface on the Settings * page. */ .folder_exclude_help tr th { vertical-align: top; width: 70px; } .folder_exclude_help tr th, .folder_exclude_help tr td { padding: 5px 5px; } .folder_exclude_help .example { font-style: italic; color: #696969; } .form-table th h2 { display: inline; } #folder_exclusion_filter { margin: 3px 0px 0px 0px; } #exclude_folders_preview ul { max-height: 300px; overflow: auto; background: #fff; padding: 5px; border: 1px solid #ddd; clear: both; } /** * This section contains the css for the "Exclude Folder" interface within a * modal, such as the "Backup Site Now" modal. */ #TB_ajaxContent { background: #f1f1f1; } #TB_ajaxContent .form-table { margin-top: 0px; } #TB_ajaxContent .form-table tr:first-of-type th, #TB_ajaxContent .form-table tr:first-of-type td { padding-top: 10px; vertical-align:top; } #TB_ajaxContent .form-table td { padding-bottom: 0px; } #TB_ajaxContent .form-table td p:first-of-type { padding-top: 0px; margin-top: 0px; } #TB_ajaxContent #exclude_folders_preview { max-width: 420px; } #TB_ajaxContent .form-table th { width: 100px; } /** * This section includes code for the "include tables" database setting. */ .include-tables, #tables_to_include .tables { margin-top: 15px; } .include-tables div { float: left; width: 300px; white-space: nowrap; overflow: hidden; margin-right: 10px; } /** * This section contains misc. code for the "Backup Site Now" modal. */ .setting-section { background:#efefef; border:1px solid #ddd; padding:0px 15px; margin-bottom: 15px; } .setting-section.last { margin-bottom: 65px; } #TB_ajaxContent .plugin-card-bottom { position: absolute; bottom: 0px; left: 0px; right: 0px; padding: 0px 10px; } .plugin-card-bottom #you_may_leave { float: left; margin-top: 5px; } .plugin-card-bottom .notice { margin-bottom: 10px; }admin/css/boldgrid-backup-admin-dashboard.css000064400000000671147577722710015231 0ustar00/** * Style for specific cards. */ #bgbkup_backups .bglib-card-icon { border-top-color: #0073aa; } #bgbkup_backups .bglib-card-icon .dashicons { color: #0073aa; } #bgbkup_updates .bglib-card-icon { border-top-color: #aa0073; } #bgbkup_updates .bglib-card-icon .dashicons { color: #aa0073; } #bgbkup_get_premium .bglib-card-icon { border-top-color: #f95b26; } #bgbkup_get_premium .bglib-card-icon .dashicons { color: #f95b26; } admin/css/boldgrid-backup-admin-customizer.css000064400000000566147577722710015511 0ustar00.control-panel-themes .customize-themes-notifications div.boldgrid-backup-protect-now, .control-panel-themes .customize-themes-notifications div.boldgrid-backup-in-progress, .control-panel-themes .customize-themes-notifications div.boldgrid-backup-complete, .control-panel-themes .customize-themes-notifications div.boldgrid-backup-protected { margin: 0px 25px 25px 25px; }admin/css/boldgrid-backup-admin.css000064400000020122147577722710013275 0ustar00[id^=toplevel_page_boldgrid-backup] .wp-menu-image::before { content: "\f178"; } .dashicons-editor-help { display: inline-block; position: relative; cursor: pointer; } .help[data-id] { display: none; } th .help[data-id] { font-weight: normal; } /* Create an inline spinner. */ .spinner.inline { float: none; visibility: visible; vertical-align: bottom; margin-left: 0px; } .spinner.inline.middle { vertical-align: middle; } .spinner.hidden { display: none; } /* When the user clicks to rollback site, show the spinner. */ #restore-now-section .spinner.is-active { display: inline-block; } /* While thickbox is loading, show something rather than nothing. */ #TB_iframeContent { background: #f1f1f1; } /* Prevent clicks on disabled links. */ .bgbkup-page-container a[disabled="disabled"], .bgbkup-page-container a[disabled="true"] { pointer-events: none; } .bgbu-wait { cursor: wait !important; } .dashicons.red { color: #dc3232; } .dashicons-warning.yellow { color: #ffb900; } .dashicons.green { color: #46b450; } div .dashicons { vertical-align: bottom; } /* Dashicon in "mine count". */ .subsubsub .dashicons { vertical-align: text-top; } /* The table of size data. */ #size-data table tr td { vertical-align: top; } .total-size { background: #ddd; width: 325px; } .usage { height: 5px; max-width: 100% !important; } .usage.size-error { background: #dc3232; } .usage.size-warning { background: #ffb900; } .usage.size-success { background: #46b450; } /* Format a table within a table. */ .form-table table td { padding: 0px 10px 0px 0px; } /* Clean up headers we place in any admin notices. */ .notice .header-notice { margin-top: 10px; } hr.separator { margin: 30px 0px; } hr.separator-small { margin: 20px 0px; } /* Get Premium link in the left nav. */ #adminmenu [class*=boldgrid-backup] .get-premium, #adminmenu [class*=boldgrid-backup] .dashicons-dashboard { color: #ffb900; } /* Needed style for bouncing help icon in mine count. */ .subsubsub .ui-effects-wrapper { display: inline-block; } /* WordPress by default has both the h2 and h3 tags set to the same font size. */ h3 { font-size: 1.2em; } input:invalid { border: 1px solid red; } #download-link-copy, #url-import-notice { display: none; } #download-copy-button .dashicons { font-size: 16px; } /** * Progress bar. * * When a backup is in progress, we show the user a progress bar. */ #boldgrid-backup-in-progress-bar:before { transition: background-color 2s ease; background-color: transparent; } .heartbeat-lost-focus #boldgrid-backup-in-progress-bar:before { content:""; display: block; height: 100%; position: absolute; top: 0; left: 0; width: 100%; background-color: rgba( 255, 255, 255, .9 ); } .heartbeat-lost-focus #boldgrid-backup-in-progress-bar #last_file_archived, .heartbeat-lost-focus #boldgrid-backup-in-progress-bar .progress-label { color: #ddd; } #boldgrid-backup-in-progress-bar { position: relative; background: #f7f7f7; border: 1px solid #ccc; clear:both; overflow: visible; height: 2em; margin: 0px; margin-bottom: 20px; } /* The actual progress bar that goes from 0% to 100%. */ #boldgrid-backup-in-progress-bar .ui-progressbar-value { background-color: #0085ba; -webkit-transition: width 1s ease-out; -moz-transition: width 1s ease-out; -o-transition: width 1s ease-out; transition: width 1s ease-out; } #boldgrid-backup-in-progress-bar #last_file_archived { font-size: 10px; position: absolute; bottom: -20px; left: 0px; white-space: nowrap; } #boldgrid-backup-in-progress-bar .spinner { vertical-align: middle; margin-top: -2px; } .ui-progressbar .ui-progressbar-value { height: 100%; } .progress-label { position: absolute; top: 4px; font-weight: bold; text-shadow: 1px 1px 0 #fff; left:0; right:0; font-weight: 600; color: #0073aa; text-align: center; } .progress-label.over-50 { color: #fff; text-shadow: none; } #boldgrid_backup_in_progress_steps .step { float: left; width: 33%; text-align:center; color: #ddd; } #boldgrid_backup_in_progress_steps .step:first-of-type { text-align: left; } #boldgrid_backup_in_progress_steps .step:last-of-type { text-align: right; } #boldgrid_backup_in_progress_steps .step.active { color: #444; font-weight: bold; } nav[class*="bgbkup-nav-tab-wrapper"] .nav-tab { cursor: pointer; } /** * A table showing when the backup started and how. */ #bgbkup_progress_status table { margin-bottom: 10px; } #bgbkup_progress_status table th { padding-right: 10px; font-weight: 500; text-align: left; } /** * Custom "smaller" nav tab wrapper. * * For example, having nav tabs in an admin notice. */ .bgbkup-nav-tab-wrapper-small { margin-bottom: 10px; } .bgbkup-nav-tab-wrapper-small .nav-tab { font-size: 13px; font-weight: normal; padding: 2px 6px; } /* * Backup Archive Details: title and description. * * This section contains styles for the title and description input fields. */ #titlediv #titlewrap #title { margin-bottom: 15px; } [name="backup_description"] { width: 100%; height: 100px; margin: 0px; } /* * Remote Storage providers. * * More specifically, logos for remote storage providers. */ .bgbkup-gdrive-logo { background-image: url('../image/remote/google-drive-logo.png'); background-repeat: no-repeat; background-size: 100% 100%; width: calc(292px / 2.3); height: calc(50px / 2.3); display: inline-block; } .bgbkup-gdrive-logo-smaller { width: calc(292px / 2.8); height: calc(50px / 2.8); } .amazon-s3-logo { background-image: url('../image/remote/amazon-s3-logo.png'); background-repeat: no-repeat; background-size: 100% 100%; width: calc(195px / 2.3); height: calc(50px / 2.3); display: inline-block; } .amazon-s3-logo-smaller { width: calc(195px / 2.8); height: calc(50px / 2.8); } p > .bgbkup-remote-logo { vertical-align: bottom; } /** * Support tab. */ .bgbkup-support-page { display: flex; margin-top: 1em; } .bgbkup-support-page ul { line-height: 1.4; margin: 0; } /* @todo For reusability, these styles handling the bg-box display can be moved to library/src/assets/css/ui.css */ .bgbkup-support-page .bg-box { margin: 1em; width: 50%; } .bgbkup-premium-support .bgbkup-upgrade-message { text-align: center; } .bgbkup-premium-support .bgbkup-upgrade-message p:first-of-type { margin-top: 0; } .bgbkup-db-lock { background-image: url('../image/db-lock-64.png'); background-position-y: 7px; background-repeat: no-repeat; background-size: 20px 20px; display: block; margin-left: 10px; padding-left: 23px; } /** * Override Library's Ui Page. */ .bgbkup-page-container #bglib-page-header { background-image: url( '../image/icon-128x128.png' ); } /** * Misc. */ /* Allow the standard Thickbox to be shown full screen. */ #TB_window.bg-full-screen { margin: 0 !important; top: 30px; left: 30px; width: calc( 100% - 60px ) !important; height: calc( 100% - 60px ); } #TB_window.bg-full-screen #TB_ajaxContent { width: calc( 100% - 40px ) !important; height: calc( 100% - 60px ) !important; } .bgbkup-transfers-destination .bg-box-bottom.premium .button-success { float: none; margin: 10px; } .page-title-actions { display: inline-block; } .bg-auto-update.dashicons { margin-right: 6px; vertical-align: bottom; } .bg-auto-update.dashicons.dashicons-warning { color: #f56e28; } .bg-auto-update.dashicons.dashicons-yes { color: #79ba49; } #upload-archive-section.wp-upload-form { flex-wrap: wrap; } .bgbkup-page-container .upload-plugin .wp-upload-form { max-width: 85%; align-items: center; } .bgbkup-page-container .upload-plugin .wp-upload-form p { padding-right: 1em; } .bgbkup-page-container .upload-plugin .wp-upload-form .error_messages p { width: 100%; } .bgbkup-page-container .upload-plugin .wp-upload-form input[type=text] { width: 30%; margin-right:6px; } .bgbkup-page-container .upload-plugin #upload-archive-section { align-items: center; } .bgbkup-page-container .upload-plugin #upload-archive-section form { width: 60%; } .bgbkup-page-container .upload-plugin #upload-archive-section form input[type="file"] { width: 50%; } .bgbkup-page-container .upload-plugin #upload-archive-section .error_messages { width: 100%; } admin/image/remote/google-drive.png000064400000012200147577722710013320 0ustar00PNG  IHDR,,N~GgAMA asRGBmvMdͣR#Z+Q.!iAјm?>`IZT"#­qofPz*Dbl3{!y=jaXnh!>)R Q _S2Z!6-}Ĺnȥv|)>+x3$0ߵ7ZwJ2Zq뗀5Z|[ap`!^6 kxdP#Y>̱4zEA d7/e& h{m3>(#xGᅊlj˚1<;Ɨ ǀ si>hcA\K R7IT  ۙ0$_W8lq7f0vvX\%ӖJ$a!)Moy*5qUzez!rSEG6"Y귁*B%~`kI=OdbYBi j؍| j[wOXV1 " +hY8fd% eѬF6?0!IaЪ+xi#p{dUb?ՃoinQ>1$S hICʹ>/ rF G+:g-6dy_^ !w_qHoaXE&|ҸJW/0s|Z#zzϛ([#m$'g3>ACh5)b$S<=G|U+qK{@+z/K1*9"/y~P;ZahEZj=;\w<mND렖NEihOO )FcؖS+4';վQh̋^bmuP~n$6E WbX^0Պ^]D)92w߬j5x%ߣahR A+~E/IY33LQXh$aZclHLT /|x!_oc?ćzrhe<;b-ԍzޱk–xOX~l<6T< cS){cb%߬ Yy<׉V"Xf-eLG:Bbzhh:}ak=Ӈ6ceɖ7Ûa%W'YMkY+FeinQ{Y+DoN ,(/Ez8Y"U 6#Xs*O^ƛváwGr`f2ѬC hyRfҬGn,zi.T7̛ CZc;+mFyxZ /mR"uwrpx!_*z>Vyw,8\ )Mލ|2ʁuGLjshZo*#T_eɭXB\M`U#Zb ?EH X縊/h{ָ,r^0Fv>iuj/C_%Zr݌ ",B;.՚Cw EHtbUZrŤU+>L Q slh'Gχvaw,]`;AZZ5.El&Cv9gR8Z,Wa2W,j ?5iZ t(=KTTb[46HJp,iG,VF.c$XGr߻ Aܫc, Ǣ= (96&&y)YѶ%rCQfD1x?DM%&S_Ǔq) jݑǗm,?":t)wg!\2E/]1 -8"NmQ[dQsN?PrElhM(g #k:̌R'QLCXtR,ć2j3æ?c?߸tS6Z460)G˱g>L`q,p{5A_9&VawߐLJiũ["ݽgkad9M6R։+"&'LJ)2l4L0Z|ݷ}lpEcEHN#? Vk|s0@dwt$= VӇjE%=!pCJA-OOT>9!X,[Ħ wI0Q>Kf}ͱ0aFɷ@'T[=*|kbCa"'UNI늰pPT%j^ʓc޿kn0+ZlRg\'JMt)|%.WVB䈱݋e֡5(T"EBĵ-A'L9j|V}-b;EWaĿ\|fjlxKخ+Ym|waH]-bMA5$W$Bc],>wwK\fW7anPl%hkClp/Tn6R⮙Ӈ؀tA٘6<`ՃV㈅%CB^S4`N"bmZgQ2><|4Kv'$b _q6eX EPф E8oH.dbYMߒki,eIA0YP? d",sN "h2tF {,+R5hLJHD0\j03u~|Elp2idתl,Erc.ol > (b$i;AuSBϵ-8FM(wLJX$)YVdžP_ _d/pX :Y~A+Sl}$>4Q$UYdYߐ/[VGK6# ,=tI>"`Ӓ*Lʹ!MKFsF o9.B,Vۗj Y'\)K`XA1u7zA (#aBXyNn5ob{7NFx[]E.eNz `/Z EKѠ?wYn*= F/Vfc ΂ RR`Ek \{rI"\ؐ#2sR h݊;-V SlMrQ'~H9"Nݒij ^Iw0fl*+Z SV+Z17duj#Blz~"^ZB-JQ2 ,kjn+}^ n Gaiգgʁn ' :wm-=i׫I0`s?D7mn:6:֑\*T" FA+D)<3L'`ŇӐ,XyQw7F`It:/ŠЍ9Z|cUycԤze?PE+֪_Rw`P ݈.HבGk:$ʂkޯUQ|H=67 NGVBLԸPL%`˜PlVjAk1>$[^@hY ъwwwkMuSO 笕1NpwH26|+V`e"9W ++DֳRj-/m E|j~݇%Ňӫ0r==Xehٓ; 9lN՘'"&-F=+αB>}{`L͉Z3HH|p'dK4V£)'Z͑f \7`^㉻{Z yi[^5Z9H2e^􊮮ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZS?b0Q8IENDB`admin/image/remote/google-drive-logo.png000064400000004075147577722710014271 0ustar00PNG  IHDR$2VfPLTE$GpL?|>!qSJː^,OH).p*vJ)M'$g4kl -coޭ +'nыC)CҖ4@.8H~:sb{#n֥iWEѿ]=4"H8~$KJ)R)P-ߕ| $qpo鈄4^y> /a9 Q9#[ unt?BrWᇡcv42=T ҹdd]iH/g FH!_sF$ 77t=!ٟ4MgRsյt' Rd{ELǾ`yDֻi3 A!%oBsW*!W=!],쏓Ev({7W[$˟ Ϭd6k{mat%X|zNM No{!*yVx.N1<Q3 p0bI1e6m>Ә N*[a:1ySgK SvZN2CZ.6^=dPrH(h\@b;f޳Dcp[4 }6u>}/nVXVS^Е^)F(P*#H}"^,{(BXS ̙?D' j:S߆2>@:0=RbbrtdA"TD WI7 JqJ} P4DXv1˗$W3h) EG^O:K}$W:|TRz[ FSu:&Hn"itФ)@ʬa)y9H(%k)nB 9v0d HњQnn$a9=ŚuL #0P^KIhU%t=QjU Ar)4ܜBҲN1S64! XnZj/!=h$wNN@g cP'߂u[3ڢ;?zwNde;ɽ}IA5NC )  4E| õs9>6HuA] ^miz}xRCtfuyFqn% \DY`̀qŪqjC-H5̌vƗU|UFÕ -|Qt&:ky Αrgm ׎ Zav*!e}=^e| r #աί[&3B{{ 8MHVS\zzMsRH_@,NuM14@㳸,~9!_%z-D\02$%M5q_J!m;Mn& [r&OU8{6n6ĝ}PЄ=BPB$~&6@zi֫nJGxgN6J~H 6$ѡ9`?6>,&!y&I2yƄ.P'mH~23 Jz%2%j W]9#aá8MBm=FcۯCSR/º9<[#(Z.l%oU3ټwlcۖΕh-f}w84C:bGZQ_ ƚ@HR}ϟD6+*tH2D2D2D.d,\x2D2D>>>>2D>>2D>\[!tRNSC*zљ {Y5`8 bIDATxb& E=a3>zOIX/}h"mm1U\ylm˲L$4ֶL'@$/c`NL.YztesK;5,sƆ}HXڼD&΍IݑR, ~DcHj^{L6'//TBzeɧյva"T#ȅR 0$իJ}OocJoT!<q})EbA%xXP%_ h\TR;+Mb2_'d!dJXL%ҵ?C gNLjJXBƗvT8"B_7+TȖ`4"j?Xl)FHRl#b`6&V@WY%VRTR{‰լrbbJ#Sj}ɇ`Y>,xyaޅeK3W/]g8B*s Uf˃U8rizV$SVgB!3XZGʤ,#'nZ +\(uX) jNY Eɇvx39'ր _WRKV),0,+,)9,d1oNƌa D}J)Y[ΰ .aQ4*E\2Pc氜Dj}l ׬d^V*}2n #Xnk5I,i0t ,fT`eL] 'l R5CM!fn3V;V}܌A-imX!o34xR9*vcb ̘`hqblֈ mV ֥7O, Rm YRj5v6>1:M-jX'NKrRlT⃵VOYZelm|r#,݄?:(#,IcaQZKeL2v=SKV*SV ’`-*,eQx^\u@ VaQ\X_uYXSaGʪ:`6,8j Ś͇`^X&Y#GZX8f\$KՂ$I<8IVY^JpYJ $~NrV(WַӪa Eyppj/8/'TOwej/ E;Ĭ 9gX)hjG[P sPzxKZThMct17޽CUm֟ޡZrZasbxI5we j>X4(]%{φ:X\RtYųe5/;g]Cl5uH-d"J-\b;~FVȷ' ҦiT_4S-LtV6H-Dx#x hV`ww"VٺB74۝RZ3ex xGp5I!ΠŁ-{ G0#nwY> ;B?̐#Zek־-+ǵ{Ͱ41kݿVt_n-]Gl[|ÌoK?d qLi d+O5a$[YҢ8VT@c [ Z#= - 89X3- dΌ!hΊ~-%fN77YA{cYM3p -|Ѣ:ZyoG=ډ`tRE_uxbNshI Zc¥)i%.\(Xғ{lVʥ(]{u[ hT8yuFk^2K,.jy6>hUV5¢gZoxA$ _+ͬʤ*wZ>K'z j7t柶H+?+>ɄUԺCȨXe<-~)q Z4f1Z K1Jg\*hX;iA}+Ѻ_5?Zه+^X arz%FV9 Fk3;x oᙗaڇX[>_6H=S[zVL7]wZhonDtoKq˱4;` N}v)i+BJ8m!xc;83jt̖҇W)z~o)F&R?*rq?5ߢ'8#Qū;ef?+X.@ƚHLZ;^C}VYHRtUGcGm¦1xe$~=6_OR-s:{ ꞀW 6ԷN /=8;_^3-=8Rlu!uҹB= " w<ZѦYסV ,iZo:B[؝VP {I1yX%Kuq膙{X=|*k*V䉞֍;[Y!5T7G.O Z+cDDwf!ǽ#p~%)&*Gq0 UQt`)=)8qCh5y"GpMPz=*?nS?bJ?.".|+YT)MgO4OlS#KvCjk]Qҫ˥}#_Y{25&^R_q{׬B[և,~mQkSafh=p4,==#ǬnwQ}eq\˾WO|˦u+ES,IENDB`admin/image/remote/amazon-s3-logo.png000064400000011575147577722710013521 0ustar00PNG  IHDR2o$PLTE Ⱦwvwdcc...>>>a``"1//nmmMKL{zz*))eddԩ$$$ӇNLLٚ---sqrQNO{zzpoo HFGYYYIII# !($%*'(***978cbbז;;;A@@snvvv%%%433<;<==<<;;;.+,QOP^\]EEEtssz}}}jjji :78B@A-NLM]\\ONNqqqPOP(Jח,,,(JHHCAB>SSSmkk\[[>>>BBBkXWWn """412###FEEJTRR;;;onn(((shghl2 5?>>?999VK\zzzZ1,,,+M[ZZQgeelkkUUUA@At] :C" +++][[W888HFHHHF111ROP 3220777bbbjb|Іٜ'TRSNMMbQ 9+### Y tRNS   Ի2  םI&̷Q ٤ #],ůtlcC9&% ~[Y6&ķysXVP=1.%¹mmcKB8.Ϳlg_C0.&ú{xWN0'mc53&#!ýwwsG975óaQ@<<˭~rf^YNEvqNJEDDCAAڦmgf>=5"vk[zMy,IDAThy\TUo g`X@vvwLvAY$0 (D%2e)sd+5%LMJ,}:6w}]4peqȱv7\fvc(,^_ok-#mN:lßJi=6K꿰u}yF,ӏp.='׿qWz'C~Y=`wya'684~כ†No?r#g&0л!c'm360%4--bt㼛߿p+ _PO2\cfথ*N4/L_Lґ0uGҨ(nf.k&TRפ̢\)a[X`x_ش0DW\7&:CectٻvuUP+띌.~7fMY 1旹xA-O睿*"E 6?5b#y˰5- 8@Ѓ0 I{#ڷbv4&6؜i'6ͷ dQ^/m0 /lb(a]3kݶ-_3*a(zNPɴS ;/Wo|\XޱW <:Ӿnqdoc|74gBS43/M0?1Gր89s&a`)1kfd`$1(zΝa[F:66q`79fU_< u+b#*VV֦\$D\DkmWU:VCmj>}LSKUWuGT3x`|` :C?)5ձۙ/}`:?x;}s`0o"h vGqH ^.[-0;S?rɋd=B5Áۂ%zǻ}~^yQoi BoЪQ$¸}M,0x€Oz.pKn5`~k]a0b0g x7Q D>>0M$?üO0`[x%2c*RcQFHcjMY1}uj~`)xrO3(h"FbߋrtWq$)r D}0A[d7 JA"Wzw ]qAk 2(Ce$a;S2xωQ=S li2-ae,43Ta^rafjs59$Lbr9&cpc)SkJ: G^#^c3AjpDn= bN '~:L'2BdeV>\7Az A {}O>QN H# s`@l]!ƀG0LˆBD6ØKn.V`M7o3\VcvS:d gDl=ư!; =x޺u#XИ}+˃3)CBؙ[ 2q.[`$R0͚Y~i,Ѝ'LsvZ%ZS9OBLJf:@Ĵ yEҐ=,dV,];/iO585@Y%ۊ!m~}Izӳap8i7aEǯ=8q]B0!lq!\HthCkV4p+" puw;O來.c E:Xwv|5ASq60LVй궓t SzKqD#D*7P*!J=C*o`no9fC*0O;{͖NDr(k21p¦[ | ZM^NS109w<_]̲c됖b#w6: g=kAM;EUy>p3t ȼ ahX ؟g l1Wn$4b\gvaX̺ią2䡌5QaĞHy"gATڨeuep`34ߟ#u~Añ.k+mrsB x R 3V>EbyL U7v0 ӥTqx: vǜ11P%87nO9N%xZz ]T+&B];K0bƃCTz̗ԚUVaPғ)A?G3bp7э(̱ڽѣ2 n|5%}k-'TX&ˬ5,FhͦR`b9=8HyVL8~J*?hgo0M&d|DQ]Z(:++ΐj:XJGfp2,)4A-e gΦR(7e,0p+&AbԹǕGm p[V!5ܧOZ#sb.9H! rdT_ş8:UVRm$0[`ltŋ3^䬌Qbag=9l;X ef腢YmA3---~ HxsWnݚ#.ps z|8/MƁ!A8$Wu0K8Nٸ? 5n,7";7zk ÖWV/ee FKˁ(0P"`oɦ߱iPs*+LvvOJz3M@3|[7!Z(eyXc<:aU1IRib { zfD$'a@q45g 6Anh#7O/Q)23g7]TZe CH rNaKjV&s)1nvqҦftWۓc;bl{>7Ǡ B:r|B3gS{)!BiExZX୕˖) ]7XYC (U,NO5HI]}a.dEFLwPcheJZsW]fNAdMq$IzN$Qps0&Zov EV~=*5+ rC1rC>;FAtm~IENDB`admin/image/icon-128x128.png000064400000003001147577722710011324 0ustar00PNG  IHDR"gAMA a cHRMz&u0`:pQ<PLTE[&[&[&[&[&[&[&[&[&[&[&[&[&j:^xf5^])컫vLŹa.aqDöz[&}Uc1nuI캪l=a +tRNSp0 @`P@0p`P qpЈdaGRbKGDH pHYs  ~tIME;' IDATxiw0E,.Zvf:KgKK@BX:sN/*C 7zFN]i?:5HgjD< g uk ҃FCx`mTؠ O,foZznf#M<hlK3A6!lDzii#1(}nC`Yo``9 fB0lquC<ts3i(4@c.jt))l. ֕?@4B(@I#XC`jAz`~PBa7*,sC`R'$#]lաo{ճF>h Xd$1N`l_p.* a#د?0' `#g%@if%#O CQ~ma-E#ؾ&Qp@5Fi+`8zݬL 6e0 [~9OK ϓDjψvqC}̶}` >B[&"k4.N@Ԡz`!XK TJ9YQ#'ֺXwKt{d!H |ȔSU@'ʔ71{E1dBE g4E7H07 ΍~~/ ]L<6խ [hXxE`Vs {T"yivQ$#C{4cXиG@DmDԦ1rCbC` df4X{%6]*"`!P@ {@jOF-+u|/9; !H˗7?} `dI"YC.QC` 4?{K诠n^Eb+i𫹚:+EW(*Kg ȥ R!c_?M뮴zδkEGչMU' NΣ)#%tEXtdate:create2020-02-27T16:59:04+00:00 %tEXtdate:modify2020-02-27T16:59:04+00:00dW-=IENDB`admin/image/db-lock-64.png000064400000032306147577722710011215 0ustar00PNG  IHDR,,tRNSv8bKGD3r pHYsodtIMEzTXtRaw profile type icc8S[! 99R HXB2˦H[KaaXAv#`v= "k\lU_GҬdd]U.: t~gCK?iiʸ`䍁EKY'/GXxmcK>9pG ~;nO&H2A6|ƿUCq` `^p޸89LK6=Evr{!p$dhTww_Cƾg\ @;\ V1bEfO<ē Û]SJD, #Ry #y2^o5ϽJLԜ'zEgt\G F1_㦍?&bo첹9ɣͼX- eR ^tF;T3P8ƭ͋*DKw~{v#ѫ ] IDATxM( KŧDSo8,2RϨJ~mw@ף :}Hйa_NQC`kG9#fj82 ];n ٌjV嚦aV;G?bALlc2y,^9Be3`Gv/}^{u 9,*dƔ칷&[ =^o8| #QcL+̮^l`.@{&XAw_ c>XsdA8mGQק]V b<ՏX'2*$ǰo:;!շYvgcvV<up`XјbEsU&iB)|Y5fb*Li-VwPCr{㭿}[|@A͊deOyN:fŴGD Zmc/0?IyNXέm q!؞<>+R `@ee0ѨlxVV S2O)W@ tPbYlVaL9BWYTɭ\Z*sժc}\hC^hK)6-w7u2s_֫]0u"*4V{*Ŀ_`>Y'X19SA1#&uЋTq0kgH@zI9J:=9\ơ&P`ssd@lR?zS`湻%Lz]uzNshwյ{]XJ?znN:MϩFW!L${DŽJeV!Z =G}*ԍe%Yp u0mXv;Bۺ?Ȝ!mUtl;t#mE/+mg]ޫOYmae ,Y~J,&bIf=YВI>NJ+,6 l`cXP&X8d]moXGq&|cgMY=֠zs!^d*/es5G{KUd7Xͭ0fu z]©(e;Uzs8]Xmᔌs_έ9lǓ0 kE9(dqٟ#UtV돢)s>u_G4 h6d܊feY-֟OZ h|CdVӴY4u˓&,Et׶+'vM~;+k_׶ 46]7 fͽ0U ] Z@ºT¸V4 Mk:ERڒ(Չ]Q U\UoS3:كv+"fVbn/s :E0R8?pꮄ7_S}y ̫ôqsks!kr^wMT 1NX7S_}2Kn` w*w ,}:w,u0򁲺uƪQoub6w Έ]ԢbRK;7rsȒI2=,])CM-}+|- ^8]EI(4wM(T/MR]~ͳ1dxXĒt0S.$Jc[XVTRórx`iPjn2C(""RrV}:O'bX@f1-PܬSԑHCQ wn/xOaKW'Y1kY!N_v $KxFה64ezJ:T(O 56sԱ~4hD^]Cۖlzހ<"}9\LF88W[`u-F(᝘wך dEYR0x >z{&ݿ+úh_#Kr77\ӯկ̛uuS@8j>״Mp?@u鞫XI<#k]$+M "sǵ|Ez^2hkqƏǘ?z( ApAI@Q@Q@ #7nRg ש#՝4gsPI>iVzUxJθ_el1ê)sEr~8ƻq%AOؓϠpQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@3AqH! 1ޠ?^=zUkx.u݉XGĞ :z~'a4UuKE"Ȥ,N='\}=5HWɅ+z((c_?7g37*[Yh Sx(((((((((((U11a+b"w;U+oxpxg3@a@FcՌrm$l9SUQEQE}UEj~.|O2CXc 1נS ܒh^kQKc6ת}LA+GtźPmݹFaC8>>zwᶹm,# :s߶zW!$o "0TƀEPEPEPEPEPEPEPE%S64ck[K녂 &F?Φۯӡ (#׵z|+fʱ;G$ǵsz.:ƪr{]Eqq P7;Qk*AfZyJFm#hSU}+E|@Q@Q@UW|`?f1bcǚ">+pOUtz=?Akrr&FA׷~:r;F]NU(%kNnL6HN1Ó|-fw={օ۳](}ᯅ${1S:xX.m9q+@#Y3v">J oJ_R=)??j?zxھj((>0e^cCzzόL4Z(]AAS#In~Ҁ<(( Q-E ?-=Cz/C,j c#=={Yќ?8olm]ˉ}9'=|M8t´3|E} 5g(o&~՟5lY;A8W?A_:Q@ ;¿'V=6 EspXF}Ap@=+-,aGN: y`j><>q Ԏ{W7E>YdFYIIePEP]oAk3Ax;[bF\O$~5Q@hwMu"@CYH׆QEQEQE}UP^Yis2VR3SBt֢E<d^aZ"u6;W?_Pjuf<0Qc9'Yub]P"۷2>QNtxhVWRC+ Gb)QEQEQEQEQEQEQEQE*;PYd@ ]>\ľ!.z/r+{MA^\ Hbs@UP#|7mi.>`~?zҴ"HXaTD0d54VI7͈#C9>*ر$u+! t@ / hZu;.؎Ey-M LmGwg΅u*s ͦTeC.xミ3\E$-VpHϳ cZUq_o'`}1mwm{kqp>}jj"F>f/J—4- v0e^cCz-/M!U;+lߎ9uZsBvˏϓǠn(u e/v$"ComhI4a h[k}t/d\9+Ї9c7"ʜR汤H}OQˏ]#]JOPGZȾ𦃩ZJwaO9(+oi3kWg**I?c\CA(۟DPӂhO&'qRvܟaZ?OjOh?OjOi=L)1s:{zP1Ew ąahy>wOҵ ܶ0o|rF((atl:ѼЊ#ק_^Qi:N=_@k~E_¬~@?99/5}6'̤a`I#!;x#XB"(PҀ̨$+e.it SZI=PO_wcl*Xo+G}$a^O@Q@($  *n\qVj;Oؠ2мAxrz|XGWž+NCcyC=AjڪFAqּUy'a`Fr?#Џj[Iִ,Ya~p{ƾt״Mjt(cs^g}êi Sq(<aI}>0e^cCzz0Ⱥv+v$1$~@sEPWluOLBg$E+(?P R=KڮB rs܁nOZ7V@?>/!d,l?l4WʒD2:0*uUe7oukTO-QުV=*,/^OM} E| _'V_gmj-Cy(诞axߤh ~*k({qI\*2Ov-gUu2KCcv2>[f+¼As^Ԋlɕ\tQϾϽf@LIo6c'ZXi]R8Իd{ 󟃶.rJF|C)??j[ԟX5']AǠQ@Q@Ś7A!Ky')$lN ^ៈNo 7ӥiG#P9'9ּ/~i_:NJM GWa>wnn3~&+>X- GVi^0Uo@08ּSUu-Ԭ巓ohQ@Q@Q@Q@Q@Q@Q@SY8՝؅UQI[6tUrvP3x_V$gUU,J;~xVúd4wt~{}`O\^xGUG6ks@F=(((G;j3[ff`@[c/ᖆ4 ԑ>c#>1ji>YDbPw0?nW?|YmO65gDm7.qq^1Fk/e4.e?v>կٵX狒T>uH0d|_]SWFBy}޼NDEm *c=Xt K,  fj7Jkyqe4Wֿ|Qm)s1TV^kn/ʲy.~wp di$ӭؖfhORN*ׅ}&Ͷ/?@?s~0 P#(>İ(xeїdc Ec+rj[2_0 U'ZHXـ%%O#5OX[X;ildadU>H{hƯ,Ǜc8$dgW:캖q{9̳dnNOAåAo,h#2X @ 0Up^bꚚj JDG^>I鞃u=QwJD+$@]F}@M) I<~5&~ɒ·o w߿өѴŠO8>qyKrWAoHM[st-2#?C)S^mkv,PƻQ`E6vıCDQ// ڛ[FI59GʧA@M30NOIF`6# [5ТfKvF2eN8I(B-CLM?%kK=e F8W)? ^'27v]#^d^vZ(((((G*3 2I"ӭaյ[m ?q8=i>x.1iH3F2IyC$I84 'W|@/q=gS~N DKgl u/=ٸi6$`y;2h<&Uț )S^mmv,PơQ`(;kh(c]0K8Ve.*"o(|o<7n֖ꎿ*uMy*_iХ_B 0oOw]kk35k%dV'#3s^s2A_B9'?I[akPl~Cܠ④ VV m};{隓nYFiW {8RWh>hŷ-1xmw21ݤrN:׾+ᗊM=&Uţ j 6G99_>Tws n%U;Yp Kk]Ggv,r$S@ EPEPEPEPEPEPdee8 ߈>$v7s/Ez͏HYu "D\|[H׆u =cqB4s+mX8V`49-8 񏈭5X 6|=Z:,QG*+uV O-5r⧉n-䵶`Fe;@/k\S s=G7֗6FYK{+i薷s,:2kN&%䥳f=+׽zJGm X %"x-pŒ:2W?ZxoN˨cۖXp2lםi6k??j>,{i"Xa.DFۗe\3Hŝ,@ (((((M҂%tEXtdate:create2020-02-06T16:06:30+00:00@%tEXtdate:modify2020-02-06T16:06:30+00:00TtEXtexif:BitsPerSample8, 8, 8>'tEXtexif:ColorSpace1I!tEXtexif:DateTime2020:02:03 08:06:31\޾tEXtexif:ExifOffset178V~tEXtexif:ImageLength300~ktEXtexif:ImageWidth300atEXtexif:SoftwareGIMP 2.10.14*P$tEXtexif:thumbnail:BitsPerSample8, 8, 8 StEXtexif:thumbnail:Compression6epWtEXtexif:thumbnail:ImageLength256Pp0tEXtexif:thumbnail:ImageWidth256(tEXtexif:thumbnail:JPEGInterchangeFormat304Gh/tEXtexif:thumbnail:JPEGInterchangeFormatLength9939*tEXtexif:thumbnail:PhotometricInterpretation6 tEXtexif:thumbnail:SamplesPerPixel3ZtEXticc:copyrightPublic Domain1["tEXticc:descriptionGIMP built-in sRGBLgAtEXticc:manufacturerGIMPLtEXticc:modelsRGB[`ICIENDB`admin/js/boldgrid-backup-admin-zip-browser.js000064400000015266147577722710015243 0ustar00/** * Browser * * @summary JS for all admin backup pages. * * @since 1.5.2 */ /* global ajaxurl,jQuery,boldgrid_backup_zip_browser */ var BoldGrid = BoldGrid || {}; BoldGrid.ZipBrowser = function( $ ) { var self = this, $zipBrowser = $( '#zip_browser' ), $listing = $zipBrowser.find( '.listing' ), spinner = ' ', loading = spinner + boldgrid_backup_zip_browser.loading + '...'; /** * @summary Handle the click of a breadcrumb. * * @since 1.5.3 */ self.onClickBreadcrumb = function() { var dir = $( this ).attr( 'data-dir' ); self.renderBrowser( dir ); }; /** * @summary Handle the click of a file. * * @since 1.5.3 */ self.onClickFile = function() { var $a = $( this ), $tr = $a.closest( 'tr' ), expanded = '1' === $tr.attr( 'data-expanded' ), colspan = $tr.find( 'td' ).length, $newTr = $( '' + loading + '' ), $dummyTr = $( '' ), data = { action: 'boldgrid_backup_browse_archive_file_actions', security: $( '#bgbkup_archive_details_nonce' ).val(), filename: $( '#filename' ).val(), file: $tr.attr( 'data-dir' ) }; if ( ! expanded ) { $newTr.css( 'background-color', $tr.css( 'background-color' ) ).insertAfter( $tr ); $dummyTr.insertAfter( $newTr ); $tr.attr( 'data-expanded', '1' ); $.post( ajaxurl, data, function( response ) { if ( response.success !== undefined ) { $newTr.find( 'td' ).html( response.data ); } else { $newTr.find( 'td' ).html( boldgrid_backup_zip_browser.unknownError ); } } ).error( function() { $newTr.find( 'td' ).html( boldgrid_backup_zip_browser.unknownError ); } ); } else { $tr .next( 'tr' ) .remove() .end() .next( 'tr' ) .remove() .end() .attr( 'data-expanded', '0' ); } }; /** * @summary Handle the click of a folder. * * @since 1.5.3 */ self.onClickFolder = function() { var $a = $( this ), $tr = $a.closest( 'tr' ), dir = $tr.attr( 'data-dir' ); self.renderBrowser( dir ); }; /** * @summary Handle the click of the "load archive browser" button. * * @since 1.6.0 */ self.onClickLoadBrowser = function() { $( this ).attr( 'disabled', 'disabled' ); self.renderBrowser( '.' ); }; /** * @summary Handle the click of the "restore this database" button. * * @since 1.6.0 */ self.onClickRestoreDb = function() { var $a = $( this ), $p = $a.closest( 'p' ), $spinner = $a.next(), data = { action: 'boldgrid_backup_browse_archive_restore_db', security: $( '#bgbkup_archive_details_nonce' ).val(), filename: $( '#filename' ).val(), file: $a.attr( 'data-file' ) }, confirmation, status = ' Restoring'; confirmation = confirm( boldgrid_backup_zip_browser.confirmDbRestore ); if ( ! confirmation ) { return false; } $p.empty().html( status ); $a.attr( 'disabled', 'disabled' ); $spinner.addClass( 'inline middle' ); $.post( ajaxurl, data, function( response ) { location.reload(); } ).error( function() { location.reload(); } ); return false; }; /** * @summary Handle the postbox-like toggle on thead th's that hide a table. * * @since 1.6.0 */ self.onClickToggle = function() { var $toggle = $( this ), $tbody = $toggle.closest( 'table' ).find( 'tbody' ); $toggle.toggleClass( 'closed' ); if ( $toggle.hasClass( 'closed' ) ) { $tbody.hide(); } else { $tbody.show(); } }; /** * @summary Handle the click of the "View details" button for a database. * * @since 1.6.0 */ self.onClickViewDb = function() { var $a = $( this ), data = { action: 'boldgrid_backup_browse_archive_view_db', security: $( '#bgbkup_archive_details_nonce' ).val(), filename: $( '#filename' ).val(), file: $( '#dump_filename' ).val() }, $details = $( '#db_details' ), errorCallback; // Only render the view once. if ( 'true' === $details.attr( 'data-rendered' ) ) { return; } $details.attr( 'data-rendered', 'true' ); $a.attr( 'disabled', 'disabled' ); $details.html( loading ); errorCallback = function() { $details.html( boldgrid_backup_zip_browser.unknownErrorNotice ); }; $.post( ajaxurl, data, function( response ) { var success = response.success !== undefined && true === response.success, fail = response.success !== undefined && false === response.success; if ( success || fail ) { $details.html( response.data ); } else { errorCallback(); } } ).error( errorCallback ); }; /** * @summary Render breadcrumbs. * * @since 1.5.3 * * @param string dir */ self.renderBreadcrumbs = function( dir ) { var split, $container = $zipBrowser.find( '.breadcrumbs' ), html = ' ' + boldgrid_backup_zip_browser.home + ' ', dataDir = ''; dir = 'undefined' !== typeof dir ? dir.trim() : '/'; split = dir.split( '/' ); split.forEach( function( element ) { if ( '' === element || '.' === element ) { return; } dataDir += element + '/'; html += ' / ' + element + ''; } ); $container.html( html ); }; /** * @summary Render the archive browser. * * @since 1.5.3 */ self.renderBrowser = function( dir ) { var data, colspan = $listing.find( 'thead th' ).length; dir = 'undefined' !== typeof dir ? dir : '.'; $zipBrowser.show(); data = { action: 'boldgrid_backup_browse_archive', security: $( '#bgbkup_archive_details_nonce' ).val(), filename: $( '#filename' ).val(), dir: dir }; self.renderBreadcrumbs( dir ); $listing.find( 'tbody' ).html( '' + loading + '' ); $.post( ajaxurl, data, function( response ) { if ( response.success !== undefined ) { $listing.html( response.data ); } else { $listing.html( boldgrid_backup_zip_browser.unknownBrowseError ); } } ).error( function() { $listing.html( boldgrid_backup_zip_browser.unknownBrowseError ); } ); }; /** * @summary Init. * * @since 1.5.3 */ $( function() { $( 'body' ).on( 'click', '.listing .folder', self.onClickFolder ); $( 'body' ).on( 'click', '.listing .file', self.onClickFile ); $( 'body' ).on( 'click', '.breadcrumbs a', self.onClickBreadcrumb ); $( 'body' ).on( 'click', '.restore-db', self.onClickRestoreDb ); $( 'body' ).on( 'click', '.view-db', self.onClickViewDb ); $( 'body' ).on( 'click', 'th .toggle-indicator', self.onClickToggle ); $( 'body' ).on( 'click', '.load-browser', self.onClickLoadBrowser ); self.renderBrowser( '.' ); } ); }; BoldGrid.ZipBrowser = new BoldGrid.ZipBrowser( jQuery ); admin/js/boldgrid-backup-admin-update-selectors.js000064400000007121147577722710016232 0ustar00/** * Update Selectors * * JavaScript for handling WordPress' native "update" buttons and links. Primary * function is to disable "update" buttons when we're in the middle of making a * backup. * * @since 1.6.0 * * @param $ The jQuery object. */ /* global boldgrid_backup_admin_update_selectors,jQuery */ var BOLDGRID = BOLDGRID || {}; BOLDGRID.BACKUP = BOLDGRID.BACKUP || {}; ( function( $ ) { BOLDGRID.BACKUP.UpdateSelectors = { lang: boldgrid_backup_admin_update_selectors, $selectors: null, selectors: [ // Plugins > Installed Plugins > "Apply" button for "Bulk Actions". '#doaction', '#doaction2', // Plugins > Installed Plugins > Inline "update now" link on Plugins > Installed Plugins. '.update-link', // Dashboard > Updates > "Update Plugins" button. '#upgrade-plugins', '#upgrade-plugins-2', // Dashboard > Updates > "Update" and "Re-install" WordPress button. '#upgrade', // Dashboard > Updates > "Update Themes" button. '#upgrade-themes', '#upgrade-themes-2', // Dashboard > Customize > Change Themes > Inline "Update now" link. // Customizer > Installed themes > "Update now" link. '.themes .update-message .button-link', // Dashboard > Customize > Changes Themes > Click a theme > "update now" link. // Customizer > Installed themes > click a theme > "update now" link. '#update-theme', // Update Protection > "Backup Site Now" button. '.notice #backup-site-now', // Backup Archive > "Backup Site Now" button. '.page-title-actions .page-title-action' ], /** * @summary Enable update selectors. * * @since 1.6.0 */ enable: function() { var self = BOLDGRID.BACKUP.UpdateSelectors; self.setSelectors(); self.$selectors.each( function() { var $el = $( this ), $target; $el.attr( 'disabled', false ); // See comment in self::disable(). $target = $el.is( 'a' ) ? $el.parent() : $el; $target.attr( 'title', '' ).removeClass( self.lang.waitClass ); } ); }, /** * @summary Disable update selectors. * * @since 1.6.0 */ disable: function() { /* * Timeout is required because some "Update" links are added via the * wp.template system and do not call a trigger to alert when they're * done. */ setTimeout( function() { var self = BOLDGRID.BACKUP.UpdateSelectors; self.setSelectors(); self.$selectors.each( function() { var $el = $( this ), $target; $el.attr( 'disabled', true ); /* * Anchors behave differently. When you set an anchor to disabled, * you cannot hover and see a title. For anchors, we'll temporarily * adjust the parent instead. */ $target = $el.is( 'a' ) ? $el.parent() : $el; $target.attr( 'title', self.lang.backupInProgress ).addClass( self.lang.waitClass ); } ); }, 250 ); }, /** * @summary Init. * * @since 1.6.0 */ init: function() { $( 'body' ).on( 'boldgrid_backup_complete', $.proxy( this.enable, this ) ); $( 'body' ).on( 'boldgrid_backup_progress_notice_added', $.proxy( this.disable, this ) ); this.onInProgress(); }, /** * @summary Actions to take when there is a backup in progress. * * @since 1.6.0 */ onInProgress: function() { if ( 1 === $( '.boldgrid-backup-in-progress' ).length ) { this.disable(); } }, /** * @summary Set our $selectors, which are used to find "update" buttons. * * @since 1.6.0 */ setSelectors: function() { this.$selectors = $( this.selectors.join( ', ' ) ); } }; $( function() { BOLDGRID.BACKUP.UpdateSelectors.init(); } ); } )( jQuery ); admin/js/boldgrid-backup-admin-table-includes.js000064400000006700147577722710015644 0ustar00/** * Table include * * @summary JavaScript for handling table include settings. * * @since 1.6.0 * * @param $ The jQuery object. */ /* global jQuery */ var BoldGrid = BoldGrid || {}; BoldGrid.TableInclude = function( $ ) { 'use strict'; var self = this, $container = $( 'div#table_inclusion' ), $includeTables = $container.find( '.include-tables [type="checkbox"]' ), $type = $container.find( '[name="table_inclusion_type"]' ), $configContainer = $container.find( '#table_inclusion_config' ), // Buttons to include / exclude all. $buttonAll = $container.find( '#include_all_tables, .include-all' ), $buttonNone = $container.find( '#exclude_all_tables' ), // Defaults are the status messages indicating default settings used. $yesDefault = $container.find( '.yes-default' ), $noDefault = $container.find( '.no-default' ); /** * @summary Action to take when the type (full / custom) has been changed. * * @since 1.6.0 * * @param typeInput The type input element clicked in the toggle. */ self.onChangeType = function( typeInput ) { self.toggleConfig( typeInput ); }; /** * @summary Toogle all database tables so they are all backed up. * * @since 1.6.0 */ self.toggleAll = function() { $includeTables.bgbuDrawAttention(); $includeTables.prop( 'checked', true ); self.toggleStatus(); return false; }; /** * @summary Toggle the area that allows you to choose which tables to backup. * * @since 1.6.0 * * @param typeInput The type input element clicked in the toggle. */ self.toggleConfig = function( typeInput ) { var type = $( typeInput ) .filter( ':checked' ) .val(); if ( 'full' === type ) { $configContainer.hide(); } else if ( 'custom' === type ) { $configContainer.show(); } }; /** * @summary Deselect all tables. * * @since 1.6.0 */ self.toggleNone = function() { $includeTables.bgbuDrawAttention(); $includeTables.prop( 'checked', false ); self.toggleStatus(); return false; }; /** * Update Values * * @since 1.6.0 * * @param eventTarget The target of the triggering event. * @param $container The set of container divs. */ self.updateValues = function( eventTarget, $container ) { var name = $( eventTarget ).attr( 'name' ), value = $( eventTarget ).val(), type = $( eventTarget ).attr( 'type' ); if ( 'radio' == type || 'checkbox' == type ) { $container .find( 'input[name="' + name + '"][value="' + value + '"]' ) .prop( 'checked', $( eventTarget ).prop( 'checked' ) ); } else { $container.find( 'input[name=' + name + ']' ).val( value ); } }; /** * @summary Toogle the status that tells the user if they're backing up all tables. * * @since 1.6.0 */ self.toggleStatus = function() { var allIncluded = $includeTables.length === $includeTables.filter( ':checked' ).length; if ( allIncluded ) { $yesDefault.show(); $noDefault.hide(); } else { $yesDefault.hide(); $noDefault.show(); } }; $( function() { $buttonAll.on( 'click', self.toggleAll ); $buttonNone.on( 'click', self.toggleNone ); self.toggleStatus(); $type.each( function() { self.toggleConfig( this ); } ); $type.on( 'change', function() { self.onChangeType( this ); } ); $container.find( 'input' ).each( function() { $( this ).on( 'input', function() { self.updateValues( this, $container ); } ); } ); $includeTables.on( 'change', self.toggleStatus ); } ); }; new BoldGrid.TableInclude( jQuery ); admin/js/boldgrid-backup-admin-settings.js000064400000017776147577722710014630 0ustar00/** * Settings page * * @summary JavaScript for the settings page. * * @since 1.0 * * @param $ The jQuery object. */ /* global ajaxurl,bglibLicense,BOLDGRID,jQuery */ var BoldGrid = BoldGrid || {}; BoldGrid.Settings = function( $ ) { 'use strict'; // General Variables. var self = this, $scheduleDow, $noBackupDays, $useSparingly, $backupDir, $body = $( 'body' ), tb_unload_count, $moveBackups, $siteCheck; /** * Directory to store backups. * * @since 1.3.6 */ $backupDir = $( '#backup-directory-path' ); // Define a context selector for schedule-dow. $scheduleDow = $( '.schedule-dow' ); // Define a context selector for no-backup-days. $noBackupDays = $( '#no-backup-days' ); /** * Message asking user if we should move their backups. * * @since 1.3.6 */ $moveBackups = $( '#move-backups' ); /** * @summary Number of times tb_unload has been triggered. * * When a thickbox is closed, tb_unload is called twice. We need to keep * track of how many times it's been called so that we know to only run our * callback once. * * @since 1.5.2 */ tb_unload_count = 0; /** * Message describing resource usage. * * @since 1.3.1 */ $useSparingly = $( '#use-sparingly' ); /** * @summary Take action when the user clicks Check again. * * The user is checking their license status again. * * @since 1.6.0 */ self.onClickCheckAgain = function() { var $button = $( this ), $parent = $button.parent(), $licenseString = $parent.find( '#license_string' ), $reloadMessage = $( '#license_reload_page' ), $spinner = $parent.find( '.spinner' ), successFunction, errorFunction; $spinner.show(); $licenseString.empty(); errorFunction = function( response ) { var error = response !== undefined && response.data !== undefined && response.data.string !== undefined ? response.data.string : bglibLicense.unknownError; $spinner.hide(); $licenseString.html( error ); }; successFunction = function( response ) { if ( true !== response.success || response.data === undefined || response.data.string === undefined ) { errorFunction( response ); return; } $spinner.hide(); $licenseString.html( response.data.string ); if ( response.data.isPremium ) { $reloadMessage.removeClass( 'hidden' ); } }; BOLDGRID.LIBRARY.License.clear( 'boldgrid-backup', successFunction, errorFunction ); return false; }; /** * @summary Action to take when a remote storage provider has been clicked. * * Primary function is to flag the clicked provider with the active class. * * @since 1.5.2 */ self.on_click_provider = function() { var $a = $( this ), $tr = $a.closest( 'tr' ), $table = $a.closest( 'table' ); $table.find( 'tr' ).removeClass( 'active' ); /* * We add the active class so that we can identify the provider that is * being updated. */ $tr.addClass( 'active' ); }; /** * @summary Action to take when the thickbox is closed. * * @since 1.5.2 */ self.on_tb_unload = function() { tb_unload_count++; // Only take action on the odd occurences of tb_unload. if ( 0 === tb_unload_count % 2 ) { return; } self.refresh_storage_configuration(); }; /** * @summary Refresh remote storage provider summary. * * For example, if Amazon S3 was unconfigured, an applicable message will * show. After being configured, the "unconfigured" message needs to be * updated. * * @since 1.5.2 */ self.refresh_storage_configuration = function() { var $tr = $( '#storage_locations tr.active:not(.refreshing)' ), $td_configure = $tr.find( 'td.configure' ), data = { action: 'boldgrid_backup_is_setup_' + $tr.attr( 'data-key' ), security: $( '#bgbkup_settings_nonce' ).val() }, $new_tr; $tr.addClass( 'refreshing' ); $td_configure.html( '' ); $.post( ajaxurl, data, function( response ) { $new_tr = $( response.data ); $tr.replaceWith( $new_tr ); self.toggleNoStorage(); } ); }; /** * @summary Check if any days of the week selected. * * @since 1.0 */ self.scheduleDowChecked = function() { // Define vars. var isDowChecked = false; if ( $scheduleDow.find( 'input' ).is( ':checked' ) ) { isDowChecked = true; } return isDowChecked; }; /** * @summary Toogle the move backups message. * * @since 1.3.6 */ self.toggleMoveBackups = function() { if ( $backupDir.val() === $backupDir.prop( 'defaultValue' ) ) { $moveBackups.hide(); } else { $moveBackups.show(); } }; /** * Toggle notice for no backup days selected. * * @since 1.0 */ self.toggleNoBackupDays = function() { // How many days of the week are checked? var daysCount = $scheduleDow.find( ':checked' ).length; /* * If the user has selected more than 1 day under "Days of the Week", show a message about * resource usage. * * @since 1.3.1 */ if ( 1 < daysCount ) { $useSparingly.show(); } else { $useSparingly.hide(); } if ( true === self.scheduleDowChecked() ) { $noBackupDays.hide(); } else { $noBackupDays.show(); } }; /** * @summary Toggle the warning about no backups if no storage selected. * * @since 1.5.2 */ self.toggleNoStorage = function() { var count_checked = $( '#storage_locations input[type="checkbox"]:checked' ).length, $noStorage = $( '#no_storage' ); if ( 0 === count_checked ) { $noStorage.show(); } else { $noStorage.hide(); } }; /** * @summary Toggle site check options. * * @since 1.10.0 */ self.toggleSiteCheck = function() { if ( '1' === $siteCheck.filter( ':checked' ).val() ) { // Site Check is enabled. $( '#site-check-interval' ).prop( 'disabled', false ); $( 'input[name="site_check_logger"]' ).prop( 'disabled', false ); $( 'input[name="auto_recovery"]' ).prop( 'disabled', false ); $( '#notification-site-check' ).prop( 'disabled', false ); } else { // Site Check is disabled. $( '#site-check-interval' ).prop( 'disabled', true ); $( 'input[name="site_check_logger"]' ).prop( 'disabled', true ); $( 'input[name="auto_recovery"]' ).prop( 'disabled', true ); $( '#notification-site-check' ).prop( 'disabled', true ); } }; self.toggleCompressionInfo = function() { var isSystemZip = false, compressorSelector = $( 'select[name="compressor"]' ); isSystemZip = 'system_zip' === $( compressorSelector ).val(); if ( isSystemZip ) { $( '.compression-level' ).show(); } else { $( '.compression-level' ).hide(); } }; /** * Toggle Cron Interval * * @summary Toggle the cron interval select element. * * @since 1.16.0 */ self.toggleCronInterval = function() { var $schedulerSelect = $( 'select[name="scheduler"]' ), toggleInterval = function( val ) { if ( 'cron' === val ) { $( '#cron_interval' ).show(); } else { $( '#cron_interval' ).hide(); } }; toggleInterval( $schedulerSelect.find( 'option:selected' ).val() ); $schedulerSelect.on( 'change', function() { toggleInterval( $( this ) .find( 'option:selected' ) .val() ); } ); }; // Onload event listener. $( function() { // Check if any days or the week are checked, toggle notice. self.toggleNoBackupDays(); self.toggleNoStorage(); self.toggleCompressionInfo(); self.toggleCronInterval(); $body.on( 'click', '#storage_locations input[type="checkbox"]', self.toggleNoStorage ); $backupDir.on( 'input', self.toggleMoveBackups ); // On click action for days, check if any days or the week are checked, // toggle notice. $scheduleDow.on( 'click', self.toggleNoBackupDays ); $( window ).on( 'tb_unload', self.on_tb_unload ); $body.on( 'click', '#storage_locations .thickbox', self.on_click_provider ); $body.on( 'click', '#license_check_again', self.onClickCheckAgain ); $siteCheck = $( 'input[name="site_check"]' ); self.toggleSiteCheck(); $body.on( 'click', $siteCheck, self.toggleSiteCheck ); $( 'select[name="compressor"]' ).on( 'change', self.toggleCompressionInfo ); } ); }; BoldGrid.Settings( jQuery ); admin/js/boldgrid-backup-admin-settings-autoupdate.js000064400000013330147577722710016757 0ustar00/** * Auto update settings * * @summary JavaScript for the auto update settings. */ /* global ajaxurl,jQuery */ var BOLDGRID = BOLDGRID || {}; BOLDGRID.SETTINGS = BOLDGRID.SETTINGS || {}; ( function( $ ) { var self; BOLDGRID.SETTINGS.AutoUpdate = { /** * Constructor. * * @since 1.7.0 */ init: function() { $( self._onLoad ); }, /** * On DOM load. * * @since 1.7.0 */ _onLoad: function() { var $bgBox = $( '.bg-box' ); // Initialize jquery-toggles. $bgBox.find( '.toggle' ).toggles( { text: { on: '', off: '' }, height: 15, width: 40 } ); self._setMasterToggles(); $bgBox.find( '.toggle-group' ).on( 'click swipe contextmenu', self._toggleGroup ); $bgBox .find( '.toggle' ) .not( '.toggle-group' ) .on( 'click swipe contextmenu', self._setMasterToggles ); $bgBox .find( '.table-help td p' ) .attr( 'style', 'height: 0em; opacity: 0%; position: relative; z-index:-1' ); $bgBox .find( '.div-table-body .dashicons-editor-help, .help-icon' ) .on( 'click', self._toggleHelp ); $bgBox.find( '.help-icon' ).css( 'cursor', 'pointer' ); $bgBox.find( '.bglib-collapsible-control' ).on( 'click', function() { var target = $( this ).attr( 'data-target' ); $( target ).animate( { height: 'toggle', opacity: 'toggle' }, 'slow' ); $( this ).toggleClass( 'bglib-collapsible-open' ); } ); if ( true === $( '#timely-updates-disabled' ).prop( 'checked' ) ) { $( '#timely-updates-days' ).prop( 'disabled', true ); $( '#timely-updates-days-hidden' ).prop( 'disabled', false ); } $( 'input[name="auto_update[timely-updates-enabled]"]' ).change( function() { if ( true === $( '#timely-updates-disabled' ).prop( 'checked' ) ) { $( '#timely-updates-days' ).prop( 'disabled', true ); $( '#timely-updates-days-hidden' ).prop( 'disabled', false ); } else { $( '#timely-updates-days' ).prop( 'disabled', false ); $( '#timely-updates-days-hidden' ).prop( 'disabled', true ); } } ); }, /** * Set inputs for toggles. * * @since 1.7.0 */ _setInputs: function() { var $bgBox = $( '.bg-box' ), $wpcoreToggles = $bgBox.find( '.wpcore-toggle' ), $pluginToggles = $bgBox.find( '.plugin-toggle' ), $themeToggles = $bgBox.find( '.theme-toggle' ), $pluginsDefault = $bgBox.find( '#toggle-default-plugins' ), $themesDefault = $bgBox.find( '#toggle-default-themes' ), $timelyUpdatesEnabled = $bgBox.find( '#timely-updates-enabled' ), $timelyUpdatesDisabled = $bgBox.find( '#timely-updates-disabled' ), $timelyUpdatesDays = $bgBox.find( '#timely-updates-days' ); // If the updates section is not in use, then just return. if ( ! $pluginsDefault.data( 'toggles' ) ) { return; } $wpcoreToggles.each( function() { var $this = $( this ); var $thisInput = $this .next( 'input' ) .attr( 'name', 'auto_update[wpcore][' + $this.data( 'wpcore' ) + ']' ) .val( $this.data( 'toggles' ).active ? 1 : 0 ); } ); $pluginToggles.each( function() { var $this = $( this ); var $thisInput = $this .next( 'input' ) .attr( 'name', 'auto_update[plugins][' + $this.data( 'plugin' ) + ']' ) .val( $this.data( 'toggles' ).active ? 1 : 0 ); } ); $themeToggles.each( function() { var $this = $( this ); var $thisInput = $this .next( 'input' ) .attr( 'name', 'auto_update[themes][' + $this.data( 'stylesheet' ) + ']' ) .val( $this.data( 'toggles' ).active ? 1 : 0 ); } ); $pluginsDefault.next( 'input' ).val( $pluginsDefault.data( 'toggles' ).active ? 1 : 0 ); $themesDefault.next( 'input' ).val( $themesDefault.data( 'toggles' ).active ? 1 : 0 ); }, /** * Set master toggles. * * @since 1.7.0 */ _setMasterToggles: function() { var $masters = $( '.bg-box' ).find( '.toggle-group' ); $masters.each( function() { var $master = $( this ), state = true; $master .closest( '.div-table-body' ) .find( '.toggle' ) .not( '.toggle-group,#toggle-default-plugins,#toggle-default-themes' ) .each( function() { if ( ! state || ! $( this ).data( 'toggles' ).active ) { state = false; } } ); $master.toggles( state ); } ); self._setInputs(); }, /** * Toggle an entire group on/off. * * @since 1.7.0 */ _toggleGroup: function() { var $this = $( this ), $toggles = $this .parent() .parent() .parent() .find( '.toggle' ) .not( '#toggle-default-plugins,#toggle-default-themes' ); $toggles.toggles( $this.data( 'toggles' ).active ); self._setInputs(); }, /** * Replace the notice with a clone when removed by dismissal. * * @since 1.7.0 */ _replaceNotice: function( $notice ) { var $noticeClone = $notice.clone(), $noticeNext = $notice.next(); $notice.one( 'click.wp-dismiss-notice', '.notice-dismiss', function() { $noticeNext.before( $noticeClone ); $notice = $noticeClone; $notice.hide(); } ); }, /** * Handle form submission. * * @since 1.7.0 */ _toggleHelp: function( e ) { var id = $( this ).attr( 'data-id' ), target = $( '.table-help[data-id="' + id + '"]' ); e.preventDefault(); if ( id === undefined ) { return false; } $( target ).toggleClass( 'show-help hide-help' ); $( '.table-help.show-help[data-id="' + id + '"] td p' ).animate( { height: '3em', opacity: '100%', 'z-index': 0 }, 400 ); $( '.table-help.hide-help[data-id="' + id + '"] td p' ).animate( { height: '0em', opacity: '0%', 'z-index': -1 }, 400 ); return false; } }; // eslint-disable-next-line vars-on-top var self = BOLDGRID.SETTINGS.AutoUpdate; BOLDGRID.SETTINGS.AutoUpdate.init(); } )( jQuery ); admin/js/boldgrid-backup-admin-rollback.js000064400000025771147577722710014553 0ustar00/** * Rollback notice * * @summary JavaScript for the rollback notice. * * @since 1.0 */ /* global ajaxurl,boldgrid_backup_admin_rollback,pagenow,jQuery,wp */ // Declare namespace. var BOLDGRID = BOLDGRID || {}; // Define sub-namespace. BOLDGRID.BACKUP = BOLDGRID.BACKUP || {}; /** * Rollback notice. * * @summary JavaScript for the rollback notice. * * @since 1.0 * * @param $ The jQuery object. */ ( function( $ ) { 'use strict'; // Onload event listener. $( function() { $( 'body' ).on( 'click', '#cancel-rollback-button', BOLDGRID.BACKUP.RollbackTimer.cancelRollback ); BOLDGRID.BACKUP.RollbackTimer.adjustOnAbout(); } ); /** * Namespace BOLDGRID.BACKUP.RollbackTimer. * * @since 1.0 */ BOLDGRID.BACKUP.RollbackTimer = { // When we show a global notice in the customizer, it is identified by this code. countdownCode: 'boldgrid-backup-countdown', /** * Cancel pending rollback. * * @since 1.0 */ cancelRollback: function() { // Declare variables. var data, cancelNonce, wpHttpReferer, errorCallback, $cancelRollbackSection, $cancelRollbackResults, $rollbackSpinner, $this = $( this ), successCallBack; // Disable the Cancel Rollback button. $this.attr( 'disabled', 'disabled' ).css( 'pointer-events', 'none' ); // Create a context selector for the cancel rollback section. $cancelRollbackSection = $( '#cancel-rollback-section' ); // Create a context selector for the cancel rollback results. $cancelRollbackResults = $( '#cancel-rollback-results' ); // Create a context selector for the cancel rollback spinner. $rollbackSpinner = $cancelRollbackSection.find( '.spinner' ); // Show the spinner. $rollbackSpinner.addClass( 'is-active' ); $rollbackSpinner.css( 'display', 'inline-block' ); // Get the wpnonce and referer values. cancelNonce = $cancelRollbackSection.find( '#cancel_rollback_auth' ).val(); wpHttpReferer = $cancelRollbackSection.find( '[name="_wp_http_referer"]' ).val(); // Create an error callback function. errorCallback = function() { // Show error message. var markup = '

There was an error processing your request. Please reload the page and try again.

'; $cancelRollbackResults.html( markup ); }; // Generate a data array for the download request. data = { action: 'boldgrid_cancel_rollback', cancel_rollback_auth: cancelNonce, _wp_http_referer: wpHttpReferer }; /** * Action to take when we successfully canceled the rollback. * * @since 1.6.0 */ successCallBack = function( response ) { // Remove the restore now section. $( '[data-restore-now]' ) .parent() .slideUp(); // Insert markup in the results section. $cancelRollbackResults.html( response ); // Hide the cancel rollback section. $cancelRollbackSection.slideUp(); if ( 'customize' === pagenow ) { wp.customize.notifications.remove( BOLDGRID.BACKUP.RollbackTimer.countdownCode ); } }; // Make the call. $.ajax( { url: ajaxurl, data: data, type: 'post', dataType: 'text', success: successCallBack, error: errorCallback, complete: function() { // Hide the spinner. $cancelRollbackSection.find( '.spinner' ).removeClass( 'is-active' ); } } ); // Return false so the page does not reload. return false; }, /** * Get the time remaining to an end time. * * @since 1.0 * * @param string endTime A data/time parsed with Date.parse(). * @return array */ getTimeRemaining: function( endTime ) { // Declare variables. var totalSeconds, seconds, minutes; // Parse data into seconds from now. totalSeconds = Date.parse( endTime ) - Date.parse( new Date() ); // If totalSeconds is less than or equal to zero, then return zero array. if ( 0 >= totalSeconds ) { return { total: 0, minutes: '0', seconds: '00' }; } // Calculate seconds, minutes, hours, days. seconds = Math.floor( ( totalSeconds / 1000 ) % 60 ); minutes = Math.floor( totalSeconds / 1000 / 60 ); // Return the data in an array. return { total: totalSeconds, minutes: minutes, seconds: ( '0' + seconds ).slice( -2 ) }; }, /** * Initialize a countdown timer, updating a DOM id. * * Uses BOLDGRID.BACKUP.RollbackTimer.deadline for the end time/deadline. * * @since 1.0 * * @see getTimeRemaining(). * @see updateDeadline(). * * @param string deadline */ initializeClock: function() { // Define variables. var $clock, interval, totalSeconds, self = this; // Get the element for the clock display. $clock = $( '#rollback-countdown-timer' ); // Use an interval of 1 second to update the clock. interval = setInterval( function() { totalSeconds = self.getTimeRemaining( BOLDGRID.BACKUP.RollbackTimer.deadline ); // Update the clock display. $clock.html( totalSeconds.minutes + ':' + totalSeconds.seconds ); // When the timer reaches zero, stop the countdown and disable the cancel button. if ( 0 >= totalSeconds.total ) { clearInterval( interval ); // Disable the Cancel Rollback button. $( '#cancel-rollback-button' ) .attr( 'disabled', 'disabled' ) .css( 'pointer-events', 'none' ); } }, 1000 ); }, /** * If updating something, then update the timer deadline. * * @since 1.2 */ updateDeadline: function() { // Declare variables. var $RollbackDeadline; // Check for the deadline in the source (when completing updates in the admin section). $RollbackDeadline = $( 'iframe' ) .contents() .find( '#rollback-deadline' ); // Update the rollback timer. if ( $RollbackDeadline.length ) { BOLDGRID.BACKUP.RollbackTimer.deadline = $RollbackDeadline.text(); BOLDGRID.BACKUP.RollbackTimer.initializeClock(); } }, /** * If updating something, then update the timer deadline from the retrieved ISO time. * * @since 1.2.1 */ getUpdatedDeadline: function() { // Declare variables. var $bulkActionForm, wpnonce, wpHttpReferer, data; // Create a context selector for bulk-action-form. $bulkActionForm = $( '#bulk-action-form' ); // Get the bulk-action-form wpnonce. wpnonce = $bulkActionForm.find( '#_wpnonce' ).val(); // Get the bulk-action-form wpnonce. wpHttpReferer = $bulkActionForm.find( '[name="_wp_http_referer"]' ).val(); // Use adminajax to get the updated deadline. // Generate the data array. data = { action: 'boldgrid_backup_deadline', _wpnonce: wpnonce, _wp_http_referer: wpHttpReferer }; // Make the call. return $.ajax( { url: ajaxurl, data: data, type: 'post', dataType: 'text', success: function( response ) { // Update the rollback timer. if ( response.length ) { BOLDGRID.BACKUP.RollbackTimer.deadline = response; } /* * Someone may be waiting to see if we have a deadline, let * them know we're done. */ $( 'body' ).trigger( 'boldgrid-backup-have-deadline' ); } } ); }, /** * @summary Show the countdown notice. * * This method makes an ajax request to get the countdown notice. Useful * when plugins / themes are updated via ajaxy. * * @since 1.6.0 */ show: function() { /* * Show only one countdown. * * If there is already a countdown showing, abort. The user may be * on the themes page updating themes, and if they update two themes, * we don't want to show two countdown notices. */ if ( 0 < $( '.boldgrid-backup-countdown:visible' ).length ) { return; } var data = { action: 'boldgrid_backup_get_countdown_notice' }, successCallback; /** * Action to take after getting the countdown notice. * * @since 1.6.0 */ successCallback = function( response ) { var $notice, notification, $headerEnd = $( '.wp-header-end' ), $wrap = $( '.wrap' ).first(); if ( response.success !== undefined && true === response.success ) { $( '.boldgrid-backup-protect-now, .boldgrid-backup-protected' ).slideUp(); $notice = $( response.data ); // Determine where and how to add the notice. if ( 'customize' === pagenow ) { notification = new wp.customize.Notification( BOLDGRID.BACKUP.RollbackTimer.countdownCode, { message: $notice.removeClass( 'notice notice-warning' ).html(), type: 'warning' } ); wp.customize.notifications.add( notification ); } else { $notice.addClass( 'hidden' ); if ( 1 === $headerEnd.length ) { $notice.insertAfter( $headerEnd ); } else { $notice.prependTo( $wrap ); } $notice.slideDown(); } /* * Allow the countdown to render (especially in the * customizer) before initializing the clock. */ setTimeout( function() { BOLDGRID.BACKUP.RollbackTimer.initializeClock(); }, 500 ); } }; $.ajax( { url: ajaxurl, data: data, type: 'post', dataType: 'json', success: successCallback } ); }, /** * @summary Show the countdown notice on the about page. * * WordPress hides all admin notices on the wp-admin/about.php page. The * countdown notice is important enough to break this mold. * * @since 1.6.0 */ adjustOnAbout: function() { if ( 'about' !== pagenow ) { return; } var $notice = $( '.notice.boldgrid-backup-countdown' ); $notice.css( 'display', 'block!important' ).insertBefore( '.wrap' ); }, /** * If the rollback countdown timer is needed, then initialize the clock. * * @since 1.0 * * @see initializeClock(). */ init: function() { // Declare vars. var $document = $( document ), haveDeadline; // Determine whether or not we have a valid deadline. haveDeadline = 'object' === typeof boldgrid_backup_admin_rollback && boldgrid_backup_admin_rollback.rolloutDeadline !== undefined && '1970' !== boldgrid_backup_admin_rollback.rolloutDeadline.slice( 0, 4 ); // If there is a defined rollout deadline, then initialize the timer. if ( haveDeadline ) { // Set the end time/deadline. BOLDGRID.BACKUP.RollbackTimer.deadline = boldgrid_backup_admin_rollback.rolloutDeadline; // Initialize the clock/timer. this.initializeClock(); } // When the update progress iframe loads, check for a new deadline. $( 'iframe' ).on( 'load', this.updateDeadline ); // When a plugin is updated via adminajax, then get the new deadline and update the timer. $document.on( 'wp-plugin-update-success', this.getUpdatedDeadline ); // When a theme is updated via adminajax, then get the new deadline and update the timer. $document.on( 'wp-theme-update-success', this.getUpdatedDeadline ); $document.on( 'wp-plugin-update-success wp-theme-update-success', this.show ); } }; // Initialize the deadline. BOLDGRID.BACKUP.RollbackTimer.deadline = ''; // Initialize the rollback timer. BOLDGRID.BACKUP.RollbackTimer.init(); } )( jQuery ); admin/js/boldgrid-backup-admin-logs.js000064400000004365147577722710013722 0ustar00/** * Backup Logs. * * @summary This file handles the displaying of log files. * * @since 1.12.5 */ /* global jQuery */ var BOLDGRID = BOLDGRID || {}; BOLDGRID.BACKUP = BOLDGRID.BACKUP || {}; ( function( $ ) { 'use strict'; var self; /** * Logs. * * @since 1.12.5 */ BOLDGRID.BACKUP.Logs = { /** * i18n. * * @since 1.7.0 * * @type object */ i18n: window.BoldGridBackupAdminLogs || {}, /** * Init. * * @since 1.12.5 */ init: function() { self._onReady(); }, /** * Steps to take when a log file is clicked on. * * @since 1.12.5 */ onClickLog: function() { var data = { action: 'boldgrid_backup_view_log', filename: $( this ).attr( 'data-filename' ), nonce: $( '#bgbup_log_nonce' ).val() }; /* * Show a loading message in the thickbox modal. * * Thickbox has a few events, but "on open" is not one of them. The timeout is required * to allow some time for the modal to open before we take action. In testing, a 1ms timeout * worked. To be on the safe side, we're using 10ms. */ setTimeout( function() { $( '#TB_window' ).addClass( 'bg-full-screen' ); $( '#TB_ajaxContent' ).html( '

' + self.i18n.loading + '

' ); }, 10 ); $.post( ajaxurl, data, function( response ) { $( '#TB_ajaxContent' ).html( response.data ); } ).fail( function( jqXHR ) { /* * @todo This error message could use some work. For 500 errors, WordPress will return * "There has been a critical error on this website. Learn more about debugging in WordPress." * Show an "unknown error" and have the user contact BoldGrid for help rather than send * the user off learning about debugging. */ var error = jqXHR.status + ' ' + jqXHR.statusText + ': ' + self.i18n.unknownError; $( '#TB_ajaxContent' ).html( '

' + error + '

' ); } ); }, /** * On ready. * * @since 1.7.0 */ _onReady: function() { $( function() { $( '#section_logs a[data-filename]' ).on( 'click', self.onClickLog ); } ); } }; self = BOLDGRID.BACKUP.Logs; } )( jQuery ); BOLDGRID.BACKUP.Logs.init(); admin/js/boldgrid-backup-admin.js000064400000013132147577722710012750 0ustar00/** * This file contains javascript to load on all admin pages of the plugin * * @summary JS for all admin backup pages. * * @since 1.3.1 */ /* global jQuery,pagenow, BoldGridBackupAdmin */ var BoldGrid = BoldGrid || {}; BoldGrid.Backup = function( $ ) { var self = this; /** * @summary Handle the click of help buttons. * * @since 1.3.1 */ this.bindHelpClick = function() { $( 'body' ).on( 'click', '.dashicons-editor-help', function() { var id = $( this ).attr( 'data-id' ); // If we don't have a data-id, abort. if ( id === undefined ) { return; } // Toggle the help text. $( '.help[data-id="' + id + '"]' ).slideToggle(); } ); }; /** * @summary Remove WordPress' important notice about backups. * * We're already adding our own notice, no need to have 2 notices. * * @since 1.5.3 */ self.hideBackupNotice = function() { if ( pagenow === undefined || 'update-core' !== pagenow ) { return; } $( 'a[href*="WordPress_Backups"]' ) .closest( '.notice' ) .remove(); }; /** * @summary Handle the clicking of a show / hide toggle. * * In the example below, the show / hide link has a data-bgbkup-toggle-target attr * that helps to identify the element to toggle. * # Show * # */ defined( 'WPINC' ) || die; $checked = Boldgrid_Backup_Admin_Filelist_Analyzer::is_enabled() ? 'checked' : ''; ob_start(); ?>

>
*/ defined( 'WPINC' ) || die; ob_start(); ?>

here. */ printf( // translators: 1: URL address link. esc_html__( 'For security purposes, please do not set this to a publicly available directory. Once you set this, it is not recommended that you change it again. You can find more help with setting your backup directory %1$s.', 'boldgrid-backup' ), sprintf( '%1$s', esc_html__( 'here', 'boldgrid-backup' ) ) ); ?>

'>
*/ // Get BoldGrid settings. \Boldgrid\Library\Util\Option::init(); $boldgrid_backup_settings = get_site_option( 'boldgrid_backup_settings', array() ); $default_auto_update_settings = array( 'plugins' => array(), 'themes' => array(), 'wpcore' => array(), ); $auto_update_settings = isset( $boldgrid_backup_settings['auto_update'] ) ? $boldgrid_backup_settings['auto_update'] : $default_auto_update_settings; $translations = array( 'active' => esc_attr__( 'Active', 'boldgrid-backup' ), 'inactive' => esc_attr__( 'Inactive', 'boldgrid-backup' ), 'parent' => esc_attr__( 'Parent', 'boldgrid-backup' ), ); /** * Get Heading markup. * * @since 1.14.0 * * @param array $boldgrid_backup_settings Boldgrid Backup Settings. * @param array $auto_update_settings Auto Update Settings from DB. * @return string */ function get_heading_markup( $boldgrid_backup_settings, $auto_update_settings ) { if ( empty( $auto_update_settings ) || 0 === $boldgrid_backup_settings['auto_backup'] ) { $bbs_link_open = ''; $bbs_link_close = ''; if ( empty( $_GET['page'] ) || 'boldgrid-backup-settings' !== $_GET['page'] ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification $bbs_link_open = ''; $bbs_link_close = ''; } return '

' . sprintf( // translators: 1: HTML anchor open tag, 2: HTML anchor close tag, 3: HTML em open tag, 4: HTML em close tag, 5: Plugin Title. esc_html__( 'You have %3$sAuto Backup Before Update%4$s disabled in the %1$s%5$s Backup and Restore Settings%2$s. Please consider enabling the setting.', 'boldgrid-backup' ), $bbs_link_open, $bbs_link_close, '', '', 'Total Upkeep' ) . '

' . PHP_EOL; } } /** * Get Premium markup. * * @since 1.14.0 * * @return string */ function get_premium_markup() { $core = apply_filters( 'boldgrid_backup_get_core', null ); $premium_url = $core->go_pro->get_premium_url( 'bgbkup-settings-auto-update' ); $premium_box = sprintf( '

%1$s %2$s

', /* 1 */ $core->go_pro->get_premium_button( $premium_url ), /* 2 */ __( 'Upgrade to Premium for the option to configure a delay on updates!', 'boldgrid-backup' ) ); return $premium_box; } /** * Get WP Core Update markup. * * @since 1.14.0 * * @param array $auto_update_settings Auto Update Settings from DB. * @return string */ function get_wpcore_update_markup( $auto_update_settings ) { $wpcore_auto_updates = ! empty( $auto_update_settings['wpcore'] ) ? $auto_update_settings['wpcore'] : array(); $wpcore_major = ! empty( $wpcore_auto_updates['major'] ); $wpcore_minor = ! isset( $wpcore_auto_updates['minor'] ) || $wpcore_auto_updates['minor']; $wpcore_dev = ! empty( $wpcore_auto_updates['dev'] ); $wpcore_translation = ! empty( $wpcore_auto_updates['translation'] ); $wpcore_all = ! empty( $wpcore_auto_updates['all'] ) || ( $wpcore_major && $wpcore_minor && $wpcore_dev && $wpcore_translation ); $wpcore_update_markup = '
' . esc_html__( 'Configure what is Auto Updated', 'boldgrid-backup' ) . '
'; return $wpcore_update_markup; } /** * Get Plugins Update Markup. * * @since 1.14.0 * * @param array $auto_update_settings Auto Update Settings from DB. * @param array $translations Translations. * @return string */ function get_plugins_update_markup( $auto_update_settings, $translations ) { $plugins_default = ! empty( $auto_update_settings['plugins']['default'] ); $plugin_auto_update = (bool) \Boldgrid\Library\Util\Option::get( 'plugin_autoupdate' ); $plugins = get_plugins(); $plugins_active = array(); $plugins_inactive = array(); foreach ( $plugins as $slug => $plugin_data ) { if ( is_plugin_inactive( $slug ) ) { $plugins_inactive[ $slug ] = $plugin_data; } else { $plugins_active[ $slug ] = $plugin_data; } } $statuses = array( 'Active', 'Inactive', ); $plugins_update_markup = ''; foreach ( $statuses as $status ) { $status_lower = strtolower( $status ); $plugins_update_markup .= ''; foreach ( ${ 'plugins_' . $status_lower } as $slug => $plugin_data ) { // Enable if global setting is on, individual settings is on, or not set and default is on. $toggle = $plugin_auto_update || ! empty( $auto_update_settings['plugins'][ $slug ] ) || ( ! isset( $auto_update_settings['plugins'][ $slug ] ) && $plugins_default ); $plugin = \Boldgrid\Library\Library\Plugin\Factory::create( $slug ); $plugin->setUpdateData(); $third_party = $plugin->updateData->thirdParty; //phpcs:ignore WordPress.NamingConventions.ValidVariableName if ( true === $third_party ) { $extra_info_icon = ''; } else { $extra_info_icon = ''; } $plugins_update_markup .= ' '; if ( true === $third_party ) { $plugins_update_markup .= ' '; } } } $plugins_update_markup .= ''; return $plugins_update_markup; } /** * Get Themes Update Markup. * * @since 1.14.0 * * @param array $auto_update_settings Auto Update Settings from DB. * @param array $translations Translations. * @return string */ function get_themes_update_markup( $auto_update_settings, $translations ) { $themes_default = ! empty( $auto_update_settings['themes']['default'] ); $active_stylesheet = get_option( 'stylesheet' ); $active_template = get_option( 'template' ); $themes = wp_get_themes(); $themes_active = array(); $themes_inactive = array(); foreach ( $themes as $stylesheet => $theme ) { $is_active = $stylesheet === $active_stylesheet; $is_parent = ( $active_stylesheet !== $active_template && $stylesheet === $active_template ); if ( $is_active || $is_parent ) { $themes_active[ $stylesheet ] = $theme; } else { $themes_inactive[ $stylesheet ] = $theme; } } $theme_statuses = array( 'Active', 'Inactive', ); $themes_update_markup = ''; foreach ( $theme_statuses as $status ) { $status_lower = strtolower( $status ); $themes_update_markup .= ''; foreach ( ${ 'themes_' . $status_lower } as $stylesheet => $theme ) { $is_parent = ( $active_stylesheet !== $active_template && $stylesheet === $active_template ); // Enable if global setting is on, individual settings is on, or not set and default is on. $toggle = ! empty( $auto_update_settings['themes'][ $stylesheet ] ) || ( ! isset( $auto_update_settings['themes'][ $stylesheet ] ) && $themes_default ); $themes_update_markup .= ' '; } } $themes_update_markup .= ''; return $themes_update_markup; } $auto_update_markup = ' ' . get_heading_markup( $boldgrid_backup_settings, $auto_update_settings ); $auto_update_markup .= '
' . esc_html__( 'Configure When Auto Updates Occur', 'boldgrid-backup' ) . '
'; // If the 'boldgrid_backup_premium_timely_auto_updates' filter does not exist, then the $auto_update_settings array will be returned. $timely_update_markup = apply_filters( 'boldgrid_backup_premium_timely_auto_updates', $auto_update_settings ); /** * This was changed to be sure that there are no errors / issues if Total Upkeep is updated, but Total Upkeep Premium is not. * If Premium IS active and the above filter returns the $auto_update_settings array instead of the markup, then the user will need * to update to the newest version. If the Premium Plugin is active and the markup is returned above, then the timely update markup is * displayed. Lastly, if the premium plugin is not active at all, then the premium upsell is displayed. */ if ( $this->core->config->is_premium_done && $timely_update_markup === $auto_update_settings ) { $auto_update_markup .= sprintf( '

%2$s %3$s

', /* 1 */ admin_url( 'update-core.php' ), /* 2 */ __( 'View Updates', 'boldgrid-backup' ), /* 3 */ __( 'Upgrade to the newest version of Premium for the option to configure a delay on updates!', 'boldgrid-backup' ) ); } elseif ( $this->core->config->is_premium_done ) { $auto_update_markup .= $timely_update_markup; } else { $auto_update_markup .= get_premium_markup( $auto_update_settings ); $auto_update_markup .= ''; } $auto_update_markup .= get_wpcore_update_markup( $auto_update_settings, $translations ) . get_plugins_update_markup( $auto_update_settings, $translations ) . get_themes_update_markup( $auto_update_settings, $translations ) . '
' . esc_html__( 'WordPress Core', 'boldgrid-backup' ) . ' ' . esc_html__( 'All Update Types', 'boldgrid-backup' ) . '

' . esc_html__( 'Select Which WordPress Core updates you wish to have automatically updated', 'boldgrid-backup' ) . '.

' . esc_html__( 'Major Updates', 'boldgrid-backup' ) . '
' . esc_html__( 'Minor Updates', 'boldgrid-backup' ) . '
' . esc_html__( 'Development Updates', 'boldgrid-backup' ) . '
' . esc_html__( 'Translation Updates', 'boldgrid-backup' ) . '
' . esc_html__( 'Plugins', 'boldgrid-backup' ) . '

' . esc_html__( 'Choose which Plugins you wish to update automatically', 'boldgrid-backup' ) . '

' . esc_html__( 'Default For New Plugins', 'boldgrid-backup' ) . '
' . esc_html__( 'All Plugins', 'boldgrid-backup' ) . '

' . $translations[ $status_lower ] . '

' . $plugin_data['Name'] . $extra_info_icon . '

' . esc_html__( 'This plugin was not installed through the WordPress Plugins Repository. If auto updates are enabled, they will take place immediately.', 'boldrid-backup' ) . '

' . esc_html__( 'Themes', 'boldgrid-backup' ) . '

' . esc_html__( 'Choose which Themes you wish to update automatically ', 'boldgrid-backup' ) . '

' . esc_html__( 'Default For New Themes', 'boldgrid-backup' ) . '
' . esc_html__( 'All Themes', 'boldgrid-backup' ) . '

' . $translations[ $status_lower ] . '

' . $theme->get( 'Name' ) . ( $is_parent ? ' (' . $translations['parent'] . ')' : '' ) . '
'; return $auto_update_markup; admin/partials/settings/auto-backup.php000064400000007724147577722710014274 0ustar00 */ defined( 'WPINC' ) || die; ob_start(); ?>

/>   />

', '' ); ?>

/>   />

*/ // phpcs:disable WordPress.VIP defined( 'WPINC' ) || die; // Get a listing of all our logs and order them asc. $logs_dir = $this->core->backup_dir->get_logs_dir(); $list = $this->core->wp_filesystem->dirlist( $logs_dir ); uasort( $list, function( $a, $b ) { return $a['lastmodunix'] > $b['lastmodunix'] ? 1 : -1; }); ob_start(); echo '

' . esc_html__( 'Logs', 'boldgrid-backup' ) . '

'; if ( empty( $list ) ) { echo '
' . esc_html__( 'No log files exist.', 'boldgrid-backup' ) . '
'; } else { echo ' '; foreach ( $list as $item ) { $this->core->time->init( $item['lastmodunix'] ); echo ' '; } echo '
' . esc_html__( 'Filename', 'boldgrid-backup' ) . ' ' . esc_html__( 'Size', 'boldgrid-backup' ) . ' ' . esc_html__( 'Timestamp', 'boldgrid-backup' ) . '
' . esc_html( $item['name'] ) . ' ' . esc_html( size_format( $item['size'] ) ) . ' ' . wp_kses( $this->core->time->get_span(), [ 'span' => [ 'title' => [], ], ] ) . '
'; } wp_nonce_field( 'boldgrid_backup_view_log', 'bgbup_log_nonce' ); echo ''; $output = ob_get_contents(); ob_end_clean(); return $output; admin/partials/tools/local-remote.php000064400000014460147577722710013737 0ustar00 */ // phpcs:disable WordPress.VIP defined( 'WPINC' ) || die; ob_start(); preg_match( '/\(([^\)]+)\).+?(MSIE|(?!Gecko.+)Firefox|(?!AppleWebKit.+Chrome.+)Safari|(?!AppleWebKit.+)Chrome|AppleWebKit(?!.+Chrome|.+Safari)|Gecko(?!.+Firefox))(?: |\/)([\d\.apre]+)/', $_SERVER['HTTP_USER_AGENT'], $browser_info ); $local_info = [ [ 'title' => __( 'Browser', 'boldgrid-backup' ), 'value' => ( ! empty( $browser_info[2] ) ? $browser_info[2] : __( 'Unknown browser', 'boldgrid-backup' ) ) . ' ' . ( ! empty( $browser_info[3] ) ? $browser_info[3] : __( 'Unknown version', 'boldgrid-backup' ) ), ], [ 'title' => __( 'Operating System', 'boldgrid-backup' ), 'value' => ! empty( $browser_info[1] ) ? $browser_info[1] : __( 'Unknown', 'boldgrid-backup' ), ], ]; $local_info_markup = ''; foreach ( $local_info as $info ) { if ( empty( $info['value'] ) ) { continue; } $local_info_markup .= sprintf( '
  • %1$s: %2$s
  • ', esc_html( $info['title'] ), esc_html( $info['value'] ) ); } $server_info = [ [ 'title' => __( 'Server Name', 'boldgrid-backup' ), 'key' => 'SERVER_NAME', ], [ 'title' => __( 'Server IP Address', 'boldgrid-backup' ), 'key' => 'SERVER_ADDR', ], [ 'title' => __( 'Server Type', 'boldgrid-backup' ), 'key' => 'SERVER_SOFTWARE', ], ]; $server_info_markup = ''; foreach ( $server_info as $info ) { if ( empty( $_SERVER[ $info['key'] ] ) ) { continue; } $server_info_markup .= sprintf( '
  • %1$s: %2$s
  • ', $info['title'], $_SERVER[ $info['key'] ] ); } if ( function_exists( 'php_uname' ) ) { $server_architecture = sprintf( '%1$s %2$s %3$s', php_uname( 's' ), php_uname( 'r' ), php_uname( 'm' ) ); } else { $server_architecture = __( 'Unknown', 'boldgrid-backup' ); } $server_info_markup .= sprintf( '
  • %1$s: %2$s
  • ', __( 'Server OS', 'boldgrid-backup' ), $server_architecture ); printf( '

    %1$s

    %2$s

    %3$s


    ', esc_html__( 'Where should I store my backups?', 'boldgrid-backup' ), sprintf( // translators: 1: HTML strong open tag. 2: HTML strong close tag, 3: Plugin title. esc_html__( 'Throughout the %3$s plugin, you will see references to %1$sLocal Machine%2$s, %1$sWeb Server%2$s, and %1$sRemote Storage%2$s. These are all locations you can save your backup archives to.', 'boldgrid-backup' ), '', '', esc_html( BOLDGRID_BACKUP_TITLE ) ), esc_html__( 'Continue reading below to find out more about each. It is recommended to store backup archives in at least 2 different storage locations.', 'boldgrid-backup' ) ); printf( '

    %1$s

    ', esc_html__( 'Local Machine', 'boldgrid-backup' ) ); echo '

    '; printf( // translators: 1: HTML strong open tag. 2: HTML strong close tag. esc_html__( 'Your %1$sLocal Machine%2$s is the device you are using right now to access the internet. It could be a desktop, laptop, tablet, or even a smart phone.', 'boldgrid-backup' ), '', '' ); echo '

    '; if ( ! empty( $local_info_markup ) ) { printf( '

    %1$s

    %2$s', sprintf( // translators: 1: HTML strong open tag. 2: HTML strong close tag. esc_html__( 'We are able to see the following information about your %1$sLocal Machine%2$s:', 'boldgrid-backup' ), '', '' ), $local_info_markup // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped ); } echo '
    '; printf( '

    %1$s

    ', esc_html__( 'Web Server', 'boldgrid-backup' ) ); echo '

    '; printf( // translators: 1: HTML strong open tag. 2: HTML strong close tag. esc_html__( 'The %1$sWeb Server%2$s is the server where your WordPress website lives. You usually pay your web hosting provider monthly or yearly for hosting.', 'boldgrid-backup' ), '', '' ); echo '

    '; if ( ! empty( $server_info_markup ) ) { printf( '

    %1$s

    %2$s', sprintf( // translators: 1: HTML strong open tag. 2: HTML strong close tag. esc_html__( 'We are able to see the following information about your %1$sWeb Server%2$s:', 'boldgrid-backup' ), '', '' ), $server_info_markup // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped ); } echo '
    '; printf( '

    %1$s

    ', esc_html__( 'Remote Storage', 'boldgrid-backup' ) ); echo '

    '; printf( // translators: 1: HTML strong open tag, 2: HTML strong close tag, 3: HTML em open tag, 4: HTML em close tag. esc_html__( '%1$sRemote Storage%2$s providers are servers other than your %3$sLocal Machine%4$s and %3$sWeb Server%4$s where you can store files. For example, %3$sFTP%4$s, %5$s, and %6$s are all considered Remote Storage Providers.', 'boldgrid-backup' ), /* 1 */ '', /* 2 */ '', /* 3 */ '', /* 4 */ '', /* 5 */ '', /* 6 */ '' ); echo '

    '; if ( ! $this->core->config->is_premium_done ) { $premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-tools-faq-storage' ); printf( '

    %2$s

    %1$s

    ', $this->core->go_pro->get_premium_button( $premium_url, esc_html__( 'Unlock Feature', 'boldgrid-backup' ) ), // phpcs:ignore WordPress.XSS.EscapeOutput, WordPress.Security.EscapeOutput sprintf( // translators: 1 Markup showing a "Google Drive" logo, 2 Markup showing an "Amazon S3" logo. esc_html__( 'Catastrophic data loss can happen at any time. Storing your archives in multiple secure locations will keep your website data safe and put your mind at ease. Upgrade now to enable automated remote backups to %1$s and %2$s', 'boldgrid-backup' ), '', '' ) ); } $output = ob_get_contents(); ob_end_clean(); return $output; admin/partials/transfers/source.php000064400000010005147577722710013512 0ustar00 */ defined( 'WPINC' ) || die; $archive_list = $this->core->archives->get_table( [ 'show_link_button' => true, 'transfers_mode' => true, ] ); $contains_encrypted = false !== strpos( $archive_list, 'bgbkup-db-encrypted' ); switch ( true ) { case ! $contains_encrypted: // Has no encrypted files. $encrypt_message = ''; break; case $contains_encrypted && $is_premium && $is_premium_active: // Has encrypted files, a premium license, and the premium plugin activated. $encrypt_message = sprintf( // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag. __( 'Note: If you are going to migrate and restore a backup containing encrypted files, then don\'t forget to copy your encryption token to your destination site. You can retrieve your encryption token on the %1$sBackup Security%2$s settings page. ', 'boldgrid-backup' ), '', '' ); break; case $contains_encrypted && ! $is_premium: // Has encrypted files but no premium license. $get_premium_url = 'https://www.boldgrid.com/update-backup?source=bgbkup-settings-transfer-source'; $encrypt_message = sprintf( // translators: 1: Get premium button/link, 2: Premium plugin title. __( 'If you are going to migrate and restore a backup containing encrypted files, then a %2$s license is required for decryption. %1$s', 'boldgrid-backup' ), $this->core->go_pro->get_premium_button( $get_premium_url, __( 'Get Premium', 'boldgrid-backup' ) ), // phpcs:ignore BOLDGRID_BACKUP_TITLE . ' Premium' ); break; case $contains_encrypted && ! $is_premium_installed: // Has encrypted files and a premium license, but no premium plugin installed. $get_plugins_url = 'https://www.boldgrid.com/central/plugins?source=bgbkup-settings-transfer-source'; $encrypt_message = sprintf( // translators: 1: Unlock Feature button/link, 2: Premium plugin title. esc_html__( 'The %2$s plugin is required for encryption. %1$s', 'boldgrid-backup' ), $this->core->go_pro->get_premium_button( $get_plugins_url, __( 'Unlock Feature', 'boldgrid-backup' ) ), // phpcs:ignore BOLDGRID_BACKUP_TITLE . ' Premium' ); break; case $contains_encrypted && $is_premium_installed && ! $is_premium_active: // Has encrypted files, a premium license, premium plugin installed, but not activated. $encrypt_message = sprintf( // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title. __( '%3$s is not active and required for encryption features. Please go to the %1$sPlugins%2$s page to activate it.', 'boldgrid-backup' ), '', '', BOLDGRID_BACKUP_TITLE . ' Premium' ); break; default: $encrypt_message = ''; break; } return sprintf( '

    %1$s

    %2$s

    %3$s

    %4$s

    %5$s
    ', esc_html__( 'Use this section if you want to select this WordPress installation as the source.', 'boldgrid_backup' ), esc_html__( 'Choose a full backup in the list, click the "Get Download Link" button, and then click the "Copy Link" button. The download link is valid for a limited time and can be used to import the backed-up website into another WordPress installation using', 'boldgrid_backup' ) . ' ' . BOLDGRID_BACKUP_TITLE . '.', esc_html__( 'Note: Backup archives only existing in remote storage must first be downloaded to this web server in order to get a download link. Click the "View Details" for an archive and use the details page to download from remote storage.', 'boldgrid_backup' ), $encrypt_message, $archive_list ); admin/partials/transfers/overview.php000064400000001433147577722710014065 0ustar00 */ defined( 'WPINC' ) || die; return sprintf( '

    %1$s

    %2$s

    %3$s

    ', esc_html__( 'Easily transfer websites!', 'boldgrid_backup' ), esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'provides an easy way to transfer a website from one installation to another.', 'boldgrid_backup' ) ), esc_html__( 'Use the section selection on the left to choose if this WordPress installation is either the source or destination.', 'boldgrid_backup' ) ); admin/partials/transfers/destination.php000064400000010360147577722710014537 0ustar00 */ defined( 'WPINC' ) || die; switch ( true ) { case $is_premium && $is_premium_active: // Has a premium license and the premium plugin activated. $encrypt_message = sprintf( // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag. __( 'Note: If you are going to import and restore a backup containing encrypted files, then don\'t forget to copy your encryption token to your source site. You can save your encryption token on the %1$sBackup Security%2$s settings page.', 'boldgrid-backup' ), '', '' ); break; case ! $is_premium: // Does not have a premium license. $get_premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-transfer-destination' ); $encrypt_message = sprintf( // translators: 1: Get premium button/link, 2: Premium plugin title. __( 'If you are going to import and restore a backup containing encrypted files, then a %2$s license is required for decryption. %1$s', 'boldgrid-backup' ), $this->core->go_pro->get_premium_button( $get_premium_url, __( 'Get Premium', 'boldgrid-backup' ) ), // phpcs:ignore BOLDGRID_BACKUP_TITLE . ' Premium' ); break; case ! $is_premium_installed: // Has a premium license, but no premium plugin is installed. $get_plugins_url = $this->core->go_pro->get_premium_url( 'bgbkup-transfer-destination' ); $encrypt_message = sprintf( // translators: 1: Unlock Feature button/link, 2: Premium plugin title. esc_html__( 'The %2$s plugin is required for encryption. %1$s', 'boldgrid-backup' ), $this->core->go_pro->get_premium_button( $get_plugins_url, __( 'Unlock Feature', 'boldgrid-backup' ) ), // phpcs:ignore BOLDGRID_BACKUP_TITLE . ' Premium' ); break; case $is_premium_installed && ! $is_premium_active: // Has a premium license and the premium plugin installed, but not activated. $encrypt_message = sprintf( // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title. __( '%3$s is not active. %3$s is required for encryption features. Please go to the %1$sPlugins%2$s page to activate it.', 'boldgrid-backup' ), '', '', BOLDGRID_BACKUP_TITLE . ' Premium' ); break; default: $encrypt_message = ''; break; } return sprintf( '

    %1$s

    %2$s

    %3$s

    %9$s

    %4$s
    %7$s %8$s
    ', esc_html__( 'Use this section if you want to select this WordPress installation as the destination.', 'boldgrid_backup' ), esc_html( sprintf( // translators: 1: Plugin title. __( 'Retrieve a download link from %1$s on another WordPress installation, paste the link in form below, and click "Upload". Once the download completes, you can either inspect the backup files and database or click "Restore".', 'boldgrid_backup' ), BOLDGRID_BACKUP_TITLE ) ), esc_html__( 'Note: Performing a restoration in this installation will replace files and the database contents.', 'boldgrid_backup' ), esc_html__( 'Import from a download link:', 'boldgrid-backup' ), esc_attr__( 'Download URL address', 'boldgrid-backup' ), esc_attr__( 'Upload', 'boldgrid-backup' ), wp_nonce_field( 'upload_archive_file' ), // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped wp_nonce_field( 'boldgrid_backup_restore_archive', '_wpnonce_restore' ), // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped $encrypt_message ); admin/partials/boldgrid-backup-admin-transfers.php000064400000004131147577722710016332 0ustar00 */ defined( 'WPINC' ) || die; $is_premium = $this->core->config->get_is_premium(); $is_premium_installed = $this->core->config->is_premium_installed; $is_premium_active = $this->core->config->is_premium_active; $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php'; $overview = include BOLDGRID_BACKUP_PATH . '/admin/partials/transfers/overview.php'; $source = include BOLDGRID_BACKUP_PATH . '/admin/partials/transfers/source.php'; $destination = include BOLDGRID_BACKUP_PATH . '/admin/partials/transfers/destination.php'; $this->core->archive_actions->enqueue_scripts(); $this->core->auto_rollback->enqueue_home_scripts(); $sections = [ 'sections' => [ [ 'id' => 'section_transfers', 'title' => __( 'Overview', 'boldgrid-backup' ), 'content' => $overview, ], [ 'id' => 'section_source', 'title' => __( 'Source', 'boldgrid-backup' ), 'content' => $source, ], [ 'id' => 'section_destination', 'title' => __( 'Destination', 'boldgrid-backup' ), 'content' => $destination, ], ], ]; /** * Allow other plugins to modify the sections of the transfers page. * * @since 1.6.0 * * @param array $sections Sections. */ $sections = apply_filters( 'boldgrid_backup_transfers_sections', $sections ); /** * Render the $sections into displayable markup. * * @since 1.6.0 * * @param array $sections Sections. * * phpcs:disable WordPress.NamingConventions.ValidHookName */ $col_container = apply_filters( 'Boldgrid\Library\Ui\render_col_container', $sections ); ?>
    admin/partials/boldgrid-backup-admin-tools.php000064400000003173147577722710015470 0ustar00 */ defined( 'WPINC' ) || die; $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php'; $sections = array( 'sections' => array( array( 'id' => 'section_locations', 'title' => __( 'Local & Remote', 'boldgrid-backup' ), 'content' => include BOLDGRID_BACKUP_PATH . '/admin/partials/tools/local-remote.php', ), array( 'id' => 'section_cron_log', 'title' => __( 'Cron Log', 'boldgrid-backup' ), 'content' => $this->core->cron_log->get_markup(), ), array( 'id' => 'section_logs', 'title' => __( 'Logs', 'boldgrid-backup' ), 'content' => include BOLDGRID_BACKUP_PATH . '/admin/partials/tools/view-logs.php', ), ), ); /** * Allow other plugins to modify the sections of the tools page. * * @since 1.6.0 * * @param array $sections */ $sections = apply_filters( 'boldgrid_backup_tools_sections', $sections ); /** * Render the $sections into displayable markup. * * @since 1.6.0 * * @param array $sections * * phpcs:disable WordPress.NamingConventions.ValidHookName */ $col_container = apply_filters( 'Boldgrid\Library\Ui\render_col_container', $sections ); echo $nav; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped require BOLDGRID_BACKUP_PATH . '/admin/partials/archives/add-new.php'; echo $col_container; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped admin/partials/boldgrid-backup-admin-test.php000064400000034547147577722710015320 0ustar00 */ // phpcs:disable WordPress.VIP defined( 'WPINC' ) || die; // Setup our lang. $lang = array( 'yes' => __( 'Yes', 'boldgrid-backup' ), 'no' => __( 'No', 'boldgrid-backup' ), 'none' => __( 'None', 'boldgrid-backup' ), 'untested' => __( 'untested', 'boldgrid-backup' ), 'PASS' => __( 'PASS', 'boldgrid-backup' ), 'FAIL' => __( 'FAIL', 'boldgrid-backup' ), 'not_set' => __( 'not set', 'boldgrid-backup' ), 'before_test_compress' => __( 'Before any compressors are tested, please be sure your backup directory is created and has proper permissions set.', 'boldgrid-backup' ), 'ensure_dir_perms' => __( 'Please be sure that your backup directory exists. If it does, also ensure it has read, write, and modify permissions.', 'boldgrid-backup' ), ); $lang['dir_of_dir'] = $lang['ensure_dir_perms']; if ( $this->test->is_windows() ) { $lang['dir_of_dir'] = __( 'Please review directory permissions. If you are on a Windows server, your user may need to be able to read BOTH the backup directory and its parent directory.', 'boldgrid-backup' ); } $error_span = '%1$s
    %2$s'; $warning_span = '%1$s
    %2$s'; $success_span = '%1$s'; $allowed_tags = array( 'span' => array( 'class' => array( 'error', 'dashicons', 'dashicons-editor-help', 'spinner', 'inline', ), 'data-id' => array( 'cron-time-zone', ), ), 'br' => array(), 'p' => array( 'class' => array( 'help', ), 'data-id' => array( 'cron-time-zone', ), ), 'pre' => array(), 'form' => array( 'method' => array(), 'action' => array( 'admin.php?page=boldgrid-backup-test', ), ), 'input' => array( 'type' => array(), 'name' => array( 'cron_timezone_test', ), 'value' => array(), 'class' => array( 'button', ), 'style' => array(), ), 'strong' => array(), ); $backup_dir_perms = $this->test->extensive_dir_test( $backup_directory ); $php_zip = new Boldgrid_Backup_Admin_Compressor_Php_Zip( $this ); $pcl_zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this ); $filesystem_method = get_filesystem_method(); $execution_functions = Boldgrid_Backup_Admin_Cli::get_execution_functions(); $valid_backup_dir = $backup_dir_perms['exists'] && $backup_dir_perms['read'] && $backup_dir_perms['write'] && $backup_dir_perms['rename'] && $backup_dir_perms['delete'] && $backup_dir_perms['dirlist']; $timezone = $this->time->get_server_timezone(); $timezone = false === $timezone ? 'UTC' . $this->time->get_server_offset() : $timezone->getName() . ' / ' . $this->time->get_server_offset(); // Run our tests. $tests = array( array( 'id' => 'pass', 'k' => __( 'Functionality test status:', 'boldgrid-backup' ), 'v' => ( $this->test->run_functionality_tests() ? sprintf( $success_span, $lang['PASS'] ) : sprintf( $error_span, $lang['FAIL'], '' ) ), ), array( 'heading' => __( 'General tests', 'boldgrid-backup' ), ), array( 'k' => __( 'User home directory:', 'boldgrid-backup' ), 'v' => $home_dir . ' (' . $home_dir_mode . ')', ), array( 'k' => __( 'User home directory writable?', 'boldgrid-backup' ), 'v' => ( $home_dir_writable ? $lang['yes'] : $lang['no'] ), ), array( 'k' => __( 'WordPress directory:', 'boldgrid-backup' ), 'v' => ABSPATH, ), array( 'k' => __( 'WordPress directory writable?', 'boldgrid-backup' ), 'v' => ( $this->test->get_is_abspath_writable() ? $lang['yes'] : sprintf( $error_span, $lang['no'], '' ) ), ), array( 'k' => __( 'Document root:', 'boldgrid-backup' ), 'v' => str_replace( '\\\\', '\\', $_SERVER['DOCUMENT_ROOT'] ), ), array( 'k' => __( 'Current user:', 'boldgrid-backup' ), 'v' => get_current_user(), ), array( 'k' => __( 'PHP in safe mode?', 'boldgrid-backup' ), 'v' => $this->test->is_php_safemode() ? sprintf( $error_span, $lang['yes'], '' ) : $lang['no'], ), array( 'k' => __( 'Filesystem Method', 'boldgrid-backup' ), 'v' => $this->test->is_filesystem_supported() ? $filesystem_method : sprintf( $error_span, $filesystem_method, __( 'Only "direct" filesystem supported.', 'boldgrid-backup' ) ), ), array( 'k' => __( 'Execution functions available', 'boldgrid-backup' ), 'v' => empty( $execution_functions ) ? sprintf( $error_span, $lang['none'], '' ) : implode( ', ', $execution_functions ), ), array( 'k' => __( 'WordPress version:', 'boldgrid-backup' ), 'v' => $wp_version, ), array( 'k' => __( 'Server time zone:', 'boldgrid-backup' ), 'v' => $timezone, ), array( 'k' => __( 'Server date:', 'boldgrid-backup' ), 'v' => $this->time->get_server_date(), ), ); $tests[] = array( 'heading' => __( 'Backup directory & permissions:', 'boldgrid-backup' ), ); $tests[] = array( 'k' => __( 'Possible backup directory parents:', 'boldgrid-backup' ), 'v' => implode( '
    ', $possible_backup_dirs ), ); $tests[] = array( 'k' => __( 'Backup directory:', 'boldgrid-backup' ), 'v' => ! empty( $backup_directory ) ? $backup_directory : sprintf( $error_span, $lang['not_set'], '' ), ); // As set of tests only to run if a backup directory is found. if ( ! empty( $backup_directory ) ) { $tests[] = array( 'k' => __( 'Backup directory without ABSPATH:', 'boldgrid-backup' ), 'v' => $this->backup_dir->without_abspath, ); $tests[] = array( 'k' => __( 'Backup directory exists?', 'boldgrid-backup' ), 'v' => $backup_dir_perms['exists'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], $lang['ensure_dir_perms'] ), ); if ( $backup_dir_perms['exists'] ) { $tests[] = array( 'k' => __( 'Backup directory has read permission?', 'boldgrid-backup' ), 'v' => $backup_dir_perms['read'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], $lang['ensure_dir_perms'] ), ); $tests[] = array( 'k' => __( 'Directory listing of backup directory can be fetched?', 'boldgrid-backup' ), 'v' => $backup_dir_perms['dirlist'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], $lang['dir_of_dir'] ), ); $tests[] = array( 'k' => __( 'Backup directory has write permission?', 'boldgrid-backup' ), 'v' => $backup_dir_perms['write'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], $lang['ensure_dir_perms'] ), ); $tests[] = array( 'k' => __( 'Backup directory has modify permission?', 'boldgrid-backup' ), 'v' => $backup_dir_perms['rename'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], $lang['ensure_dir_perms'] ), ); $tests[] = array( 'k' => __( 'Backup directory has delete permission?', 'boldgrid-backup' ), 'v' => $backup_dir_perms['delete'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], $lang['ensure_dir_perms'] ), ); } } $tests[] = array( 'heading' => 'Available compressors', ); $tests[] = array( 'k' => __( 'PHP ZipArchive available?', 'boldgrid-backup' ), 'v' => ( $this->config->is_compressor_available( 'php_zip' ) ? 'Yes' : 'No' ), ); if ( 'php_zip' === $this->compressors->get() ) { if ( ! $valid_backup_dir ) { $status = sprintf( $warning_span, $lang['untested'], $lang['before_test_compress'] ); } elseif ( $php_zip->test() ) { $status = $lang['yes']; } else { $status = sprintf( $error_span, $lang['no'], '' ); } $tests[] = array( 'k' => __( 'PHP ZipArchive test passed?', 'boldgrid-backup' ), 'v' => $status, ); } $tests[] = array( 'k' => __( 'PclZip available?', 'boldgrid-backup' ), 'v' => ( $this->config->is_compressor_available( 'pcl_zip' ) ? 'Yes' : 'No' ), ); if ( 'pcl_zip' === $this->compressors->get() ) { if ( ! $valid_backup_dir ) { $status = sprintf( $warning_span, $lang['untested'], $lang['before_test_compress'] ); } elseif ( $pcl_zip->test() ) { $status = $lang['yes']; } else { $status = sprintf( $error_span, $lang['no'], '' ); } $tests[] = array( 'k' => __( 'PclZip test passed?', 'boldgrid-backup' ), 'v' => $status, ); } $tests[] = array( 'k' => __( 'PHP Bzip2 available?', 'boldgrid-backup' ), 'v' => ( $this->config->is_compressor_available( 'php_bz2' ) ? 'Yes' : 'No' ), ); $tests[] = array( 'k' => __( 'PHP Zlib available?', 'boldgrid-backup' ), 'v' => ( $this->config->is_compressor_available( 'php_zlib' ) ? 'Yes' : 'No' ), ); $tests[] = array( 'k' => __( 'PHP LZF available?', 'boldgrid-backup' ), 'v' => ( $this->config->is_compressor_available( 'php_lzf' ) ? 'Yes' : 'No' ), ); $tests[] = array( 'k' => __( 'System TAR available?', 'boldgrid-backup' ), 'v' => ( $this->config->is_compressor_available( 'system_tar' ) ? 'Yes' : 'No' ), ); $system_zip_test = new Boldgrid_Backup_Admin_Compressor_System_Zip_Test( $this ); $tests[] = array( 'k' => __( 'System ZIP available?', 'boldgrid-backup' ), 'v' => $system_zip_test->run() ? 'Yes' : sprintf( $warning_span, $lang['no'], $system_zip_test->get_error() ), ); $tests[] = array( 'heading' => __( 'Cron', 'boldgrid-backup' ), ); $tests[] = array( 'k' => __( 'System crontab available?', 'boldgrid-backup' ), 'v' => ( $this->test->is_crontab_available() ? $lang['yes'] : sprintf( $warning_span, $lang['no'], '' ) ), ); $tests[] = array( 'k' => __( 'PHP allow_url_fopen enabled?', 'boldgrid-backup' ), 'v' => true === $cli_support['has_url_fopen'] ? $lang['yes'] : sprintf( $warning_span, $lang['no'], '' ), ); $tests[] = array( 'k' => __( 'Curl SSL enabled?', 'boldgrid-backup' ), 'v' => true === $cli_support['has_curl_ssl'] ? $lang['yes'] : sprintf( $warning_span, $lang['no'], '' ), ); $tests[] = array( 'k' => __( 'Can fetch a remote url via CLI?', 'boldgrid-backup' ), 'v' => true === $cli_support['can_remote_get'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], '' ), ); $tests[] = array( 'k' => __( 'Cron time zone matches server time zone? ', 'boldgrid-backup' ), 'v' => $this->cron_test->get_preflight_markup(), ); $tests[] = array( 'k' => __( 'Cron jobs:', 'boldgrid-backup' ), 'v' => '
    ' . implode( '

    ', $our_crons ) . '
    ', ); $tests[] = array( 'k' => __( 'Method used to read cron:', 'boldgrid-backup' ), 'v' => $this->backup_dir->can_exec_write() ? __( 'Crontab output to file.', 'boldgrid-backup' ) : __( 'Crontab read via exec function.', 'boldgrid-backup' ), ); $tests[] = array( 'k' => __( 'WP Cron enabled?', 'boldgrid-backup' ), 'v' => ( $this->test->wp_cron_enabled() ? 'Yes' : 'No' ), ); $tests[] = array( 'k' => __( 'WP Cron jobs:', 'boldgrid-backup' ), 'v' => '
    ' . implode( '

    ', $our_wp_crons ) . '
    ', ); // Run only these tests if the server is compatible. if ( $is_functional ) { $tests[] = array( 'heading' => __( 'Disk space', 'boldgrid-backup' ), ); $tests[] = array( 'k' => __( 'Directory used to calculate disk space:', 'boldgrid-backup' ), 'v' => $this->home_dir->get_for_disk(), ); $tests[] = array( 'k' => __( 'Disk total space:', 'boldgrid-backup' ), 'v' => Boldgrid_Backup_Admin_Utility::bytes_to_human( $disk_space[0] ), ); $tests[] = array( 'k' => __( 'Disk used space:', 'boldgrid-backup' ), 'v' => Boldgrid_Backup_Admin_Utility::bytes_to_human( $disk_space[1] ), ); $tests[] = array( 'k' => __( 'Disk free space:', 'boldgrid-backup' ), 'v' => Boldgrid_Backup_Admin_Utility::bytes_to_human( $disk_space[2] ), ); if ( ! empty( $disk_space[3] ) ) { $tests[] = array( 'k' => __( 'WordPress directory size:', 'boldgrid-backup' ), 'v' => Boldgrid_Backup_Admin_Utility::bytes_to_human( $disk_space[3] ), ); } // Calculate possible disk free space after a backup, using the entire WP directory size. $disk_free_post = $disk_space[2] - $disk_space[3] - $db_size; if ( $disk_free_post > 0 ) { $tests[] = array( 'k' => __( 'Estimated free space after backup:', 'boldgrid-backup' ), 'v' => Boldgrid_Backup_Admin_Utility::bytes_to_human( $disk_free_post ), ); } else { $tests[] = array( 'v' => __( 'THERE IS NOT ENOUGH SPACE TO PERFORM A BACKUP!', 'boldgrid-backup' ), ); } $tests[] = array( 'heading' => __( 'Database', 'boldgrid-backup' ), ); $tests[] = array( 'k' => __( 'Database size:', 'boldgrid-backup' ), 'v' => Boldgrid_Backup_Admin_Utility::bytes_to_human( $db_size ), ); $tests[] = array( 'k' => __( 'WordPress database charset:', 'boldgrid-backup' ), 'v' => $db_charset, ); if ( ! empty( $db_collate ) ) { $tests[] = array( 'k' => __( 'WordPress database collate:', 'boldgrid-backup' ), 'v' => $db_collate, ); } } // If server is not compatible, create fail message. if ( $is_functional ) { $fail_tips = ''; } else { $fail_tips = sprintf( '

    %1$s
    %2$s

    ', esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'is not compatible with your hosting account. For further help please see:', 'boldgrid-backup' ) ), esc_html( __( 'Making your web hosting account compatible with', 'boldgrid-backup' ) . ' ' . BOLDGRID_BACKUP_TITLE ), esc_url( $this->configs['urls']['compatibility'] ) ); } // Create the table that will contain the tests data. $table = ''; foreach ( $tests as $test ) { if ( ! empty( $test['heading'] ) ) { $table .= sprintf( '', esc_html( $test['heading'] ) ); } elseif ( isset( $test['id'] ) && 'pass' === $test['id'] ) { $table .= sprintf( '', esc_html( $test['k'] ), wp_kses( $test['v'], $allowed_tags ) ); } elseif ( isset( $test['k'] ) ) { $table .= sprintf( '', wp_kses( $test['k'], $allowed_tags ), wp_kses( $test['v'], $allowed_tags ) ); } else { $table .= sprintf( '', esc_html( $test['v'] ) ); } } $table .= '

    %1$s

    %1$s%2$s
    %1$s%2$s
    %1$s
    '; ?>
    admin/partials/boldgrid-backup-admin-support.php000064400000010065147577722710016042 0ustar00 * * phpcs:disable WordPress.NamingConventions.ValidHookName */ defined( 'WPINC' ) || die; $allowed_tags = [ 'a' => [ 'href' => [], 'target' => [], ], ]; $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php'; $reseller = get_option( 'boldgrid_reseller' ); if ( ! empty( $reseller ) ) { // Is under a reseller. $premium_markup = '
    • ' . sprintf( wp_kses( /* translators: 1: Anchored URL address for reseller support, 2: Reseller title/name, 3: HTML anchor close tag. */ __( 'You can receive premium support from your official reseller %1$s%2$s%3$s', 'boldgrid-backup' ), $allowed_tags ), '', $reseller['reseller_title'], '' ) . '
    • '; if ( ! empty( $reseller['reseller_phone'] ) ) { $premium_markup .= '
    • ' . sprintf( wp_kses( /* translators: 1: Reseller telephone number */ __( 'Telephone: %1$s', 'boldgrid-backup' ), $allowed_tags ), $reseller['reseller_phone'] ) . '
    • '; } if ( ! empty( $reseller['reseller_email'] ) ) { $premium_markup .= '
    • ' . sprintf( wp_kses( /* translators: Reseller email address. */ __( 'Email: %1$s', 'boldgrid-backup' ), $allowed_tags ), '' . esc_attr( $reseller['reseller_email'] ) . '' ) . '
    • '; } $premium_markup .= '
    '; } elseif ( $this->core->config->is_premium_done ) { // Is BoldGrid Premium. $premium_markup = '