is_offline_mode(); // If user is not an admin and site is in Offline Mode or not connected yet then don't do anything. if ( ! current_user_can( 'manage_options' ) && ( $is_offline_mode || ! Jetpack::is_connection_ready() ) ) { return; } // Is Jetpack not connected and not offline? // True means that Jetpack is NOT connected and NOT in offline mode. // If Jetpack is connected OR in offline mode, this will be false. $connectable = ! Jetpack::is_connection_ready() && ! $is_offline_mode; // Don't add in the modules page unless modules are available! if ( $this->dont_show_if_not_active && $connectable ) { return; } // Initialize menu item for the page in the admin. $hook = $this->get_page_hook(); // Attach hooks common to all Jetpack admin pages based on the created hook. add_action( "load-$hook", array( $this, 'admin_page_load' ) ); add_action( "admin_print_styles-$hook", array( $this, 'admin_styles' ) ); add_action( "admin_print_scripts-$hook", array( $this, 'admin_scripts' ) ); add_action( "admin_print_styles-$hook", array( $this, 'additional_styles' ) ); // Check if the site plan changed and deactivate modules accordingly. add_action( 'current_screen', array( $this, 'check_plan_deactivate_modules' ) ); // Attach page specific actions in addition to the above. $this->add_page_actions( $hook ); } /** * Render the page with a common top and bottom part, and page specific content. */ public function render() { /** This action is documented in class.jetpack.php */ do_action( 'jetpack_initialize_tracking' ); // We're in an IDC: we need a decision made before we show the UI again. if ( $this->block_page_rendering_for_idc() ) { return; } // Check if we are looking at the main dashboard. if ( isset( $_GET['page'] ) && 'jetpack' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- View logic. $this->page_render(); return; } $args = array(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['page'] ) && 'jetpack_modules' === $_GET['page'] ) { $args['is-wide'] = true; } self::wrap_ui( array( $this, 'page_render' ), $args ); } /** * Call the existing admin page events. */ public function admin_page_load() { Jetpack::init()->admin_page_load(); } /** * Add page specific scripts and jetpack stats for all menu pages. */ public function admin_scripts() { $this->page_admin_scripts(); // Delegate to inheriting class. add_action( 'admin_footer', array( Jetpack::init(), 'do_stats' ) ); } /** * Enqueue the Jetpack admin stylesheet. */ public function admin_styles() { $min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; wp_enqueue_style( 'jetpack-admin', plugins_url( "css/jetpack-admin{$min}.css", JETPACK__PLUGIN_FILE ), array( 'genericons', 'jetpack-connection' ), JETPACK__VERSION . '-20121016' ); wp_style_add_data( 'jetpack-admin', 'rtl', 'replace' ); wp_style_add_data( 'jetpack-admin', 'suffix', $min ); } /** * Checks if REST API is enabled. * * @since 4.4.2 * * @return bool */ public function is_rest_api_enabled() { return /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */ apply_filters( 'rest_enabled', true ) && /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */ apply_filters( 'rest_authentication_errors', true ); } /** * Checks the site plan and deactivates modules that were active but are no longer included in the plan. * * @since 4.4.0 * * @param WP_Screen $page Current WP_Screen object. * * @return array */ public function check_plan_deactivate_modules( $page ) { if ( ( new Status() )->is_offline_mode() || ! in_array( $page->base, array( 'toplevel_page_jetpack', 'admin_page_jetpack_modules', 'jetpack_page_vaultpress', 'jetpack_page_stats', 'jetpack_page_akismet-key-config', ), true ) ) { return false; } $current = Jetpack_Plan::get(); $to_deactivate = array(); if ( isset( $current['product_slug'] ) ) { $active = Jetpack::get_active_modules(); switch ( $current['product_slug'] ) { case 'jetpack_free': case 'jetpack_personal': case 'jetpack_personal_monthly': $to_deactivate = array( 'google-analytics', 'wordads', 'search' ); break; case 'jetpack_premium': case 'jetpack_premium_monthly': $to_deactivate = array( 'google-analytics', 'search' ); break; } $to_deactivate = array_intersect( $active, $to_deactivate ); $to_leave_enabled = array(); foreach ( $to_deactivate as $feature ) { if ( Jetpack_Plan::supports( $feature ) ) { $to_leave_enabled [] = $feature; } } $to_deactivate = array_diff( $to_deactivate, $to_leave_enabled ); if ( ! empty( $to_deactivate ) ) { Jetpack::update_active_modules( array_filter( array_diff( $active, $to_deactivate ) ) ); } } return array( 'current' => $current, 'deactivate' => $to_deactivate, ); } /** * Enqueue inline wrapper styles for the main container. */ public static function load_wrapper_styles() { $rtl = is_rtl() ? '.rtl' : ''; wp_enqueue_style( 'dops-css', plugins_url( "_inc/build/admin{$rtl}.css", JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION ); wp_enqueue_style( 'components-css', plugins_url( "_inc/build/style.min{$rtl}.css", JETPACK__PLUGIN_FILE ), array( 'wp-components' ), JETPACK__VERSION ); } /** * Build header, content, and footer for admin page. * * @param callable $callback Callback to produce the content of the page. The callback is responsible for any needed escaping. * @param array $args Options for the wrapping. Also passed to the `jetpack_admin_pages_wrap_ui_after_callback` action. * - is-wide: (bool) Set the "is-wide" class on the wrapper div, which increases the max width. Default false. * - show-nav: (bool) Whether to show the navigation bar at the top of the page. Default true. */ public static function wrap_ui( $callback, $args = array() ) { $defaults = array( 'is-wide' => false, 'show-nav' => true, ); $args = wp_parse_args( $args, $defaults ); // Is Jetpack not connected and not offline? // True means that Jetpack is NOT connected and NOT in offline mode. // If Jetpack is connected OR in offline mode, this will be false. $connectable = ! Jetpack::is_connection_ready() && ! ( new Status() )->is_offline_mode(); $jetpack_admin_url = admin_url( 'admin.php?page=jetpack' ); $jetpack_about_url = ! $connectable ? admin_url( 'admin.php?page=jetpack_about' ) : Redirect::get_url( 'jetpack' ); $jetpack_privacy_url = ! $connectable ? $jetpack_admin_url . '#/privacy' : Redirect::get_url( 'a8c-privacy' ); $external_link_icon = ''; ?>