diff --git a/admin/disable-wp-admin.php b/admin/disable-wp-admin.php index d640f4f..0750bf5 100644 --- a/admin/disable-wp-admin.php +++ b/admin/disable-wp-admin.php @@ -1,119 +1,172 @@ id, array( 'toplevel_page_helix', 'toplevel_page_wordpress-admin' ), true ) ) { - return; - } - - // Check if user wants to use default WordPress admin - $use_default_admin = get_option('helix_use_default_admin', false); - if ($use_default_admin) { - return; - } - - // Don't redirect if Helix is not ready or the user opted into default admin - if (!helix_should_hijack_admin()) { - return; - } +/** + * Redirect the user to the Helix admin page when accessing an admin page. + * + * @param WP_Screen $current_screen The current screen object. + */ +add_action( + 'current_screen', + function ( $current_screen ) { + // Don't redirect if not in admin. + if ( ! is_admin() ) { + return; + } - // Don't redirect critical WordPress admin functions - global $pagenow; - $critical_pages = [ - 'admin-ajax.php', - 'admin-post.php', - 'async-upload.php', - 'update.php', - 'update-core.php', - 'upgrade.php', - ]; - - if (in_array($pagenow, $critical_pages)) return; - - // Capture the current admin URL to pass to Helix for routing - $current_url = helix_normalize_route($_SERVER['REQUEST_URI']); - - // Build the redirect URL with the original path for React routing - // Always use '&' because admin.php already has a query string (page=helix) - $redirect_url = admin_url('admin.php?page=helix&helix_route=' . urlencode($current_url)); - - // Redirect all other admin pages to Helix - wp_redirect($redirect_url); - exit; -}); + // Don't redirect AJAX requests. + if ( wp_doing_ajax() ) { + return; + } + + // Don't redirect REST API requests. + if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + return; + } + + // Don't redirect cron jobs. + if ( defined( 'DOING_CRON' ) && DOING_CRON ) { + return; + } + + // Check if we're already on the helix page or WordPress admin page. + if ( in_array( $current_screen->id, array( 'toplevel_page_helix', 'toplevel_page_wordpress-admin' ), true ) ) { + return; + } + + // Check if user wants to use default WordPress admin. + $use_default_admin = get_option( 'helix_use_default_admin', false ); + if ( $use_default_admin ) { + return; + } + + // Don't redirect if Helix is not ready or the user opted into default admin. + if ( ! helix_should_hijack_admin() ) { + return; + } + + // Don't redirect critical WordPress admin functions. + global $pagenow; + $critical_pages = array( + 'admin-ajax.php', + 'admin-post.php', + 'async-upload.php', + 'update.php', + 'update-core.php', + 'upgrade.php', + ); + + if ( in_array( $pagenow, $critical_pages, true ) ) { + return; + } + + // Capture the current admin URL to pass to Helix for routing. + $current_url = helix_normalize_route( filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL ) ); + + // Build the redirect URL with the original path for React routing. + // Always use '&' because admin.php already has a query string (page=helix). + $redirect_url = admin_url( 'admin.php?page=helix&helix_route=' . rawurlencode( $current_url ) ); + + // Redirect all other admin pages to Helix. + wp_safe_redirect( $redirect_url ); + exit; + } +); diff --git a/admin/init.php b/admin/init.php index 199ce9c..f92f18c 100644 --- a/admin/init.php +++ b/admin/init.php @@ -1,6 +1,35 @@ '; - }, 'dashicons-admin-generic', 1); -}); +/** + * Registers the Helix admin top-level menu page. + * + * @package Helix + */ + +add_action( + 'admin_menu', + function () { + $helix_hook_suffix = add_menu_page( + 'Helix', + 'Helix', + 'read', + 'helix', + function () { + echo '
'; + }, + 'dashicons-admin-generic', + 1 + ); + + if ( $helix_hook_suffix ) { + // Mark when the Helix screen is loading. Used elsewhere to conditionally modify admin UI. + add_action( + "load-$helix_hook_suffix", + function () { + $GLOBALS['helix_is_current_screen'] = true; + // Ensure we are in Helix mode when visiting the Helix page. + update_option( 'helix_use_default_admin', false ); + } + ); + } + } +); diff --git a/admin/menu-customization.php b/admin/menu-customization.php index 5b7cc4c..71fdc8f 100644 --- a/admin/menu-customization.php +++ b/admin/menu-customization.php @@ -1,127 +1,156 @@ id ) { + return; + } - // Remove all admin menu separators - remove_all_admin_menu_separators(); -}, 999); // High priority to run after other plugins + // 1) Remove default WordPress admin menus when viewing Helix. + remove_menu_page( 'index.php' ); // Dashboard. + remove_menu_page( 'edit.php' ); // Posts. + remove_menu_page( 'upload.php' ); // Media. + remove_menu_page( 'edit.php?post_type=page' ); // Pages. + remove_menu_page( 'edit-comments.php' ); // Comments. + remove_menu_page( 'themes.php' ); // Appearance. + remove_menu_page( 'plugins.php' ); // Plugins. + remove_menu_page( 'users.php' ); // Users. + remove_menu_page( 'tools.php' ); // Tools. + remove_menu_page( 'options-general.php' ); // Settings. + // Remove all admin menu separators. + remove_all_admin_menu_separators(); + + // 2) Ensure the "WordPress Admin" return link is present on first load. + if ( ! get_option( 'helix_use_default_admin', false ) ) { + global $admin_page_hooks; + if ( ! isset( $admin_page_hooks['wordpress-admin'] ) ) { + add_menu_page( + 'WordPress Admin', + 'WordPress Admin', + 'read', + 'wordpress-admin', + 'wordpress_admin_callback', + 'dashicons-wordpress', + 2 + ); + } + } + + // 3) Add custom Helix menu items. + add_menu_page( + 'Helix Posts', + 'Posts', + 'edit_posts', + 'helix-posts', + 'helix_posts_callback', + 'dashicons-admin-post', + 3 + ); + + add_menu_page( + 'Helix Users', + 'Users', + 'list_users', + 'helix-users', + 'helix_users_callback', + 'dashicons-admin-users', + 4 + ); + }, + 10 +); + +/** + * Ensure the "WordPress Admin" return link is present when landing on Helix, even on the first load + * after switching modes in the same request. + */ + +/** + * Remove all admin menu separators. + */ function remove_all_admin_menu_separators() { - global $menu; - if (is_array($menu)) { - foreach ($menu as $key => $item) { - // Check if menu item is a separator - if ( false !== strpos( $item[4], 'wp-menu-separator' ) ) { - unset( $menu[ $key ] ); - } - } - } + global $menu; + if ( is_array( $menu ) ) { + foreach ( $menu as $key => $item ) { + // Check if menu item is a separator. + if ( false !== strpos( $item[4], 'wp-menu-separator' ) ) { + unset( $menu[ $key ] ); + } + } + } } /** - * Add custom menu items + * Add WordPress Admin menu item conditionally. */ +add_action( + 'admin_menu', + function () { + // Only show the "WordPress Admin" link when in Helix mode. + $use_default_admin = get_option( 'helix_use_default_admin', false ); + if ( $use_default_admin ) { + return; + } -// Add WordPress Admin menu item conditionally -add_action('admin_menu', function () { - // Reset to Helix mode when accessing Helix page (do this before checking the option) - if (isset($_GET['page']) && $_GET['page'] === 'helix') { - update_option('helix_use_default_admin', false); - } - - // Only show the "WordPress Admin" link when in Helix mode. - $use_default_admin = get_option('helix_use_default_admin', false); - if ($use_default_admin) { - return; - } + // Add a menu item to go back to default WordPress admin. + add_menu_page( + 'WordPress Admin', // Page title. + 'WordPress Admin', // Menu title. + 'read', // Capability. + 'wordpress-admin', // Menu slug. + 'wordpress_admin_callback', // Callback function. + 'dashicons-wordpress', // Icon. + 2 // Position (after main Helix menu). + ); + }, + 1000 +); - // Add a menu item to go back to default WordPress admin - add_menu_page( - 'WordPress Admin', // Page title - 'WordPress Admin', // Menu title - 'read', // Capability - 'wordpress-admin', // Menu slug - 'wordpress_admin_callback', // Callback function - 'dashicons-wordpress', // Icon - 2 // Position (after main Helix menu) - ); -}, 1000); // Higher priority to run after menu removal +/** + * Add custom Helix menu items (only when on Helix page). + */ +/* previous current_screen callbacks combined into the single handler above */ -// Add custom Helix menu items (only when on Helix page) -add_action('admin_menu', function () { - // Only add when on Helix page - if (!isset($_GET['page']) || $_GET['page'] !== 'helix') { - return; - } - - // Example: Add a Posts menu item - add_menu_page( - 'Helix Posts', - 'Posts', - 'edit_posts', - 'helix-posts', - 'helix_posts_callback', - 'dashicons-admin-post', - 3 - ); - - // Example: Add a Users menu item - add_menu_page( - 'Helix Users', - 'Users', - 'list_users', - 'helix-users', - 'helix_users_callback', - 'dashicons-admin-users', - 4 - ); - -}, 1001); // Even higher priority to run after WordPress Admin menu - -// Callback functions for custom menu items +/** + * Callback functions for custom menu items. + */ function wordpress_admin_callback() { - // Set the option to use default WordPress admin - update_option('helix_use_default_admin', true); - - // Show a clean message and let the user navigate naturally - ?> -
-

✓ Switched to WordPress Admin

-

You can now navigate to any WordPress admin page normally.

-

Go to Dashboard

-

Posts - Users - Settings

-
- +
+

✓ Switched to WordPress Admin

+

You can now navigate to any WordPress admin page normally.

+

Go to Dashboard

+

Posts + Users + Settings +

+
+ '; + echo '
'; } +/** + * Callback function for Users menu item. + */ function helix_users_callback() { - echo '
'; + echo '
'; } - \ No newline at end of file diff --git a/admin/rest-routes.php b/admin/rest-routes.php index 99e307c..d3f27f0 100644 --- a/admin/rest-routes.php +++ b/admin/rest-routes.php @@ -1,13 +1,26 @@ 'GET', - 'permission_callback' => '__return_true', - 'callback' => function () { - return [ - 'siteTitle' => get_option('blogname'), - 'language' => get_option('WPLANG'), - ]; - } - ]); -}); +/** + * Registers REST API routes for Helix. + * + * @package Helix + */ + +add_action( + 'rest_api_init', + function () { + register_rest_route( + 'helix/v1', + '/settings', + array( + 'methods' => 'GET', + 'permission_callback' => '__return_true', + 'callback' => function () { + return array( + 'siteTitle' => get_option( 'blogname' ), + 'language' => get_option( 'WPLANG' ), + ); + }, + ) + ); + } +); diff --git a/composer.json b/composer.json index 92cd704..e53bacb 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "Helix", + "name": "helix/helix", "description": "Helix – Modern WP Admin", "type": "project", "license": "GPL-2.0-or-later", diff --git a/enqueue.php b/enqueue.php index 1bb8e17..f9283da 100644 --- a/enqueue.php +++ b/enqueue.php @@ -1,17 +1,39 @@ esc_url_raw(rest_url('helix/v1/')), - 'nonce' => wp_create_nonce('wp_rest'), - 'user' => wp_get_current_user(), - 'originalRoute' => $original_route, - 'adminUrl' => admin_url(), - ]); -}); +add_action( + 'admin_enqueue_scripts', + function ( $hook ) { + if ( 'toplevel_page_helix' !== $hook ) { + return; + } + + wp_enqueue_script( + 'helix-app', + plugin_dir_url( __FILE__ ) . 'build/index.js', + array(), + '0.1.0', + array() + ); + + // Get the original route that was redirected. + $original_route = filter_input( INPUT_GET, 'helix_route', FILTER_SANITIZE_URL ); + $original_route = $original_route ? esc_url_raw( $original_route ) : '/wp-admin/'; + + wp_localize_script( + 'helix-app', + 'helixData', + array( + 'restUrl' => esc_url_raw( rest_url( 'helix/v1/' ) ), + 'nonce' => wp_create_nonce( 'wp_rest' ), + 'user' => wp_get_current_user(), + 'originalRoute' => $original_route, + 'adminUrl' => admin_url(), + ) + ); + } +); diff --git a/helix.php b/helix.php index a14bbd5..2adf458 100644 --- a/helix.php +++ b/helix.php @@ -1,10 +1,16 @@