PluginProbe
ActivityPub / 8.2.0
ActivityPub v8.2.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 / collection / class-actors.php

class-actors.php in ActivityPub 8.2.0, at includes/collection/class-actors.php

853 lines 22.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Actors collection file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Collection;
9
10 use Activitypub\Activity\Actor;
11 use Activitypub\Model\Application;
12 use Activitypub\Model\Blog;
13 use Activitypub\Model\User;
14
15 use function Activitypub\is_user_type_disabled;
16 use function Activitypub\normalize_host;
17 use function Activitypub\normalize_url;
18 use function Activitypub\object_to_uri;
19 use function Activitypub\url_to_authorid;
20 use function Activitypub\user_can_activitypub;
21
22 /**
23 * Actors collection.
24 *
25 * Provides methods to retrieve, create, update, and manage ActivityPub actors (users, blogs, applications, and remote actors).
26 */
27 class Actors {
28 /**
29 * The ID of the Blog User.
30 *
31 * @var int
32 */
33 const BLOG_USER_ID = 0;
34
35 /**
36 * The ID of the Application User.
37 *
38 * @var int
39 */
40 const APPLICATION_USER_ID = -1;
41
42 /**
43 * Get the Actor by ID.
44 *
45 * @param int $user_id The user ID.
46 *
47 * @return Actor|User|Blog|Application|\WP_Error Actor object or WP_Error if not found or not permitted.
48 */
49 public static function get_by_id( $user_id ) {
50 if ( is_numeric( $user_id ) ) {
51 $user_id = (int) $user_id;
52 }
53
54 /**
55 * Filter the actor before resolving by ID.
56 *
57 * Allows third-party plugins to register custom virtual actors
58 * resolved by ID, mirroring the `activitypub_pre_get_by_username`
59 * filter for username lookups.
60 *
61 * @since 8.1.0
62 *
63 * @param null $pre The pre-existing value.
64 * @param int $user_id The user ID.
65 */
66 $pre = \apply_filters( 'activitypub_pre_get_by_id', null, $user_id );
67 if ( null !== $pre ) {
68 return $pre;
69 }
70
71 if ( ! user_can_activitypub( $user_id ) ) {
72 return new \WP_Error(
73 'activitypub_user_not_found',
74 \__( 'Actor not found', 'activitypub' ),
75 array( 'status' => 404 )
76 );
77 }
78
79 switch ( $user_id ) {
80 case self::BLOG_USER_ID:
81 return new Blog();
82 case self::APPLICATION_USER_ID:
83 return new Application();
84 default:
85 return User::from_wp_user( $user_id );
86 }
87 }
88
89 /**
90 * Get the Actor by username.
91 *
92 * @param string $username Name of the actor.
93 *
94 * @return User|Blog|Application|\WP_Error Actor object or WP_Error if not found.
95 */
96 public static function get_by_username( $username ) {
97 /**
98 * Filter the username before we do anything else.
99 *
100 * @param null $pre The pre-existing value.
101 * @param string $username The username.
102 */
103 $pre = apply_filters( 'activitypub_pre_get_by_username', null, $username );
104 if ( null !== $pre ) {
105 return $pre;
106 }
107
108 $id = self::get_id_by_username( $username );
109 if ( \is_wp_error( $id ) ) {
110 return $id;
111 }
112
113 return self::get_by_id( $id );
114 }
115
116 /**
117 * Get the Actor by username.
118 *
119 * @param string $username Name of the actor.
120 *
121 * @return int|\WP_Error Actor id or WP_Error if not found.
122 */
123 public static function get_id_by_username( $username ) {
124 // Check for blog user.
125 if (
126 Blog::get_default_username() === $username ||
127 \get_option( 'activitypub_blog_identifier' ) === $username
128 ) {
129 if ( is_user_type_disabled( 'blog' ) ) {
130 return new \WP_Error(
131 'activitypub_user_not_found',
132 \__( 'Actor not found', 'activitypub' ),
133 array( 'status' => 404 )
134 );
135 }
136
137 return self::BLOG_USER_ID;
138 }
139
140 // Check for application user.
141 if ( 'application' === $username ) {
142 return self::APPLICATION_USER_ID;
143 }
144
145 // Check for 'activitypub_username' meta.
146 $user = new \WP_User_Query(
147 array(
148 'count_total' => false,
149 'number' => 1,
150 'hide_empty' => true,
151 'fields' => 'ID',
152 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
153 'meta_query' => array(
154 'relation' => 'OR',
155 array(
156 'key' => '_activitypub_user_identifier',
157 'value' => $username,
158 'compare' => 'LIKE',
159 ),
160 ),
161 )
162 );
163
164 if ( $user->get_results() ) {
165 return \current( $user->get_results() );
166 }
167
168 $username = str_replace( array( '*', '%' ), '', $username );
169
170 // Check for login or nicename.
171 $user = new \WP_User_Query(
172 array(
173 'count_total' => false,
174 'search' => $username,
175 'search_columns' => array( 'user_login', 'user_nicename' ),
176 'number' => 1,
177 'hide_empty' => true,
178 'fields' => 'ID',
179 )
180 );
181
182 if ( $user->get_results() ) {
183 return \current( $user->get_results() );
184 }
185
186 return new \WP_Error(
187 'activitypub_user_not_found',
188 \__( 'Actor not found', 'activitypub' ),
189 array( 'status' => 404 )
190 );
191 }
192
193 /**
194 * Get the Actor by resource URI (acct, http(s), etc).
195 *
196 * @param string $uri The actor resource URI.
197 *
198 * @return User|Blog|Application|\WP_Error Actor object or WP_Error if not found.
199 */
200 public static function get_by_resource( $uri ) {
201 $id = self::get_id_by_resource( $uri );
202 if ( \is_wp_error( $id ) ) {
203 return $id;
204 }
205
206 return self::get_by_id( $id );
207 }
208
209 /**
210 * Get the Actor by resource URI (acct, http(s), etc).
211 *
212 * @param string $uri The actor resource URI.
213 *
214 * @return int|\WP_Error Actor id or WP_Error if not found.
215 */
216 public static function get_id_by_resource( $uri ) {
217 $uri = object_to_uri( $uri );
218
219 if ( ! $uri ) {
220 return new \WP_Error(
221 'activitypub_no_uri',
222 \__( 'No URI provided', 'activitypub' ),
223 array( 'status' => 404 )
224 );
225 }
226
227 $scheme = 'acct';
228 $match = array();
229 // Try to extract the scheme and the host.
230 if ( preg_match( '/^([a-zA-Z^:]+):(.*)$/i', $uri, $match ) ) {
231 // Extract the scheme.
232 $scheme = \esc_attr( $match[1] );
233 }
234
235 // @todo: handle old domain URIs here before we serve a new domain below when we shouldn't.
236 // Although maybe passing through to ::get_by_username() is enough?
237
238 switch ( $scheme ) {
239 // Check for http(s) URIs.
240 case 'http':
241 case 'https':
242 // Check for http(s)://blog.example.com/@username.
243 $resource_path = \wp_parse_url( $uri, PHP_URL_PATH );
244
245 if ( $resource_path ) {
246 $blog_path = \wp_parse_url( \home_url(), PHP_URL_PATH );
247
248 if ( $blog_path ) {
249 $resource_path = \str_replace( $blog_path, '', $resource_path );
250 }
251
252 $resource_path = \trim( $resource_path, '/' );
253
254 if ( str_starts_with( $resource_path, '@' ) ) {
255 $identifier = \str_replace( '@', '', $resource_path );
256 $identifier = \trim( $identifier, '/' );
257
258 return self::get_id_by_username( $identifier );
259 }
260 }
261
262 // Check for http(s)://blog.example.com/author/username.
263 $user_id = url_to_authorid( $uri );
264
265 if ( \is_int( $user_id ) ) {
266 return $user_id;
267 }
268
269 // Check for http(s)://blog.example.com/.
270 $normalized_uri = normalize_url( $uri );
271
272 if (
273 normalize_url( site_url() ) === $normalized_uri ||
274 normalize_url( home_url() ) === $normalized_uri
275 ) {
276 return self::BLOG_USER_ID;
277 }
278
279 return new \WP_Error(
280 'activitypub_no_user_found',
281 \__( 'Actor not found', 'activitypub' ),
282 array( 'status' => 404 )
283 );
284 // Check for acct URIs.
285 case 'acct':
286 $uri = \str_replace( 'acct:', '', $uri );
287 $identifier = \substr( $uri, 0, \strrpos( $uri, '@' ) );
288 $host = normalize_host( \substr( \strrchr( $uri, '@' ), 1 ) );
289 $blog_host = normalize_host( \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) );
290
291 if ( $blog_host !== $host && get_option( 'activitypub_old_host' ) !== $host ) {
292 return new \WP_Error(
293 'activitypub_wrong_host',
294 \__( 'Resource host does not match blog host', 'activitypub' ),
295 array( 'status' => 404 )
296 );
297 }
298
299 // Prepare wildcards https://github.com/mastodon/mastodon/issues/22213.
300 if ( in_array( $identifier, array( '_', '*', '' ), true ) ) {
301 return self::BLOG_USER_ID;
302 }
303
304 return self::get_id_by_username( $identifier );
305 default:
306 return new \WP_Error(
307 'activitypub_wrong_scheme',
308 \__( 'Wrong scheme', 'activitypub' ),
309 array( 'status' => 404 )
310 );
311 }
312 }
313
314 /**
315 * Get the Actor by various identifier types (ID, URI, username, or email).
316 *
317 * @param string|int $id Actor identifier (user ID, URI, username, or email).
318 *
319 * @return User|Blog|Application|\WP_Error Actor object or WP_Error if not found.
320 */
321 public static function get_by_various( $id ) {
322 $id = self::get_id_by_various( $id );
323 if ( \is_wp_error( $id ) ) {
324 return $id;
325 }
326
327 return self::get_by_id( $id );
328 }
329
330 /**
331 * Get the Actor by various identifier types (ID, URI, username, or email).
332 *
333 * @param string|int $id Actor identifier (user ID, URI, username, or email).
334 *
335 * @return int|\WP_Error Actor id or WP_Error if not found.
336 */
337 public static function get_id_by_various( $id ) {
338 if ( is_numeric( $id ) ) {
339 $id = (int) $id;
340 } elseif (
341 // Is URL.
342 filter_var( $id, FILTER_VALIDATE_URL ) ||
343 // Is acct.
344 str_starts_with( $id, 'acct:' ) ||
345 // Is email.
346 filter_var( $id, FILTER_VALIDATE_EMAIL )
347 ) {
348 $id = self::get_id_by_resource( $id );
349 } else {
350 $id = self::get_id_by_username( $id );
351 }
352
353 return $id;
354 }
355
356 /**
357 * Get the collection of all local user actors.
358 *
359 * @return Actor[] Array of User actor objects.
360 */
361 public static function get_collection() {
362 if ( is_user_type_disabled( 'user' ) ) {
363 return array();
364 }
365
366 $users = \get_users(
367 array(
368 'capability__in' => array( 'activitypub' ),
369 )
370 );
371
372 $return = array();
373
374 foreach ( $users as $user ) {
375 $actor = User::from_wp_user( $user->ID );
376
377 if ( \is_wp_error( $actor ) ) {
378 continue;
379 }
380
381 $return[] = $actor;
382 }
383
384 return $return;
385 }
386
387 /**
388 * Get all active actors, including the Blog actor if enabled.
389 *
390 * @return int[] Array of User and Blog actor IDs.
391 */
392 public static function get_all_ids() {
393 $user_ids = array();
394
395 if ( ! is_user_type_disabled( 'user' ) ) {
396 $user_ids = \get_users(
397 array(
398 'fields' => 'ID',
399 'capability__in' => array( 'activitypub' ),
400 )
401 );
402 }
403
404 // Also include the blog actor if active.
405 if ( ! is_user_type_disabled( 'blog' ) ) {
406 $user_ids[] = self::BLOG_USER_ID;
407 }
408
409 return array_map( 'intval', $user_ids );
410 }
411
412 /**
413 * Get all active actors, including the Blog actor if enabled.
414 *
415 * @return Actor[] Array of User and Blog actor objects.
416 */
417 public static function get_all() {
418 $user_ids = self::get_all_ids();
419
420 $actors = array_map( array( self::class, 'get_by_id' ), $user_ids );
421
422 // Filter out any WP_Error instances.
423 return array_filter(
424 $actors,
425 static function ( $actor ) {
426 return ! \is_wp_error( $actor );
427 }
428 );
429 }
430
431 /**
432 * Returns the actor type based on the user ID.
433 *
434 * @param int $user_id The user ID to check.
435 *
436 * @return string Actor type: 'user', 'blog', or 'application'.
437 */
438 public static function get_type_by_id( $user_id ) {
439 $user_id = (int) $user_id;
440
441 if ( self::APPLICATION_USER_ID === $user_id ) {
442 return 'application';
443 }
444
445 if ( self::BLOG_USER_ID === $user_id ) {
446 return 'blog';
447 }
448
449 return 'user';
450 }
451
452 /**
453 * Return the public key for a given actor.
454 *
455 * @param int $user_id The WordPress User ID.
456 * @param bool $force Optional. Force the generation of a new key pair. Default false.
457 *
458 * @return string The public key.
459 */
460 public static function get_public_key( $user_id, $force = false ) {
461 if ( $force ) {
462 self::generate_key_pair( $user_id );
463 }
464
465 $key_pair = self::get_keypair( $user_id );
466
467 return $key_pair['public_key'];
468 }
469
470 /**
471 * Return the private key for a given actor.
472 *
473 * @param int $user_id The WordPress User ID.
474 * @param bool $force Optional. Force the generation of a new key pair. Default false.
475 *
476 * @return string The private key.
477 */
478 public static function get_private_key( $user_id, $force = false ) {
479 if ( $force ) {
480 self::generate_key_pair( $user_id );
481 }
482
483 $key_pair = self::get_keypair( $user_id );
484
485 return $key_pair['private_key'];
486 }
487
488 /**
489 * Return the key pair for a given actor.
490 *
491 * @param int $user_id The WordPress User ID.
492 *
493 * @return array The key pair.
494 */
495 public static function get_keypair( $user_id ) {
496 $option_key = self::get_signature_options_key( $user_id );
497 $key_pair = \get_option( $option_key );
498
499 if ( ! $key_pair ) {
500 $key_pair = self::generate_key_pair( $user_id );
501 }
502
503 return $key_pair;
504 }
505
506 /**
507 * Generates the pair of keys.
508 *
509 * @param int $user_id The WordPress User ID.
510 *
511 * @return array The key pair.
512 */
513 protected static function generate_key_pair( $user_id ) {
514 $option_key = self::get_signature_options_key( $user_id );
515 $key_pair = self::check_legacy_key_pair( $user_id );
516
517 if ( $key_pair ) {
518 \add_option( $option_key, $key_pair );
519
520 return $key_pair;
521 }
522
523 $config = array(
524 'digest_alg' => 'sha512',
525 'private_key_bits' => 2048,
526 'private_key_type' => \OPENSSL_KEYTYPE_RSA,
527 );
528
529 $key = \openssl_pkey_new( $config );
530 $private_key = null;
531 $detail = array();
532 if ( $key ) {
533 \openssl_pkey_export( $key, $private_key );
534
535 $detail = \openssl_pkey_get_details( $key );
536 }
537
538 // Check if keys are valid.
539 if (
540 empty( $private_key ) || ! is_string( $private_key ) ||
541 ! isset( $detail['key'] ) || ! is_string( $detail['key'] )
542 ) {
543 return array(
544 'private_key' => null,
545 'public_key' => null,
546 );
547 }
548
549 $key_pair = array(
550 'private_key' => $private_key,
551 'public_key' => $detail['key'],
552 );
553
554 // Persist keys.
555 \add_option( $option_key, $key_pair );
556
557 return $key_pair;
558 }
559
560 /**
561 * Return the option key for a given user.
562 *
563 * @param int $user_id The WordPress User ID.
564 *
565 * @return string The option key.
566 */
567 protected static function get_signature_options_key( $user_id ) {
568 if ( $user_id > 0 ) {
569 $user = \get_userdata( $user_id );
570 // Sanitize username because it could include spaces and special chars.
571 $user_id = \sanitize_title( $user->user_login );
572 }
573
574 return 'activitypub_keypair_for_' . $user_id;
575 }
576
577 /**
578 * Check if there is a legacy key pair
579 *
580 * @param int $user_id The WordPress User ID.
581 *
582 * @return array|bool The key pair or false.
583 */
584 protected static function check_legacy_key_pair( $user_id ) {
585 switch ( $user_id ) {
586 case 0:
587 $public_key = \get_option( 'activitypub_blog_user_public_key' );
588 $private_key = \get_option( 'activitypub_blog_user_private_key' );
589 break;
590 case -1:
591 $public_key = \get_option( 'activitypub_application_user_public_key' );
592 $private_key = \get_option( 'activitypub_application_user_private_key' );
593 break;
594 default:
595 $public_key = \get_user_meta( $user_id, 'magic_sig_public_key', true );
596 $private_key = \get_user_meta( $user_id, 'magic_sig_private_key', true );
597 break;
598 }
599
600 if ( ! empty( $public_key ) && is_string( $public_key ) && ! empty( $private_key ) && is_string( $private_key ) ) {
601 return array(
602 'private_key' => $private_key,
603 'public_key' => $public_key,
604 );
605 }
606
607 return false;
608 }
609
610 /**
611 * Returns all Inboxes for all known remote Actors.
612 *
613 * @deprecated 7.4.0 Use {@see Remote_Actors::get_inboxes()}
614 *
615 * @return array The list of Inboxes.
616 */
617 public static function get_inboxes() {
618 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_inboxes' );
619 return Remote_Actors::get_inboxes();
620 }
621
622 /**
623 * Upsert (insert or update) a remote actor as a custom post type.
624 *
625 * @deprecated 7.4.0 Use {@see Remote_Actors::upsert()}
626 *
627 * @param array|Actor $actor ActivityPub actor object (array or actor, must include 'id').
628 *
629 * @return int|\WP_Error Post ID on success, WP_Error on failure.
630 */
631 public static function upsert( $actor ) {
632 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::upsert' );
633 return Remote_Actors::upsert( $actor );
634 }
635
636 /**
637 * Create a remote actor as a custom post type.
638 *
639 * @deprecated 7.4.0 Use {@see Remote_Actors::create()}
640 *
641 * @param array|Actor $actor ActivityPub actor object (array or Actor, must include 'id').
642 *
643 * @return int|\WP_Error Post ID on success, WP_Error on failure.
644 */
645 public static function create( $actor ) {
646 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::create' );
647 return Remote_Actors::create( $actor );
648 }
649
650 /**
651 * Update a remote Actor object by actor URL (guid).
652 *
653 * @deprecated 7.4.0 Use {@see Remote_Actors::update()}
654 *
655 * @param int|\WP_Post $post The post ID or object.
656 * @param array|Actor $actor The ActivityPub actor object as associative array (must include 'id').
657 *
658 * @return int|\WP_Error The post ID or WP_Error.
659 */
660 public static function update( $post, $actor ) {
661 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::update' );
662 return Remote_Actors::update( $post, $actor );
663 }
664
665 /**
666 * Delete a remote actor object by actor URL (guid).
667 *
668 * @deprecated 7.4.0 Use {@see Remote_Actors::delete()}
669 *
670 * @param int $post_id The post ID.
671 *
672 * @return bool True on success, false on failure.
673 */
674 public static function delete( $post_id ) {
675 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::delete' );
676 return Remote_Actors::delete( $post_id );
677 }
678
679 /**
680 * Get a remote actor post by actor URI (guid).
681 *
682 * @deprecated 7.4.0 Use {@see Remote_Actors::get_by_uri()}
683 *
684 * @param string $actor_uri The actor URI.
685 *
686 * @return \WP_Post|\WP_Error Post object or WP_Error if not found.
687 */
688 public static function get_remote_by_uri( $actor_uri ) {
689 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_by_uri' );
690 return Remote_Actors::get_by_uri( $actor_uri );
691 }
692
693 /**
694 * Lookup a remote actor post by actor URI (guid), fetching from remote if not found locally.
695 *
696 * @deprecated 7.4.0 Use {@see Remote_Actors::fetch_by_uri()}
697 *
698 * @param string $actor_uri The actor URI.
699 *
700 * @return \WP_Post|\WP_Error Post object or WP_Error if not found.
701 */
702 public static function fetch_remote_by_uri( $actor_uri ) {
703 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::fetch_by_uri' );
704 return Remote_Actors::fetch_by_uri( $actor_uri );
705 }
706
707 /**
708 * Store an error that occurred when sending an ActivityPub message to a follower.
709 *
710 * The error will be stored in post meta.
711 *
712 * @deprecated 7.4.0 Use {@see Remote_Actors::add_error()}
713 *
714 * @param int $post_id The ID of the WordPress Custom-Post-Type.
715 * @param string|\WP_Error $error The error message.
716 *
717 * @return int|false The meta ID on success, false on failure.
718 */
719 public static function add_error( $post_id, $error ) {
720 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::add_error' );
721 return Remote_Actors::add_error( $post_id, $error );
722 }
723
724 /**
725 * Count the errors for an actor.
726 *
727 * @deprecated 7.4.0 Use {@see Remote_Actors::count_errors()}
728 *
729 * @param int $post_id The ID of the WordPress Custom-Post-Type.
730 *
731 * @return int The number of errors.
732 */
733 public static function count_errors( $post_id ) {
734 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::count_errors' );
735 return Remote_Actors::count_errors( $post_id );
736 }
737
738 /**
739 * Get all error messages for an actor.
740 *
741 * @deprecated 7.4.0 Use {@see Remote_Actors::get_errors()}
742 *
743 * @param int $post_id The post ID.
744 *
745 * @return string[] Array of error messages.
746 */
747 public static function get_errors( $post_id ) {
748 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_errors' );
749 return Remote_Actors::get_errors( $post_id );
750 }
751
752 /**
753 * Clear all errors for an actor.
754 *
755 * @deprecated 7.4.0 Use {@see Remote_Actors::clear_errors()}
756 *
757 * @param int $post_id The ID of the WordPress Custom-Post-Type.
758 *
759 * @return bool True on success, false on failure.
760 */
761 public static function clear_errors( $post_id ) {
762 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::clear_errors' );
763 return Remote_Actors::clear_errors( $post_id );
764 }
765
766 /**
767 * Get all remote actors (Custom Post Type) that had errors.
768 *
769 * @deprecated 7.4.0 Use {@see Remote_Actors::get_faulty()}
770 *
771 * @param int $number Optional. Number of actors to return. Default 20.
772 *
773 * @return \WP_Post[] Array of faulty actor posts.
774 */
775 public static function get_faulty( $number = 20 ) {
776 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_faulty' );
777 return Remote_Actors::get_faulty( $number );
778 }
779
780 /**
781 * Get all remote actor posts not updated for a given time.
782 *
783 * @deprecated 7.4.0 Use {@see Remote_Actors::get_outdated()}
784 *
785 * @param int $number Optional. Limits the result. Default 50.
786 * @param int $older_than Optional. The time in seconds. Default DAY_IN_SECONDS.
787 *
788 * @return \WP_Post[] The list of actors.
789 */
790 public static function get_outdated( $number = 50, $older_than = DAY_IN_SECONDS ) {
791 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_outdated' );
792 return Remote_Actors::get_outdated( $number, $older_than );
793 }
794
795 /**
796 * Convert a custom post type input to an Activitypub\Activity\Actor.
797 *
798 * @deprecated 7.4.0 Use {@see Remote_Actors::get_actor()}
799 *
800 * @param int|\WP_Post $post The post ID or object.
801 *
802 * @return Actor|\WP_Error The actor object or WP_Error on failure.
803 */
804 public static function get_actor( $post ) {
805 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_actor' );
806 return Remote_Actors::get_actor( $post );
807 }
808
809 /**
810 * Get public key from key_id.
811 *
812 * @deprecated 7.4.0 Use {@see Remote_Actors::get_public_key()}
813 *
814 * @param string $key_id The URL to the public key.
815 *
816 * @return resource|\WP_Error The public key resource or WP_Error.
817 */
818 public static function get_remote_key( $key_id ) {
819 _deprecated_function( __METHOD__, '7.4.0', 'Activitypub\Collection\Remote_Actors::get_public_key' );
820 return Remote_Actors::get_public_key( $key_id );
821 }
822
823 /**
824 * Normalize actor identifier to a URI.
825 *
826 * Handles webfinger addresses, URLs without schemes, objects, and arrays.
827 *
828 * @deprecated 7.4.0 Use {@see Remote_Actors::normalize_identifier()}
829 *
830 * @param string|object|array $actor Actor URI, webfinger address, actor object, or array.
831 * @return string|null Normalized actor URI or null if unable to resolve.
832 */
833 public static function normalize_identifier( $actor ) {
834 _deprecated_function( __METHOD__, '7.4.0', 'Remote_Actors::normalize_identifier' );
835 return Remote_Actors::normalize_identifier( $actor );
836 }
837
838 /**
839 * Determine if social graph (followers and following) should be shown for a given user.
840 *
841 * @param int $user_id The user ID.
842 *
843 * @return bool True if social graph should be shown, false otherwise.
844 */
845 public static function show_social_graph( $user_id ) {
846 if ( self::BLOG_USER_ID === (int) $user_id ) {
847 return ! (bool) \get_option( 'activitypub_hide_social_graph' );
848 } else {
849 return ! (bool) \get_user_option( 'activitypub_hide_social_graph', $user_id );
850 }
851 }
852 }
853