From 0914c92da22824025992c368c745546e41fbeb84 Mon Sep 17 00:00:00 2001 From: Yury German Date: Wed, 22 May 2019 01:01:36 -0400 Subject: Adding Plugins Updating the following akismet.4.1.2, google-authenticator.0.52, jetpack.7.3.1 Signed-off-by: Yury German --- .../lib/admin-pages/class-jetpack-about-page.php | 679 +++++++++++++++++++++ .../lib/admin-pages/class.jetpack-admin-page.php | 353 +++++++++++ .../lib/admin-pages/class.jetpack-landing-page.php | 3 + .../lib/admin-pages/class.jetpack-react-page.php | 399 ++++++++++++ .../admin-pages/class.jetpack-settings-page.php | 141 +++++ 5 files changed, 1575 insertions(+) create mode 100644 plugins/jetpack/_inc/lib/admin-pages/class-jetpack-about-page.php create mode 100644 plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php create mode 100644 plugins/jetpack/_inc/lib/admin-pages/class.jetpack-landing-page.php create mode 100644 plugins/jetpack/_inc/lib/admin-pages/class.jetpack-react-page.php create mode 100644 plugins/jetpack/_inc/lib/admin-pages/class.jetpack-settings-page.php (limited to 'plugins/jetpack/_inc/lib/admin-pages') diff --git a/plugins/jetpack/_inc/lib/admin-pages/class-jetpack-about-page.php b/plugins/jetpack/_inc/lib/admin-pages/class-jetpack-about-page.php new file mode 100644 index 00000000..b9987a0f --- /dev/null +++ b/plugins/jetpack/_inc/lib/admin-pages/class-jetpack-about-page.php @@ -0,0 +1,679 @@ + false ) ); + } + + /** + * Change order of menu item so the About page menu item is below Site Stats. + * + * @param array $menu_order List of menu slugs. It's unaffected. This filter is used to reorder the Jetpack submenu items. + * + * @return array + */ + public function submenu_order( $menu_order ) { + global $submenu; + + $stats_key = null; + $about_key = null; + + foreach ( $submenu['jetpack'] as $index => $menu_item ) { + if ( false !== array_search( 'stats', $menu_item, true ) ) { + $stats_key = $index; + } + if ( false !== array_search( 'jetpack_about', $menu_item, true ) ) { + $about_key = $index; + } + } + + if ( $stats_key && $about_key ) { + $temp = $submenu['jetpack'][ $stats_key ]; + $submenu['jetpack'][ $stats_key ] = $submenu['jetpack'][ $about_key ]; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + $submenu['jetpack'][ $about_key ] = $temp; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + } + + return $menu_order; + } + + /** + * Render the page content + */ + public function page_render() { + ?> + + array( + 'href' => array(), + 'title' => array(), + 'target' => array(), + ), + 'abbr' => array( 'title' => array() ), + 'acronym' => array( 'title' => array() ), + 'code' => array(), + 'pre' => array(), + 'em' => array(), + 'strong' => array(), + 'ul' => array(), + 'ol' => array(), + 'li' => array(), + 'p' => array(), + 'br' => array(), + ); + + // slugs for plugins we want to display. + $a8c_plugins = array( + 'woocommerce', + 'wp-super-cache', + 'wp-job-manager', + 'co-authors-plus', + ); + + // need this to access the plugins_api() function. + include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + + $plugins = array(); + foreach ( $a8c_plugins as $slug ) { + $args = array( + 'slug' => $slug, + 'fields' => array( + 'added' => false, + 'author' => false, + 'author_profile' => false, + 'banners' => false, + 'contributors' => false, + 'donate_link' => false, + 'homepage' => false, + 'reviews' => false, + 'screenshots' => false, + 'support_threads' => false, + 'support_threads_resolved' => false, + 'sections' => false, + 'tags' => false, + 'versions' => false, + + 'compatibility' => true, + 'downloaded' => true, + 'downloadlink' => true, + 'icons' => true, + 'last_updated' => true, + 'num_ratings' => true, + 'rating' => true, + 'requires' => true, + 'requires_php' => true, + 'short_description' => true, + 'tested' => true, + ), + ); + + // should probably add some error checking here too. + $api = plugins_api( 'plugin_information', $args ); + $plugins[] = $api; + } + + foreach ( $plugins as $plugin ) { + if ( is_object( $plugin ) ) { + $plugin = (array) $plugin; + } + + $title = wp_kses( $plugin['name'], $plugins_allowedtags ); + $version = wp_kses( $plugin['version'], $plugins_allowedtags ); + + $name = wp_strip_all_tags( $title . ' ' . $version ); + + // Remove any HTML from the description. + $description = wp_strip_all_tags( $plugin['short_description'] ); + + $wp_version = get_bloginfo( 'version' ); + + $compatible_php = ( empty( $plugin['requires_php'] ) || version_compare( phpversion(), $plugin['requires_php'], '>=' ) ); + $compatible_wp = ( empty( $plugin['requires'] ) || version_compare( $wp_version, $plugin['requires'], '>=' ) ); + + $action_links = array(); + + // install button. + if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) { + $status = install_plugin_install_status( $plugin ); + switch ( $status['status'] ) { + case 'install': + if ( $status['url'] ) { + if ( $compatible_php && $compatible_wp ) { + $action_links[] = sprintf( + '%5$s', + esc_attr( $plugin['slug'] ), + esc_url( $status['url'] ), + /* translators: %s: plugin name and version */ + esc_attr( sprintf( __( 'Install %s now', 'jetpack' ), $name ) ), + esc_attr( $name ), + esc_html__( 'Install Now', 'jetpack' ) + ); + } else { + $action_links[] = sprintf( + '', + _x( 'Cannot Install', 'plugin', 'jetpack' ) + ); + } + } + break; + + case 'update_available': + if ( $status['url'] ) { + $action_links[] = sprintf( + '%6$s', + esc_attr( $status['file'] ), + esc_attr( $plugin['slug'] ), + esc_url( $status['url'] ), + /* translators: %s: plugin name and version */ + esc_attr( sprintf( __( 'Update %s now', 'jetpack' ), $name ) ), + esc_attr( $name ), + __( 'Update Now', 'jetpack' ) + ); + } + break; + + case 'latest_installed': + case 'newer_installed': + if ( is_plugin_active( $status['file'] ) ) { + $action_links[] = sprintf( + '', + _x( 'Active', 'plugin', 'jetpack' ) + ); + } elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) { + $button_text = __( 'Activate', 'jetpack' ); + /* translators: %s: plugin name */ + $button_label = _x( 'Activate %s', 'plugin', 'jetpack' ); + $activate_url = add_query_arg( + array( + '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $status['file'] ), + 'action' => 'activate', + 'plugin' => $status['file'], + ), + network_admin_url( 'plugins.php' ) + ); + + if ( is_network_admin() ) { + $button_text = __( 'Network Activate', 'jetpack' ); + /* translators: %s: plugin name */ + $button_label = _x( 'Network Activate %s', 'plugin', 'jetpack' ); + $activate_url = add_query_arg( array( 'networkwide' => 1 ), $activate_url ); + } + + $action_links[] = sprintf( + '%4$s', + esc_url( $activate_url ), + esc_attr( sprintf( $button_label, $plugin['name'] ) ), + esc_attr( $plugin['name'] ), + $button_text + ); + } else { + $action_links[] = sprintf( + '', + _x( 'Installed', 'plugin', 'jetpack' ) + ); + } + break; + } + } + + $plugin_install = "plugin-install.php?tab=plugin-information&plugin={$plugin['slug']}&TB_iframe=true&width=600&height=550"; + $details_link = is_multisite() + ? network_admin_url( $plugin_install ) + : admin_url( $plugin_install ); + + if ( ! empty( $plugin['icons']['svg'] ) ) { + $plugin_icon_url = $plugin['icons']['svg']; + } elseif ( ! empty( $plugin['icons']['2x'] ) ) { + $plugin_icon_url = $plugin['icons']['2x']; + } elseif ( ! empty( $plugin['icons']['1x'] ) ) { + $plugin_icon_url = $plugin['icons']['1x']; + } else { + $plugin_icon_url = $plugin['icons']['default']; + } + ?> + +
  • +

    '; + if ( ! $compatible_php && ! $compatible_wp ) { + esc_html_e( 'This plugin doesn’t work with your versions of WordPress and PHP.', 'jetpack' ); + if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { + printf( + /* translators: 1: "Update WordPress" screen URL, 2: "Update PHP" page URL */ + ' ' . wp_kses( __( 'Please update WordPress, and then learn more about updating PHP.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ), + esc_url( self_admin_url( 'update-core.php' ) ), + esc_url( $this->jp_get_update_php_url() ) + ); + $this->jp_update_php_annotation(); + } elseif ( current_user_can( 'update_core' ) ) { + printf( + /* translators: %s: "Update WordPress" screen URL */ + ' ' . wp_kses( __( 'Please update WordPress.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ), + esc_url( self_admin_url( 'update-core.php' ) ) + ); + } elseif ( current_user_can( 'update_php' ) ) { + printf( + /* translators: %s: "Update PHP" page URL */ + ' ' . wp_kses( __( 'Learn more about updating PHP.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ), + esc_url( $this->jp_get_update_php_url() ) + ); + $this->jp_update_php_annotation(); + } + } elseif ( ! $compatible_wp ) { + esc_html_e( 'This plugin doesn’t work with your version of WordPress.', 'jetpack' ); + if ( current_user_can( 'update_core' ) ) { + printf( + /* translators: %s: "Update WordPress" screen URL */ + ' ' . wp_kses( __( 'Please update WordPress.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ), + esc_url( self_admin_url( 'update-core.php' ) ) + ); + } + } elseif ( ! $compatible_php ) { + esc_html_e( 'This plugin doesn’t work with your version of PHP.', 'jetpack' ); + if ( current_user_can( 'update_php' ) ) { + printf( + /* translators: %s: "Update PHP" page URL */ + ' ' . wp_kses( __( 'Learn more about updating PHP.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ), + esc_url( $this->jp_get_update_php_url() ) + ); + $this->jp_update_php_annotation(); + } + } + echo '

    '; + } + ?> + +
    +
    +

    + + + + +

    +
    +
    +

    +
    + + +
    + +
    +
    + $plugin['rating'], + 'type' => 'percent', + 'number' => $plugin['num_ratings'], + ) + ); + ?> + +
    + = 1000000 ) { + $active_installs_millions = floor( $plugin['active_installs'] / 1000000 ); + $active_installs_text = sprintf( + /* translators: number of millions of installs. */ + _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations', 'jetpack' ), + number_format_i18n( $active_installs_millions ) + ); + } elseif ( 0 === $plugin['active_installs'] ) { + $active_installs_text = _x( 'Less Than 10', 'Active plugin installations', 'jetpack' ); + } else { + $active_installs_text = number_format_i18n( $plugin['active_installs'] ) . '+'; + } + /* translators: number of active installs */ + printf( esc_html__( '%s Active Installations', 'jetpack' ), esc_html( $active_installs_text ) ); + ?> +
    +
    + +
  • ' . implode( '
  • ', $action_links ) . '
  • '; + } + ?> + + + + ' . "\n"; + } + echo wp_kses( + $output, + array( + 'li' => true, + 'img' => array( + 'src' => true, + ), + ) + ); + } + + // The following methods jp_get_update_php_url, jp_get_default_update_php_url, and jp_update_php_annotation, + // are copies of functions introduced in WP 5.1 + // At the time of releasing this, we're still supporting WP 5.0, so we needed + // to have them here to avoid fatal errors in old installations. + + /** + * Gets the URL to learn more about updating the PHP version the site is running on. + * + * This URL can be overridden by specifying an environment variable `WP_UPDATE_PHP_URL` or by using the + * {@see 'wp_update_php_url'} filter. Providing an empty string is not allowed and will result in the + * default URL being used. Furthermore the page the URL links to should preferably be localized in the + * site language. + * + * @todo: Remove when 5.1 is minimum WP version. + * @since 5.1.0 + * + * @return string URL to learn more about updating PHP. + */ + private function jp_get_update_php_url() { + $default_url = $this->jp_get_default_update_php_url(); + + $update_url = $default_url; + if ( false !== getenv( 'WP_UPDATE_PHP_URL' ) ) { + $update_url = getenv( 'WP_UPDATE_PHP_URL' ); + } + + /** + * Filters the URL to learn more about updating the PHP version the site is running on. + * + * Providing an empty string is not allowed and will result in the default URL being used. Furthermore + * the page the URL links to should preferably be localized in the site language. + * + * @since 5.1.0 + * + * @param string $update_url URL to learn more about updating PHP. + */ + $update_url = apply_filters( 'wp_update_php_url', $update_url ); + + if ( empty( $update_url ) ) { + $update_url = $default_url; + } + + return $update_url; + } + + /** + * Gets the default URL to learn more about updating the PHP version the site is running on. + * + * Do not use this function to retrieve this URL. Instead, use {@see wp_get_update_php_url()} when relying on the URL. + * This function does not allow modifying the returned URL, and is only used to compare the actually used URL with the + * default one. + * + * @todo: Remove when 5.1 is minimum WP version. + * @since 5.1.0 + * @access private + * + * @return string Default URL to learn more about updating PHP. + */ + private function jp_get_default_update_php_url() { + return _x( 'https://wordpress.org/support/update-php/', 'localized PHP upgrade information page', 'jetpack' ); + } + + /** + * Prints the default annotation for the web host altering the "Update PHP" page URL. + * + * This function is to be used after {@see wp_get_update_php_url()} to display a consistent + * annotation if the web host has altered the default "Update PHP" page URL. + * + * @todo: Remove when 5.1 is minimum WP version. + * @since 5.1.0 + */ + private function jp_update_php_annotation() { + $update_url = $this->jp_get_update_php_url(); + $default_url = $this->jp_get_default_update_php_url(); + + if ( $update_url === $default_url ) { + return; + } + + echo '

    '; + printf( + wp_kses( + /* translators: %s: default Update PHP page URL */ + __( 'This resource is provided by your web host, and is specific to your site. For more information, see the official WordPress documentation.', 'jetpack' ), + array( + 'a' => array( + 'href' => true, + 'rel' => true, + ), + ) + ), + esc_url( $default_url ) + ); + echo '

    '; + } + +} diff --git a/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php new file mode 100644 index 00000000..a6822678 --- /dev/null +++ b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php @@ -0,0 +1,353 @@ +jetpack = Jetpack::init(); + self::$block_page_rendering_for_idc = ( + Jetpack::validate_sync_error_idc_option() && ! Jetpack_Options::get_option( 'safe_mode_confirmed' ) + ); + } + + function add_actions() { + global $pagenow; + + // If user is not an admin and site is in Dev Mode, don't do anything + if ( ! current_user_can( 'manage_options' ) && Jetpack::is_development_mode() ) { + return; + } + + // Don't add in the modules page unless modules are available! + if ( $this->dont_show_if_not_active && ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) { + 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_help' ) ); + 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' ) ); + + if ( ! self::$block_page_rendering_for_idc ) { + add_action( "admin_print_styles-$hook", array( $this, 'additional_styles' ) ); + } + // If someone just activated Jetpack, let's show them a fullscreen connection banner. + if ( + ( 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'jetpack' === $_GET['page'] ) + && ! Jetpack::is_active() + && current_user_can( 'jetpack_connect' ) + && ! Jetpack::is_development_mode() + ) { + add_action( 'admin_enqueue_scripts', array( 'Jetpack_Connection_Banner', 'enqueue_banner_scripts' ) ); + add_action( 'admin_print_styles', array( Jetpack::init(), 'admin_banner_styles' ) ); + add_action( 'admin_notices', array( 'Jetpack_Connection_Banner', 'render_connect_prompt_full_screen' ) ); + delete_transient( 'activated_jetpack' ); + } + + // 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 + function render() { + // We're in an IDC: we need a decision made before we show the UI again. + if ( self::$block_page_rendering_for_idc ) { + return; + } + + // Check if we are looking at the main dashboard + if ( isset( $_GET['page'] ) && 'jetpack' === $_GET['page'] ) { + $this->page_render(); + return; + } + self::wrap_ui( array( $this, 'page_render' ) ); + } + + function admin_help() { + $this->jetpack->admin_help(); + } + + function admin_page_load() { + // This is big. For the moment, just call the existing one. + $this->jetpack->admin_page_load(); + } + + // Add page specific scripts and jetpack stats for all menu pages + function admin_scripts() { + $this->page_admin_scripts(); // Delegate to inheriting class + add_action( 'admin_footer', array( $this->jetpack, 'do_stats' ) ); + } + + // Enqueue the Jetpack admin stylesheet + 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__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 + */ + 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_jsonp_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 $page + * + * @return array + */ + function check_plan_deactivate_modules( $page ) { + if ( + Jetpack::is_development_mode() + || ! in_array( + $page->base, + array( + 'toplevel_page_jetpack', + 'admin_page_jetpack_modules', + 'jetpack_page_vaultpress', + 'jetpack_page_stats', + 'jetpack_page_akismet-key-config', + ) + ) + ) { + 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': + $to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics', 'wordads', 'search' ); + break; + case 'jetpack_personal': + case 'jetpack_personal_monthly': + $to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics', 'wordads', 'search' ); + break; + case 'jetpack_premium': + case 'jetpack_premium_monthly': + $to_deactivate = array( 'seo-tools', '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, + ); + } + + static function load_wrapper_styles() { + $rtl = is_rtl() ? '.rtl' : ''; + wp_enqueue_style( 'dops-css', plugins_url( "_inc/build/admin.dops-style{$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(), JETPACK__VERSION ); + $custom_css = ' + #wpcontent { + padding-left: 0 !important; + } + #wpbody-content { + background-color: #f6f6f6; + } + + #jp-plugin-container .wrap { + margin: 0 auto; + max-width:45rem; + padding: 0 1.5rem; + } + #jp-plugin-container.is-wide .wrap { + max-width: 1040px; + } + #jp-plugin-container .wrap .jetpack-wrap-container { + margin-top: 1em; + } + .wp-admin #dolly { + float: none; + position: relative; + right: 0; + left: 0; + top: 0; + padding: .625rem; + text-align: right; + background: #fff; + font-size: .75rem; + font-style: italic; + color: #87a6bc; + border-bottom: 1px #e9eff3 solid; + } + '; + wp_add_inline_style( 'dops-css', $custom_css ); + } + + public static function wrap_ui( $callback, $args = array() ) { + $defaults = array( + 'is-wide' => false, + 'show-nav' => true, + ); + $args = wp_parse_args( $args, $defaults ); + $jetpack_admin_url = admin_url( 'admin.php?page=jetpack' ); + + ?> +
    + + +
    + + + + +
    + is_rest_api_enabled() ) { + $this->is_redirecting = true; + add_action( 'admin_head', array( $this, 'add_fallback_head_meta' ) ); + } + + // Adding a redirect meta tag wrapped in noscript tags for all browsers in case they have JavaScript disabled + add_action( 'admin_head', array( $this, 'add_noscript_head_meta' ) ); + + // If this is the first time the user is viewing the admin, don't show JITMs. + // This filter is added just in time because this function is called on admin_menu + // and JITMs are initialized on admin_init + if ( Jetpack::is_active() && ! Jetpack_Options::get_option( 'first_admin_view', false ) ) { + Jetpack_Options::update_option( 'first_admin_view', true ); + add_filter( 'jetpack_just_in_time_msgs', '__return_false' ); + } + } + + /** + * Add Jetpack Dashboard sub-link and point it to AAG if the user can view stats, manage modules or if Protect is active. + * + * Works in Dev Mode or when user is connected. + * + * @since 4.3.0 + */ + function jetpack_add_dashboard_sub_nav_item() { + if ( Jetpack::is_development_mode() || Jetpack::is_active() ) { + global $submenu; + if ( current_user_can( 'jetpack_admin_page' ) ) { + $submenu['jetpack'][] = array( __( 'Dashboard', 'jetpack' ), 'jetpack_admin_page', 'admin.php?page=jetpack#/dashboard' ); + } + } + } + + /** + * If user is allowed to see the Jetpack Admin, add Settings sub-link. + * + * @since 4.3.0 + */ + function jetpack_add_settings_sub_nav_item() { + if ( ( Jetpack::is_development_mode() || Jetpack::is_active() ) && current_user_can( 'jetpack_admin_page' ) && current_user_can( 'edit_posts' ) ) { + global $submenu; + $submenu['jetpack'][] = array( __( 'Settings', 'jetpack' ), 'jetpack_admin_page', 'admin.php?page=jetpack#/settings' ); + } + } + + function add_fallback_head_meta() { + echo ''; + } + + function add_noscript_head_meta() { + echo ''; + } + + function jetpack_menu_order( $menu_order ) { + $jp_menu_order = array(); + + foreach ( $menu_order as $index => $item ) { + if ( $item != 'jetpack' ) + $jp_menu_order[] = $item; + + if ( $index == 0 ) + $jp_menu_order[] = 'jetpack'; + } + + return $jp_menu_order; + } + + function page_render() { + /** This action is already documented in views/admin/admin-page.php */ + do_action( 'jetpack_notices' ); + + // Try fetching by patch + $static_html = @file_get_contents( JETPACK__PLUGIN_DIR . '_inc/build/static.html' ); + + if ( false === $static_html ) { + + // If we still have nothing, display an error + echo '

    '; + esc_html_e( 'Error fetching static.html. Try running: ', 'jetpack' ); + echo 'yarn distclean && yarn build'; + echo '

    '; + } else { + + // We got the static.html so let's display it + echo $static_html; + } + } + + /** + * Gets array of any Jetpack notices that have been dismissed. + * + * @since 4.0.1 + * @return mixed|void + */ + function get_dismissed_jetpack_notices() { + $jetpack_dismissed_notices = get_option( 'jetpack_dismissed_notices', array() ); + /** + * Array of notices that have been dismissed. + * + * @since 4.0.1 + * + * @param array $jetpack_dismissed_notices If empty, will not show any Jetpack notices. + */ + $dismissed_notices = apply_filters( 'jetpack_dismissed_notices', $jetpack_dismissed_notices ); + return $dismissed_notices; + } + + function additional_styles() { + Jetpack_Admin_Page::load_wrapper_styles(); + } + + function page_admin_scripts() { + if ( $this->is_redirecting ) { + return; // No need for scripts on a fallback page + } + + $script_deps_path = JETPACK__PLUGIN_DIR . '_inc/build/admin.deps.json'; + $script_dependencies = file_exists( $script_deps_path ) + ? json_decode( file_get_contents( $script_deps_path ) ) + : array(); + $script_dependencies[] = 'wp-polyfill'; + + wp_enqueue_script( + 'react-plugin', + plugins_url( '_inc/build/admin.js', JETPACK__PLUGIN_FILE ), + $script_dependencies, + JETPACK__VERSION, + true + ); + + if ( ! Jetpack::is_development_mode() && Jetpack::is_active() ) { + // Required for Analytics. + wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), gmdate( 'YW' ), true ); + } + + // Add objects to be passed to the initial state of the app. + wp_localize_script( 'react-plugin', 'Initial_State', $this->get_initial_state() ); + } + + function get_initial_state() { + // Load API endpoint base classes and endpoints for getting the module list fed into the JS Admin Page + require_once JETPACK__PLUGIN_DIR . '_inc/lib/core-api/class.jetpack-core-api-xmlrpc-consumer-endpoint.php'; + require_once JETPACK__PLUGIN_DIR . '_inc/lib/core-api/class.jetpack-core-api-module-endpoints.php'; + $moduleListEndpoint = new Jetpack_Core_API_Module_List_Endpoint(); + $modules = $moduleListEndpoint->get_modules(); + + // Preparing translated fields for JSON encoding by transforming all HTML entities to + // respective characters. + foreach( $modules as $slug => $data ) { + $modules[ $slug ]['name'] = html_entity_decode( $data['name'] ); + $modules[ $slug ]['description'] = html_entity_decode( $data['description'] ); + $modules[ $slug ]['short_description'] = html_entity_decode( $data['short_description'] ); + $modules[ $slug ]['long_description'] = html_entity_decode( $data['long_description'] ); + } + + // Collecting roles that can view site stats. + $stats_roles = array(); + $enabled_roles = function_exists( 'stats_get_option' ) ? stats_get_option( 'roles' ) : array( 'administrator' ); + + if ( ! function_exists( 'get_editable_roles' ) ) { + require_once ABSPATH . 'wp-admin/includes/user.php'; + } + foreach ( get_editable_roles() as $slug => $role ) { + $stats_roles[ $slug ] = array( + 'name' => translate_user_role( $role['name'] ), + 'canView' => is_array( $enabled_roles ) ? in_array( $slug, $enabled_roles, true ) : false, + ); + } + + // Get information about current theme. + $current_theme = wp_get_theme(); + + // Get all themes that Infinite Scroll provides support for natively. + $inf_scr_support_themes = array(); + foreach ( Jetpack::glob_php( JETPACK__PLUGIN_DIR . 'modules/infinite-scroll/themes' ) as $path ) { + if ( is_readable( $path ) ) { + $inf_scr_support_themes[] = basename( $path, '.php' ); + } + } + + // Get last post, to build the link to Customizer in the Related Posts module. + $last_post = get_posts( array( 'posts_per_page' => 1 ) ); + $last_post = isset( $last_post[0] ) && $last_post[0] instanceof WP_Post + ? get_permalink( $last_post[0]->ID ) + : get_home_url(); + + // Ensure that class to get the affiliate code is loaded + if ( ! class_exists( 'Jetpack_Affiliate' ) ) { + require_once JETPACK__PLUGIN_DIR . 'class.jetpack-affiliate.php'; + } + + return array( + 'WP_API_root' => esc_url_raw( rest_url() ), + 'WP_API_nonce' => wp_create_nonce( 'wp_rest' ), + 'pluginBaseUrl' => plugins_url( '', JETPACK__PLUGIN_FILE ), + 'connectionStatus' => array( + 'isActive' => Jetpack::is_active(), + 'isStaging' => Jetpack::is_staging_site(), + 'devMode' => array( + 'isActive' => Jetpack::is_development_mode(), + 'constant' => defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG, + 'url' => site_url() && false === strpos( site_url(), '.' ), + 'filter' => apply_filters( 'jetpack_development_mode', false ), + ), + 'isPublic' => '1' == get_option( 'blog_public' ), + 'isInIdentityCrisis' => Jetpack::validate_sync_error_idc_option(), + 'sandboxDomain' => JETPACK__SANDBOX_DOMAIN, + ), + 'connectUrl' => Jetpack::init()->build_connect_url( true, false, false ), + 'dismissedNotices' => $this->get_dismissed_jetpack_notices(), + 'isDevVersion' => Jetpack::is_development_version(), + 'currentVersion' => JETPACK__VERSION, + 'is_gutenberg_available' => true, + 'getModules' => $modules, + 'showJumpstart' => jetpack_show_jumpstart(), + 'rawUrl' => Jetpack::build_raw_urls( get_home_url() ), + 'adminUrl' => esc_url( admin_url() ), + 'stats' => array( + // data is populated asynchronously on page load + 'data' => array( + 'general' => false, + 'day' => false, + 'week' => false, + 'month' => false, + ), + 'roles' => $stats_roles, + ), + 'aff' => Jetpack_Affiliate::init()->get_affiliate_code(), + 'settings' => $this->get_flattened_settings( $modules ), + 'userData' => array( +// 'othersLinked' => Jetpack::get_other_linked_admins(), + 'currentUser' => jetpack_current_user_data(), + ), + 'siteData' => array( + 'icon' => has_site_icon() + ? apply_filters( 'jetpack_photon_url', get_site_icon_url(), array( 'w' => 64 ) ) + : '', + 'siteVisibleToSearchEngines' => '1' == get_option( 'blog_public' ), + /** + * Whether promotions are visible or not. + * + * @since 4.8.0 + * + * @param bool $are_promotions_active Status of promotions visibility. True by default. + */ + 'showPromotions' => apply_filters( 'jetpack_show_promotions', true ), + 'isAtomicSite' => jetpack_is_atomic_site(), + 'plan' => Jetpack_Plan::get(), + 'showBackups' => Jetpack::show_backups_ui(), + ), + 'themeData' => array( + 'name' => $current_theme->get( 'Name' ), + 'hasUpdate' => (bool) get_theme_update_available( $current_theme ), + 'support' => array( + 'infinite-scroll' => current_theme_supports( 'infinite-scroll' ) || in_array( $current_theme->get_stylesheet(), $inf_scr_support_themes ), + ), + ), + 'locale' => Jetpack::get_i18n_data_json(), + 'localeSlug' => join( '-', explode( '_', get_user_locale() ) ), + 'jetpackStateNotices' => array( + 'messageCode' => Jetpack::state( 'message' ), + 'errorCode' => Jetpack::state( 'error' ), + 'errorDescription' => Jetpack::state( 'error_description' ), + ), + 'tracksUserData' => Jetpack_Tracks_Client::get_connected_user_tracks_identity(), + 'currentIp' => function_exists( 'jetpack_protect_get_ip' ) ? jetpack_protect_get_ip() : false, + 'lastPostUrl' => esc_url( $last_post ), + 'externalServicesConnectUrls' => $this->get_external_services_connect_urls() + ); + } + + function get_external_services_connect_urls() { + $connect_urls = array(); + jetpack_require_lib( 'class.jetpack-keyring-service-helper' ); + foreach ( Jetpack_Keyring_Service_Helper::$SERVICES as $service_name => $service_info ) { + $connect_urls[ $service_name ] = Jetpack_Keyring_Service_Helper::connect_url( $service_name, $service_info[ 'for' ] ); + } + return $connect_urls; + } + + /** + * Returns an array of modules and settings both as first class members of the object. + * + * @param array $modules the result of an API request to get all modules. + * + * @return array flattened settings with modules. + */ + function get_flattened_settings( $modules ) { + $core_api_endpoint = new Jetpack_Core_API_Data(); + $settings = $core_api_endpoint->get_all_options(); + return $settings->data; + } +} + +/* + * Only show Jump Start on first activation. + * Any option 'jumpstart' other than 'new connection' will hide it. + * + * The option can be of 4 things, and will be stored as such: + * new_connection : Brand new connection - Show + * jumpstart_activated : Jump Start has been activated - dismiss + * jumpstart_dismissed : Manual dismissal of Jump Start - dismiss + * jetpack_action_taken: Deprecated since 7.3 But still listed here to respect behaviour for old versions. + * Manual activation of a module already happened - dismiss. + * + * @todo move to functions.global.php when available + * @since 3.6 + * @return bool | show or hide + */ +function jetpack_show_jumpstart() { + if ( ! Jetpack::is_active() ) { + return false; + } + $jumpstart_option = Jetpack_Options::get_option( 'jumpstart' ); + + $hide_options = array( + 'jumpstart_activated', + 'jetpack_action_taken', + 'jumpstart_dismissed' + ); + + if ( ! $jumpstart_option || in_array( $jumpstart_option, $hide_options ) ) { + return false; + } + + return true; +} + +/** + * Gather data about the current user. + * + * @since 4.1.0 + * + * @return array + */ +function jetpack_current_user_data() { + $current_user = wp_get_current_user(); + $is_master_user = $current_user->ID == Jetpack_Options::get_option( 'master_user' ); + $dotcom_data = Jetpack::get_connected_user_data(); + // Add connected user gravatar to the returned dotcom_data. + $dotcom_data['avatar'] = get_avatar_url( $dotcom_data['email'], array( 'size' => 64, 'default' => 'mysteryman' ) ); + + $current_user_data = array( + 'isConnected' => Jetpack::is_user_connected( $current_user->ID ), + 'isMaster' => $is_master_user, + 'username' => $current_user->user_login, + 'id' => $current_user->ID, + 'wpcomUser' => $dotcom_data, + 'gravatar' => get_avatar( $current_user->ID, 40, 'mm', '', array( 'force_display' => true ) ), + 'permissions' => array( + 'admin_page' => current_user_can( 'jetpack_admin_page' ), + 'connect' => current_user_can( 'jetpack_connect' ), + 'disconnect' => current_user_can( 'jetpack_disconnect' ), + 'manage_modules' => current_user_can( 'jetpack_manage_modules' ), + 'network_admin' => current_user_can( 'jetpack_network_admin_page' ), + 'network_sites_page' => current_user_can( 'jetpack_network_sites_page' ), + 'edit_posts' => current_user_can( 'edit_posts' ), + 'publish_posts' => current_user_can( 'publish_posts' ), + 'manage_options' => current_user_can( 'manage_options' ), + 'view_stats' => current_user_can( 'view_stats' ), + 'manage_plugins' => current_user_can( 'install_plugins' ) + && current_user_can( 'activate_plugins' ) + && current_user_can( 'update_plugins' ) + && current_user_can( 'delete_plugins' ), + ), + ); + + return $current_user_data; +} diff --git a/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-settings-page.php b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-settings-page.php new file mode 100644 index 00000000..69991c70 --- /dev/null +++ b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-settings-page.php @@ -0,0 +1,141 @@ +is_rest_api_enabled() ) { + echo $rest_api_notice; + } + echo $noscript_notice; + ?> + +
    +
    +
    +
    + + + + + + + +
    + unprotected_display_tablenav( 'top' ); ?> + + + +
    +
    +
    +
    +
    +
    + +
    +
    + + + display_rows_or_placeholder(); ?> + +
    +
    +
    +
    +
    +
    + 'old_settings' ) ); + } + + /** + * Load styles for static page. + * + * @since 4.3.0 + */ + function additional_styles() { + Jetpack_Admin_Page::load_wrapper_styles(); + } + + // Javascript logic specific to the list table + function page_admin_scripts() { + wp_enqueue_script( + 'jetpack-admin-js', + Jetpack::get_file_url_for_environment( '_inc/build/jetpack-admin.min.js', '_inc/jetpack-admin.js' ), + array( 'jquery' ), + JETPACK__VERSION + ); + } +} -- cgit v1.2.3-65-gdbad