settings = $settings; } public function register() { add_action( 'admin_menu', array( $this, 'menu' ), 99 ); add_action( 'admin_enqueue_scripts', array( $this, 'assets' ) ); add_action( 'in_admin_header', array( $this, 'strip_preview_chrome' ), 0 ); add_filter( 'admin_body_class', array( $this, 'body_class' ) ); add_filter( 'parent_file', array( $this, 'highlight_artbees_menu' ) ); add_filter( 'submenu_file', array( $this, 'highlight_quick_view_submenu' ) ); } public function menu() { if ( ! $this->artbees_parent_exists() ) { add_menu_page( __( 'Artbees', 'artbees-quick-view' ), __( 'Artbees', 'artbees-quick-view' ), 'manage_woocommerce', self::ARTBEES_MENU_SLUG, array( $this, 'redirect_to_workspace' ), $this->admin_menu_icon(), 56 ); } add_submenu_page( self::ARTBEES_MENU_SLUG, __( 'Artbees Quick View', 'artbees-quick-view' ), __( 'Quick View', 'artbees-quick-view' ), 'manage_woocommerce', 'artbees-quick-view', array( $this, 'setup_screen' ) ); remove_submenu_page( self::ARTBEES_MENU_SLUG, self::ARTBEES_MENU_SLUG ); // A null parent makes admin-header.php pass null into strip_tags(). These // screens stay URL-reachable and keep the admin_page_{slug} hook Pro matches. // WordPress recalculates the parent after parent_file filters, so the hidden // parent is mapped back to Artbees and Quick View stays highlighted. $this->hidden_screen( __( 'Quick View Settings', 'artbees-quick-view' ), __( 'Settings', 'artbees-quick-view' ), 'artbees-quick-view-settings', array( $this, 'settings_screen' ) ); $this->hidden_screen( __( 'Quick View Visibility', 'artbees-quick-view' ), __( 'Visibility', 'artbees-quick-view' ), 'artbees-quick-view-visibility', array( $this, 'visibility_screen' ) ); $this->hidden_screen( __( 'Quick View Status', 'artbees-quick-view' ), __( 'Status', 'artbees-quick-view' ), 'artbees-quick-view-status', array( $this, 'status_screen' ) ); if ( defined( 'artbees_QV_PRO_VERSION' ) ) { $this->hidden_screen( __( 'Quick View Advanced', 'artbees-quick-view' ), __( 'Advanced', 'artbees-quick-view' ), 'artbees-quick-view-advanced', array( $this, 'advanced_screen' ) ); } $this->hidden_screen( __( 'Quick View preview', 'artbees-quick-view' ), __( 'Quick View preview', 'artbees-quick-view' ), 'artbees-quick-view-preview', array( $this, 'preview_screen' ) ); global $_wp_real_parent_file; if ( ! is_array( $_wp_real_parent_file ) ) { $_wp_real_parent_file = array(); } $_wp_real_parent_file[ self::HIDDEN_PARENT ] = self::ARTBEES_MENU_SLUG; } private function hidden_screen( $page_title, $menu_title, $slug, $callback ) { global $_registered_pages; add_submenu_page( self::HIDDEN_PARENT, $page_title, $menu_title, 'manage_woocommerce', $slug, $callback ); // Authorization resolves the highlighted Artbees parent and checks that hook. if ( ! is_array( $_registered_pages ) ) { $_registered_pages = array(); } $_registered_pages[ get_plugin_page_hookname( $slug, self::ARTBEES_MENU_SLUG ) ] = true; } public function redirect_to_workspace() { wp_safe_redirect( admin_url( 'admin.php?page=artbees-quick-view' ) ); exit; } private function artbees_parent_exists() { global $menu; foreach ( is_array( $menu ) ? $menu : array() as $menu_item ) { if ( is_array( $menu_item ) && isset( $menu_item[2] ) && self::ARTBEES_MENU_SLUG === $menu_item[2] ) { return true; } } return false; } private function admin_menu_icon() { $path = __DIR__ . '/assets/artbees-admin-menu-icon.svg'; if ( ! is_readable( $path ) ) { return 'dashicons-art'; } $svg = file_get_contents( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents return is_string( $svg ) && '' !== $svg ? 'data:image/svg+xml;base64,' . base64_encode( $svg ) : 'dashicons-art'; // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode } public function highlight_artbees_menu( $parent_file ) { return $this->is_workspace_page() && $this->artbees_parent_exists() ? self::ARTBEES_MENU_SLUG : $parent_file; } public function highlight_quick_view_submenu( $submenu_file ) { return $this->is_workspace_page() ? 'artbees-quick-view' : $submenu_file; } private function is_workspace_page() { $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin page identifier. return 'artbees-quick-view' === $page || 0 === strpos( $page, 'artbees-quick-view-' ); } public function setup_screen() { $this->screen( 'setup' ); } public function settings_screen() { $this->screen( 'settings' ); } public function visibility_screen() { $this->screen( 'visibility' ); } public function status_screen() { $this->screen( 'status' ); } public function advanced_screen() { $this->screen( 'advanced' ); } public function preview_screen() { $this->screen( 'preview' ); } public function is_preview_page() { return isset( $_GET['page'] ) && 'artbees-quick-view-preview' === $_GET['page']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin page flag. } public function strip_preview_chrome() { if ( ! $this->is_preview_page() ) { return; } remove_all_actions( 'admin_notices' ); remove_all_actions( 'all_admin_notices' ); remove_all_actions( 'user_admin_notices' ); remove_all_actions( 'network_admin_notices' ); } public function body_class( $classes ) { if ( $this->is_preview_page() ) { $classes .= ' artbees-qv-preview-page'; } return $classes; } private function screen( $tab ) { if ( ! current_user_can( 'manage_woocommerce' ) ) { wp_die( esc_html__( 'You do not have permission to manage Artbees Quick View for WooCommerce.', 'artbees-quick-view' ) ); } if ( 'advanced' === $tab && defined( 'artbees_QV_PRO_VERSION' ) ) { echo '
' . esc_html__( 'Loading Quick View…', 'artbees-quick-view' ) . '
' . esc_html__( 'Loading Artbees Quick View for WooCommerce preview…', 'artbees-quick-view' ) . '
' . esc_html__( 'Loading Artbees Quick View for WooCommerce settings…', 'artbees-quick-view' ) . '