error_handler = $error_handler;
add_action( 'admin_notices', array( $this, 'display_notices' ) );
add_action( 'admin_init', array( $this, 'handle_notice_dismissal' ) );
}
/**
* Display admin notices
*/
public function display_notices(): void {
$screen = get_current_screen();
if ( ! $screen ) {
return;
}
// Only show notices on plugin pages or dashboard.
if ( ! $this->should_show_notices( $screen->id ) ) {
return;
}
// Show error notices.
$this->show_error_notices();
// Show configuration warnings.
$this->show_configuration_warnings();
}
/**
* Check if notices should be shown on current screen
*
* @param string $screen_id Current screen ID.
* @return bool True if notices should be shown.
*/
private function should_show_notices( string $screen_id ): bool {
$allowed_screens = array(
'dashboard',
'toplevel_page_ai-checkout',
'ai-checkout_page_ai-checkout-settings',
'ai-checkout_page_ai-checkout-products',
'ai-checkout_page_ai-checkout-analytics',
'ai-checkout_page_ai-checkout-wizard',
'ai-checkout_page_ai-checkout-testing',
'ai-checkout_page_ai-checkout-logs',
);
return in_array( $screen_id, $allowed_screens, true );
}
/**
* Show error notices from error handler
*/
private function show_error_notices(): void {
$notices = $this->error_handler->get_admin_notices( false );
if ( empty( $notices ) ) {
return;
}
// Group notices by error code to avoid duplicates.
$grouped_notices = array();
foreach ( $notices as $index => $notice ) {
$code = $notice['code'];
if ( ! isset( $grouped_notices[ $code ] ) ) {
$grouped_notices[ $code ] = array(
'notice' => $notice,
'index' => $index,
'count' => 1,
);
} else {
++$grouped_notices[ $code ]['count'];
}
}
// Display grouped notices.
foreach ( $grouped_notices as $code => $data ) {
$notice = $data['notice'];
$count = $data['count'];
$notice_html = sprintf(
'%s',
esc_html( $notice['message'] )
);
if ( $count > 1 ) {
$notice_html .= sprintf(
' (occurred %d times)',
$count
);
}
if ( current_user_can( 'manage_woocommerce' ) && ! empty( $notice['technical'] ) ) {
$notice_html .= sprintf(
'
Technical: %s',
esc_html( $notice['technical'] )
);
}
$this->render_notice(
'error',
'AI Checkout Error',
$notice_html,
true,
$data['index']
);
}
}
/**
* Show configuration warnings
*/
private function show_configuration_warnings(): void {
// Check if API key is set.
$api_key = get_option( 'carticy_ai_checkout_api_key', '' );
if ( empty( $api_key ) && $this->is_plugin_page() ) {
$this->render_notice(
'warning',
'API Key Not Configured',
'Please generate an API key in Settings to enable ChatGPT Instant Checkout.',
true
);
}
// Check if in test mode.
$test_mode = get_option( 'carticy_ai_checkout_test_mode', 'yes' );
if ( 'yes' === $test_mode && $this->is_plugin_page() ) {
$this->render_notice(
'info',
'Test Mode Active',
'ChatGPT Instant Checkout is running in test mode. Disable test mode in Settings when ready for production.',
true
);
}
}
/**
* Render a notice
*
* @param string $type Notice type (error, warning, info, success).
* @param string $title Notice title.
* @param string $message Notice message (can contain HTML).
* @param bool $dismissible Whether notice is dismissible.
* @param int|null $notice_index Notice index for dismissal.
*/
private function render_notice(
string $type,
string $title,
string $message,
bool $dismissible = false,
?int $notice_index = null
): void {
$class = 'notice notice-' . $type;
if ( $dismissible ) {
$class .= ' is-dismissible';
}
$dismiss_url = '';
if ( $dismissible && null !== $notice_index ) {
$dismiss_url = add_query_arg(
array(
'action' => 'carticy_dismiss_notice',
'notice_index' => $notice_index,
'_wpnonce' => wp_create_nonce( 'carticy_dismiss_notice' ),
),
admin_url( 'admin.php' )
);
}
?>