Use wp_term_taxonomy.parent to link feeds to subscriptions#594
Merged
akirk merged 10 commits intoremove-friendship-functionalityfrom Mar 20, 2026
Merged
Use wp_term_taxonomy.parent to link feeds to subscriptions#594akirk merged 10 commits intoremove-friendship-functionalityfrom
akirk merged 10 commits intoremove-friendship-functionalityfrom
Conversation
Contributor
Test this PR in WordPress PlaygroundYou can test this pull request directly in WordPress Playground: This will install and activate the plugin with the changes from this PR. |
984c12b to
10ab921
Compare
Instead of wp_set_object_terms() (which links feeds to subscriptions via wp_term_relationships), store the subscription term_id in the parent field of wp_term_taxonomy for each feed term. This eliminates the off-label use of the object relationship table for term-to-term links, which caused sync issues when WordPress's internal machinery modified or recounted relationships for non-post objects. Subscription now overrides get_feeds() and save_feeds() to use the parent field. User_Feed::get_all_friend_users() prefers the parent lookup, falling back to the legacy object relationship path for feed terms not yet migrated. A batched migration (link_feeds_as_term_children) converts existing feed-to-subscription object relationships to parent links and removes the now-redundant wp_term_relationships rows. Also removes the dead User_Feed::save_multiple() method.
…eries - Remove get_objects_in_term fallback from get_all_friend_users(); feeds now exclusively use wp_term_taxonomy.parent to link to subscriptions - Add hierarchical => true to feed taxonomy registration so parent queries work - Add hide_empty => false to all User_Feed term queries (get_by_url, get_all_users, get_all_due, get_by_parser) since feed terms have count=0 in the new parent-based approach - Update test-feed.php to use User::create() instead of WP user factory, matching the Subscription-based architecture
- test_convert_friend_user_to_subscription: verifies Subscription::convert_from_user() migrates feeds (parent set via direct SQL), posts (author=0, subscription term), and user options from a WP-user-backed friend to a virtual subscription - test_convert_friend_users_batch: verifies the batch migration finds users with old friend/acquaintance roles and converts them all to subscriptions - test_link_feeds_as_term_children: verifies the batch that converts pre-existing object_terms feed relationships (subscription_term_id → feed_term) to the new parent-based hierarchy, and removes the old term_relationships entries Note: wp_cache_flush() is required after these migrations in tests because the direct SQL updates bypass WordPress's object cache; in production this is not an issue since migrations run in a cron/batch context before the next page request.
Remote_Actors::get_by_uri() returns a WP_Post, not an Actor object. Pass it through get_actor() to get the Actor with get_image()/get_summary().
In multisite, delete() calls remove_user_from_blog() rather than wp_delete_user(), so the user still exists network-wide. Check that the user is either deleted or no longer a member of the current blog.
The direct $wpdb->query UPDATE on term_taxonomy.parent doesn't invalidate WordPress term caches, causing get_feeds() to return stale results.
…sion The delete_user hook in Admin::delete_user() finds feeds via object_id-based term relationships and deletes them. Since convert_from_user sets the parent but leaves the old term_relationships intact, the subsequent user deletion would delete the just-migrated feeds. Remove the old relationships after re-parenting to prevent this.
wp_remove_object_terms() triggers WordPress hooks that cause side effects breaking the migration. Use a direct $wpdb DELETE instead, followed by clean_term_cache to invalidate stale caches. This also prevents the Admin::delete_user hook from finding and deleting the just-migrated feeds (which only happened for users with the subscription capability).
d0c4d9e to
ca76be1
Compare
get_private_url() still called $friends->access_control->append_auth() which was removed with the friendship functionality. This crashed the cron on every RSS feed poll, breaking automatic feed checking since the migration deployed on March 11.
Private URL authentication was part of the removed friendship functionality. Replace all get_private_url() calls with get_url(). Add a test that verifies cron_friends_refresh_feeds() can resolve the friend user via parent term and create posts — the flow that was broken by the stale access_control reference.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
wp_term_taxonomy.parentinstead ofwp_term_relationshipsobject linkslink_feeds_as_term_children) to convert existing installations; usesclean_term_cache()for targeted cache invalidation after direct SQL updatesget_objects_in_termfallback fromget_all_friend_users()and addshide_empty => falseto allUser_Feedterm queries (feed terms have no object links so their count is 0)Test plan
composer test)convert_from_user(),convert_friend_users_batch(), andlink_feeds_as_term_children()