PluginProbe
ActivityPub / 7.7.0
ActivityPub v7.7.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 7.7.0, at includes/collection/class-actors.php

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