Flag imported episodes your own way
The Migration Wizard’s reconciliation report, an add-on’s own “what came across?” screen, or a WP-CLI audit all need the same thing: one row per imported draft with the fields an import can leave empty. Core computes that once — GET /shows/{id}/import-review, Episode\ImportReviewQuery.
Narrow it by source — rows_for_show( $show_id, [ 'rss' ] ), or ?source=rss on the REST route, which also accepts a comma-separated list. A source that names nothing recognised returns no rows, not all of them, so a typo fails closed rather than looking like it worked.
Each row also carries flags, a list of completeness codes: no_audio_url, platform_hosted_audio, no_artwork, no_description, no_duration, no_episode_type, no_explicit. Six of the seven are gaps, not faults — a flagged episode imported fine. platform_hosted_audio is the exception and the one worth acting on; extend what it matches with benecaster_platform_audio_hosts. no_episode_type and no_explicit are true only when the source feed said nothing at all: an episode whose explicit setting is deliberately Inherit is not flagged, because choosing Inherit is a choice. Don’t treat flags as a validation result you can refuse to publish on.
This is a read. Its write counterpart is POST /shows/{id}/import-review/bulk — see Set tier and availability on imported episodes in bulk. Don’t write availability yourself from a row here: that route hands AvailabilityRepository::upsert() site-local time and the repository converts to UTC once, so a hand-rolled write that converts first lands every episode wrong by the site’s offset.
Not the same as GET /shows/{id}/ssp-review. That one is SSP/PowerPress only and carries the shortcode-detection fields behind the one-click replacement button. This one covers every importer and does not.
Code
<?php
add_action( 'benecaster_boot', function ( \Benecaster\Container $container ): void {
$rows = $container->make( \Benecaster\Episode\ImportReviewQuery::class )
->rows_for_show( $show_id );
foreach ( $rows as $row ) {
// $row['source'] is 'rss', 'ssp' or 'powerpress'.
// Every optional field is '' when unset, never absent.
if ( '' === $row['audio_url'] ) {
error_log( "No audio: {$row['title']} ({$row['edit_url']})" );
}
}
} );
Need this built rather than just documented? See our services →