From bf1522cc70041884608a93cfd39f28ca6266500c Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:05:37 -0300 Subject: [PATCH 01/12] move view switch methods into dashboard static methods --- .../forms/src/dashboard/class-dashboard.php | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/projects/packages/forms/src/dashboard/class-dashboard.php b/projects/packages/forms/src/dashboard/class-dashboard.php index 75ffc1475d08b..4c2784c769fc5 100644 --- a/projects/packages/forms/src/dashboard/class-dashboard.php +++ b/projects/packages/forms/src/dashboard/class-dashboard.php @@ -220,7 +220,7 @@ public function render_dashboard( $extra_config = array() ) { 'hasFeedback' => $this->has_feedback(), 'hasAI' => $has_ai, 'renderMigrationPage' => $this->switch->is_jetpack_forms_announcing_new_menu(), - 'dashboardURL' => add_query_arg( 'jetpack_forms_migration_announcement_seen', 'yes', $this->switch->get_forms_admin_url() ), + 'dashboardURL' => self::get_forms_admin_url(), 'isMailpoetEnabled' => Jetpack_Forms::is_mailpoet_enabled(), ); @@ -247,4 +247,57 @@ public function has_feedback() { return $posts->found_posts > 0; } + + /** + * Returns url of forms admin page. + * + * @param string|null $tab Tab to open in the forms admin page. + * + * @return string + */ + public static function get_forms_admin_url( $tab = null ) { + $base_url = get_admin_url() . 'admin.php?page=jetpack-forms-admin'; + + return self::append_tab_to_url( $base_url, $tab ); + } + + /** + * Appends the appropriate tab parameter to the URL based on the view type. + * + * @param string $url Base URL to append to. + * @param string $tab Tab to open. + * + * @return string + */ + private static function append_tab_to_url( $url, $tab ) { + if ( ! $tab ) { + return $url; + } + + $status_map = array( + 'spam' => 'spam', + 'inbox' => 'inbox', + 'trash' => 'trash', + ); + + if ( ! isset( $status_map[ $tab ] ) ) { + return $url; + } + + return $url . '#/responses?status=' . $status_map[ $tab ]; + } + + /** + * Returns true if the current screen is the Jetpack Forms admin page. + * + * @return boolean + */ + public static function is_jetpack_forms_admin_page() { + if ( ! function_exists( 'get_current_screen' ) ) { + return false; + } + + $screen = get_current_screen(); + return $screen && $screen->id === 'jetpack_page_jetpack-forms-admin'; + } } From 5a6a8f83a25c277df0882cfff5f61ba607e34ec8 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:09:16 -0300 Subject: [PATCH 02/12] remove migration page and all related consts --- .../dashboard/admin-migrate-page/index.tsx | 137 ------------------ .../dashboard/admin-migrate-page/style.scss | 11 -- .../forms/src/dashboard/class-dashboard.php | 14 +- .../inbox/export-responses/google-drive.tsx | 5 +- .../packages/forms/src/dashboard/index.tsx | 11 -- projects/packages/forms/src/types/index.ts | 2 - .../src/util/get-preferred-responses-view.js | 1 - 7 files changed, 4 insertions(+), 177 deletions(-) delete mode 100644 projects/packages/forms/src/dashboard/admin-migrate-page/index.tsx delete mode 100644 projects/packages/forms/src/dashboard/admin-migrate-page/style.scss diff --git a/projects/packages/forms/src/dashboard/admin-migrate-page/index.tsx b/projects/packages/forms/src/dashboard/admin-migrate-page/index.tsx deleted file mode 100644 index 2cda810d982d6..0000000000000 --- a/projects/packages/forms/src/dashboard/admin-migrate-page/index.tsx +++ /dev/null @@ -1,137 +0,0 @@ -/** - * External dependencies - */ -import jetpackAnalytics from '@automattic/jetpack-analytics'; -import { - AdminPage, - AdminSectionHero, - Container, - Col, - JetpackLogo, - useBreakpointMatch, - getUserLocale, -} from '@automattic/jetpack-components'; -import { Button } from '@wordpress/components'; -import { useEffect, useMemo, useCallback } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; -/** - * Internal dependencies - */ -import { config } from '../index'; -import './style.scss'; - -// Mag-16, see https://wp.me/PCYsg-9nE -// Exception: pt-br, since mag-16 code is BR and it's the variation, not the language -const availableScreenshotLanguages = [ - 'ar', - 'pt-br', - 'de', - 'en', - 'es', - 'fr', - 'he', - 'id', - 'it', - 'ja', - 'ko', - 'nl', - 'ru', - 'sv', - 'tr', - 'zh-cn', - 'zh-tw', -]; - -const getLocaleScreenshotName = ( locale = '', isMobile = false ) => { - const baseName = `forms-moved`; - let languageSuffix = ''; - const lowercaseLocale = locale.toLowerCase(); - if ( availableScreenshotLanguages.includes( lowercaseLocale ) ) { - languageSuffix = `-${ lowercaseLocale }`; - } else { - const language = lowercaseLocale.split( '-' )[ 0 ]; - - if ( availableScreenshotLanguages.includes( language ) ) { - languageSuffix = `-${ language }`; - } - } - - return `${ baseName }${ languageSuffix }${ isMobile ? '-mobile' : '' }.png`; -}; - -const AdminMigratePage = () => { - const [ isSm ] = useBreakpointMatch( 'sm' ); - const ASSETS_URL = useMemo( () => config( 'pluginAssetsURL' ), [] ); - const dashboardURL = useMemo( () => config( 'dashboardURL' ), [] ); - - const header = ( -
- { ' ' } - - { 'Forms' } - -
- ); - const screenshotName = useMemo( - () => getLocaleScreenshotName( getUserLocale(), isSm ), - [ isSm ] - ); - - useEffect( () => { - jetpackAnalytics.tracks.recordEvent( 'jetpack_forms_admin_migrate_page_view', { - viewport: isSm ? 'mobile' : 'desktop', - } ); - }, [ isSm ] ); - - const onCheckNewFormsClick = useCallback( () => { - jetpackAnalytics.tracks.recordEvent( - 'jetpack_forms_admin_migrate_page_check_new_forms_button_click', - { - viewport: isSm ? 'mobile' : 'desktop', - } - ); - - window.location.href = dashboardURL; - }, [ isSm, dashboardURL ] ); - - return ( -
- - - - -

- { __( 'Forms responses have moved', 'jetpack-forms' ) } -

-

- { __( 'They can now be found at Jetpack → Forms', 'jetpack-forms' ) } -

-

- -

-

- { -

- -
-
-
-
- ); -}; - -export default AdminMigratePage; diff --git a/projects/packages/forms/src/dashboard/admin-migrate-page/style.scss b/projects/packages/forms/src/dashboard/admin-migrate-page/style.scss deleted file mode 100644 index 7ee35c690c569..0000000000000 --- a/projects/packages/forms/src/dashboard/admin-migrate-page/style.scss +++ /dev/null @@ -1,11 +0,0 @@ -.jp-forms__admin-migrate-page-wrapper { - padding: 0; - - > div:first-child { - margin-left: 0; - } - - h1 { - line-height: 1.2; - } -} diff --git a/projects/packages/forms/src/dashboard/class-dashboard.php b/projects/packages/forms/src/dashboard/class-dashboard.php index 4c2784c769fc5..9b6c46196dcf6 100644 --- a/projects/packages/forms/src/dashboard/class-dashboard.php +++ b/projects/packages/forms/src/dashboard/class-dashboard.php @@ -174,17 +174,13 @@ public function add_admin_submenu() { * Register the NEW dashboard admin submenu Forms under Jetpack menu. */ public function add_new_admin_submenu() { - if ( ! $this->switch->is_jetpack_forms_admin_page_available() ) { - return; - } - Admin_Menu::add_menu( /** "Jetpack Forms" and "Forms" are Product names, do not translate. */ 'Jetpack Forms', 'Forms', 'edit_pages', self::ADMIN_SLUG, - array( $this, 'render_new_dashboard' ), + array( $this, 'render_dashboard' ), 10 ); } @@ -198,10 +194,8 @@ public function render_new_dashboard() { /** * Render the dashboard. - * - * @param array $extra_config Extra configuration to pass to the dashboard. */ - public function render_dashboard( $extra_config = array() ) { + public function render_dashboard() { if ( ! class_exists( 'Jetpack_AI_Helper' ) ) { require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-ai-helper.php'; } @@ -219,14 +213,10 @@ public function render_dashboard( $extra_config = array() ) { 'siteURL' => ( new Status() )->get_site_suffix(), 'hasFeedback' => $this->has_feedback(), 'hasAI' => $has_ai, - 'renderMigrationPage' => $this->switch->is_jetpack_forms_announcing_new_menu(), 'dashboardURL' => self::get_forms_admin_url(), 'isMailpoetEnabled' => Jetpack_Forms::is_mailpoet_enabled(), ); - if ( ! empty( $extra_config ) ) { - $config = array_merge( $config, $extra_config ); - } ?>
{ const [ isExporting, setIsExporting ] = useState( false ); @@ -25,8 +25,7 @@ const GoogleDriveExport = ( { onExport, autoConnect = false } ) => { const [ isTogglingConnection, setIsTogglingConnection ] = useState( false ); const { isUserConnected, handleConnectUser, userIsConnecting, isOfflineMode } = useConnection( { - redirectUri: - PARTIAL_RESPONSES_PATH + ( PREFERRED_VIEW === 'classic' ? '' : '&connect-gdrive=true' ), + redirectUri: PARTIAL_RESPONSES_PATH + '&connect-gdrive=true', } ); const needsUserConnection = ! isSimpleSite() && ! isUserConnected; diff --git a/projects/packages/forms/src/dashboard/index.tsx b/projects/packages/forms/src/dashboard/index.tsx index c276417feeca0..03b2e9f03e16f 100644 --- a/projects/packages/forms/src/dashboard/index.tsx +++ b/projects/packages/forms/src/dashboard/index.tsx @@ -9,7 +9,6 @@ import { RouterProvider } from 'react-router/dom'; * Internal dependencies */ import About from './about'; -import AdminMigratePage from './admin-migrate-page'; import Layout from './components/layout'; import Inbox from './inbox'; import Integrations from './integrations'; @@ -26,16 +25,6 @@ window.addEventListener( 'load', () => { settings = JSON.parse( decodeURIComponent( container.dataset.config ) ); delete container.dataset.config; - if ( config( 'renderMigrationPage' ) ) { - const root = createRoot( container ); - root.render( - - - - ); - return; - } - const router = createHashRouter( [ { path: '/', diff --git a/projects/packages/forms/src/types/index.ts b/projects/packages/forms/src/types/index.ts index 373d26d5d0010..92a8434df94ce 100644 --- a/projects/packages/forms/src/types/index.ts +++ b/projects/packages/forms/src/types/index.ts @@ -214,8 +214,6 @@ export interface FormsConfigData { canInstallPlugins?: boolean; /** Whether the current user can activate plugins (activate_plugins). */ canActivatePlugins?: boolean; - /** Whether to render the migration/announcement page instead of the main dashboard. */ - renderMigrationPage?: boolean; /** Whether there are any feedback (form response) posts on the site. */ hasFeedback?: boolean; /** Whether AI Assist features are available for the site/user. */ diff --git a/projects/packages/forms/src/util/get-preferred-responses-view.js b/projects/packages/forms/src/util/get-preferred-responses-view.js index 77a49cc369152..e6d51cb70fc39 100644 --- a/projects/packages/forms/src/util/get-preferred-responses-view.js +++ b/projects/packages/forms/src/util/get-preferred-responses-view.js @@ -1,5 +1,4 @@ import { getJetpackData } from '@automattic/jetpack-shared-extension-utils'; -export const PREFERRED_VIEW = window?.jpFormsBlocks?.defaults?.preferredView; export const PARTIAL_RESPONSES_PATH = 'admin.php?page=jetpack-forms-admin'; export const FULL_RESPONSES_PATH = getJetpackData()?.adminUrl + PARTIAL_RESPONSES_PATH; From 42079015ab6ddb7643ad8180b1dd7c3192758619 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:13:47 -0300 Subject: [PATCH 03/12] remove/replace references/calls to Dashboard_View_Switch for Dashboard new static methods --- .../contact-form/class-contact-form-block.php | 7 ++--- .../class-contact-form-endpoint.php | 11 +++----- .../class-contact-form-plugin.php | 2 +- .../src/contact-form/class-contact-form.php | 5 ++-- .../forms/src/dashboard/class-dashboard.php | 27 +------------------ 5 files changed, 9 insertions(+), 43 deletions(-) diff --git a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php index 3cef22b6e531e..990eef65a8f2f 100644 --- a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php +++ b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php @@ -12,7 +12,7 @@ use Automattic\Jetpack\Current_Plan; use Automattic\Jetpack\Forms\ContactForm\Contact_Form; use Automattic\Jetpack\Forms\ContactForm\Contact_Form_Plugin; -use Automattic\Jetpack\Forms\Dashboard\Dashboard_View_Switch; +use Automattic\Jetpack\Forms\Dashboard\Dashboard as Forms_Dashboard; use Automattic\Jetpack\Forms\Jetpack_Forms; use Automattic\Jetpack\Modules; use Automattic\Jetpack\Status\Request; @@ -779,11 +779,9 @@ public static function load_editor_scripts() { ); // Create a Contact_Form instance to get the default values - $dashboard_view_switch = new Dashboard_View_Switch(); - $form_responses_url = $dashboard_view_switch->get_forms_admin_url(); + $form_responses_url = Forms_Dashboard::get_forms_admin_url(); $akismet_active_with_key = Jetpack::is_akismet_active(); $akismet_key_url = admin_url( 'admin.php?page=akismet-key-config' ); - $preferred_view = $dashboard_view_switch->get_preferred_view(); $data = array( 'defaults' => array( @@ -793,7 +791,6 @@ public static function load_editor_scripts() { 'akismetActiveWithKey' => $akismet_active_with_key, 'akismetUrl' => $akismet_key_url, 'assetsUrl' => Jetpack_Forms::assets_url(), - 'preferredView' => $preferred_view, 'isMailPoetEnabled' => Jetpack_Forms::is_mailpoet_enabled(), ), ); diff --git a/projects/packages/forms/src/contact-form/class-contact-form-endpoint.php b/projects/packages/forms/src/contact-form/class-contact-form-endpoint.php index 9dfb36f420bb0..dbbdfe8a84093 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form-endpoint.php +++ b/projects/packages/forms/src/contact-form/class-contact-form-endpoint.php @@ -10,7 +10,6 @@ use Automattic\Jetpack\Connection\Manager as Connection_Manager; use Automattic\Jetpack\External_Connections; use Automattic\Jetpack\Forms\Dashboard\Dashboard as Forms_Dashboard; -use Automattic\Jetpack\Forms\Dashboard\Dashboard_View_Switch; use Automattic\Jetpack\Forms\Jetpack_Forms; use Automattic\Jetpack\Forms\Service\Google_Drive; use Automattic\Jetpack\Forms\Service\MailPoet_Integration; @@ -985,9 +984,8 @@ private function get_plugin_status( $plugin_slug, array $status ) { // Override base shape for specific plugins. switch ( $plugin_slug ) { case 'akismet': - $dashboard_view_switch = new Dashboard_View_Switch(); $status['isConnected'] = class_exists( 'Jetpack' ) && \Jetpack::is_akismet_active(); - $status['details']['formSubmissionsSpamUrl'] = $dashboard_view_switch->get_forms_admin_url( 'spam' ); + $status['details']['formSubmissionsSpamUrl'] = Forms_Dashboard::get_forms_admin_url( 'spam' ); $status['needsConnection'] = true; break; case 'zero-bs-crm': @@ -1042,7 +1040,6 @@ public function disable_integration( $request ) { * @return WP_REST_Response */ public function get_forms_config( WP_REST_Request $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - $switch = new Dashboard_View_Switch(); $has_ai = false; if ( class_exists( 'Jetpack_AI_Helper' ) ) { $feature = Jetpack_AI_Helper::get_ai_assistance_feature(); @@ -1051,8 +1048,7 @@ public function get_forms_config( WP_REST_Request $request ) { // phpcs:ignore V $config = array( // From jpFormsBlocks in class-contact-form-block.php. - 'formsResponsesUrl' => $switch->get_forms_admin_url(), - 'preferredView' => $switch->get_preferred_view(), + 'formsResponsesUrl' => Forms_Dashboard::get_forms_admin_url(), 'isMailPoetEnabled' => Jetpack_Forms::is_mailpoet_enabled(), // From config in class-dashboard.php. 'blogId' => get_current_blog_id(), @@ -1062,8 +1058,7 @@ public function get_forms_config( WP_REST_Request $request ) { // phpcs:ignore V 'hasFeedback' => ( new Forms_Dashboard() )->has_feedback(), 'hasAI' => $has_ai, 'isIntegrationsEnabled' => Jetpack_Forms::is_integrations_enabled(), - 'renderMigrationPage' => $switch->is_jetpack_forms_announcing_new_menu(), - 'dashboardURL' => add_query_arg( 'jetpack_forms_migration_announcement_seen', 'yes', $switch->get_forms_admin_url() ), + 'dashboardURL' => Forms_Dashboard::get_forms_admin_url(), // New data. 'canInstallPlugins' => current_user_can( 'install_plugins' ), 'canActivatePlugins' => current_user_can( 'activate_plugins' ), diff --git a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php index 86dca7d957d1f..8523c2928b4b1 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php +++ b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php @@ -235,7 +235,7 @@ protected function __construct() { ), 'menu_icon' => 'dashicons-feedback', // when the legacy menu item is retired, we don't want to show the default post type listing - 'show_ui' => ! Jetpack_Forms::is_legacy_menu_item_retired(), + 'show_ui' => false, 'show_in_menu' => false, 'show_in_admin_bar' => false, 'public' => false, diff --git a/projects/packages/forms/src/contact-form/class-contact-form.php b/projects/packages/forms/src/contact-form/class-contact-form.php index 32fba3dcb6a41..a32ff0df5302c 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form.php +++ b/projects/packages/forms/src/contact-form/class-contact-form.php @@ -8,7 +8,6 @@ namespace Automattic\Jetpack\Forms\ContactForm; use Automattic\Jetpack\Connection\Tokens; -use Automattic\Jetpack\Forms\Dashboard\Dashboard_View_Switch; use Automattic\Jetpack\JWT; use Automattic\Jetpack\Sync\Settings; use Jetpack_Tracks_Event; @@ -504,7 +503,7 @@ public static function add_quick_link_to_admin_bar( \WP_Admin_Bar $admin_bar ) { return; } - $url = ( new Dashboard_View_Switch() )->get_forms_admin_url(); + $url = Dashboard::get_forms_admin_url(); $admin_bar->add_menu( array( @@ -1978,7 +1977,7 @@ public function process_submission() { $dashboard_url = ''; $footer_mark_as_spam_url = ''; if ( $feedback_status !== 'jp-temp-feedback' ) { - $dashboard_url = ( new Dashboard_View_Switch() )->get_forms_admin_url( $status, true ) . '&r=' . $post_id; + $dashboard_url = Dashboard::get_forms_admin_url( $status ) . '&r=' . $post_id; $mark_as_spam_url = $dashboard_url . '&mark_as_spam'; $footer_mark_as_spam_url = sprintf( '%2$s', diff --git a/projects/packages/forms/src/dashboard/class-dashboard.php b/projects/packages/forms/src/dashboard/class-dashboard.php index 9b6c46196dcf6..718786b1693fc 100644 --- a/projects/packages/forms/src/dashboard/class-dashboard.php +++ b/projects/packages/forms/src/dashboard/class-dashboard.php @@ -42,22 +42,6 @@ class Dashboard { */ const MENU_PRIORITY = 999; - /** - * Dashboard_View_Switch instance - * - * @var Dashboard_View_Switch - */ - private $switch; - - /** - * Creates a new Dashboard instance. - * - * @param Dashboard_View_Switch|null $switch Dashboard_View_Switch instance to use. - */ - public function __construct( ?Dashboard_View_Switch $switch = null ) { - $this->switch = $switch ?? new Dashboard_View_Switch(); - } - /** * Initialize the dashboard. */ @@ -71,15 +55,13 @@ public function init() { if ( isset( $_GET['page'] ) && $_GET['page'] === self::ADMIN_SLUG ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended remove_all_actions( 'admin_notices' ); } - - $this->switch->init(); } /** * Load JavaScript for the dashboard. */ public function load_admin_scripts() { - if ( ! $this->switch->is_modern_view() && ! $this->switch->is_jetpack_forms_admin_page() ) { + if ( ! self::is_jetpack_forms_admin_page() ) { return; } @@ -185,13 +167,6 @@ public function add_new_admin_submenu() { ); } - /** - * Render the new dashboard. - */ - public function render_new_dashboard() { - $this->render_dashboard( array( 'renderMigrationPage' => false ) ); - } - /** * Render the dashboard. */ From 29ad5fb30c6e9a0404fcd6deaa3675f43bf39909 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:15:39 -0300 Subject: [PATCH 04/12] assume defaults and not conditional menu rendering --- .../src/contact-form/class-contact-form-plugin.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php index 8523c2928b4b1..7fc8bb5229949 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php +++ b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php @@ -1358,7 +1358,7 @@ public static function gutenblock_render_field_image_select( $atts, $content, $b public function admin_menu() { $slug = 'feedback'; - if ( is_plugin_active( 'polldaddy/polldaddy.php' ) || ! Jetpack_Forms::is_legacy_menu_item_retired() ) { + if ( is_plugin_active( 'polldaddy/polldaddy.php' ) ) { add_menu_page( __( 'Feedback', 'jetpack-forms' ), __( 'Feedback', 'jetpack-forms' ), @@ -1385,12 +1385,11 @@ public function admin_menu() { $slug ); - if ( Jetpack_Forms::is_legacy_menu_item_retired() ) { - remove_submenu_page( - $slug, - 'edit.php?post_type=feedback' - ); - } + // remove the first default submenu item + remove_submenu_page( + $slug, + 'edit.php?post_type=feedback' + ); } /** From 43749025191d13a65c76ce0da7f9ae996e2ad4e4 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:16:08 -0300 Subject: [PATCH 05/12] remove old menu hook --- .../forms/src/dashboard/class-dashboard.php | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/projects/packages/forms/src/dashboard/class-dashboard.php b/projects/packages/forms/src/dashboard/class-dashboard.php index 718786b1693fc..40a45b10fbeb7 100644 --- a/projects/packages/forms/src/dashboard/class-dashboard.php +++ b/projects/packages/forms/src/dashboard/class-dashboard.php @@ -14,7 +14,6 @@ use Automattic\Jetpack\Forms\Jetpack_Forms; use Automattic\Jetpack\Redirect; use Automattic\Jetpack\Status; -use Automattic\Jetpack\Status\Host; use Automattic\Jetpack\Tracking; if ( ! defined( 'ABSPATH' ) ) { @@ -46,7 +45,6 @@ class Dashboard { * Initialize the dashboard. */ public function init() { - add_action( 'admin_menu', array( $this, 'add_admin_submenu' ), self::MENU_PRIORITY ); add_action( 'admin_menu', array( $this, 'add_new_admin_submenu' ), self::MENU_PRIORITY ); add_action( 'admin_enqueue_scripts', array( $this, 'load_admin_scripts' ) ); @@ -97,61 +95,6 @@ public function load_admin_scripts() { ); } - /** - * Register the dashboard admin submenu. - */ - public function add_admin_submenu() { - if ( Jetpack_Forms::is_legacy_menu_item_retired() ) { - return; - } - - if ( $this->switch->get_preferred_view() === Dashboard_View_Switch::CLASSIC_VIEW ) { - // We still need to register the jetpack forms page so it can be accessed manually. - // NOTE: adding submenu this (parent = '') way DOESN'T SHOW ANYWHERE, - // it's done just so the page URL doesn't break. - add_submenu_page( - '', - __( 'Form Responses', 'jetpack-forms' ), - _x( 'Form Responses', 'menu label for form responses', 'jetpack-forms' ), - 'edit_pages', - 'jetpack-forms', - array( $this, 'render_dashboard' ) - ); - - return; - } - - $is_wpcom = ( new Host() )->is_wpcom_simple(); - - // MODERN VIEW -- remove the old submenu and add the new one. - // Check if Polldaddy/Crowdsignal plugin is active - if ( ! $is_wpcom && ! is_plugin_active( 'polldaddy/polldaddy.php' ) ) { - remove_menu_page( 'feedback' ); - - add_menu_page( - __( 'Form Responses', 'jetpack-forms' ), - _x( 'Feedback', 'post type name shown in menu', 'jetpack-forms' ), - 'edit_pages', - 'jetpack-forms', - array( $this, 'render_dashboard' ), - 'dashicons-feedback', - 25 // Places 'Feedback' under 'Comments' in the menu - ); - } else { - remove_submenu_page( 'feedback', 'edit.php?post_type=feedback' ); - - add_submenu_page( - 'feedback', - __( 'Form Responses', 'jetpack-forms' ), - _x( 'Form Responses', 'menu label for form responses', 'jetpack-forms' ), - 'edit_pages', - 'jetpack-forms', - array( $this, 'render_dashboard' ), - 0 // as far top as we can go since responses are the default feedback page. - ); - } - } - /** * Register the NEW dashboard admin submenu Forms under Jetpack menu. */ From 3e3f48216e9f8e4c1c193238546ab58596c0ed8d Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:18:44 -0300 Subject: [PATCH 06/12] declare class usage --- .../packages/forms/src/contact-form/class-contact-form.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/projects/packages/forms/src/contact-form/class-contact-form.php b/projects/packages/forms/src/contact-form/class-contact-form.php index a32ff0df5302c..2b98d2619b1d6 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form.php +++ b/projects/packages/forms/src/contact-form/class-contact-form.php @@ -8,6 +8,7 @@ namespace Automattic\Jetpack\Forms\ContactForm; use Automattic\Jetpack\Connection\Tokens; +use Automattic\Jetpack\Forms\Dashboard\Dashboard as Forms_Dashboard; use Automattic\Jetpack\JWT; use Automattic\Jetpack\Sync\Settings; use Jetpack_Tracks_Event; @@ -503,7 +504,7 @@ public static function add_quick_link_to_admin_bar( \WP_Admin_Bar $admin_bar ) { return; } - $url = Dashboard::get_forms_admin_url(); + $url = Forms_Dashboard::get_forms_admin_url(); $admin_bar->add_menu( array( @@ -1977,7 +1978,7 @@ public function process_submission() { $dashboard_url = ''; $footer_mark_as_spam_url = ''; if ( $feedback_status !== 'jp-temp-feedback' ) { - $dashboard_url = Dashboard::get_forms_admin_url( $status ) . '&r=' . $post_id; + $dashboard_url = Forms_Dashboard::get_forms_admin_url( $status ) . '&r=' . $post_id; $mark_as_spam_url = $dashboard_url . '&mark_as_spam'; $footer_mark_as_spam_url = sprintf( '%2$s', From 579e96bbee557b2cb942c63cd0f1bcbda9a51964 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:19:48 -0300 Subject: [PATCH 07/12] changelog --- .../forms/changelog/remove-forms-dashboard-switch-class | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/packages/forms/changelog/remove-forms-dashboard-switch-class diff --git a/projects/packages/forms/changelog/remove-forms-dashboard-switch-class b/projects/packages/forms/changelog/remove-forms-dashboard-switch-class new file mode 100644 index 0000000000000..5303fdde005b3 --- /dev/null +++ b/projects/packages/forms/changelog/remove-forms-dashboard-switch-class @@ -0,0 +1,4 @@ +Significance: minor +Type: removed + +Forms: remove unused code Dashboard_View_Switch and move useful methods into Dashboard static methods From 41ac9abb043569667b5069ba936f7dc4064ff269 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:23:22 -0300 Subject: [PATCH 08/12] remove expected keys after deprecation --- .../forms/tests/php/contact-form/Contact_Form_Endpoint_Test.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/projects/packages/forms/tests/php/contact-form/Contact_Form_Endpoint_Test.php b/projects/packages/forms/tests/php/contact-form/Contact_Form_Endpoint_Test.php index 98fdeee48269a..363ff2e7686dc 100644 --- a/projects/packages/forms/tests/php/contact-form/Contact_Form_Endpoint_Test.php +++ b/projects/packages/forms/tests/php/contact-form/Contact_Form_Endpoint_Test.php @@ -424,7 +424,6 @@ public function test_get_forms_config_returns_200_and_keys() { // Required keys $expected_keys = array( 'formsResponsesUrl', - 'preferredView', 'isMailPoetEnabled', 'blogId', 'gdriveConnectSupportURL', @@ -433,7 +432,6 @@ public function test_get_forms_config_returns_200_and_keys() { 'hasFeedback', 'hasAI', 'isIntegrationsEnabled', - 'renderMigrationPage', 'dashboardURL', 'canInstallPlugins', 'canActivatePlugins', From 0b0a59c4f5f5cd767eb5eaddc560fb733851fb00 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 23 Sep 2025 18:46:58 -0300 Subject: [PATCH 09/12] update phan baselines --- projects/packages/forms/.phan/baseline.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/projects/packages/forms/.phan/baseline.php b/projects/packages/forms/.phan/baseline.php index 0d4d756714afc..2ec6ef1124c32 100644 --- a/projects/packages/forms/.phan/baseline.php +++ b/projects/packages/forms/.phan/baseline.php @@ -11,9 +11,9 @@ // # Issue statistics: // PhanTypeMismatchArgument : 45+ occurrences // PhanPluginDuplicateConditionalNullCoalescing : 30+ occurrences - // PhanTypeMismatchReturnProbablyReal : 7 occurrences + // PhanTypeMismatchReturnProbablyReal : 8 occurrences // PhanTypeMismatchArgumentProbablyReal : 6 occurrences - // PhanPluginDuplicateAdjacentStatement : 2 occurrences + // PhanPluginDuplicateAdjacentStatement : 3 occurrences // PhanTypeConversionFromArray : 2 occurrences // PhanTypeMismatchReturn : 2 occurrences // PhanPluginMixedKeyNoKey : 1 occurrence @@ -21,7 +21,6 @@ // PhanPossiblyNullTypeMismatchProperty : 1 occurrence // PhanTypeArraySuspiciousNullable : 1 occurrence // PhanTypeMismatchReturnNullable : 1 occurrence - // PhanUnreferencedUseNormal : 1 occurrence // Currently, file_suppressions and directory_suppressions are the only supported suppressions 'file_suppressions' => [ @@ -30,7 +29,6 @@ 'src/contact-form/class-contact-form-plugin.php' => ['PhanPluginDuplicateAdjacentStatement', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchReturnProbablyReal'], 'src/contact-form/class-contact-form-shortcode.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchReturnProbablyReal'], 'src/contact-form/class-contact-form.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginRedundantAssignment', 'PhanTypeMismatchArgument', 'PhanTypeMismatchReturnNullable', 'PhanTypeMismatchReturnProbablyReal'], - 'src/dashboard/class-dashboard-view-switch.php' => ['PhanUnreferencedUseNormal'], 'src/service/class-google-drive.php' => ['PhanTypeMismatchReturnProbablyReal'], 'tests/php/contact-form/Contact_Form_Plugin_Test.php' => ['PhanPluginMixedKeyNoKey'], ], From 0e9a2ceb8c757e65b1d34004244227ab94613e00 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Wed, 24 Sep 2025 01:41:38 -0300 Subject: [PATCH 10/12] instead of deleting the class file, add tests and tag for deprecation --- .../packages/forms/src/dashboard/README.md | 2 +- .../dashboard/class-dashboard-view-switch.php | 14 +++ .../tests/php/dashboard/Dashboard_Test.php | 58 +++++++++ .../dashboard/Dashboard_View_Switch_Test.php | 112 ++++++++++++++++++ 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 projects/packages/forms/tests/php/dashboard/Dashboard_Test.php create mode 100644 projects/packages/forms/tests/php/dashboard/Dashboard_View_Switch_Test.php diff --git a/projects/packages/forms/src/dashboard/README.md b/projects/packages/forms/src/dashboard/README.md index 9d74872f4f4aa..d2c5d9a855e6a 100644 --- a/projects/packages/forms/src/dashboard/README.md +++ b/projects/packages/forms/src/dashboard/README.md @@ -14,7 +14,7 @@ This is the React-app implementation for the new Jetpack Forms dashboard. ├── state/ - App state. ├── index.js - App entrypoint. ├── class-dashboard.php - Jetpack Forms WP Admin setup. -└── class-dashboard-view-switch.php - Feedback view toggle implementation. +└── class-dashboard-view-switch.php - Feedback view toggle implementation (deprecated, unused). ``` *\**: All views get their own dedicated directory while reusable components go into `components/`. diff --git a/projects/packages/forms/src/dashboard/class-dashboard-view-switch.php b/projects/packages/forms/src/dashboard/class-dashboard-view-switch.php index 56ead95d7fecb..40cc8ade6eaab 100644 --- a/projects/packages/forms/src/dashboard/class-dashboard-view-switch.php +++ b/projects/packages/forms/src/dashboard/class-dashboard-view-switch.php @@ -16,6 +16,8 @@ /** * Understands switching between classic and redesigned versions of the feedback admin area. + * + * @deprecated $$next-version$$ This class is no longer needed and has been removed from active use. */ class Dashboard_View_Switch { @@ -35,8 +37,11 @@ class Dashboard_View_Switch { /** * Initialize the switch. + * + * @deprecated $$next-version$$ This class is no longer needed and has been removed from active use. */ public function init() { + _deprecated_function( __METHOD__, 'jetpack-$$next-version$$' ); add_action( 'admin_print_styles', array( $this, 'print_styles' ) ); add_filter( 'in_admin_header', array( $this, 'render_switch' ) ); add_action( 'admin_footer', array( $this, 'add_scripts' ) ); @@ -339,9 +344,12 @@ public function is_modern_view() { /** * Returns true if the current screen is the Jetpack Forms admin page. * + * @deprecated $$next-version$$ Use Dashboard::is_jetpack_forms_admin_page() instead. + * * @return boolean */ public function is_jetpack_forms_admin_page() { + _deprecated_function( __METHOD__, 'jetpack-$$next-version$$', 'Dashboard::is_jetpack_forms_admin_page' ); if ( ! function_exists( 'get_current_screen' ) ) { return false; } @@ -353,12 +361,15 @@ public function is_jetpack_forms_admin_page() { /** * Returns url of forms admin page. * + * @deprecated $$next-version$$ Use Dashboard::get_forms_admin_url() instead. + * * @param string|null $tab Tab to open in the forms admin page. * @param boolean $force_inbox Whether to force the inbox view URL. * * @return string */ public function get_forms_admin_url( $tab = null, $force_inbox = false ) { + _deprecated_function( __METHOD__, 'jetpack-$$next-version$$', 'Dashboard::get_forms_admin_url' ); $is_classic = $this->get_preferred_view() === self::CLASSIC_VIEW; $switch_is_available = $this->is_jetpack_forms_view_switch_available(); @@ -401,9 +412,12 @@ private function append_tab_to_url( $url, $tab, $is_classic_view ) { /** * Returns true if the new Jetpack Forms admin page is available. * + * @deprecated $$next-version$$ Use Dashboard::is_jetpack_forms_admin_page_available() instead. + * * @return boolean */ public static function is_jetpack_forms_admin_page_available() { + _deprecated_function( __METHOD__, 'jetpack-$$next-version$$', 'Dashboard::is_jetpack_forms_admin_page_available' ); return apply_filters( 'jetpack_forms_use_new_menu_parent', true ); } diff --git a/projects/packages/forms/tests/php/dashboard/Dashboard_Test.php b/projects/packages/forms/tests/php/dashboard/Dashboard_Test.php new file mode 100644 index 0000000000000..53334199169f5 --- /dev/null +++ b/projects/packages/forms/tests/php/dashboard/Dashboard_Test.php @@ -0,0 +1,58 @@ +assertEquals( $expected, Dashboard::get_forms_admin_url() ); + } + + /** + * Test get_forms_admin_url with valid tab parameter + */ + public function test_get_forms_admin_url_with_valid_tab() { + $expected = get_admin_url() . 'admin.php?page=jetpack-forms-admin#/responses?status=inbox'; + $this->assertEquals( $expected, Dashboard::get_forms_admin_url( 'inbox' ) ); + + $expected = get_admin_url() . 'admin.php?page=jetpack-forms-admin#/responses?status=spam'; + $this->assertEquals( $expected, Dashboard::get_forms_admin_url( 'spam' ) ); + + $expected = get_admin_url() . 'admin.php?page=jetpack-forms-admin#/responses?status=trash'; + $this->assertEquals( $expected, Dashboard::get_forms_admin_url( 'trash' ) ); + } + + /** + * Test get_forms_admin_url with invalid tab parameter + */ + public function test_get_forms_admin_url_with_invalid_tab() { + $expected = get_admin_url() . 'admin.php?page=jetpack-forms-admin'; + $this->assertEquals( $expected, Dashboard::get_forms_admin_url( 'invalid' ) ); + } + + /** + * Test is_jetpack_forms_admin_page when get_current_screen is not available + */ + public function test_is_jetpack_forms_admin_page_no_get_current_screen() { + // When get_current_screen doesn't exist, should return false + $this->assertFalse( Dashboard::is_jetpack_forms_admin_page() ); + } +} diff --git a/projects/packages/forms/tests/php/dashboard/Dashboard_View_Switch_Test.php b/projects/packages/forms/tests/php/dashboard/Dashboard_View_Switch_Test.php new file mode 100644 index 0000000000000..01bfffb336377 --- /dev/null +++ b/projects/packages/forms/tests/php/dashboard/Dashboard_View_Switch_Test.php @@ -0,0 +1,112 @@ +dashboard_view_switch = new Dashboard_View_Switch(); + } + + /** + * Test that deprecated init method still works + */ + public function test_deprecated_init_method_still_works() { + // Test that the method doesn't fatal error when called + // Note: We can't test for deprecation warnings with WorDBless + $this->dashboard_view_switch->init(); + $this->assertTrue( true ); // If we reach here, no fatal error occurred + } + + /** + * Test that deprecated get_forms_admin_url method still works + */ + public function test_deprecated_get_forms_admin_url_still_works() { + $result = $this->dashboard_view_switch->get_forms_admin_url(); + $this->assertIsString( $result ); + } + + /** + * Test that deprecated is_jetpack_forms_admin_page method still works + */ + public function test_deprecated_is_jetpack_forms_admin_page_still_works() { + $result = $this->dashboard_view_switch->is_jetpack_forms_admin_page(); + $this->assertIsBool( $result ); + } + + /** + * Test that deprecated static is_jetpack_forms_admin_page_available method still works + */ + public function test_deprecated_static_is_jetpack_forms_admin_page_available_still_works() { + $result = Dashboard_View_Switch::is_jetpack_forms_admin_page_available(); + $this->assertTrue( $result ); // Should return true (default filter value) + } + + /** + * Test that deprecated static is_jetpack_forms_view_switch_available method still works + */ + public function test_deprecated_static_is_jetpack_forms_view_switch_available_still_works() { + $result = Dashboard_View_Switch::is_jetpack_forms_view_switch_available(); + $this->assertFalse( $result ); // Should return false (retire_view_switch filter is true by default) + } + + /** + * Test that deprecated static is_jetpack_forms_announcing_new_menu method still works + */ + public function test_deprecated_static_is_jetpack_forms_announcing_new_menu_still_works() { + $result = Dashboard_View_Switch::is_jetpack_forms_announcing_new_menu(); + $this->assertTrue( $result ); // Should return true (default filter value) + } + + /** + * Test that deprecated static is_classic_view_available method still works + */ + public function test_deprecated_static_is_classic_view_available_still_works() { + $result = Dashboard_View_Switch::is_classic_view_available(); + $this->assertIsBool( $result ); + } + + /** + * Test class constants are still accessible + */ + public function test_class_constants() { + $this->assertEquals( 'classic', Dashboard_View_Switch::CLASSIC_VIEW ); + $this->assertEquals( 'modern', Dashboard_View_Switch::MODERN_VIEW ); + } + + /** + * Test that the deprecated class is properly marked with @deprecated annotation + */ + public function test_class_has_deprecation_annotation() { + $reflection = new \ReflectionClass( Dashboard_View_Switch::class ); + $doc_comment = $reflection->getDocComment(); + + $this->assertStringContainsString( '@deprecated', $doc_comment ); + $this->assertStringContainsString( 'This class is no longer needed', $doc_comment ); + } +} From 9c62d1c62e295256d4c8856ea21827c869e85bef Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Wed, 24 Sep 2025 01:46:12 -0300 Subject: [PATCH 11/12] update phan baseline after deprecation tests --- projects/packages/forms/.phan/baseline.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/projects/packages/forms/.phan/baseline.php b/projects/packages/forms/.phan/baseline.php index 2ec6ef1124c32..d244c961dff67 100644 --- a/projects/packages/forms/.phan/baseline.php +++ b/projects/packages/forms/.phan/baseline.php @@ -11,16 +11,19 @@ // # Issue statistics: // PhanTypeMismatchArgument : 45+ occurrences // PhanPluginDuplicateConditionalNullCoalescing : 30+ occurrences + // PhanDeprecatedFunction : 8 occurrences // PhanTypeMismatchReturnProbablyReal : 8 occurrences // PhanTypeMismatchArgumentProbablyReal : 6 occurrences // PhanPluginDuplicateAdjacentStatement : 3 occurrences // PhanTypeConversionFromArray : 2 occurrences // PhanTypeMismatchReturn : 2 occurrences + // PhanDeprecatedClass : 1 occurrence // PhanPluginMixedKeyNoKey : 1 occurrence // PhanPluginRedundantAssignment : 1 occurrence // PhanPossiblyNullTypeMismatchProperty : 1 occurrence // PhanTypeArraySuspiciousNullable : 1 occurrence // PhanTypeMismatchReturnNullable : 1 occurrence + // PhanUnreferencedUseNormal : 1 occurrence // Currently, file_suppressions and directory_suppressions are the only supported suppressions 'file_suppressions' => [ @@ -29,8 +32,10 @@ 'src/contact-form/class-contact-form-plugin.php' => ['PhanPluginDuplicateAdjacentStatement', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchReturnProbablyReal'], 'src/contact-form/class-contact-form-shortcode.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchReturnProbablyReal'], 'src/contact-form/class-contact-form.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginRedundantAssignment', 'PhanTypeMismatchArgument', 'PhanTypeMismatchReturnNullable', 'PhanTypeMismatchReturnProbablyReal'], + 'src/dashboard/class-dashboard-view-switch.php' => ['PhanDeprecatedFunction', 'PhanUnreferencedUseNormal'], 'src/service/class-google-drive.php' => ['PhanTypeMismatchReturnProbablyReal'], 'tests/php/contact-form/Contact_Form_Plugin_Test.php' => ['PhanPluginMixedKeyNoKey'], + 'tests/php/dashboard/Dashboard_View_Switch_Test.php' => ['PhanDeprecatedClass', 'PhanDeprecatedFunction'], ], // 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed. // (directory_suppressions will currently be ignored by subsequent calls to --save-baseline, but may be preserved in future Phan releases) From 4f5ef235a1c87599cc41ae22abbdd968d2fb9680 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Wed, 24 Sep 2025 09:37:12 -0300 Subject: [PATCH 12/12] improve append_tab_to_url method --- .../forms/src/dashboard/class-dashboard.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/projects/packages/forms/src/dashboard/class-dashboard.php b/projects/packages/forms/src/dashboard/class-dashboard.php index 40a45b10fbeb7..3f4eafd68d3c7 100644 --- a/projects/packages/forms/src/dashboard/class-dashboard.php +++ b/projects/packages/forms/src/dashboard/class-dashboard.php @@ -178,21 +178,12 @@ public static function get_forms_admin_url( $tab = null ) { * @return string */ private static function append_tab_to_url( $url, $tab ) { - if ( ! $tab ) { + $valid_tabs = array( 'spam', 'inbox', 'trash' ); + if ( ! in_array( $tab, $valid_tabs, true ) ) { return $url; } - $status_map = array( - 'spam' => 'spam', - 'inbox' => 'inbox', - 'trash' => 'trash', - ); - - if ( ! isset( $status_map[ $tab ] ) ) { - return $url; - } - - return $url . '#/responses?status=' . $status_map[ $tab ]; + return $url . '#/responses?status=' . $tab; } /**