Render a site-wide show-limit admin notice
The built-in show-limit banner appears only on the React Shows portfolio screen (/#/shows). Use this recipe to surface the same alert on every wp-admin page — useful when you’re working on episodes, subscribers, or settings and don’t want to navigate back to Shows to notice the over-limit state.
The recipe hooks benecaster_show_limit_exceeded and benecaster_show_limit_recovered to stash and clear a wp_option, then renders an admin_notices banner on each wp-admin page load that reads from that option.
Why the wp_option indirection? Both lifecycle actions fire from the daily license cron job — there is no HTML output happening at that moment, so you cannot render a notice directly from the action callbacks. Stash the state in a persistent option and let the next wp-admin page load pick it up via admin_notices.
Delta-only payloads. benecaster_show_limit_exceeded carries newly_disabled_show_ids (the IDs that changed this cycle, not the full disabled set). The recipe uses active_show_count and show_limit from the payload for the notice text. If you need the full current disabled set for a richer message, call benecaster_get_over_limit_show_ids().
Idempotency. Both actions fire only when the disabled set changes — repeat cron ticks with identical license server responses fire nothing, so the wp_option is not rewritten on every cron run.
Code
<?php
// On over-limit: stash the current state so admin_notices can render it.
// Fires from the daily license cron, so we can't render directly — the
// notice hook runs on wp-admin page loads.
add_action( 'benecaster_show_limit_exceeded', function ( array $payload ): void {
update_option( 'my_theme_show_limit_alert', [
'active_show_count' => (int) ( $payload['active_show_count'] ?? 0 ),
'show_limit' => $payload['show_limit'] ?? null,
'first_seen_at' => time(),
], false );
} );
// On recovery: clear the stashed state so the notice stops rendering.
// Fires when the license server confirms the site is back under its
// show_limit (upgrade or archive freed capacity).
add_action( 'benecaster_show_limit_recovered', function (): void {
delete_option( 'my_theme_show_limit_alert' );
} );
// Render on every wp-admin page. The React Shows portfolio's own banner
// renders separately — this is additive, not a replacement.
add_action( 'admin_notices', function (): void {
$state = get_option( 'my_theme_show_limit_alert' );
if ( ! is_array( $state ) ) {
return;
}
$active = (int) ( $state['active_show_count'] ?? 0 );
$limit = $state['show_limit'];
printf(
'<div class="notice notice-error"><p><strong>%s</strong> %s <a href="%s">%s</a></p></div>',
esc_html__( 'Benecaster:', 'my-theme' ),
esc_html( sprintf(
/* translators: 1: active show count, 2: plan show limit */
__( 'Your site has %1$d shows on a plan that allows %2$d. Some shows have been disabled — upgrade your plan or archive a different show to restore them.', 'my-theme' ),
$active,
null === $limit ? 0 : (int) $limit
) ),
esc_url( admin_url( 'admin.php?page=benecaster#/shows' ) ),
esc_html__( 'Open Shows', 'my-theme' )
);
} );
Hooks Used
-
benecaster-show-limit-exceeded -
benecaster-show-limit-recovered
Need this built rather than just documented? See our services →