PluginProbe
ActivityPub / 9.3.0
ActivityPub v9.3.0
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / scheduler / class-collection-sync.php

class-collection-sync.php in ActivityPub 9.3.0, at includes/scheduler/class-collection-sync.php

103 lines 3.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Collection Sync Scheduler.
4 *
5 * Handles async reconciliation when FEP-8fcf Collection-Synchronization
6 * digest mismatches are detected.
7 *
8 * @package Activitypub
9 */
10
11 namespace Activitypub\Scheduler;
12
13 use Activitypub\Collection\Following;
14 use Activitypub\Http;
15
16 use function Activitypub\get_url_authority;
17
18 /**
19 * Collection_Sync class.
20 */
21 class Collection_Sync {
22 /**
23 * Initialize the scheduler.
24 */
25 public static function init() {
26 \add_action( 'activitypub_collection_sync', array( self::class, 'schedule_reconciliation' ), 10, 4 );
27 \add_action( 'activitypub_followers_sync_reconcile', array( self::class, 'reconcile_followers' ), 10, 3 );
28 }
29
30 /**
31 * Schedule a reconciliation job.
32 *
33 * @param string $type The collection type (e.g., 'followers').
34 * @param int $user_id The local user ID.
35 * @param string $actor_url The remote actor URL.
36 * @param array $params The Collection-Synchronization header parameters.
37 */
38 public static function schedule_reconciliation( $type, $user_id, $actor_url, $params ) {
39 // Schedule async processing to avoid blocking the inbox.
40 \wp_schedule_single_event(
41 \time() + MINUTE_IN_SECONDS,
42 "activitypub_{$type}_sync_reconcile",
43 array( $user_id, $actor_url, $params )
44 );
45 }
46
47 /**
48 * Reconcile followers based on remote partial collection.
49 *
50 * @param int $user_id The local user ID.
51 * @param string $actor_url The remote actor URL.
52 * @param array $params The Collection-Synchronization header parameters.
53 */
54 public static function reconcile_followers( $user_id, $actor_url, $params ) {
55 if ( empty( $params['url'] ) ) {
56 return;
57 }
58
59 // Fetch the authoritative partial followers collection.
60 $data = Http::get_remote_object( $params['url'], 5 * MINUTE_IN_SECONDS );
61
62 if ( \is_wp_error( $data ) || ! isset( $data['orderedItems'] ) || ! \is_array( $data['orderedItems'] ) ) {
63 return;
64 }
65
66 $remote_followers = $data['orderedItems'];
67
68 // Get our authority.
69 $home_authority = get_url_authority( \home_url() );
70
71 $accepted = Following::get_by_authority( $user_id, $home_authority );
72 foreach ( $accepted as $following ) {
73 $key = \array_search( $following->guid, $remote_followers, true );
74 if ( false === $key ) {
75 Following::reject( $following, $user_id );
76 } else {
77 unset( $remote_followers[ $key ] );
78 }
79 }
80
81 $remote_followers = \array_values( $remote_followers ); // Reindex.
82
83 $pending = Following::get_by_authority( $user_id, $home_authority, Following::PENDING_META_KEY );
84 foreach ( $pending as $following ) {
85 $key = \array_search( $following->guid, $remote_followers, true );
86 if ( false === $key ) {
87 Following::reject( $following, $user_id );
88 } else {
89 Following::accept( $following, $user_id );
90 unset( $remote_followers[ $key ] );
91 }
92 }
93
94 /**
95 * Action triggered after reconciliation is complete.
96 *
97 * @param int $user_id The local user ID that triggered the reconciliation.
98 * @param string $actor_url The remote actor URL.
99 */
100 \do_action( 'activitypub_followers_sync_reconciled', $user_id, $actor_url );
101 }
102 }
103