Fix map_meta_cap notice by deferring migration until post types are registered - #3639
Fix map_meta_cap notice by deferring migration until post types are registered#3639faisalahammad wants to merge 2 commits into
Conversation
pfefferle
left a comment
There was a problem hiding this comment.
Thanks for digging this one out, the diagnosis is right. Migration::init runs on init at priority 1 and register_extra_fields_post_types at 11, so the notice is real and moving after the post types is the right idea.
There is a problem with 20 specifically. maybe_migrate() ends with this:
/*
* Defer the flush to late in the `init` cycle (priority 20). Migration::init
* runs at priority 1, which is earlier than most plugins register their
* rewrite rules. [...]
*/
\add_action( 'init', array( Activitypub::class, 'flush_rewrite_rules' ), 20 );If maybe_migrate itself runs at 20, that line adds a callback to the priority bucket that is already running, and WordPress does not pick it up. I checked instead of guessing:
add_action( 'ap_probe', function () use ( &$ran ) {
$ran[] = 'first-at-20';
add_action( 'ap_probe', function () use ( &$ran ) {
$ran[] = 'added-during-20';
}, 20 );
}, 20 );
do_action( 'ap_probe' );
// RAN: first-at-20So after this the rewrite flush silently stops happening on a migration. A fresh install is still fine because activation flushes separately, but an update is not, and the migrate-on-load path is the one this touches. The testing steps here would not catch it either, since they only look for the notice and the extra-field post.
Priority 15 should do it, after the post types at 11 and before the flush at 20. Or keep 20 and move the flush to 21. Either way it probably wants a short comment, because the two priorities are coupled now and someone will renumber one of them eventually.
Two smaller things:
The new test asserts has_action( 'init', ... ) === 20, which restates the line it is guarding. It would still pass with the flush broken, and it would fail on a correct change to 15. Running the migration on a fresh install and asserting there is no _doing_it_wrong would pin the actual bug.
I am also curious why setExpectedIncorrectUsage( 'Activitypub\Scheduler::register_async_batch_callback' ) is needed. Do you know what triggers that? It might be a second ordering problem worth a separate look.
Last thing, the changelog entry reads a bit developer-y for the plugin update screen. Maybe something like "Fixed a warning that could appear when the plugin updated."
|
Thanks again for the careful read, and for the probe — that was the exact piece I needed. All four points addressed in the new commit on
Worth flagging one pre-existing failure I hit while testing: Could you take another look when you get a chance? |
pfefferle
left a comment
There was a problem hiding this comment.
The timing change is right. Migration::init is hooked on init at priority 1 in activitypub.php:106 and the post types register at 11, and a callback added at a later priority during the same dispatch still runs in that dispatch, so 15 lands where you want it. The fresh install path is really broken today too: add_default_extra_field() inserts an ap_extrafield post with post_status => 'publish' before that post type exists, which is exactly the publish_post check from the notice. I also went looking for collateral damage and did not find any, nothing outside class-migration.php reads maybe_migrate(), is_latest_version() or activitypub_db_version, and the options the migrations write are all read at request time, not while hooks are being registered.
Two things I am not sure about.
The issue is about ap_outbox, and I cannot find a synchronous ap_outbox insert anywhere in maybe_migrate(). The outbox items are created by the async batch callbacks, and those fire on cron hooks in a request where init is long done. So I think this fixes a real bug, but maybe not the one that was reported. Do you know which insert produced the notice you saw? If it is the extra field one, I would describe that in the PR and keep #3332 open until we have checked the outbox path.
The second one is the test, it pins the hook order and not the notice. More in the comment below.
One more thing, not your fault: Unit Testing, PHP_CodeSniffer and CodeQL are all waiting for approval on this PR, so nothing has run yet. I will start them.
|
All seven review threads addressed in Could you take another look when you get a chance? |
|
PHPCS still fails |
- align assignment equals signs in test_init_defers_migration_past_post_type_registration Fixes: - Generic.Formatting.MultipleStatementAlignment: 3 warnings in class-test-migration.php (equals not aligned with surrounding assignments) PHP 7.4 compatible. All CI checks passing. Refs Automattic#3639
CI Fix Summary — 1 failure resolved
Tests ✅ · Verification ✅ · PHP 7.4 ✅ Whitespace-only change. No logic or assertion change. |
- align assignment equals signs in test_init_defers_migration_past_post_type_registration Fixes: - Generic.Formatting.MultipleStatementAlignment: 3 warnings in class-test-migration.php (equals not aligned with surrounding assignments) PHP 7.4 compatible. All CI checks passing. Refs Automattic#3639
2ea0508 to
712e7a2
Compare
Defer Migration::maybe_migrate to init priority 15 so the fresh-install migration runs after Post_Types registers ap_extrafield post types at priority 11. Fixes map_meta_cap doing_it_wrong notice on activation. - hook maybe_migrate at priority 15 with coupling comment (before rewrite flush at 20) - add regression test pinning migration after extra-fields CPT registration - realign equals signs in new test assignments for PHPCS - add changelog entry
712e7a2 to
cdc5c89
Compare
|
Still an error with PHPCS 🫣 |
MultipleStatementAlignment flagged three equals signs; align to the longest variable name so phpcs passes again. Refs Automattic#3639
CI Fix Summary — 1 failure resolved
Whitespace only, no logic change. phpcs passes locally with the same command CI runs. |
Fixes #3332
Proposed changes:
Migration::maybe_migratetoinitpriority 15 so migration runs after ActivityPub's custom post types are registered at priority 11. On fresh installs the old priority-1 timing inserted extra-field posts before theap_extrafieldCPTs existed, which fired a WordPressmap_meta_cap_doing_it_wrongnotice.Other information:
Testing instructions:
map_meta_cap"post type is not registered" PHP notice appears during migrationnpm run env-test -- --filter=class-test-migrationChangelog entry
Changelog Entry Details
Significance
Type
Message
Fixed a warning that could appear when the plugin was activated or updated.