Search a secondary data source and inject episode IDs into the Benecaster result set
Use when your add-on stores searchable content in a table of its own — chapter titles, guest notes, show-prep documents — and you want those episodes to appear in the standard [benecaster_search] results. Return the matching episode IDs; Benecaster merges them into the SQL so pagination totals stay correct. Apply your own visibility and tier gating before returning IDs — the filter result is trusted. The example is a generic add-on’s own guest-notes table, whose members-only notes are sold as a buy-up.
Gate buy-up content on $holdings, not $tiers. $holdings is everything the searcher holds on the show — tier, buy-up and grant slugs, resolved the same way as their feed. $tiers is what the search query filters by: normally the same slugs, but ['public'] for someone who holds nothing, and whatever a benecaster_search_query_args callback narrowed it to. $user_id is the searcher, or 0 for an anonymous visitor. An episode the searcher cannot reach at all is still left out by Benecaster’s own access check, whatever you return.
Transcripts are already searched. With the Transcription Service add-on installed, its own callback on this filter adds the episodes whose transcript matches, under each transcript’s visibility setting, and shows the matching passage as the result’s excerpt. If your add-on works with transcript text, don’t query Transcription Service’s storage: read the text with benecaster_get_episode_transcript_text() and check benecaster_user_can_see_transcript() before showing anything built from it.
On querying your own tables. The example below queries an add-on’s own table, which is yours to change and safe to rely on. Querying Benecaster’s tables, or another add-on’s, directly is a different matter: that schema is internal and can change in any release without notice, so a query written against it will break. Where a hook, shortcode, or public function can get you the data, use that instead — those we keep stable.
Code
<?php
add_filter(
'benecaster_search_supplemental_episode_ids',
function ( array $ids, string $term, int $show_id, array $tiers, array $holdings = [], int $user_id = 0 ): array {
global $wpdb;
// Your add-on's own table, which is yours to change and safe to rely on.
$table = $wpdb->prefix . 'my_addon_guest_notes';
if ( ! $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) ) {
return $ids;
}
// Members-only notes are searchable only by holders of your buy-up. 'guest-notes' stands in
// for the slug benecaster_get_buyup_slug() gives your buy-up on this show.
// $holdings is what Benecaster resolved; $tiers is what the SQL filters by, which a filter may have narrowed.
$public_only = in_array( 'guest-notes', $holdings, true ) ? '' : 'AND is_public = 1';
$like = '%' . $wpdb->esc_like( $term ) . '%';
$rows = $wpdb->get_col(
$wpdb->prepare(
"SELECT DISTINCT episode_id
FROM {$table}
WHERE show_id = %d
AND notes LIKE %s
{$public_only}",
$show_id,
$like
)
);
return array_merge( $ids, array_map( 'intval', $rows ) );
},
10, 6
);
Hooks Used
Need this built rather than just documented? See our services →