Skip to content

Commit 359c801

Browse files
authored
Add upgrade routine to enable ActivityPub feeds in WordPress.com Reader (#2243)
1 parent ba1caef commit 359c801

File tree

4 files changed

+142
-0
lines changed

4 files changed

+142
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: added
3+
4+
Add upgrade routine to enable ActivityPub feeds in WordPress.com Reader

includes/class-migration.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Activitypub\Collection\Actors;
1111
use Activitypub\Collection\Extra_Fields;
1212
use Activitypub\Collection\Followers;
13+
use Activitypub\Collection\Following;
1314
use Activitypub\Collection\Outbox;
1415
use Activitypub\Collection\Remote_Actors;
1516
use Activitypub\Transformer\Factory;
@@ -204,6 +205,10 @@ public static function maybe_migrate() {
204205
self::remove_pending_application_user_follow_requests();
205206
}
206207

208+
if ( \version_compare( $version_from_db, 'unreleased', '<' ) ) {
209+
self::sync_jetpack_following_meta();
210+
}
211+
207212
// Ensure all required cron schedules are registered.
208213
Scheduler::register_schedules();
209214

@@ -1011,4 +1016,39 @@ public static function remove_pending_application_user_follow_requests() {
10111016
)
10121017
);
10131018
}
1019+
1020+
/**
1021+
* Sync Jetpack meta for all followings.
1022+
*
1023+
* Replays the added_post_meta sync action for Jetpack with the Following::FOLLOWING_META_KEY meta key.
1024+
*/
1025+
public static function sync_jetpack_following_meta() {
1026+
if ( ! \class_exists( 'Jetpack' ) || ! \Jetpack::is_connection_ready() ) {
1027+
return;
1028+
}
1029+
1030+
global $wpdb;
1031+
1032+
// Get all posts that have the following meta key.
1033+
$posts_with_following = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
1034+
$wpdb->prepare(
1035+
"SELECT meta_id, post_id, meta_key, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s",
1036+
Following::FOLLOWING_META_KEY
1037+
),
1038+
ARRAY_N
1039+
);
1040+
1041+
// Trigger the added_post_meta action for each following relationship.
1042+
foreach ( $posts_with_following as $meta ) {
1043+
/**
1044+
* Fires when post meta is added.
1045+
*
1046+
* @param int $meta_id ID of the metadata entry.
1047+
* @param int $object_id Post ID.
1048+
* @param string $meta_key Metadata key.
1049+
* @param mixed $meta_value Metadata value.
1050+
*/
1051+
\do_action( 'added_post_meta', ...$meta );
1052+
}
1053+
}
10141054
}

tests/data/class-jetpack.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Mock Jetpack class for testing.
4+
*
5+
* @package Activitypub
6+
*/
7+
8+
if ( ! class_exists( 'Jetpack' ) ) {
9+
/**
10+
* Mock Jetpack class for testing purposes.
11+
*/
12+
class Jetpack {
13+
/**
14+
* Mock method to simulate Jetpack connection status.
15+
*
16+
* @return bool Always returns true for testing.
17+
*/
18+
public static function is_connection_ready() {
19+
return true;
20+
}
21+
}
22+
}

tests/includes/class-test-migration.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Activitypub\Collection\Actors;
1212
use Activitypub\Collection\Extra_Fields;
1313
use Activitypub\Collection\Followers;
14+
use Activitypub\Collection\Following;
1415
use Activitypub\Collection\Outbox;
1516
use Activitypub\Collection\Remote_Actors;
1617
use Activitypub\Comment;
@@ -35,6 +36,11 @@ class Test_Migration extends \WP_UnitTestCase {
3536
* Set up the test.
3637
*/
3738
public static function set_up_before_class() {
39+
// Mock Jetpack class if it doesn't exist.
40+
if ( ! class_exists( 'Jetpack' ) ) {
41+
require_once AP_TESTS_DIR . '/data/class-jetpack.php';
42+
}
43+
3844
\remove_action( 'wp_after_insert_post', array( \Activitypub\Scheduler\Post::class, 'schedule_post_activity' ), 33 );
3945
\remove_action( 'transition_comment_status', array( \Activitypub\Scheduler\Comment::class, 'schedule_comment_activity' ), 20 );
4046
\remove_action( 'wp_insert_comment', array( \Activitypub\Scheduler\Comment::class, 'schedule_comment_activity_on_insert' ) );
@@ -1097,4 +1103,74 @@ public function test_remove_pending_application_user_follow_requests_multiple_en
10971103
// Clean up.
10981104
\wp_delete_post( $post_id, true );
10991105
}
1106+
1107+
/**
1108+
* Test sync_jetpack_following_meta triggers actions correctly.
1109+
*
1110+
* @covers ::sync_jetpack_following_meta
1111+
*/
1112+
public function test_sync_jetpack_following_meta() {
1113+
// Create test posts with following meta.
1114+
$posts = self::factory()->post->create_many( 3, array( 'post_type' => Remote_Actors::POST_TYPE ) );
1115+
1116+
// Add following meta to each post.
1117+
\add_post_meta( $posts[0], Following::FOLLOWING_META_KEY, '123' );
1118+
\add_post_meta( $posts[1], Following::FOLLOWING_META_KEY, '456' );
1119+
\add_post_meta( $posts[2], Following::FOLLOWING_META_KEY, '789' );
1120+
1121+
// Track action calls.
1122+
$action_calls = array();
1123+
$capture_action = function () use ( &$action_calls ) {
1124+
$action_calls[] = func_get_args();
1125+
};
1126+
1127+
\add_action( 'added_post_meta', $capture_action, 10, 4 );
1128+
1129+
// Run the migration with Jetpack available.
1130+
Migration::sync_jetpack_following_meta();
1131+
1132+
// Verify the correct actions were triggered.
1133+
$this->assertCount( 3, $action_calls, 'Should trigger action for each following meta entry' );
1134+
1135+
// Check the first action call structure.
1136+
$this->assertCount( 4, $action_calls[0], 'Action should be called with 4 parameters' );
1137+
list( $meta_id, $post_id, $meta_key, $meta_value ) = $action_calls[0];
1138+
1139+
$this->assertEquals( Following::FOLLOWING_META_KEY, $meta_key, 'Meta key should be Following::FOLLOWING_META_KEY' );
1140+
$this->assertIsNumeric( $meta_id, 'Meta ID should be numeric' );
1141+
$this->assertIsNumeric( $post_id, 'Post ID should be numeric' );
1142+
$this->assertContains( $meta_value, array( '123', '456', '789' ), 'Meta value should be one of the test values' );
1143+
1144+
// Clean up.
1145+
\remove_action( 'added_post_meta', $capture_action, 10 );
1146+
foreach ( $posts as $post ) {
1147+
\wp_delete_post( $post, true );
1148+
}
1149+
}
1150+
1151+
/**
1152+
* Test sync_jetpack_following_meta with no following meta.
1153+
*
1154+
* @covers ::sync_jetpack_following_meta
1155+
*/
1156+
public function test_sync_jetpack_following_meta_no_entries() {
1157+
// Track action calls for the specific meta key we care about.
1158+
$following_actions = array();
1159+
$capture_action = function ( $meta_id, $post_id, $meta_key, $meta_value ) use ( &$following_actions ) {
1160+
if ( Following::FOLLOWING_META_KEY === $meta_key ) {
1161+
$following_actions[] = array( $meta_id, $post_id, $meta_key, $meta_value );
1162+
}
1163+
};
1164+
1165+
\add_action( 'added_post_meta', $capture_action, 10, 4 );
1166+
1167+
// Run migration with no following meta (should not trigger our specific actions).
1168+
Migration::sync_jetpack_following_meta();
1169+
1170+
// Verify no following-specific actions were triggered.
1171+
$this->assertEmpty( $following_actions, 'No following-specific actions should be triggered when no following meta exists' );
1172+
1173+
// Clean up.
1174+
\remove_action( 'added_post_meta', $capture_action, 10 );
1175+
}
11001176
}

0 commit comments

Comments
 (0)