Move the settings screen to its own top-level menu
Adds an "M365 Login" menu entry with a Microsoft-style icon and one submenu per tab (Connection, Button, Security). The active tab is taken from the URL, kept in the post-save redirect and highlighted in the submenu. Notices are printed explicitly because top-level pages do not include options-head.php. Links, docs and screenshots updated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJxAHYdMfKPoN4koRc4Ci2
This commit is contained in:
parent
8766927123
commit
662756bc75
12 changed files with 664 additions and 576 deletions
|
|
@ -18,6 +18,7 @@ class M365_Login_Admin {
|
|||
const AJAX_GROUPS = 'm365_login_search_groups';
|
||||
const AJAX_CERT = 'm365_login_certificate';
|
||||
const POST_CERT = 'm365_login_download_cert';
|
||||
const MENU_ICON = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+PHBhdGggZmlsbD0iYmxhY2siIGQ9Ik0yIDJoNy41djcuNUgyek0xMC41IDJIMTh2Ny41aC03LjV6TTIgMTAuNWg3LjVWMThIMnpNMTAuNSAxMC41SDE4VjE4aC03LjV6Ii8+PC9zdmc+';
|
||||
const NONCE_TEST = 'm365_login_test';
|
||||
|
||||
/**
|
||||
|
|
@ -69,19 +70,85 @@ class M365_Login_Admin {
|
|||
add_action( 'admin_post_' . self::POST_CERT, array( $this, 'download_certificate' ) );
|
||||
add_action( 'update_option_' . M365_LOGIN_OPTION, array( $this->graph, 'flush_token' ) );
|
||||
add_action( 'admin_notices', array( $this, 'setup_notice' ) );
|
||||
add_filter( 'submenu_file', array( $this, 'highlight_submenu' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the menu entry under Settings.
|
||||
* Adds a top-level menu entry with one submenu per tab.
|
||||
*/
|
||||
public function menu() {
|
||||
$this->hook = add_options_page(
|
||||
$this->hook = add_menu_page(
|
||||
__( 'M365 Login', 'm365-login' ),
|
||||
__( 'M365 Login', 'm365-login' ),
|
||||
'manage_options',
|
||||
self::PAGE,
|
||||
array( $this, 'render' )
|
||||
array( $this, 'render' ),
|
||||
self::MENU_ICON,
|
||||
81
|
||||
);
|
||||
|
||||
foreach ( self::tabs() as $tab => $label ) {
|
||||
add_submenu_page(
|
||||
self::PAGE,
|
||||
$label . ' – ' . __( 'M365 Login', 'm365-login' ),
|
||||
$label,
|
||||
'manage_options',
|
||||
'connection' === $tab ? self::PAGE : 'admin.php?page=' . self::PAGE . '&tab=' . $tab
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tab slugs and labels.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function tabs() {
|
||||
return array(
|
||||
'connection' => __( 'Connection', 'm365-login' ),
|
||||
'button' => __( 'Button', 'm365-login' ),
|
||||
'security' => __( 'Security', 'm365-login' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently requested tab (from ?tab=).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function current_tab() {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only UI state.
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';
|
||||
return array_key_exists( $tab, self::tabs() ) ? $tab : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights the submenu entry matching the requested tab.
|
||||
*
|
||||
* @param string|null $submenu_file Current submenu file.
|
||||
* @return string|null
|
||||
*/
|
||||
public function highlight_submenu( $submenu_file ) {
|
||||
$screen = get_current_screen();
|
||||
if ( ! $screen || $this->hook !== $screen->id ) {
|
||||
return $submenu_file;
|
||||
}
|
||||
$tab = $this->current_tab();
|
||||
if ( '' === $tab || 'connection' === $tab ) {
|
||||
return self::PAGE;
|
||||
}
|
||||
return 'admin.php?page=' . self::PAGE . '&tab=' . $tab;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL of the settings screen (optionally a specific tab).
|
||||
*
|
||||
* @param string $tab Tab slug.
|
||||
* @return string
|
||||
*/
|
||||
public static function url( $tab = '' ) {
|
||||
$url = admin_url( 'admin.php?page=' . self::PAGE );
|
||||
return '' === $tab ? $url : add_query_arg( 'tab', $tab, $url );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -116,7 +183,7 @@ class M365_Login_Admin {
|
|||
printf(
|
||||
'<div class="notice notice-info is-dismissible"><p>%s <a href="%s">%s</a></p></div>',
|
||||
esc_html__( 'M365 Login is active but not connected to Microsoft Entra ID yet.', 'm365-login' ),
|
||||
esc_url( admin_url( 'options-general.php?page=' . self::PAGE ) ),
|
||||
esc_url( self::url() ),
|
||||
esc_html__( 'Open the settings', 'm365-login' )
|
||||
);
|
||||
}
|
||||
|
|
@ -322,13 +389,16 @@ class M365_Login_Admin {
|
|||
</span>
|
||||
</header>
|
||||
|
||||
<?php settings_errors(); ?>
|
||||
|
||||
<form method="post" action="options.php" class="m365-admin__form" novalidate>
|
||||
<?php settings_fields( self::GROUP ); ?>
|
||||
<input type="hidden" name="_wp_http_referer" value="<?php echo esc_attr( self::url( $this->current_tab() ) ); ?>" id="m365-referer" />
|
||||
|
||||
<nav class="m365-admin__tabs" role="tablist">
|
||||
<button type="button" class="m365-admin__tab is-active" role="tab" data-tab="connection" aria-selected="true"><?php esc_html_e( 'Connection', 'm365-login' ); ?></button>
|
||||
<button type="button" class="m365-admin__tab" role="tab" data-tab="button" aria-selected="false"><?php esc_html_e( 'Button', 'm365-login' ); ?></button>
|
||||
<button type="button" class="m365-admin__tab" role="tab" data-tab="security" aria-selected="false"><?php esc_html_e( 'Security', 'm365-login' ); ?></button>
|
||||
<nav class="m365-admin__tabs" role="tablist" data-initial-tab="<?php echo esc_attr( $this->current_tab() ); ?>">
|
||||
<?php foreach ( self::tabs() as $tab => $label ) : ?>
|
||||
<button type="button" class="m365-admin__tab<?php echo 'connection' === $tab ? ' is-active' : ''; ?>" role="tab" data-tab="<?php echo esc_attr( $tab ); ?>" aria-selected="<?php echo 'connection' === $tab ? 'true' : 'false'; ?>"><?php echo esc_html( $label ); ?></button>
|
||||
<?php endforeach; ?>
|
||||
</nav>
|
||||
|
||||
<div class="m365-admin__layout">
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ final class M365_Login {
|
|||
* @return string[]
|
||||
*/
|
||||
public function action_links( $links ) {
|
||||
$url = admin_url( 'options-general.php?page=m365-login' );
|
||||
$url = admin_url( 'admin.php?page=m365-login' );
|
||||
array_unshift( $links, '<a href="' . esc_url( $url ) . '">' . esc_html__( 'Settings', 'm365-login' ) . '</a>' );
|
||||
return $links;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue