settings = $settings; } /** * Enqueues main css file. */ public function admin_css() { $plugin_dir = untrailingslashit( BackWPup::get_plugin_data( 'plugindir' ) ); $file_path = "{$plugin_dir}/assets/css/main.min.css"; wp_enqueue_style( 'backwpup', BackWPup::get_plugin_data( 'URL' ) . '/assets/css/main.min.css', [], BackWPup::get_plugin_data( 'Version' ), 'screen' ); } /** * Enqueues main js file. */ public function enqueue_backup_generation() { $job_object = BackWPup_Job::get_working_data(); if ( ! empty( $job_object->logfile ) ) { wp_enqueue_script( 'backwpup-generate', BackWPup::get_plugin_data( 'URL' ) . '/assets/js/backwpup-generate.js', [ 'jquery' ], BackWPup::get_plugin_data( 'Version' ), true ); wp_localize_script( 'backwpup-generate', 'backwpupApi', $this->get_backwpup_api_data( $job_object ) ); wp_localize_script( 'backwpup-generate', 'backwpup', [ 'adminUrl' => network_admin_url( 'admin.php?page=backwpup' ), ] ); } } /** * Enqueues main css/js file. */ public function enqueue_admin_assets() { // Get the current screen object. $screen = get_current_screen(); $is_backwpup_page = isset( $screen->id ) && strpos( $screen->id, 'backwpup' ) !== false; // Check if we're on a BackWPUp page. if ( $is_backwpup_page && 'admin_page_backwpupjobs' !== $screen->id ) { wp_enqueue_style( 'backwpup-admin', BackWPup::get_plugin_data( 'URL' ) . '/assets/css/backwpup-admin.css', [], BackWPup::get_plugin_data( 'Version' ) ); } if ( $is_backwpup_page ) { wp_enqueue_script( 'backwpup-admin', BackWPup::get_plugin_data( 'URL' ) . '/assets/js/backwpup-admin.js', [ 'jquery' ], BackWPup::get_plugin_data( 'Version' ), true ); wp_localize_script( 'backwpup-admin', 'backwpupApi', $this->get_backwpup_api_data() ); } } /** * Load for all BackWPup pages. */ public static function init_general() { add_thickbox(); $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; wp_register_script( 'backwpupgeneral', BackWPup::get_plugin_data( 'URL' ) . "/assets/js/general{$suffix}.js", [ 'jquery' ], ( $suffix ? BackWPup::get_plugin_data( 'Version' ) : time() ), false ); // Get the current screen object. $screen = get_current_screen(); // Check if we're on a BackWPUp page. if ( isset( $screen->id ) && strpos( $screen->id, 'backwpup' ) !== false ) { // Register clipboard.js script. wp_register_script( 'backwpup_clipboard', BackWPup::get_plugin_data( 'URL' ) . '/assets/js/vendor/clipboard.min.js', [ 'jquery' ], '1.7.1', true ); } } /** * Add Message (across site loadings). * * @param string $message Message text. * @param bool $error Whether this is an error message. */ public static function message( $message, $error = false ) { if ( empty( $message ) ) { return; } $saved_message = self::get_messages(); if ( $error ) { $saved_message['error'][] = $message; } else { $saved_message['updated'][] = $message; } update_site_option( 'backwpup_messages', $saved_message ); } /** * Return the user-facing notice for an unavailable archive format. * * @param string $job_name The job name. * @param string $format The unavailable archive format extension (e.g. '.zip'). * * @return string Translated notice string. */ public static function unavailable_archive_format_notice( string $job_name, string $format ): string { return sprintf( /* translators: 1: archive format (e.g. .zip), 2: job name */ __( 'The archive format "%1$s" configured for job "%2$s" is no longer available. .tar will be used instead.', 'backwpup' ), $format, $job_name ); } /** * Get all Message that not displayed. * * @return array */ public static function get_messages() { return get_site_option( 'backwpup_messages', [] ); } /** * Display Messages. * * @param bool $do_echo Whether to echo the output. * * @return string */ public static function display_messages( $do_echo = true ) { /** * This hook can be used to display more messages in all BackWPup pages. */ do_action( 'backwpup_admin_messages' ); $message_updated = ''; $message_error = ''; $saved_message = self::get_messages(); $message_id = ' id="message"'; if ( empty( $saved_message ) ) { return ''; } if ( ! empty( $saved_message['updated'] ) ) { foreach ( $saved_message['updated'] as $msg ) { $message_updated .= '

' . $msg . '

'; } } if ( ! empty( $saved_message['error'] ) ) { foreach ( $saved_message['error'] as $msg ) { $message_error .= '

' . $msg . '

'; } } update_site_option( 'backwpup_messages', [] ); if ( ! empty( $message_updated ) ) { $message_updated = '' . $message_updated . ''; $message_id = ''; } if ( ! empty( $message_error ) ) { $message_error = '' . $message_error . ''; } $output = $message_updated . $message_error; if ( $do_echo ) { echo wp_kses_post( $output ); } return wp_kses_post( $output ); } /** * Admin init function. */ public function admin_init() { if ( ! is_admin() ) { return; } $is_onboarding = get_site_option( 'backwpup_onboarding', false ); $allowed_pages = [ 'backwpupabout', 'backwpuponboarding', 'backwpupfirstbackup', 'backwpupsupport' ]; // Redirect only if onboarding is active and the current page is not in the allowed pages. if ( $is_onboarding && ( isset( $_GET['page'] ) && false !== strpos( sanitize_text_field( wp_unslash( $_GET['page'] ) ), 'backwpup' ) && ! in_array( $_GET['page'], $allowed_pages, true ) ) // phpcs:ignore WordPress.Security.NonceVerification ) { wp_safe_redirect( network_admin_url( 'admin.php?page=backwpuponboarding' ) ); exit; } if ( \BackWPup::is_pro() ) { $this->admin_init_pro(); } if ( ! wp_doing_ajax() ) { // Only init notices if this is not an AJAX request. $this->init_notices(); // Everything after this point applies to AJAX. return; } $jobtypes = BackWPup::get_job_types(); $destinations = BackWPup::get_registered_destinations(); add_action( 'wp_ajax_backwpup_debug_info', function () { echo '' . esc_html__( 'Debug Information', 'backwpup' ) . ''; $information = BackWPup_Page_Settings::get_information(); foreach ( $information as $item ) { echo esc_html( trim( $item['label'] ) ) . ': ' . esc_html( trim( $item['value'] ) ) . "\n
"; } echo ''; wp_die(); } ); add_action( 'wp_ajax_backwpup_working', [ \BackWPup_Page_Jobs::class, 'ajax_working' ] ); add_action( 'wp_ajax_backwpup_cron_text', [ \BackWPup_Page_Editjob::class, 'ajax_cron_text' ] ); add_action( 'wp_ajax_backwpup_view_log', [ \BackWPup_Page_Logs::class, 'ajax_view_log' ] ); add_action( 'wp_ajax_download_backup_file', [ \BackWPup_Destination_Downloader::class, 'download_by_ajax' ] ); foreach ( $jobtypes as $id => $jobtypeclass ) { add_action( 'wp_ajax_backwpup_jobtype_' . strtolower( $id ), [ $jobtypeclass, 'edit_ajax' ] ); } foreach ( $destinations as $id => $dest ) { if ( ! empty( $dest['class'] ) ) { add_action( 'wp_ajax_backwpup_dest_' . strtolower( $id ), [ BackWPup::get_destination( $id ), 'edit_ajax', ], 10, 0 ); } } } /** * Initialize pro-specific admin features. * * @return void */ private function admin_init_pro() { $ajax_encryption_key_handler = new AjaxEncryptionKeyHandler(); add_action( 'wp_ajax_encrypt_key_handler', [ $ajax_encryption_key_handler, 'handle' ] ); $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; wp_enqueue_script( 'backwpuppagesettings-encryption', untrailingslashit( BackWPup::get_plugin_data( 'URL' ) ) . "/assets/js/settings-encryption{$suffix}.js", [ 'underscore', 'jquery', 'thickbox', ], BackWPup::get_plugin_data( 'Version' ), false ); wp_localize_script( 'backwpuppagesettings-encryption', 'settingsEncryptionVariables', [ 'validPublicKey' => esc_html__( 'Public key is valid.', 'backwpup' ), 'invalidPublicKey' => esc_html__( 'Public key is invalid.', 'backwpup' ), 'privateKeyMissed' => esc_html__( 'Please enter your private key.', 'backwpup' ), 'publicKeyMissed' => esc_html__( 'Please enter a public key first, or generate a key pair.', 'backwpup' ), 'mustDownloadPrivateKey' => esc_html__( 'Please download the private key before continuing. If you do not save it locally, you cannot decrypt your backups later.', 'backwpup' ), 'mustDownloadSymmetricKey' => esc_html__( 'Please download the key before continuing. If you do not save it locally, you cannot decrypt your backups later.', 'backwpup' ), ] ); } /** * Init the plugin notices. */ private function init_notices() { // Show notice if PHP < 7.4. $php_notice = new PhpNotice( // phpcs:ignore new NoticeView( PhpNotice::ID ) ); $php_notice->init( PhpNotice::TYPE_ADMIN ); // Show notice if WordPress < 5.0. $wp_notice = new WordPressNotice( new NoticeView( WordPressNotice::ID ) ); $wp_notice->init( WordPressNotice::TYPE_ADMIN ); // Show notice if Dropbox needs to be reauthenticated. $dropbox_notice = new DropboxNotice( new NoticeView( DropboxNotice::ID ), false // Not dismissible. ); $dropbox_notice->init( DropboxNotice::TYPE_ADMIN ); $evaluate_notice = new EvaluateNotice( new NoticeView( EvaluateNotice::ID ) ); // $evaluate_notice->init( EvaluateNotice::TYPE_ADMIN ); $restore_feature_information_notice = new RestoreFeatureInformationNotice( new NoticeView( RestoreFeatureInformationNotice::ID ), true ); // $restore_feature_information_notice->init( RestoreFeatureInformationNotice::TYPE_ADMIN ); } /** * Add Links in Plugins Menu to BackWPup. * * @param array $links Links list. * @param string $file Plugin file. * * @return array */ public function plugin_links( $links, $file ) { if ( plugin_basename( BackWPup::get_plugin_data( 'MainFile' ) ) === $file ) { $links = array_filter( $links, function ( $link ) { return strpos( $link, 'Visit plugin site' ) === false; } ); if ( BackWPup::is_pro() ) { $links[] = '' . __( 'View details', 'backwpup' ) . ''; } } return $links; } /** * Adds custom links to the plugin's action links in the Plugins page. * * @param array $links An array of the plugin's existing action links. * @return array Modified array of action links with custom links added. */ public function plugin_name_links( $links ) { $is_pro_user = BackWPup::is_pro(); $settings_link = '' . __( 'Settings', 'backwpup' ) . ''; $faqs_link = 'FAQ'; $docs_link = 'Docs'; if ( $is_pro_user ) { // Pro user links. $support_link = 'Support'; // Append custom links for pro users. $links = array_merge( [ $settings_link, $faqs_link, $docs_link, $support_link ], $links ); } else { // Free user links. $buy_pro_link = 'Upgrade to Pro'; // Append custom links for free users. $links = array_merge( [ $buy_pro_link, $settings_link, $faqs_link, $docs_link ], $links ); } return $links; } /** * Add menu entries. */ public function admin_menu() { add_menu_page( BackWPup::get_plugin_data( 'name' ), BackWPup::get_plugin_data( 'name' ), 'backwpup', 'backwpup', [ \BackWPup_Page_Backups::class, 'page', ], 'div' ); // External menu pages. $this->page_hooks['backwpupdocs'] = add_submenu_page( 'backwpup', __( 'Docs', 'backwpup' ), __( 'Docs', 'backwpup' ), 'backwpup', 'docs', '__return_false', ); add_action( 'load-' . $this->page_hooks['backwpupdocs'], function () { wp_redirect( $this->backwpup_url . '/docs/?utm_source=backwpup_plugin&utm_medium=plugin&utm_campaign=in_product&utm_content=docs_link' ); //phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect } ); if ( ! BackWPup::is_pro() ) { $this->page_hooks['backwpupbuypro'] = add_submenu_page( 'backwpup', __( 'Upgrade to Pro', 'backwpup' ), '' . __( 'Upgrade to Pro', 'backwpup' ) . '', 'backwpup', 'buypro', '__return_false', ); add_action( 'load-' . $this->page_hooks['backwpupbuypro'], function () { wp_redirect( $this->backwpup_url . '/pricing/?utm_source=backwpup_plugin&utm_medium=plugin&utm_campaign=in_product&utm_content=upgrade_cta_plugin' ); //phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect } ); } // Add pages form plugins. $this->page_hooks = wpm_apply_filters_typed( 'array', 'backwpup_admin_pages', $this->page_hooks ); global $submenu; if ( isset( $submenu['backwpup'] ) ) { $submenu['backwpup'][0][0] = __( 'Settings', 'backwpup' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited } } /** * Handle the "First Backup" page. * * @param array $page_hooks The page hooks list. * @return mixed */ public function admin_page_first_backup( $page_hooks ) { $this->page_hooks['backwpupfirstbackup'] = add_submenu_page( 'backwpup_null', __( 'First Backup', 'backwpup' ), __( 'First Backup', 'backwpup' ), 'backwpup', 'backwpupfirstbackup', [ \BackWPup_Page_First_Backup::class, 'page' ] ); add_action( 'load-' . $this->page_hooks['backwpupfirstbackup'], [ self::class, 'init_general' ] ); add_action( 'load-' . $this->page_hooks['backwpupfirstbackup'], [ \BackWPup_Page_First_Backup::class, 'init' ] ); return $page_hooks; } /** * Register the legacy jobs page. * * @param array $page_hooks The page hooks list. * * @return mixed */ public function admin_page_jobs( $page_hooks ) { $this->page_hooks['backwpupjobs'] = add_submenu_page( 'backwpup_null', __( 'Legacy Jobs', 'backwpup' ), __( 'Legacy Jobs', 'backwpup' ), 'backwpup_jobs', 'backwpupjobs', [ \BackWPup_Page_Jobs::class, 'page', ] ); add_action( 'load-' . $this->page_hooks['backwpupjobs'], [ self::class, 'init_general' ] ); add_action( 'load-' . $this->page_hooks['backwpupjobs'], [ \BackWPup_Page_Jobs::class, 'load' ] ); add_action( 'admin_print_styles-' . $this->page_hooks['backwpupjobs'], [ \BackWPup_Page_Jobs::class, 'admin_print_styles', ] ); add_action( 'admin_print_scripts-' . $this->page_hooks['backwpupjobs'], [ \BackWPup_Page_Jobs::class, 'admin_print_scripts', ] ); return $page_hooks; } /** * Register the edit job page. * * @param array $page_hooks The page hooks list. * * @return mixed */ public function admin_page_editjob( $page_hooks ) { $this->page_hooks['backwpupeditjob'] = add_submenu_page( 'backwpup_null', __( 'Add new job', 'backwpup' ), __( 'Add new job', 'backwpup' ), 'backwpup_jobs_edit', 'backwpupeditjob', [ \BackWPup_Page_Editjob::class, 'page', ] ); add_action( 'load-' . $this->page_hooks['backwpupeditjob'], [ self::class, 'init_general' ] ); add_action( 'load-' . $this->page_hooks['backwpupeditjob'], [ \BackWPup_Page_Editjob::class, 'auth' ] ); add_action( 'admin_print_styles-' . $this->page_hooks['backwpupeditjob'], [ \BackWPup_Page_Editjob::class, 'admin_print_styles', ] ); add_action( 'admin_print_scripts-' . $this->page_hooks['backwpupeditjob'], [ \BackWPup_Page_Editjob::class, 'admin_print_scripts', ] ); return $page_hooks; } /** * Register the logs page. * * @param array $page_hooks The page hooks list. * * @return mixed */ public function admin_page_logs( $page_hooks ) { $this->page_hooks['backwpuplogs'] = add_submenu_page( 'backwpup_null', __( 'Logs', 'backwpup' ), __( 'Logs', 'backwpup' ), 'backwpup_logs', 'backwpuplogs', [ \BackWPup_Page_Logs::class, 'page', ] ); add_action( 'load-' . $this->page_hooks['backwpuplogs'], [ self::class, 'init_general' ] ); add_action( 'load-' . $this->page_hooks['backwpuplogs'], [ \BackWPup_Page_Logs::class, 'load' ] ); add_action( 'admin_print_styles-' . $this->page_hooks['backwpuplogs'], [ \BackWPup_Page_Logs::class, 'admin_print_styles', ] ); add_action( 'admin_print_scripts-' . $this->page_hooks['backwpuplogs'], [ \BackWPup_Page_Logs::class, 'admin_print_scripts', ] ); return $page_hooks; } /** * The onboarding admin page. * * @param array $page_hooks The page hooks list. * * @return mixed */ public function admin_page_onboarding( $page_hooks ) { if ( ! get_site_option( 'backwpup_onboarding', false ) ) { return $page_hooks; } $this->page_hooks['backwpupbackups'] = add_submenu_page( 'backwpup', __( 'Onboarding', 'backwpup' ), __( 'Onboarding', 'backwpup' ), 'backwpup_backups', 'backwpuponboarding', [ \BackWPup_Page_Onboarding::class, 'page', ] ); return $page_hooks; } /** * Register the backups page. * * @param array $page_hooks The page hooks list. * * @return mixed */ public function admin_page_backups( $page_hooks ) { $this->page_hooks['backwpupbackups'] = add_submenu_page( 'backwpup_null', __( 'Backups', 'backwpup' ), __( 'Backups', 'backwpup' ), 'backwpup_backups', 'backwpupbackups', [ \BackWPup_Page_Backups::class, 'page', ] ); add_action( 'load-' . $this->page_hooks['backwpupbackups'], [ self::class, 'init_general' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_backup_generation' ] ); add_action( 'load-' . $this->page_hooks['backwpupbackups'], [ \BackWPup_Page_Backups::class, 'load' ] ); add_action( 'admin_print_styles-' . $this->page_hooks['backwpupbackups'], [ \BackWPup_Page_Backups::class, 'admin_print_styles', ] ); add_action( 'admin_print_scripts-' . $this->page_hooks['backwpupbackups'], [ \BackWPup_Page_Backups::class, 'admin_print_scripts', ] ); return $page_hooks; } /** * Register the settings page. * * @param array $page_hooks The page hooks list. * * @return mixed */ public function admin_page_settings( $page_hooks ) { $this->page_hooks['backwpupsettings'] = add_submenu_page( 'backwpup_null', esc_html__( 'Settings', 'backwpup' ), esc_html__( 'Settings', 'backwpup' ), 'backwpup_settings', 'backwpupsettings', [ $this->settings, 'page' ] ); add_action( 'load-' . $this->page_hooks['backwpupsettings'], [ self::class, 'init_general' ] ); add_action( 'admin_print_scripts-' . $this->page_hooks['backwpupsettings'], [ $this->settings, 'admin_print_scripts' ] ); return $page_hooks; } /** * Admin Page Restore. * * @param array $page_hooks The page hooks list. * * @return array */ public function admin_page_restore( $page_hooks ) { $this->page_hooks['backwpuprestore'] = add_submenu_page( 'backwpup', esc_html__( 'Restore backup', 'backwpup' ), esc_html__( 'Restore backup', 'backwpup' ), 'backwpup_restore', 'backwpuprestore', [ \BackWPup_Page_Restore::class, 'page', ], 1 ); // Register the submenu page (WP take care of capability) but prevent other stuffs if user doesn't have correct privileges. if ( ! current_user_can( 'backwpup_restore' ) ) { return $page_hooks; } add_action( 'load-' . $this->page_hooks['backwpuprestore'], [ self::class, 'init_general' ] ); add_action( 'load-' . $this->page_hooks['backwpuprestore'], [ \BackWPup_Page_Restore::class, 'load' ] ); add_action( 'admin_print_scripts-' . $this->page_hooks['backwpuprestore'], [ \BackWPup_Page_Restore::class, 'admin_print_scripts', ] ); return $page_hooks; } /** * Register the about page. * * @param array $page_hooks The page hooks list. * * @return mixed */ public function admin_page_about( $page_hooks ) { $this->page_hooks['backwpupabout'] = add_submenu_page( 'backwpup_null', __( 'About', 'backwpup' ), __( 'About', 'backwpup' ), 'backwpup', 'backwpupabout', [ \BackWPup_Page_About::class, 'page', ] ); add_action( 'load-' . $this->page_hooks['backwpupabout'], [ self::class, 'init_general' ] ); add_action( 'admin_print_styles-' . $this->page_hooks['backwpupabout'], [ \BackWPup_Page_About::class, 'admin_print_styles', ] ); add_action( 'admin_print_scripts-' . $this->page_hooks['backwpupabout'], [ \BackWPup_Page_About::class, 'admin_print_scripts', ] ); return $page_hooks; } /** * Called on save form. Only POST allowed. * * @throws Exception If the files job is not found. */ public function save_post_form() { // TODO delete backwpupsettings option in $allowed_pages. $allowed_pages = [ 'backwpupeditjob', 'backwpupinformation', 'backwpupsettings', 'backwpup', 'backwpupfirstbackup', ]; // Sanitize $_POST data. $post_page = isset( $_POST['page'] ) ? sanitize_text_field( wp_unslash( $_POST['page'] ) ) : null; $post_anchor = isset( $_POST['anchor'] ) ? sanitize_text_field( wp_unslash( $_POST['anchor'] ) ) : null; $post_tab = isset( $_POST['tab'] ) ? sanitize_text_field( wp_unslash( $_POST['tab'] ) ) : null; $post_nexttab = isset( $_POST['nexttab'] ) ? sanitize_text_field( wp_unslash( $_POST['nexttab'] ) ) : null; $post_archiveformat = isset( $_POST['archiveformat'] ) ? sanitize_text_field( wp_unslash( $_POST['archiveformat'] ) ) : null; if ( isset( $post_page ) && ! in_array( $post_page, $allowed_pages, true ) ) { wp_die( esc_html__( 'Cheating, huh?', 'backwpup' ) ); } // nonce check. check_admin_referer( $post_page . '_page' ); if ( ! current_user_can( 'backwpup' ) ) { wp_die( esc_html__( 'Cheating, huh?', 'backwpup' ) ); } $query_args = []; if ( isset( $post_page ) ) { $query_args['page'] = $post_page; } if ( isset( $post_tab ) ) { $query_args['tab'] = $post_tab; } if ( isset( $post_tab, $post_nexttab ) && $post_tab !== $post_nexttab ) { $query_args['tab'] = $post_nexttab; } $jobid = null; if ( isset( $_POST['jobid'] ) ) { $jobid = (int) $_POST['jobid']; $query_args['jobid'] = $jobid; } // Update the job archive only if it's set. if ( null !== $post_archiveformat ) { $archiveformat = in_array( $post_archiveformat, BackWPup_Option::get_allowed_archive_formats(), true ) ? $post_archiveformat : '.tar'; // Save archive format general value. do_action( 'backwpup_save_archiveformat', $archiveformat ); // Save the settings only if the archive is set to be sure it's not empty from the log part. do_action( 'backwpup_page_settings_save' ); } // Call method to save data. if ( 'backwpupeditjob' === $post_page ) { BackWPup_Page_Editjob::save_post_form( $post_tab, $jobid ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput } elseif ( 'backwpup' === $post_page ) { if ( isset( $_POST['onboarding'] ) && '1' === $_POST['onboarding'] ) { BackWPup_Page_Onboarding::save_post_form(); } else { $this->settings->save_post_form(); } } // Back to topic. wp_safe_redirect( add_query_arg( $query_args, network_admin_url( 'admin.php' ) ) . $post_anchor ); exit; } /** * Overrides WordPress text in Footer. * * @param string $admin_footer_text Admin footer text. * * @return string */ public function admin_footer_text( $admin_footer_text ) { $default_text = $admin_footer_text; $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); if ( ! empty( $page ) && false !== strpos( $page, 'backwpup' ) ) { $admin_footer_text = <<<'EOT' EOT; if ( ! BackWPup::is_pro() ) { $admin_footer_text .= sprintf( // translators: %s: BackWPup website URL. __( 'Get BackWPup Pro now.', 'backwpup' ), wpm_apply_filters_typed( 'string', 'backwpup_url_add_hash', 'https://backwpup.com/pricing/?utm_source=backwpup_plugin&utm_medium=plugin&utm_campaign=in_product&utm_content=upgrade_cta_plugin' ) ); } return $admin_footer_text . $default_text; } return $admin_footer_text; } /** * Overrides WordPress Version in Footer. * * @param string $update_footer_text Update footer text. * * @return string */ public function update_footer( $update_footer_text ) { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; $screen_id = ( $screen && isset( $screen->id ) ) ? (string) $screen->id : ''; if ( '' === $screen_id || false === strpos( $screen_id, 'backwpup' ) ) { return $update_footer_text; } ob_start(); do_action( 'backwpup_admin_footer_before_version' ); $before_version = ob_get_clean(); $update_footer_text = ' ' . esc_html( BackWPup::get_plugin_data( 'Name' ) ) . ' ' . sprintf( // translators: %s: BackWPup version. esc_html__( 'version %s', 'backwpup' ), esc_html( BackWPup::get_plugin_data( 'Version' ) ) ) . '
'; $update_footer_text .= sprintf( // translators: %s: WordPress version number. __( 'WordPress version %s', 'backwpup' ), get_bloginfo( 'version' ) ); return '

' . $before_version . '

' . $update_footer_text . '

'; } /** * Add filed for selecting user role in user section. * * @param WP_User $user User object. */ public function user_profile_fields( $user ) { global $wp_roles; if ( ! is_super_admin() && ! current_user_can( 'backwpup_admin' ) ) { return; } // User is admin and has BackWPup rights. if ( $user->has_cap( 'administrator' ) && $user->has_cap( 'backwpup_settings' ) ) { return; } // Get BackWPup roles. $backwpup_roles = []; foreach ( $wp_roles->roles as $role => $role_value ) { if ( 'backwpup' !== substr( (string) $role, 0, 8 ) ) { continue; } $backwpup_roles[ $role ] = $role_value; } // Only if user has other than BackWPup role. if ( ! empty( $user->roles[0] ) && in_array( $user->roles[0], array_keys( $backwpup_roles ), true ) ) { return; } ?>

roles ) as $role ) { if ( ! strstr( $role, 'backwpup_' ) ) { continue; } $backwpup_roles[] = $role; } // Get user for adding/removing role. $user = new WP_User( $user_id ); // An admin needs no extra role. if ( $user->has_cap( 'administrator' ) && $user->has_cap( 'backwpup_settings' ) ) { $backwpup_role = ''; } // Remove BackWPup role from user if it not the actual. foreach ( $user->roles as $role ) { if ( ! strstr( $role, 'backwpup_' ) ) { continue; } if ( $role !== $backwpup_role ) { $user->remove_role( $role ); } else { $backwpup_role = ''; } } // Add new role to user if it not the actual. if ( $backwpup_role && in_array( $backwpup_role, $backwpup_roles, true ) ) { $user->add_role( $backwpup_role ); } } /** * Initializes the plugin by setting up hooks, filters, and actions. * * This method ensures proper integration into the WordPress admin interface by adding menu pages, * registering scripts, handling form submissions, and updating relevant user profile fields. * It also manages various filters and actions required for the plugin to function, including * plugin links, admin-specific actions, and footer text customization. * * @return void */ public function init() { if ( ! current_user_can( 'backwpup' ) ) { return; } $restore = new Restore(); $restore->set_hooks()->init(); // Add menu pages. add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_onboarding' ], 2 ); add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_restore' ], 2 ); add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_backups' ], 3 ); add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_jobs' ], 4 ); add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_about' ], 5 ); // Hidden menu pages. add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_editjob' ], 20 ); add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_first_backup' ], 21 ); // Desactivated menu pages. add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_logs' ], 5 ); // add_filter( 'backwpup_admin_pages', [ $this, 'admin_page_settings' ], 7 );. // Add Menu. if ( is_multisite() ) { add_action( 'network_admin_menu', [ $this, 'admin_menu' ] ); } else { add_action( 'admin_menu', [ $this, 'admin_menu' ] ); } add_action( 'admin_enqueue_scripts', [ self::class, 'init_general', ] ); add_action( 'admin_enqueue_scripts', [ \BackWPup_Page_Backups::class, 'admin_print_scripts', ] ); // add Plugin links. add_filter( 'plugin_row_meta', [ $this, 'plugin_links' ], 10, 2 ); add_filter( 'plugin_action_links_backwpup/backwpup.php', [ $this, 'plugin_name_links' ], 10, 1 ); add_filter( 'plugin_action_links_backwpup-pro/backwpup.php', [ $this, 'plugin_name_links' ], 10, 1 ); // add more actions. add_action( 'admin_init', [ $this, 'admin_init' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'admin_css' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_assets' ] ); // Save Form posts general. add_action( 'admin_post_backwpup', [ $this, 'save_post_form' ] ); // Save form posts for support. add_action( 'admin_post_backwpup_support', [ \BackWPup_Pro_Page_Support::class, 'save_post_form' ] ); // Admin Footer Text replacement. add_filter( 'admin_footer_text', [ $this, 'admin_footer_text' ], 100 ); add_filter( 'update_footer', [ $this, 'update_footer' ], 100 ); // User Profile fields. add_action( 'show_user_profile', [ $this, 'user_profile_fields' ] ); add_action( 'edit_user_profile', [ $this, 'user_profile_fields' ] ); add_action( 'profile_update', [ $this, 'save_profile_update' ] ); } /** * Prevent cloning. */ private function __clone() { } /** * Retrieves the BackWPup API data. * * This function generates an array of data required for various BackWPup API endpoints, * including nonces for security and REST URLs for different actions. * * @param object|null $job_object Optional. The job object containing the logfile information. * If provided, the logfile basename will be included in the returned data. * * @return array An associative array containing the BackWPup API data. * - 'nonce_generate' (string): Nonce for BackWPup working AJAX. * - 'backupslistings' (string): REST URL for backups listings. * - 'backupspagination' (string): REST URL for backups pagination. * - 'addjob' (string): REST URL for adding a job. * - 'updatejob' (string): REST URL for updating a job. * - 'nonce' (string): Nonce for WP REST API. * - 'cloudsaveandtest' (string): REST URL for cloud save and test. * - 'storagelistcompact' (string): REST URL for storage list compact. * - 'save_database_settings' (string): REST URL for saving database settings. * - 'save_files_settings' (string): REST URL for saving files settings. * - 'startbackup' (string): REST URL for starting a backup. * - 'save_excluded_tables' (string): REST URL for saving excluded tables. * - 'backups_bulk_actions' (string): REST URL for processing bulk actions. * - 'save_file_exclusions' (string): REST URL for saving file exclusions. * - 'cloud_is_authenticated' (string): REST URL for checking cloud authentication. * - 'authenticate_cloud' (string): REST URL for authenticating cloud. * - 'delete_auth_cloud' (string): REST URL for deleting cloud authentication. * - 'getblock' (string): REST URL for getting a block. * - 'backupslistingslength' (int): Length of backups listings. * - 'logfile' (string): Optional. Basename of the logfile if $job_object is provided. * - 'delete_job' (string): REST URL for deleting a job. */ private function get_backwpup_api_data( $job_object = null ) { $data = [ 'nonce_generate' => wp_create_nonce( 'backwpupworking_ajax_nonce' ), 'backupslistings' => rest_url( 'backwpup/v1/backups' ), 'backupspagination' => rest_url( 'backwpup/v1/pagination' ), 'getjobslist' => rest_url( 'backwpup/v1/getjobslist' ), 'addjob' => rest_url( 'backwpup/v1/addjob' ), 'updatejob' => rest_url( 'backwpup/v1/updatejob' ), 'updatejobtitle' => rest_url( 'backwpup/v1/update-job-title' ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'cloudsaveandtest' => rest_url( 'backwpup/v1/cloudsaveandtest' ), 'storagelistcompact' => rest_url( 'backwpup/v1/storagelistcompact' ), 'save_job_settings' => rest_url( 'backwpup/v1/save_job_settings' ), 'save_job_format' => rest_url( 'backwpup/v2/save_job_format' ), 'startbackup' => rest_url( 'backwpup/v1/startbackup' ), 'save_excluded_tables' => rest_url( 'backwpup/v1/save_excluded_tables' ), 'backups_bulk_actions' => rest_url( 'backwpup/v1/process_bulk_actions' ), 'save_file_exclusions' => rest_url( 'backwpup/v1/save_files_exclusions' ), 'cloud_is_authenticated' => rest_url( 'backwpup/v1/cloud_is_authenticated' ), 'authenticate_cloud' => rest_url( 'backwpup/v1/authenticate_cloud' ), 'delete_auth_cloud' => rest_url( 'backwpup/v1/delete_auth_cloud' ), 'getblock' => rest_url( 'backwpup/v1/getblock' ), 'license_update' => rest_url( 'backwpup/v1/license_update' ), 'save_site_option' => rest_url( 'backwpup/v1/save_site_option' ), 'delete_job' => rest_url( 'backwpup/v1/delete_job' ), 'backupslistingslength' => 10, 'storages' => rest_url( 'backwpup/v2/storages' ), 'messages' => rest_url( 'backwpup/v2/messages' ), 'updates_backup_type' => trailingslashit( rest_url( 'backwpup/v2/backups' ) ) . '%d/type', 'nudge_nonce' => wp_create_nonce( 'backwpup_track_nudge' ), 'job_abort_status' => rest_url( 'backwpup/v1/job-abort-status' ), ]; if ( $job_object ) { $data['logfile'] = basename( (string) $job_object->logfile ); $data['job_id'] = (int) ( $job_object->job['jobid'] ?? 0 ); } return $data; } }