Files
WooNooW/includes/Admin/Menu.php

158 lines
6.4 KiB
PHP

<?php
namespace WooNooW\Admin;
class Menu {
public static function init() {
add_action('admin_menu', [__CLASS__, 'register']);
// After all plugins/themes add their menus, collect Woo menus for SPA
add_action('admin_head', [__CLASS__, 'localize_wc_menus'], 999);
// Add link to standalone admin in admin bar
add_action('admin_bar_menu', [__CLASS__, 'add_admin_bar_link'], 100);
// Add custom state for SPA Front Page
add_filter('display_post_states', [__CLASS__, 'add_spa_page_state'], 10, 2);
}
public static function register() {
add_menu_page(
'WooNooW',
'WooNooW',
'manage_woocommerce',
'woonoow',
[__CLASS__, 'render'],
'dashicons-store',
55
);
}
public static function render() {
echo '<div id="woonoow-admin-app" class="wrap"></div>';
}
/**
* Collect all WooCommerce-related admin menus (including add-ons) and expose to SPA via window.WNW_WC_MENUS.
*/
public static function localize_wc_menus() : void {
// Ensure we're in admin and script handle exists later; safe to call regardless
global $menu, $submenu;
if ( ! is_array( $menu ) ) return;
$items = [];
$seen = [];
$is_wc_slug = static function(string $slug) : bool {
$s = strtolower($slug);
return (
strpos($s, 'woocommerce') !== false ||
strpos($s, 'wc-admin') !== false ||
strpos($s, 'wc-') === 0 ||
strpos($s, 'edit.php?post_type=product') !== false ||
strpos($s, 'edit.php?post_type=shop_order') !== false ||
strpos($s, 'edit.php?post_type=shop_coupon') !== false
);
};
foreach ( $menu as $m ) {
// $m: [0] title, [1] cap, [2] slug, [3] page_title, [4] class, [5] id, [6] icon, [7] position
if ( ! isset( $m[2] ) || ! is_string( $m[2] ) ) continue;
$slug = (string) $m[2];
if ( ! $is_wc_slug( $slug ) ) continue;
$title = wp_strip_all_tags( (string) ($m[0] ?? $m[3] ?? 'Woo') );
$key = md5( $slug . '|' . $title );
if ( isset($seen[$key]) ) continue;
$seen[$key] = true;
$children = [];
if ( isset($submenu[$slug]) && is_array($submenu[$slug]) ) {
foreach ( $submenu[$slug] as $sm ) {
// $sm: [0] title, [1] cap, [2] slug
$childTitle = wp_strip_all_tags( (string) ($sm[0] ?? '') );
$childSlug = (string) ($sm[2] ?? '' );
if ( $childSlug === '' ) continue;
$children[] = [
'key' => md5( $childSlug . '|' . $childTitle ),
'title' => $childTitle,
'href' => admin_url( $childSlug ),
'slug' => $childSlug,
];
}
}
$items[] = [
'key' => $key,
'title' => $title,
'href' => admin_url( $slug ),
'slug' => $slug,
'children' => $children,
];
}
// Attach to both possible script handles (dev/prod)
foreach ( [ 'wnw-admin-dev-config', 'wnw-admin' ] as $handle ) {
if ( wp_script_is( $handle, 'enqueued' ) || wp_script_is( $handle, 'registered' ) ) {
wp_localize_script( $handle, 'WNW_WC_MENUS', [ 'items' => $items ] );
wp_add_inline_script( $handle, 'window.WNW_WC_MENUS = window.WNW_WC_MENUS || WNW_WC_MENUS;', 'after' );
}
}
// Absolute last resort: inject a tiny inline if no handle was matched (e.g., race condition)
if ( ! isset( $GLOBALS['wp_scripts']->registered['wnw-admin'] ) && ! isset( $GLOBALS['wp_scripts']->registered['wnw-admin-dev-config'] ) ) {
printf( '<script>window.WNW_WC_MENUS = window.WNW_WC_MENUS || %s;</script>', wp_json_encode( [ 'items' => $items ] ) );
}
}
/**
* Add link to standalone admin in WordPress admin bar
*/
public static function add_admin_bar_link( $wp_admin_bar ) {
// Only show for users with WooCommerce permissions
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
$wp_admin_bar->add_node( [
'id' => 'woonoow-standalone',
'title' => '<span class="ab-icon dashicons-store"></span><span class="ab-label">WooNooW</span>',
'href' => home_url( '/admin' ),
'meta' => [
'title' => __( 'WooNooW Standalone Admin', 'woonoow' ),
],
] );
// Add Store link if customer SPA is not disabled
$appearance_settings = get_option('woonoow_appearance_settings', []);
$spa_page_id = $appearance_settings['general']['spa_page'] ?? 0;
$spa_page = get_post($spa_page_id);
$customer_spa_enabled = get_option( 'woonoow_customer_spa_enabled', true );
if ( $customer_spa_enabled && $spa_page) {
$spa_slug = $spa_page->post_name;
$store_url = home_url( '/' . $spa_slug );
$wp_admin_bar->add_node( [
'id' => 'woonoow-store',
'title' => '<span class="ab-icon dashicons-cart"></span><span class="ab-label">' . __( 'Store', 'woonoow' ) . '</span>',
'href' => $store_url,
'meta' => [
'title' => __( 'View Customer Store', 'woonoow' ),
'target' => '_blank',
],
] );
}
}
/**
* Add "WooNooW SPA Page" state to the pages list
*
* @param array $states Array of post states.
* @param \WP_Post $post Current post object.
* @return array Modified post states.
*/
public static function add_spa_page_state($states, $post) {
$settings = get_option('woonoow_appearance_settings', []);
$spa_frontpage_id = $settings['general']['spa_frontpage'] ?? 0;
if ((int)$post->ID === (int)$spa_frontpage_id) {
$states['spa_frontpage'] = __('WooNooW Front Page', 'woonoow');
} elseif (!empty(get_post_meta($post->ID, '_wn_page_structure', true))) {
$states['woonoow_page'] = __('WooNooW Page', 'woonoow');
}
return $states;
}
}