JezK
Edit File: LegacySwitcher.php
<?php namespace WeDevs\Dokan\Admin\Dashboard; use WeDevs\Dokan\Contracts\Hookable; /** * LegacySwitcher Class * * Handles legacy URL switching and menu title clearing for admin dashboard and settings. * * @since 4.1.3 */ class LegacySwitcher implements Hookable { /** * Value of `dokan_action` that triggers the product editor switch. * * @since 5.0.0 */ public const PRODUCT_EDITOR_SWITCH_ACTION = 'switch_product_editor'; /** * Default transient expiration time in seconds (15 days) * * @since 4.1.3 * * @var int */ protected int $transient_expiration = 15 * DAY_IN_SECONDS; /** * Register hooks for the LegacySwitcher * * @since 4.1.3 * * @return void */ public function register_hooks(): void { add_action( 'admin_menu', [ $this, 'handle_dokan_admin_submenu' ], 20 ); add_action( 'admin_init', [ $this, 'handle_dashboard_redirect' ] ); } /** * Clear admin submenu title based on legacy dashboard preference. * * @since 4.1.3 * * @return void */ public function handle_dokan_admin_submenu(): void { global $submenu; // Check if the submenu exists. if ( ! isset( $submenu['dokan'] ) || ! is_array( $submenu['dokan'] ) ) { return; } // Filter the submenu items based on legacy dashboard preference. $filtered = array_reduce( $submenu['dokan'], function ( $filtered, $menu_item ) { $menu_title = explode( ' <', $menu_item[0] ); $title = sanitize_title_with_dashes( $menu_title[0] ); $is_legacy = get_transient( 'dokan_legacy_' . $title . '_page' ); $is_new_dashboard = strpos( $menu_item[2], 'dokan-dashboard' ) !== false; // Handle the admin dashboard menu item based on legacy dashboard preference. // Dashboard legacy and the new menu should keep (both) for the frontend mounting purpose, that's why we are handling the dashboard menu item separately. if ( 'dashboard' === $title ) { // Clear the title if the legacy dashboard is enabled. if ( $is_new_dashboard && $is_legacy ) { $menu_item[0] = ''; } // Clear the title and update the url if the legacy dashboard is disabled. if ( ! $is_new_dashboard && ! $is_legacy ) { $menu_item[0] = ''; $menu_item[2] = 'admin.php?page=dokan-dashboard'; } // Add dashboard menu item based on legacy dashboard preference. $filtered[] = $menu_item; return $filtered; } // Check if the menu item for handle the admin legacy page switching. if ( isset( $menu_item[2] ) && $is_new_dashboard ) { if ( ! $is_legacy ) { $filtered[ $title ] = $menu_item; } } elseif ( ! isset( $filtered[ $title ] ) ) { $filtered[ $title ] = $menu_item; } return $filtered; }, [] ); $submenu['dokan'] = array_values( $filtered ); // phpcs:ignore } /** * Handle dashboard redirect based on legacy dashboard preference. * * @since 4.1.3 * * @return void */ public function handle_dashboard_redirect(): void { // Early return if not a switch request. if ( ! isset( $_GET['dokan_action'] ) || 'switch_admin_panel' !== sanitize_key( wp_unslash( $_GET['dokan_action'] ) ) ) { return; } // Early return if nonce verification fails. if ( ! isset( $_GET['dokan_admin_switching_nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['dokan_admin_switching_nonce'] ) ), 'dokan_switch_admin_panel' ) ) { return; } $legacy_key = sanitize_key( wp_unslash( $_GET['legacy_key'] ?? 'dashboard' ) ); $filtered_legacy_key = $this->get_custom_transient_key( $legacy_key ); $current_is_legacy = get_transient( $filtered_legacy_key ); $new_legacy_state = ! $current_is_legacy; if ( $current_is_legacy ) { delete_transient( $filtered_legacy_key ); } else { set_transient( $filtered_legacy_key, $new_legacy_state, $this->transient_expiration ); } // Redirect to the new admin page, if needed. $page_slug = $new_legacy_state ? 'dokan' : 'dokan-dashboard'; $endpoint = str_replace( 'dashboard', '', $legacy_key ); // Remove 'dashboard' from the endpoint as the default endpoint. $redirect_url = add_query_arg( [ 'page' => $page_slug ], admin_url( 'admin.php' ) ) . '#/' . $endpoint; // TODO: Remove this legacy option cleanup after 2-3 versions // Check if the legacy option exists and remove it. $legacy_dashboard_page = get_option( 'dokan_legacy_dashboard_page', false ); if ( $legacy_dashboard_page ) { // This removes the old option from the database as we've migrated to transients. delete_option( 'dokan_legacy_dashboard_page' ); } wp_safe_redirect( $redirect_url ); exit; } /** * Get admin menu transient key. * * @since 4.1.3 * * @param string $key * * @return string */ public function get_custom_transient_key( $key ) { $admin_url_map = apply_filters( 'dokan_admin_legacy_url_map', [ 'refund' => 'refunds', 'request-for-quote' => 'rfq', 'announcement' => 'announcements', 'dokan-seller-badge' => 'seller-badge', 'product-advertising' => 'advertising', 'admin-store-support' => 'store-support', 'product-qa' => 'product-qa', ] ); // Get the legacy key from the map or the original key. $legacy_key = sanitize_key( wp_unslash( $admin_url_map[ $key ] ?? $key ) ); return 'dokan_legacy_' . $legacy_key . '_page'; } /** * Whether the given user prefers the legacy product editor. * * Defaults to `false` — the new (React) product editor. * * @since 5.0.0 * * @param int $user_id Optional. Defaults to current user. * * @return bool */ public function is_product_editor_legacy_preferred( int $user_id = 0 ): bool { if ( ! $user_id ) { $user_id = get_current_user_id(); } // Anonymous context (cron, emails without a current user) → prefer the new editor. if ( ! $user_id ) { return false; } $appearance = get_option( 'dokan_appearance', [] ); if ( isset( $appearance['vendor_product_editor'] ) && 'latest' === $appearance['vendor_product_editor'] ) { return false; } return true; } /** * Build the new (React) product editor URL. * * @since 5.0.0 * * @param int $product_id * * @return string */ public function get_new_product_editor_url( int $product_id ): string { // `dokan_get_navigation_url( 'products', true )` already ends with `#products/`. $base = dokan_get_navigation_url( 'products', true ); $suffix = $product_id ? $product_id . '/edit' : 'create'; return $base . $suffix; } /** * Build the legacy product editor URL, falling back to the * create-new-product URL when no product id is supplied. * * @since 5.0.0 * * @param int $product_id * * @return string */ protected function get_legacy_product_editor_url( int $product_id ): string { if ( ! $product_id ) { return (string) dokan_get_new_product_url(); } return (string) dokan_edit_product_url( $product_id ); } }