Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 11
CRAP
n/a
0 / 0
wpcomsh_wpcom_admin_interface_settings_field
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
wpcom_admin_interface_display
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
wpcom_admin_interface_track_changed_event
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
wpcom_should_disable_calypso_links
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
90
wpcom_admin_interface_pre_update_option
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
72
wpcom_admin_get_current_screen
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
wpcom_admin_interface_pre_get_option
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
wpcom_admin_get_user_option_jetpack
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
wpcom_has_admin_interface_changed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wpcom_show_admin_interface_notice
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
wpcom_get_custom_admin_menu_class
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * Additional wpcom_admin_interface option on settings.
4 *
5 * @package automattic/jetpack-mu-wpcom
6 */
7
8use Automattic\Jetpack\Masterbar\Admin_Menu;
9use Automattic\Jetpack\Status\Host;
10
11/**
12 * Add the Admin Interface Style setting on the General settings page.
13 * This setting allows users to switch between the classic WP-Admin interface and the WordPress.com legacy dashboard.
14 * The setting is stored in the wpcom_admin_interface option.
15 * The setting is displayed only if the has the wp-admin interface selected.
16 */
17function wpcomsh_wpcom_admin_interface_settings_field() {
18    add_settings_field( 'wpcom_admin_interface', __( 'Admin Interface Style', 'jetpack-mu-wpcom' ), 'wpcom_admin_interface_display', 'general', 'default' );
19
20    register_setting( 'general', 'wpcom_admin_interface', array( 'sanitize_callback' => 'esc_attr' ) );
21}
22
23/**
24 * Display the wpcom_admin_interface setting on the General settings page.
25 */
26function wpcom_admin_interface_display() {
27    remove_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 );
28    $value = get_option( 'wpcom_admin_interface', 'calypso' );
29    add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 );
30
31    echo '<fieldset>';
32    echo '<label><input type="radio" name="wpcom_admin_interface" value="wp-admin" ' . checked( 'wp-admin', $value, false ) . '/> <span>' . esc_html__( 'Classic style', 'jetpack-mu-wpcom' ) . '</span></label><p>' . esc_html__( 'Use WP-Admin to manage your site.', 'jetpack-mu-wpcom' ) . '</p><br>';
33    echo '<label><input type="radio" name="wpcom_admin_interface" value="calypso" ' . checked( 'calypso', $value, false ) . '/> <span>' . esc_html__( 'Default style', 'jetpack-mu-wpcom' ) . '</span></label><p>' . esc_html__( 'Use WordPress.com’s native dashboard to manage your site.', 'jetpack-mu-wpcom' ) . '</p><br>';
34    echo '</fieldset>';
35}
36add_action( 'admin_init', 'wpcomsh_wpcom_admin_interface_settings_field' );
37
38/**
39 * Track the wpcom_admin_interface_changed event.
40 *
41 * @param string $value The new value.
42 * @return void
43 */
44function wpcom_admin_interface_track_changed_event( $value ) {
45    $event_name = 'wpcom_admin_interface_changed';
46    $properties = array( 'interface' => $value );
47    if ( function_exists( 'wpcomsh_record_tracks_event' ) ) {
48        wpcomsh_record_tracks_event( $event_name, $properties );
49    } else {
50        require_lib( 'tracks/client' );
51        tracks_record_event( get_current_user_id(), $event_name, $properties );
52    }
53}
54
55/**
56 * Check if we should disable the calypso links.
57 *
58 * @param string $screen The given screen.
59 *
60 * @return bool
61 */
62function wpcom_should_disable_calypso_links( string $screen ): bool {
63    if ( get_option( 'wpcom_admin_interface' ) === 'wp-admin' || ! ( new Host() )->is_wpcom_platform() ) {
64        return true;
65    }
66
67    if ( ( new Host() )->is_wpcom_simple() && function_exists( '\Automattic\Jetpack\Dashboard_Customizations\show_unified_nav' ) && ! \Automattic\Jetpack\Dashboard_Customizations\show_unified_nav() ) {
68        return true;
69    }
70
71    if ( ( new Host() )->is_woa_site() && ! apply_filters( 'jetpack_load_admin_menu_class', true ) ) {
72        return true;
73    }
74
75    $admin_menu = wpcom_get_custom_admin_menu_class();
76
77    if ( ! $admin_menu ) {
78        return true;
79    }
80
81    return $admin_menu::get_instance()->get_preferred_view( $screen ) === Admin_Menu::CLASSIC_VIEW;
82}
83
84/**
85 * Update the wpcom_admin_interface option on wpcom as it's the persistent data.
86 * Also implements the redirect from WP Admin to Calypso when the interface option
87 * is changed.
88 *
89 * @access private
90 * @since 4.20.0
91 *
92 * @param string $new_value The new settings value.
93 * @param string $old_value The old settings value.
94 * @return string The value to update.
95 */
96function wpcom_admin_interface_pre_update_option( $new_value, $old_value ) {
97    if ( $new_value === $old_value ) {
98        return $new_value;
99    }
100
101    if ( ! class_exists( 'Jetpack_Options' ) || ! class_exists( 'Automattic\Jetpack\Connection\Client' ) || ! class_exists( 'Automattic\Jetpack\Status\Host' ) ) {
102        return $new_value;
103    }
104
105    global $pagenow;
106    $on_wp_admin_options_page = isset( $pagenow ) && 'options.php' === $pagenow;
107
108    if ( $on_wp_admin_options_page ) {
109        wpcom_admin_interface_track_changed_event( $new_value );
110    }
111
112    if ( ! ( new Automattic\Jetpack\Status\Host() )->is_wpcom_simple() ) {
113        $blog_id = Jetpack_Options::get_option( 'id' );
114        Automattic\Jetpack\Connection\Client::wpcom_json_api_request_as_user(
115            "/sites/$blog_id/hosting/admin-interface",
116            'v2',
117            array( 'method' => 'POST' ),
118            array( 'interface' => $new_value )
119        );
120    }
121
122    return $new_value;
123}
124add_filter( 'pre_update_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_update_option', 10, 2 );
125
126const WPCOM_DUPLICATED_VIEW = array(
127    'edit.php',
128    'edit.php?post_type=page',
129    'edit.php?post_type=post', // Alias for posts. It's used for the post filters (published, draft, sticky, etc).
130    'edit.php?post_type=jetpack-portfolio',
131    'edit.php?post_type=jetpack-testimonial',
132    'edit-comments.php',
133    'edit-tags.php?taxonomy=category',
134    'edit-tags.php?taxonomy=post_tag',
135    'export.php',
136    'options-general.php',
137    'options-writing.php',
138    'options-reading.php',
139    'options-discussion.php',
140    'upload.php',
141    'import.php',
142);
143
144/**
145 * Get the current screen section.
146 *
147 * Temporary function copied from Base_Admin_Menu.
148 *
149 * return string
150 */
151function wpcom_admin_get_current_screen() {
152    // phpcs:disable WordPress.Security.NonceVerification
153    global $pagenow;
154    $screen = isset( $_REQUEST['screen'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['screen'] ) ) : $pagenow;
155    if ( isset( $_GET['post_type'] ) ) {
156        $screen = add_query_arg( 'post_type', sanitize_text_field( wp_unslash( $_GET['post_type'] ) ), $screen );
157    }
158    if ( isset( $_GET['taxonomy'] ) ) {
159        $screen = add_query_arg( 'taxonomy', sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ), $screen );
160    }
161    if ( isset( $_GET['page'] ) ) {
162        $screen = add_query_arg( 'page', sanitize_text_field( wp_unslash( $_GET['page'] ) ), $screen );
163    }
164    return $screen;
165    // phpcs:enable WordPress.Security.NonceVerification
166}
167
168/**
169 * Override the wpcom_admin_interface option with experiment variation.
170 *
171 * @param mixed $default_value The value to return instead of the option value.
172 *
173 * @return string Filtered wpcom_admin_interface option.
174 */
175function wpcom_admin_interface_pre_get_option( $default_value ) {
176    $current_screen = wpcom_admin_get_current_screen();
177
178    // If the user is on a screen that has been untangled, we need to return the wp-admin interface.
179    if ( in_array( $current_screen, WPCOM_DUPLICATED_VIEW, true ) ) {
180        return 'wp-admin';
181    }
182
183    return $default_value;
184}
185
186/**
187 * Change the Admin menu links to WP-Admin for specific sections.
188 *
189 * @param array $value Preferred views.
190 *
191 * @return array Filtered preferred views.
192 */
193function wpcom_admin_get_user_option_jetpack( $value ) {
194    if ( ! is_array( $value ) ) {
195        $value = array();
196    }
197
198    foreach ( WPCOM_DUPLICATED_VIEW as $path ) {
199        $value[ $path ] = Automattic\Jetpack\Masterbar\Base_Admin_Menu::CLASSIC_VIEW;
200    }
201
202    return $value;
203}
204
205add_filter( 'get_user_option_jetpack_admin_menu_preferred_views', 'wpcom_admin_get_user_option_jetpack' );
206add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 );
207
208add_action(
209    'admin_menu',
210    function () {
211        remove_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option' );
212    },
213    PHP_INT_MIN
214);
215
216add_action(
217    'admin_menu',
218    function () {
219        add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 );
220    },
221    PHP_INT_MAX
222);
223
224/**
225 * Determines whether the admin interface has been recently changed by checking the presence of the `admin-interface-changed` query param.
226 *
227 * @return bool
228 */
229function wpcom_has_admin_interface_changed() {
230    // phpcs:disable WordPress.Security.NonceVerification.Recommended
231    return ( sanitize_key( wp_unslash( $_GET['admin-interface-changed'] ?? 'false' ) ) ) === 'true';
232}
233
234/**
235 * Displays a success notice in the dashboard after changing the admin interface.
236 */
237function wpcom_show_admin_interface_notice() {
238    if ( ! wpcom_has_admin_interface_changed() ) {
239        return;
240    }
241
242    global $pagenow;
243    if ( $pagenow !== 'index.php' ) {
244        return;
245    }
246
247    wp_admin_notice(
248        __( 'Admin interface style changed.', 'jetpack-mu-wpcom' ),
249        array(
250            'type'        => 'success',
251            'dismissible' => true,
252        )
253    );
254}
255add_action( 'admin_notices', 'wpcom_show_admin_interface_notice' );
256
257/**
258 * Gets the name of the class used to customize the admin menu when Nav Unification is enabled.
259 *
260 * @return false|class-string<\Automattic\Jetpack\Masterbar\Base_Admin_Menu> The class name of the customized admin menu if any, false otherwise.
261 */
262function wpcom_get_custom_admin_menu_class() {
263    if ( ! function_exists( '\Automattic\Jetpack\Masterbar\get_admin_menu_class' ) || ! function_exists( '\Automattic\Jetpack\Masterbar\should_customize_nav' ) ) {
264        return false;
265    }
266
267    $admin_menu_class = apply_filters( 'jetpack_admin_menu_class', \Automattic\Jetpack\Masterbar\get_admin_menu_class() );
268    if ( ! \Automattic\Jetpack\Masterbar\should_customize_nav( $admin_menu_class ) ) {
269        return false;
270    }
271
272    return $admin_menu_class;
273}
274
275/**
276 * Enable the Blaze dashboard (WP-Admin) for users.
277 *
278 * @param bool $activation_status The activation status - use WP-Admin or Calypso.
279 * @return mixed|true
280 */
281add_filter( 'jetpack_blaze_dashboard_enable', '__return_true' );