Repository navigation
Pass $post to the get_the_excerpt filter - #641
Conversation
Content::get_post_summary() applied get_the_excerpt with only the excerpt, but core has passed the post as a second argument since WordPress 4.5. A callback registered for both arguments with a required $post threw ArgumentCountError on PHP 8, failing content aggregation; one with an optional $post fell back to the global post, which is wrong or empty in the cron and REST contexts generation runs in. Only reached when "prepend excerpt" is on and the post has an excerpt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
gouravkhunger
left a comment
There was a problem hiding this comment.
@galbus This is an automated PR review.
Soft score: Approve.
Minimal fix that matches core's get_the_excerpt contract, and both regression tests fail without it.
Full review
Summary
Content::get_post_summary() now calls apply_filters( 'get_the_excerpt', $summary, $post ), which matches the signature core has used since WordPress 4.5. The misindented phpcs:ignore line is re-tabbed. Two regression tests and a changelog bullet are added.
Affected subsystems
- Only
src/post/class-content.php, the content aggregation step of audio generation. - The change only matters when the "Prepend excerpt" setting is on and the post has a manual excerpt.
Dependency graph changes
None. No new classes, imports or wiring in Plugin::init().
Risky files
src/post/class-content.php:137: low risk.$postis already normalized withget_post()and checked withinstanceof \WP_Postbefore this call, so callbacks always get aWP_Post, never an int. A callback type-hinted\WP_Postis safe.- Callbacks registered with the default
$accepted_args = 1still get one argument, so nothing changes for them.
Public API changes
The get_the_excerpt filter now receives a second argument. This is additive and matches core's contract, so there's no breaking change.
DB changes
None. The tests set beyondwords_prepend_excerpt and delete it again in finally.
Auth/security changes
None. The excerpt is still passed through htmlentities() before the filter runs, same as before.
Deployment/config changes
None. The changelog entry is in the unreleased block of readme.txt under Fixes, as AGENTS.md rule 5 requires.
Tests
- Test 1 registers a callback with a required
$post. Before the fix it reproduced theArgumentCountError. - Test 2 sets the global
$postto a different post, as happens in cron or REST, and asserts the callback reads the post being processed. - Both tests clean up in
finally, so a failure doesn't leak state into other tests.
Pre-existing (not blocking)
Callbacks receive an HTML-entity-encoded excerpt, while core passes the raw post_excerpt. That behaviour predates this PR. It could be looked at separately if third-party filters misbehave on the encoded text.
Review priority
src/post/class-content.phptests/phpunit/post/test-content.phpreadme.txt
Verdict: Approve. Small, correct fix that matches core's contract, covered by tests that fail without it.
Summary
A publisher reported that audio generation failed for some posts, and traced it to
Content::get_post_summary()insrc/post/class-content.php. We call:WordPress core has passed the post as a second argument since 4.5 (
apply_filters( 'get_the_excerpt', $post->post_excerpt, $post )), so callbacks written against core's signature can rely on it:$postthrowsArgumentCountErroron PHP 8. That aborts content aggregation, so no audio is generated.$postfalls back to the global post. In the cron and REST contexts generation runs in, that global is empty or a different post, so the summary can be built from the wrong post.The fix passes
$post:The misplaced
phpcs:ignoreabove it is also re-indented from spaces to tabs.Risk and blast radius
This only affected a narrow set of publishers. All three conditions must hold:
beyondwords_prepend_excerpt) is enabled. It is off by default.get_the_excerptcallback that uses the second argument. WordPress's own callback (wp_trim_excerpt) makes$postoptional and returns an existing excerpt unchanged, so sites without such a plugin or theme were unaffected.The same call has been in the plugin since at least 6.3, so this is a long-standing edge case, not a 7.x regression. The change only adds an argument that core itself always supplies, so existing callbacks that ignore it behave exactly as before.
Test plan
Written test-first. Both tests go through
Content::get_content_body():get_content_body_with_summary_supports_excerpt_callbacks_requiring_post: registers a callback with a required$post. Before the fix it failed withArgumentCountError: Too few arguments … 1 passed … exactly 2 expected, the reported crash. It passes after the fix.get_content_body_with_summary_passes_the_processed_post_to_excerpt_callbacks: sets the global$postto a different post, as in cron or REST, and asserts the callback receives the post being processed. It fails without the fix, because the callback read the other post, and passes with it.phpcs(WordPress-VIP-Go) clean.🤖 Generated with Claude Code