Route all enclosure URLs through Podtrac
Podtrac is a podcast download measurement prefix service. By routing every enclosure URL through Podtrac’s prefix, you gain cross-platform download attribution without changing your audio host. This recipe…
Drop-in code examples for extending the Benecaster plugin.
Podtrac is a podcast download measurement prefix service. By routing every enclosure URL through Podtrac’s prefix, you gain cross-platform download attribution without changing your audio host. This recipe…
By default Benecaster builds token URLs using a query parameter format. Use this recipe to rewrite them to a pretty permalink structure — e.g. /podcast/feed/abc123xyz — that looks…
benecaster_feed_xml fires at two call sites: once per tier inside FeedCompiler::compile() and once in FeedAssembler::assemble() after all tiers are merged. This recipe demonstrates how to target only the…
The itunes:new-feed-url redirect tag is driven by stored post meta, but sometimes you need to suppress it for a specific tier feed without touching the settings — for…
Two hooks work in combination here: benecaster_episode_custom_fields exposes a custom field’s value through the episode data layer, and benecaster_rss_extra_item_tags appends the corresponding XML to each RSS item. Use…
Slow feed compilations are hard to notice until listeners start complaining. This multi-hook pattern timestamps the start of each feed render, then computes elapsed time and compiled size…
Shows the manual filter approach for adding podcast:chapters to RSS items by appending the tag directly via benecaster_rss_extra_item_tags. With the Chapter Markers add-on the data is managed via…
Pull chapter data from any external service — Podlove, Ausha, or a custom endpoint — and emit a podcast:chapters tag pointing to a JSON chapters file. With the…
Emit podcast:transcript tags per episode by pulling transcript URLs from post meta. Supports multiple formats per episode (SRT, VTT, etc.) and works with Rev, Sonix, Descript, or any…
Instead of showing a blank locked-content placeholder, give visitors a taste of the episode with a 60-second preview. This recipe hooks into the episode player render to conditionally…
The default locked-content message is generic. This recipe customizes the message based on the tier required to access the episode — showing “Upgrade to Premium” for paid-only content…
Benecaster’s bridge system handles subscription-based access, but sometimes access should be granted based on a one-time product purchase rather than a recurring membership. This recipe uses benecaster_episode_is_accessible to…
When a valid, unexpired token is presented but the subscription bridge returns no active tiers, Benecaster fires this hook before returning a 403. The gap between token validity…
Invalid token attempts — wrong hash, revoked token, or unknown prefix — signal token sharing, credential stuffing, or misconfigured apps. This recipe logs each attempt with the token…
When a subscriber stops polling their feed for longer than the configured threshold, Benecaster marks them at_risk and fires benecaster_subscriber_feed_inactive — once, not daily. This recipe enqueues a…
benecaster_token_generated fires at signup regardless of whether the subscriber ever opens their app. benecaster_token_first_accessed fires the first time the feed is actually polled — confirming the subscriber has…
WooCommerce’s My Account page is where subscribers naturally look for order details. Adding the Benecaster feed URL here — using benecaster_get_feed_url() — gives subscribers a familiar place to…
When Benecaster’s built-in Mailchimp integration isn’t available or doesn’t fit your audience tagging model, wire the token and subscription hooks directly to Mailchimp’s API. This recipe adds the…
SubscriptionListener relays bridge events as WordPress actions, making the same code work regardless of whether the site uses MemberPress, WooCommerce Subscriptions, Restrict Content Pro, or a custom bridge.…
Forward subscriber lifecycle events — join, churn, and tier change — to an external analytics or data platform (GA4 Measurement Protocol, Segment, Mixpanel, or a custom webhook). These…
When your source of truth for subscriber counts is external — a hosting platform, payment processor, or BI tool — override benecaster_get_subscriber_count() to return the external figure. Cache…
The availability check cron fires after each pass and reports how many tier/episode pairs just became available. When $unlocked_count > 0, new content just unlocked — use this…
benecaster_subscriber_access_revoked fires only for explicit human-initiated revocations (via the admin dashboard), distinct from benecaster_token_revoked which fires for all revocations including programmatic ones. Use for compliance audit trails, CRM…
When an admin resets a subscriber’s token and checks “Send notification email”, this hook fires with the new plaintext token — allowing any notification channel (Slack, CRM, custom…
Fires only when the admin enables “Send notification” at the time of the tier change — not on every tier change. Use to supplement the built-in tier_change email…
Fires when an admin revokes access and the “Send notification” option is enabled. Distinct from benecaster_subscriber_access_revoked which fires on every admin revocation regardless of the notification toggle. Use…
Fire a webhook — to a notification service, automation platform, or custom endpoint — the moment a new episode goes live. benecaster_episode_published fires at save_post priority 20, after…
Fires when an episode leaves ‘publish’ — whether trashed, reverted to draft, or set to private. Pair with benecaster_episode_published to keep external CDN caches and search indexes in…
Fires exactly once per episode lifetime on the first save. Use to bootstrap external records — a project management task, a CMS entry, or an audit trail row…
Fires on every episode save that is not the first creation. $changed_fields lists only the post-table columns that actually changed (title, content, post_status, post_date) — it is empty…
Fires from before_delete_post — the episode still exists in the database at this point, so get_post(), get_post_meta(), and get_the_title() all return valid data. Use to remove external analytics…
Fires after EpisodesController::save_meta() when at least one _benecaster_* meta key actually changed. $changed_meta is an associative array keyed by meta key; each value has old and new entries.…
Benecaster assigns max + 1 across all published episodes by default. Use this filter to suppress auto-numbering for trailers and bonus episodes, restart numbering per season, or skip…
When a show has custom episode types that need to resolve to a specific iTunes value regardless of admin configuration, use this filter to override the resolved type…
Three show lifecycle hooks cover the full CRUD lifecycle. benecaster_show_created fires once on first save; benecaster_show_updated fires on every subsequent save with a $changed_fields array listing post-level changes;…
Fires each time an admin saves a bridge selection — from both the setup wizard and the Settings → Subscription tab. Use to seed bridge-specific defaults, trigger an…
The daily cron removes expired itunes:new-feed-url redirect tags automatically. benecaster_redirect_expiry_run fires once per run with the count and affected show IDs. Use to notify show owners, update an…
Fires when a new tier appears in the membership plugin without a matching row in benecaster_tier_map — both in real time (via on_tier_saved()) and from the daily sync…
Benecaster’s built-in welcome email covers the basics, but many podcasters have existing welcome sequences in SendGrid with branding, sequences, and conditional logic that the built-in template can’t replicate.…
Custom merge tags registered via benecaster_email_merge_tags are available in all Benecaster emails. With the Email Editor add-on active, these tags are also available in the drag-and-drop template builder…
When a subscriber opts out of Benecaster emails via the unsubscribe link, propagate the opt-out to your Mailchimp audience so the preference is consistent across systems. benecaster_email_resubscribed fires…
Benecaster generates a plain text version of every HTML email automatically by stripping tags. The result is often acceptable but sometimes the automated plain text is hard to…
Sends Benecaster emails with SendGrid category tags for segmenting analytics by email type in the SendGrid dashboard. This approach requires SMTP delivery — WordPress must be sending email…
The email unsubscribe endpoint is public by design, but a bad actor with a list of subscriber IDs could use it to mass-unsubscribe your audience. Return false from…
Any email type registered via benecaster_managed_email_types appears as an editable template in the Email Editor UI. Add-ons that send their own email types — episode notifications, community alerts,…
When the Migration Wizard or Feed Sync imports episodes, benecaster_feed_sync_import_data lets you reshape the raw RSS item data before it’s written, and benecaster_episode_imported fires after each episode is…
Feed sync imports every episode it finds by default. Return false from benecaster_feed_sync_should_import to skip specific episodes — trailers, bonus content, or episodes from dates before the migration…
benecaster_feed_sync_after fires after each feed sync run. Use it to notify the production team when new episodes are detected — useful during the migration period when the team…
Some podcast hosts use custom RSS namespace elements (e.g. myhost:episode_id, myhost:season) that don’t map to standard fields. benecaster_feed_sync_import_data receives the raw parsed RSS item and lets you extract…
Three hooks wrap the nightly analytics prune: a skip filter (abort if a backup is in progress), a before action (log the start), and an after action (log…
Core registers benecaster_episode with the field system automatically. Add-ons that introduce their own CPTs (e.g. Guest Manager’s benecaster_guest) must call benecaster_register_field_cpt() inside a benecaster_boot callback so the CPT…
Fires after POST /benecaster/v1/field-values/benecaster_episode/{id} when at least one field value actually changed (before/after snapshot diff). $changed_field_ids is an array of benecaster_fields.id values. Use to sync episode content to…
Prepend or append field groups generated at runtime — from external data, plugin state, or computed summaries — without storing them in the database. Synthetic groups (non-integer IDs)…
benecaster_field_value fires on every read — including inside the episode editor UI and REST API responses. Use it to format raw stored values: convert a date string to…
Fires after every FieldValueStore::set() call, including when a value is cleared (null). Fires once per field per save — not once per batch. Guard with a $cpt_slug check…
The simplest way to extend the episode editor. Declare a tab with sections and fields using a PHP array — no JavaScript required. The core React app fetches…
For interactive UI that can’t be expressed as a field declaration — custom pickers, live previews, embedded third-party widgets — add-ons register React components directly into named extension…
Extend Benecaster\REST\RestController in your add-on and register it via benecaster_boot. Your routes live under benecaster/v1/ with the same permission callbacks used by core. Use permission_callback_admin() for admin-only routes…
Prepend or append reference groups managed outside the database — for example, the Outlinks add-on can inject a “Tracked Links” group without storing it in benecaster_reference_groups. Synthetic groups…
Fires before references is returned in the episode REST response. Each entry is a full reference object. Use to inject extra fields (e.g. a tracked redirect URL) or…
Implement BridgeInterface for a custom membership plugin, register it via benecaster_boot, and activate it for a show with BridgeManager::set_active_bridge(). Covers all nine required methods, the NullBridge fallback pattern,…
BridgeInterface::get_all_user_tiers() returns all tier slugs a user is active on for a given show. The default implementation wraps get_user_tier() and returns a single-element array. Override it when subscribers…
BridgeManager is available from the container via $container->make(). Use get_active_bridge() to read the configured bridge for a show (returns NullBridge when nothing is configured), and set_active_bridge() to programmatically…
Implement CommunityPlatformInterface in your add-on and register it via benecaster_boot. The Community Integrations add-on routes all subscription events to every registered platform automatically — including Discord and Circle…
CommunityPlatformRegistry calls onEpisodePublished() on every registered, configured platform when benecaster_episode_published fires. Implement this method to create a discussion thread, post an announcement, pin a notification, or update a…
Build a fully custom subscriber account page using benecaster_get_template_part(), benecaster_get_feed_url(), and benecaster_get_subscriber_count() directly in a theme template. This is an alternative to the built-in Blocks & Widgets account…
Add-ons inject additional wizard steps by appending entries to the steps array. Each step entry must include id, component (React component registered on window.BenecasterExtensions), required, and condition (a…
Add-ons that provide a non-core subscription bridge inject their card into the wizard’s Subscription step. The slug must match the bridge’s get_plugin_slug() return value so POST /bridge/activate can…
Fires once when POST /benecaster/v1/wizard/complete is called. Use to seed default add-on settings for the new show, send a welcome notification, or trigger an external onboarding webhook. $show_id…
Add your add-on’s data to any Benecaster Analytics Digest (daily, weekly, or monthly) by injecting a data payload via benecaster_analytics_digest_data and registering a custom section via benecaster_analytics_digest_sections. This…
Trigger a Benecaster feed cache clear from any plugin, mu-plugin, or WP-CLI cron job using the benecaster_clear_feed_cache action. Supports global, show-scoped, and tier-scoped clears. benecaster_feed_cache_cleared fires after any…
Use the benecaster_upgrade_prompt_html filter to change copy or add a link to the upgrade prompt shown to logged-in subscribers at the wrong tier. Scope changes to a single…
Use benecaster_after_show_episode_list to inject HTML below the episode listing without overriding a template file. Each show page action hook fires with $show_id as its only argument. Swap to…
Use benecaster_after_account_qr_code to append a section after all built-in account content. The action fires with ( int $show_id, int $user_id ). To insert before a built-in section instead,…
Fires before channel-level podcast: namespace tags are rendered to XML. The initial array is pre-populated from show meta (guid, locked, funding, block, txt, license). Add-ons receive the populated…
Fires before per-episode podcast: namespace tags are rendered to XML. The initial array is pre-populated from episode meta (transcript, soundbites, feed_credits, season, images). Add-ons receive the populated array…
Inject read-only Podcasting 2.0 credits into an episode’s Feed Credits section without writing to post meta. Benecaster calls benecaster_podcast2_episode_auto_feed_credits after loading meta-stored credits, merges the returned array into…
benecaster_current_tier_output fires immediately before the shortcode returns. $tier_slug and $user are null on the fallback path (guest, no token, non-active token). Use the filter to greet the subscriber…
Use benecaster_episode_page_blocks when you need to add, remove, or reorder blocks per render based on episode or show context without touching the Show → Episode Page panel. Runs…
Use these filters to change which episode “prev” or “next” points to — for example, skipping bonus episodes, enforcing season boundaries in the Episode Page block, or implementing…
Use benecaster_related_episodes_query_types to add a custom query strategy to the [benecaster_related_episodes] shortcode and the related_episodes Episode Page block. Any add-on can register one or more strategies; they appear…
Filter the resolved episode list before the shortcode or Episode Page block renders it. Return a modified array to inject specific episodes, enforce premium-only results, or suppress the…
Filter the resolved social links array before [benecaster_social_links] or the episode page social block renders them. Each item is ['platform' => string, 'url' => string, 'label' => string].…
Filter the final HTML string produced by [benecaster_social_links] or the episode page social block. Use to swap in a custom icon set, wrap the list in additional markup,…
Filter the final output of [benecaster_rss_link]. Use to wrap the link in additional markup, swap in a custom SVG icon, conditionally suppress the link on certain pages, or…
Filter the final output of [benecaster_platform_links]. Use to wrap in additional markup, inject custom badge HTML for a specific platform, suppress the block on certain pages, or replace…
Return a non-null array from benecaster_search_pre_results to skip the core SQL entirely and substitute your own results — Elasticsearch, Typesense, or a custom DB query. Return null to…
Return false to remove an episode from every search response regardless of tier or query term. Useful when an episode is published but should not be discoverable —…
Override the per-result excerpt returned by the search endpoint. Useful to substitute transcript snippets, chapter titles, or custom-formatted highlights. The Transcription Service add-on uses this pattern to surface…
Use when your add-on stores searchable content outside of wp_posts — transcripts, chapter titles, guest notes — and you want those episodes to appear in the standard [benecaster_search]…
Benecaster fires benecaster_installed_addons during admin bootstrapping to build the list of loaded add-ons. Each add-on plugin should hook this filter inside its benecaster_boot callback and append its fully-qualified…
OAuthCallbackHandler fires do_action( 'benecaster_site_connected', array $data ) after a successful OAuth token exchange. $data contains token, prefix, granted_at, license_id, plan, and show_uuid. Use it for one-time bootstrapping —…
LicenseValidationCron uses a two-strike counter per show on HTTP 401 from /validate. The first 401 fires benecaster_license_unauthorized_strike( int $strike_count, string $show_uuid ) — useful for observability. A second…
Push a TourDef onto window.BenecasterExtensions.tours before or after the React app mounts. TourManager reads the registry, launches the tour when ?bc_tour=[id] is in the URL, and POSTs to…
Core resolves the audio URL via AudioVariantResolver (exact-tier match → cascade-down → base URL). The benecaster_episode_audio_url filter runs after that resolution, letting add-ons override the URL per-request (geo-routing,…
Implement FeedNamespaceInterface and append your instance inside a benecaster_feed_namespaces callback. The registry handles xmlns injection, channel-level merging, and per-episode merging automatically — no FeedCompiler changes needed. Required methods:…
Use the benecaster_psc_chapters filter to supply a structured chapters array for each episode. The compiler injects psc:chapters and psc:chapter elements inline into the feed item.
benecaster_download_logged fires from DownloadLog::record() immediately after a row lands in benecaster_download_log. Use it to fan the event out to a webhook receiver, Slack channel, or real-time pipeline without…
benecaster_download_log_entry runs right before $wpdb->insert(). Use it to add columns from a schema migration your add-on shipped (e.g. a campaign ID resolved from the request), normalise an existing…
benecaster_download_app_patterns controls the substring-to-label table used to bucket user-agent strings on GET /shows/{id}/analytics and GET /episodes/{id}/analytics. Keys are lowercased substrings (first match wins); values are the display label.…
Benchmark data refreshes on a 24-hour cron cycle. Add-ons that need to drive a refresh in response to their own events can trigger one directly via the service…
The tokens table mixes three populations: paying subscribers, free-tier bridge members, and direct followers. Counting paying subscribers accurately requires excluding both non-paying populations simultaneously — one filter targets…
[benecaster_follower_signup] creates a WordPress user and inserts a token_type = 'follower' row, then fires benecaster_follower_signed_up( int $user_id, int $show_id, string $tier_slug ) before the welcome email is dispatched.…
Benecaster resolves a broadcast audience slug to a list of eligible WordPress user IDs. Built-in slugs: paying (paying subscribers only), followers (direct followers only), all (every active token…
benecaster_account_page_url( int $show_id = 0 ) returns the permalink of the plugin-created /podcast-account/ page. Use this filter when a podcaster places [benecaster_account] on a differently-named page and wants…
GET /benecaster/v1/account/subscriptions (cookie auth) returns { items: [...] } — each item carries show_id, show_title, show_artwork, tier_name, feed_url (masked, first 8 chars + placeholder), status, and token_prefix. Use…
When a previously-cancelled subscriber resubscribes, core deletes their prior token row and mints a fresh one (new hash, new feed URL). The activation hook fires with $source ===…
ShowsController::archive_show() fires benecaster_show_archived( int $show_id ) immediately after the _benecaster_show_archived meta flips to '1'; unarchive_show() fires benecaster_show_unarchived( int $show_id ) symmetrically. The feed returns HTTP 410 for archived…
The three outer plugin templates call benecaster_get_header() / benecaster_get_footer() instead of WP core get_header() / get_footer(). The helpers dispatch to block_template_part( 'header'/'footer' ) on block themes, fall back…
LicensePricingFetcher::refresh() fires benecaster_pricing_data_changed( array $pricing, ?string $previous_updated_at, string $new_updated_at ) whenever the freshly-fetched updated_at differs from the cached value. Use this to invalidate any pricing-derived cache (UI snapshots,…
GET /pricing uses short display slugs (e.g. email-editor); the entitlement system uses fully-qualified slugs (e.g. benecaster-addon-email-editor). Pass the wrong form to addon_is_active() and you will silently get false…
The outbound webhook system POSTs subscription/token events with a sha256= HMAC header. benecaster_webhook_payload runs once per event after the dispatcher assembles the payload, before signing. Add custom keys,…
Fires when a transferred subscriber’s grace period elapses without re-authorization. By the time the action fires the subscriber’s token has already been revoked and a promote_grace_expired email has…
PromotionService::run() fires benecaster_bridge_promote_complete( int $show_id, string $target_bridge_slug, int $promoted, int $skipped, int $errors ) after the migration loop completes and the active bridge has been switched — regardless…
A bridge that only implements BridgeInterface can be a migration source but not a target. The Promote-to-Bridge wizard filters the target grid to bridges that also implement BridgeWritable.…
ShowMeta exposes set_episode_single_pages_disabled( bool ), set_episode_archive_disabled( bool ), and their read counterparts. Use them programmatically to gate a show’s public visibility — useful for time-locked launches, paywall integrations,…
BadgeIconRegistry::get_icons() runs benecaster_badge_icons to merge add-on icons into the built-in set. Each entry is [ 'slug' => string, 'label' => string, 'svg' => string ]; the SVG must…
benecaster_badge_definition_deleted fires after a badge definition row is removed. The hook passes the badge ID, its parent tier ID, and the full pre-delete badge data — label, icon,…
Badges are assembled from tier assignments and manual grants, then passed through benecaster_user_badges before rendering. Hook into this filter to change what a subscriber sees — hide a…
benecaster_render_user_badges( int $user_id = 0, ?int $show_id = null ): string looks up the user’s badges via benecaster_get_user_badges() (so the benecaster_user_badges filter applies) and returns the chip HTML.…
AvatarManager::get_fallback_url() runs benecaster_avatar_fallback when the subscriber has no uploaded avatar AND the site-wide show_avatars option is off. Return a URL string to substitute (e.g. a generated initials PNG)…
SupporterWallManager::set_subscriber_visible() fires benecaster_subscriber_wall_visible( int $user_id, bool $visible ) after every write — including same-value writes (the action fires on every save so add-ons can observe explicit re-confirmation events,…
ShowMeta::set_supporter_wall_enabled() fires benecaster_supporter_wall_enabled( int $show_id ) on a 0→1 transition and benecaster_supporter_wall_disabled( int $show_id ) on a 1→0 transition. Same-value writes do not fire either action, so callbacks…
When the Supporter Wall has no opted-in subscribers to show, it displays a default empty message — “No supporters yet — be the first!” Use this filter to…
Fires after the default markup is assembled for both the populated and empty branches of [benecaster_supporter_wall]. $html is the complete rendered output. $subscribers is the raw row array…
AccountController::delete_avatar() fires benecaster_avatar_deleted( int $user_id, int $attachment_id ) after the user meta is cleared and the attachment is deleted. The action does NOT fire when the delete request…
BillingPortalController fires three actions for subscriber self-service actions in the native portal. These complement webhook-driven events: portal actions identify the actor (current $user_id); webhook actions identify the eventual…
BuyupsAccountController fires benecaster_buyup_purchased( int $user_id, int $buyup_id, int $show_id, string $stripe_subscription_item_id ) after a successful Stripe subscriptionItems.create and a successful insert into wp_benecaster_subscriber_buyups. benecaster_buyup_cancelled fires when a subscriber…
StripeBuyupProvisioner runs apply_filters( 'benecaster_buyup_currency', 'usd', $buyup_id ) when minting Stripe Prices. Return a different ISO-4217 currency code to provision in that currency instead. The same Price is reused…
Buy-ups are optional add-ons subscribers can purchase on top of their existing plan — things like transcripts, bonus content, or extended access — without upgrading to a higher…
Three actions track the lifecycle of a buy-up grant. Normal customer flow: _purchased (subscriber clicks Add to my plan) → _cancelled (subscriber clicks Remove; cancel-at-period-end is set but…
Fires inside templates/account/buyups.php only when a buy-up has subscriber_cap set, live grants are at or above the cap (including lame-duck cancel_at_period_end = 1 rows), and the current user…
Benecaster ships with a curated set of languages available in the Settings → Language tab and the setup wizard’s language picker. This filter lets you extend or trim…
LanguageSettingsController::update_settings() fires benecaster_supported_locales_updated( array $supported, string $primary, array $previous_supported, string $previous_primary ) after a successful save. Use to invalidate template-sync notices, refresh locale-keyed transient caches, or run a…
MembershipTiersController fires these three actions after each successful tier create/update/delete. Create and update receive the full hydrated tier array (tier_slug, tier_name, monthly_price, annual_price, is_free, is_active, description, tier_order, show_id);…
When a listener completes a donation, you probably want to do something with that — log it to a CRM, add the donor to an email list, push…
SubscribeShortcode fires benecaster_subscribe_tiers( array $rows, int $show_id ) after is_active = 1 filtering and tier_order sorting, before the rows are localised for the React picker. Removing a row…
SubscribeController fires benecaster_subscribe_user_created( int $user_id, string $email ) immediately after wp_create_user() succeeds for a guest signup, before the subscription row is written and before the feed token is…
If you collect email addresses through Gravity Forms — for a live event, a manual enrollment flow, or a waitlist — you can have each submission automatically create…
Implement PodcastPaymentGateway and register your gateway with PaymentGatewayRegistry during benecaster_boot. is_test_mode(): bool is mandatory — a class missing it raises a PHP fatal at load (the interface declares…
StripeWebhookController is a single shared endpoint at POST /benecaster/v1/stripe-webhook that verifies the Stripe-Signature header once and dispatches to per-event handlers. Add-ons register additional handlers via benecaster_stripe_webhook_handlers rather than…
MembershipWebhookHandlers registers four handlers on the shared Stripe webhook and re-emits each Stripe event as a normalised core action carrying (string $stripe_subscription_id, \Stripe\Event $event). Add-ons should hook these…
If you store donor information in an external system — a CRM, a mailing list, or your own database — you need to remove it there when a…
UnsubscribeManager protects a fixed set of transactional types from broadcast opt-out suppression. Add-ons that send time-sensitive operational emails (access-expiry warnings, billing notifications) should add their type here so…
EmailRenderer resolves locale from benecaster_subscriber_locale user meta before locating any template file. Hook benecaster_email_template_locale to normalise locale codes, map unsupported locales to a fallback, or force a specific…
The tier change email fires on every benecaster_subscription_tier_changed action — both bridge-initiated and admin-initiated. Use type-specific filters to suppress it for specific tier combinations or to add tier-specific…
By default {{unsubscribe_url}} points to the WordPress site’s query-string endpoint. Override it to redirect subscribers to a custom opt-out centre. Use priority 20 (runs after core’s inject_unsubscribe_url at…
When you test on a staging site, Benecaster fires the same hooks as on production — which means any integration you’ve built (CRM sync, Slack notification, mailing list…
benecaster_after_gdpr_purge( string $source, array $result ) fires after every successful purge, whether operator-driven ($source = 'manual') or retention-sweep-driven ($source = 'cron'). $result contains user_id and email (one may…
The sheets filter fires twice per export request: once when the React UI renders checkboxes and once when the XLSX file is generated (only checked sheets are written).…
Use benecaster_feed_sync_completed instead of benecaster_feed_sync_after when you need the feed URL, timing, or error message. The action fires on both success and failure with a $result array containing…
When migrating episodes from Seriously Simple Podcasting (SSP) or PowerPress, Benecaster creates a draft episode for each imported post. This filter runs just before each draft is saved,…
Both hooks have identical signature ( int $show_id, int $imported, int $skipped ) so a single callback can handle both importers. Wire it to both action hooks using…
Theme developers can replace any single template part by placing a matching file in their child theme’s benecaster/ directory — the full plugin templates/ path is mirrored exactly.…
Add-ons that render HTML can use benecaster_get_template_part() to load their own template files and automatically allow theme developers to override them. Pass the add-on’s own templates directory path…
Use TemplateUpload from the container to install a zip and activate it in a single call — useful for add-ons that bundle a companion template and auto-install it…
Use benecaster_teaser_content to replace the default word-count or description teaser with any custom preview — for example the first chapter heading from the Chapter Markers add-on. The filter…
Use the public access-check functions to conditionally render premium content in any PHP context. benecaster_user_can_access_episode() returns true for public episodes regardless of subscription status. benecaster_get_user_tier_for_show() returns the tier…
The default episode/share.php renders X, Facebook, and LinkedIn share links. Replace the whole set or inject additional platforms via benecaster_episode_share_links. Each entry is an associative array with label…
Use benecaster_after_episode_card_title to append markup after the episode title inside each card — without overriding the whole archive/episode-card/title.php template. Useful for adding a listen button, a tier badge,…
Return false from benecaster_archive_show_filters to suppress the sort/filter bar entirely. Useful when the archive is embedded in a page layout where external filtering is handled by JavaScript or…
Use the per-section before/after hooks to inject contextual help content, notices, or UI elements around a specific account section without touching the template file. The hook fires with…
benecaster_locked_content_message receives the full locked state HTML and the episode/user tier context. Return custom HTML to embed a styled pricing table, a direct trial CTA, or any tier-specific…
Push a key→object pair onto benecaster_member_thanks_query_types where the value implements BenecasterMemberThanksQueryInterface. Required methods: get_label(): string, get_description(): string, and get_results( int $show_id, int $episode_id, array $args ): array. The…
Implement the HealthCheck interface (single evaluate(): void method), then attach an instance to NoticeManager from your add-on’s boot hook. evaluate() is responsible for both publishing the notice when…
Attach a health check to benecaster_license_cron_complete so the notice shows up even if no admin ever opens wp-admin between firings. Use NoticeManager::run_health_check( $check ) rather than $check->evaluate() directly…
Runs from NoticesController::get_notices() once per display context (bell and/or bar) a notice would appear in. Return the array (modified or unchanged) to keep the notice, or return null/false…
Core’s Support Mode bumps DebugLog verbosity for the next 7 days and auto-disables on a one-shot WP-Cron event. Add-ons that have their own logger or diagnostic recorder should…
benecaster_support_mode_log_limit caps how many benecaster_debug_log rows are bundled into the gzipped payload POSTed to the license server when an admin clicks “Send diagnostic log to Benecaster support”. Default…
RateLimiter short-circuits over-quota requests on /benecaster/v1/ routes with 429 + Retry-After before any controller runs. benecaster_rest_rate_limit_buckets lets add-ons raise the catch-all bucket or add a custom bucket for…
benecaster_get_referral_credit_cents(), benecaster_get_referral_code(), and benecaster_get_referral_link() read locally cached options written by LicenseValidationCron::handle_valid() — no HTTP call per request, safe to call on every admin page load. All three return…
Use benecaster_credit_before_stamp to pull the current sponsorship copy from an external source — a custom options page, a remote API, or a post meta field — and merge…
Use benecaster_credit_options to reorder or mark a specific credit template as default based on episode metadata — for example, always pre-select the guest interview credit template when the…
Use benecaster_credit_applied to send a record to an external system — a webhook, Slack notification, analytics endpoint, or spreadsheet — each time a credit template is stamped onto…
Auto-apply the default credit template when a new episode is created so the podcaster never has to click Apply manually. Uses benecaster_apply_default_credit() — the public helper that resolves…
SupporterWallManager::set_subscriber_message() fires benecaster_subscriber_wall_message after every write of the subscriber’s “Why I support” message — including empty-value clears. Use to auto-moderate flagged content, mirror the message to an external…
No recipes match the selected filters.