['label' => ..., 'callback' => callable]]. * @type bool $support_module Si true, ajoute auto un onglet 'support' avec Support+Avis 2 colonnes. * @type string $logo_url URL du logo AIFORYA (défaut : auto depuis assets/). * @type string $plugin_basename Basename du plugin (ex: 'aiforya-cart-recovery-ai/aiforya-cart-recovery-ai.php') * utilisé pour Support form. * } */ public static function render_admin_page( array $args ): void { $defaults = [ 'slug' => '', 'title' => '', 'description' => '', 'tabs' => [], 'support_module' => false, 'logo_url' => self::get_assets_base_url() . 'assets/aiforya-logo.svg', 'plugin_basename' => '', ]; $args = array_merge( $defaults, $args ); // Onglet actif : depuis $_GET['tab'] ou premier tab. $first_tab = $args['tabs'] ? array_key_first( $args['tabs'] ) : ''; // Read-only tab navigation: the value is sanitized with sanitize_key() and then // validated against the whitelist of declared tabs below. Nothing is written, and a // nonce here would break every admin tab link and bookmark. // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only tab navigation, sanitized with sanitize_key() and validated against the declared tabs; no state change. $active_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : $first_tab; if ( ! isset( $args['tabs'][ $active_tab ] ) ) { $active_tab = $first_tab; } ?>

0 ) : ?> natif synchronisé avec la nav desktop. Visible uniquement < 782px (cf aiforya-shell.css §13b). */ ?>

%s

', esc_html__( 'This tab has no valid render callback.', 'aiforya-faq-generator' ) ); } else { printf( '

%s

', esc_html__( 'No tab configured for this plugin.', 'aiforya-faq-generator' ) ); } ?> $args['slug'], 'page_title' => $args['title'], 'menu_title' => $args['title'], 'plugin_name' => $args['title'], 'plugin_image' => $args['plugin_image'] ?? '', 'category' => $args['category'] ?? '', 'description' => $args['description'] ?? '', 'capability' => $args['capability'] ?? 'manage_options', 'callback' => function () use ( $args ) { AIFORYA_FAQ_Shell::render_admin_page( $args ); }, 'icon' => $args['icon'] ?? 'dashicons-admin-generic', 'position' => $args['position'] ?? 20, ] ); } } // Auto-init au plugins_loaded — idempotent grâce à did_action. add_action( 'plugins_loaded', [ 'AIFORYA_FAQ_Shell', 'init' ], 5 );