0 && ( time() - $first ) >= WEEK_IN_SECONDS; } /** * True only on AddOnBoss's own pages: its landing and the Option Sets library * under the BossMage menu, or the product editor when that product actually * carries AddOnBoss options. * * Deliberately NOT the whole products list or every product's editor. * WordPress.org asks that notices stay contextual to the plugin rather than * being sprayed across the admin, and a merchant editing an unrelated product * is not being asked about AddOnBoss. */ function addon_boss_is_own_admin_screen(): bool { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; if ( ! $screen ) { return false; } $id = (string) $screen->id; if ( false !== strpos( $id, 'addon-boss' ) || false !== strpos( $id, 'bossmage' ) ) { return true; } if ( 'product' === $screen->id ) { global $post; if ( ! $post || ! function_exists( 'wc_get_product' ) ) { return false; } $product = wc_get_product( $post->ID ); return $product instanceof WC_Product && (bool) addon_boss_product_option_config( $product ); } return false; } // Let the review/support redirects reach wordpress.org via wp_safe_redirect. add_filter( 'allowed_redirect_hosts', function ( $hosts ) { $hosts[] = 'wordpress.org'; return $hosts; } ); // Settle the request. Any choice retires it forever; "Leave a review" and // "I have feedback" also send the merchant on to the right wp.org page. add_action( 'admin_init', function () { if ( ! isset( $_GET['addon_boss_review'] ) ) { return; } if ( ! current_user_can( 'manage_woocommerce' ) ) { return; } check_admin_referer( 'addon_boss_review' ); update_option( 'addon_boss_review_state', 'done', false ); $choice = sanitize_key( wp_unslash( $_GET['addon_boss_review'] ) ); if ( 'yes' === $choice ) { wp_safe_redirect( 'https://wordpress.org/support/plugin/addon-boss/reviews/#new-post' ); exit; } if ( 'feedback' === $choice ) { wp_safe_redirect( 'https://wordpress.org/support/plugin/addon-boss/' ); exit; } wp_safe_redirect( remove_query_arg( array( 'addon_boss_review', '_wpnonce' ) ) ); exit; } ); // Persist the native "x" dismissal so the ask is final, exactly like clicking a // button. Standard practice: a dismissed review notice never returns. Registered // unconditionally because AJAX runs as its own request. add_action( 'wp_ajax_addon_boss_review_dismiss', function () { if ( ! current_user_can( 'manage_woocommerce' ) ) { wp_die( '', '', array( 'response' => 403 ) ); } check_ajax_referer( 'addon_boss_review_dismiss' ); update_option( 'addon_boss_review_state', 'done', false ); wp_send_json_success(); } ); add_action( 'admin_notices', 'addon_boss_render_review_notice' ); function addon_boss_render_review_notice(): void { if ( ! current_user_can( 'manage_woocommerce' ) ) { return; } if ( ! addon_boss_should_request_review() || ! addon_boss_is_own_admin_screen() ) { return; } // Seen enough? Retire it on its own, even if never clicked. $shown = (int) get_option( 'addon_boss_review_shown', 0 ); if ( $shown >= 5 ) { update_option( 'addon_boss_review_state', 'done', false ); return; } update_option( 'addon_boss_review_shown', $shown + 1, false ); $review = wp_nonce_url( add_query_arg( 'addon_boss_review', 'yes' ), 'addon_boss_review' ); $feedback = wp_nonce_url( add_query_arg( 'addon_boss_review', 'feedback' ), 'addon_boss_review' ); $dismiss = wp_nonce_url( add_query_arg( 'addon_boss_review', 'no' ), 'addon_boss_review' ); ?>