Settings > WordPress Plugin * Promo Banner) — this class only renders whatever config it fetches. * * @package Schema_AI * @since 1.0.5 */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Class Schema_AI_Promo_Banner */ class Schema_AI_Promo_Banner { /** * User meta key storing the last dismissal for this banner: * array( 'banner_id' => string, 'dismissed_at' => int ). * * @var string */ const DISMISS_META_KEY = 'schema_ai_dismissed_promo_banner'; /** * Transient key the fetched remote config is cached under. * * @var string */ const CACHE_KEY = 'schema_ai_promo_banner_config'; /** * Remote config fetched once per request. * * @var array|null|false False = not yet loaded. */ private $config = false; /** * Register hooks. */ public function __construct() { add_action( 'admin_notices', array( $this, 'render' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); add_action( 'wp_ajax_schema_ai_dismiss_promo_banner', array( $this, 'ajax_dismiss' ) ); } /** * Fetch the banner config set in the SaaS dashboard, cached in a * transient so it doesn't add a request to every admin page load. * * @return array|null Null if disabled, unset, or unreachable. */ private function get_config() { if ( false !== $this->config ) { return $this->config; } $cached = get_transient( self::CACHE_KEY ); if ( false !== $cached ) { $this->config = ( is_array( $cached ) && ! empty( $cached ) ) ? $cached : null; return $this->config; } $settings = get_option( 'schema_ai_settings', array() ); $api_key = ! empty( $settings['api_key'] ) ? $settings['api_key'] : ''; if ( empty( $api_key ) ) { $this->config = null; return null; } $response = wp_remote_get( SCHEMA_AI_API_BASE . '/app/public-settings', array( 'headers' => array( 'X-API-Key' => $api_key ), 'timeout' => 8, ) ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { // Retry sooner on failure than the normal cache lifetime. set_transient( self::CACHE_KEY, array(), 5 * MINUTE_IN_SECONDS ); $this->config = null; return null; } $body = json_decode( wp_remote_retrieve_body( $response ), true ); $banner = isset( $body['data']['promo_banner'] ) && is_array( $body['data']['promo_banner'] ) ? $body['data']['promo_banner'] : array(); $valid = ! empty( $banner['enabled'] ) && ! empty( $banner['id'] ) && ! empty( $banner['headline'] ); set_transient( self::CACHE_KEY, $valid ? $banner : array(), HOUR_IN_SECONDS ); $this->config = $valid ? $banner : null; return $this->config; } /** * Whether the current user should see the current banner, based on the * configured show frequency and this user's last dismissal. * * @param array $config Remote banner config. * @return bool */ private function should_show( $config ) { if ( ! current_user_can( 'manage_options' ) ) { return false; } $dismissed = get_user_meta( get_current_user_id(), self::DISMISS_META_KEY, true ); if ( empty( $dismissed ) || ! is_array( $dismissed ) || $dismissed['banner_id'] !== $config['id'] ) { return true; // Never dismissed, or this is a newly published banner. } $elapsed = time() - (int) $dismissed['dismissed_at']; $frequency = isset( $config['frequency'] ) ? $config['frequency'] : 'once'; switch ( $frequency ) { case 'daily': return $elapsed >= DAY_IN_SECONDS; case 'weekly': return $elapsed >= WEEK_IN_SECONDS; default: // 'once' — a dismissed one-time/special-offer banner stays hidden. return false; } } /** * Print the banner markup on admin_notices. */ public function render() { $config = $this->get_config(); if ( ! $config || ! $this->should_show( $config ) ) { return; } ?>
00
00
00
00
→
get_config(); if ( ! $config || ! $this->should_show( $config ) ) { return; } wp_enqueue_style( 'ai-schema-gen-promo-banner', SCHEMA_AI_PLUGIN_URL . 'admin/assets/css/promo-banner.css', array(), SCHEMA_AI_VERSION ); wp_enqueue_script( 'ai-schema-gen-promo-banner', SCHEMA_AI_PLUGIN_URL . 'admin/assets/js/promo-banner.js', array(), SCHEMA_AI_VERSION, true ); wp_localize_script( 'ai-schema-gen-promo-banner', 'schemaAiPromoBanner', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'schema_ai_dismiss_promo_banner' ), 'bannerId' => $config['id'], ) ); } /** * AJAX handler: remember that the current user dismissed this banner, * and when — so daily/weekly banners know when to reappear. */ public function ajax_dismiss() { check_ajax_referer( 'schema_ai_dismiss_promo_banner' ); $banner_id = isset( $_POST['banner_id'] ) ? sanitize_text_field( wp_unslash( $_POST['banner_id'] ) ) : ''; if ( empty( $banner_id ) ) { wp_send_json_error(); } update_user_meta( get_current_user_id(), self::DISMISS_META_KEY, array( 'banner_id' => $banner_id, 'dismissed_at' => time(), ) ); wp_send_json_success(); } }