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
← All changes | includes/model/class-blog.php +51 -127 9.2.0 → 7.7.0 View file →
@@ -15,9 +15,8 @@
15 15 use function Activitypub\get_attribution_domains;
16 16 use function Activitypub\get_rest_url_by_path;
17 17 use function Activitypub\is_blog_public;
18 18 use function Activitypub\is_single_user;
19 -use function Activitypub\site_icon;
20 19
21 20 /**
22 21 * Blog class.
23 22 *
@@ -93,9 +92,9 @@
93 92
94 93 $permalink = \get_option( 'activitypub_use_permalink_as_id_for_blog', false );
95 94
96 95 if ( $permalink ) {
97 - return \esc_url_raw( \home_url( '/@' . $this->get_preferred_username() ) );
96 + return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
98 97 }
99 98
100 99 return \add_query_arg( 'author', $this->_id, \home_url( '/' ) );
101 100 }
@@ -102,18 +101,13 @@
102 101
103 102 /**
104 103 * Get the type of the object.
105 104 *
106 - * If relay mode is enabled, return "Service".
107 105 * If the Blog is in "single user" mode, return "Person" instead of "Group".
108 106 *
109 107 * @return string The type of the object.
110 108 */
111 109 public function get_type() {
112 - if ( \get_option( 'activitypub_relay_mode', false ) ) {
113 - return 'Service';
114 - }
115 -
116 110 if ( is_single_user() ) {
117 111 return 'Person';
118 112 } else {
119 113 return 'Group';
@@ -169,9 +163,9 @@
169 163 *
170 164 * @return string The User-Url.
171 165 */
172 166 public function get_alternate_url() {
173 - return \esc_url_raw( \trailingslashit( \get_home_url() ) );
167 + return \esc_url( \trailingslashit( get_home_url() ) );
174 168 }
175 169
176 170 /**
177 171 * Generate a default Username.
@@ -191,9 +185,9 @@
191 185 * without the 'www.' prefix.
192 186 *
193 187 * @param string $host The default username (site's host name).
194 188 */
195 - return \apply_filters( 'activitypub_default_blog_username', $host );
189 + return apply_filters( 'activitypub_default_blog_username', $host );
196 190 }
197 191
198 192 /**
199 193 * Get the preferred Username.
@@ -215,9 +209,34 @@
215 209 *
216 210 * @return string[] The User icon.
217 211 */
218 212 public function get_icon() {
219 - return site_icon();
213 + // Try site_logo, falling back to site_icon, first.
214 + $icon_id = get_option( 'site_icon' );
215 +
216 + // Try custom logo second.
217 + if ( ! $icon_id ) {
218 + $icon_id = get_theme_mod( 'custom_logo' );
219 + }
220 +
221 + $icon_url = false;
222 +
223 + if ( $icon_id ) {
224 + $icon = wp_get_attachment_image_src( $icon_id, 'full' );
225 + if ( $icon ) {
226 + $icon_url = $icon[0];
227 + }
228 + }
229 +
230 + if ( ! $icon_url ) {
231 + // Fallback to default icon.
232 + $icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE );
233 + }
234 +
235 + return array(
236 + 'type' => 'Image',
237 + 'url' => esc_url( $icon_url ),
238 + );
220 239 }
221 240
222 241 /**
223 242 * Get the User-Header-Image.
@@ -224,9 +243,9 @@
224 243 *
225 244 * @return string[]|null The User-Header-Image.
226 245 */
227 246 public function get_image() {
228 - $header_image = \get_option( 'activitypub_header_image' );
247 + $header_image = get_option( 'activitypub_header_image' );
229 248 $image_url = null;
230 249
231 250 if ( $header_image ) {
232 251 $image_url = \wp_get_attachment_url( $header_image );
@@ -238,9 +257,9 @@
238 257
239 258 if ( $image_url ) {
240 259 return array(
241 260 'type' => 'Image',
242 - 'url' => \esc_url_raw( $image_url ),
261 + 'url' => esc_url( $image_url ),
243 262 );
244 263 }
245 264
246 265 return null;
@@ -251,46 +270,23 @@
251 270 *
252 271 * @return string The published date.
253 272 */
254 273 public function get_published() {
255 - $published = \get_option( 'activitypub_blog_published' );
256 -
257 - if ( $published ) {
258 - return $published;
259 - }
260 -
261 - // Backfill from the first federated post.
262 - $first_federated = new \WP_Query(
274 + $first_post = new \WP_Query(
263 275 array(
264 - 'orderby' => 'date',
265 - 'order' => 'ASC',
266 - 'posts_per_page' => 1,
267 - 'post_status' => 'publish',
268 - 'no_found_rows' => true,
269 - 'ignore_sticky_posts' => true,
270 - 'update_post_meta_cache' => false,
271 - 'update_post_term_cache' => false,
272 - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
273 - 'meta_query' => array(
274 - array(
275 - 'key' => 'activitypub_status',
276 - 'compare' => 'EXISTS',
277 - ),
278 - ),
276 + 'orderby' => 'date',
277 + 'order' => 'ASC',
278 + 'number' => 1,
279 279 )
280 280 );
281 281
282 - if ( ! empty( $first_federated->posts[0] ) ) {
283 - $time = \strtotime( $first_federated->posts[0]->post_date_gmt );
282 + if ( ! empty( $first_post->posts[0] ) ) {
283 + $time = \strtotime( $first_post->posts[0]->post_date_gmt );
284 284 } else {
285 285 $time = \time();
286 286 }
287 287
288 - $published = \gmdate( ACTIVITYPUB_DATE_TIME_RFC3339, $time );
289 -
290 - \update_option( 'activitypub_blog_published', $published, false );
291 -
292 - return $published;
288 + return \gmdate( ACTIVITYPUB_DATE_TIME_RFC3339, $time );
293 289 }
294 290
295 291 /**
296 292 * Get the canonical URL.
@@ -358,9 +354,9 @@
358 354 *
359 355 * @return string The Inbox-Endpoint.
360 356 */
361 357 public function get_inbox() {
362 - return get_rest_url_by_path( \sprintf( 'actors/%d/inbox', $this->get__id() ) );
358 + return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) );
363 359 }
364 360
365 361 /**
366 362 * Returns the Outbox-API-Endpoint.
@@ -367,9 +363,9 @@
367 363 *
368 364 * @return string The Outbox-Endpoint.
369 365 */
370 366 public function get_outbox() {
371 - return get_rest_url_by_path( \sprintf( 'actors/%d/outbox', $this->get__id() ) );
367 + return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) );
372 368 }
373 369
374 370 /**
375 371 * Returns the Followers-API-Endpoint.
@@ -376,9 +372,9 @@
376 372 *
377 373 * @return string The Followers-Endpoint.
378 374 */
379 375 public function get_followers() {
380 - return get_rest_url_by_path( \sprintf( 'actors/%d/followers', $this->get__id() ) );
376 + return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) );
381 377 }
382 378
383 379 /**
384 380 * Returns the Following-API-Endpoint.
@@ -385,9 +381,9 @@
385 381 *
386 382 * @return string The Following-Endpoint.
387 383 */
388 384 public function get_following() {
389 - return get_rest_url_by_path( \sprintf( 'actors/%d/following', $this->get__id() ) );
385 + return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) );
390 386 }
391 387
392 388 /**
393 389 * Returns endpoints.
@@ -394,26 +390,11 @@
394 390 *
395 391 * @return string[]|null The endpoints.
396 392 */
397 393 public function get_endpoints() {
398 - $endpoints = array(
399 - 'sharedInbox' => get_rest_url_by_path( 'inbox' ),
400 - 'oauthAuthorizationEndpoint' => get_rest_url_by_path( 'oauth/authorize' ),
401 - 'oauthTokenEndpoint' => get_rest_url_by_path( 'oauth/token' ),
402 - 'oauthRegistrationEndpoint' => get_rest_url_by_path( 'oauth/clients' ),
403 - 'proxyUrl' => get_rest_url_by_path( 'proxy' ),
404 - 'proxyEventStream' => get_rest_url_by_path( 'proxy/stream' ),
394 + return array(
395 + 'sharedInbox' => get_rest_url_by_path( 'inbox' ),
405 396 );
406 -
407 - if ( \get_option( 'activitypub_api', false ) ) {
408 - /*
409 - * RFC 6570 template. add_query_arg() picks the ?/& separator (plain permalinks already
410 - * carry a query string) and does not encode values, so the {q} placeholder stays intact.
411 - */
412 - $endpoints['actorAutocomplete'] = \add_query_arg( 'q', '{q}', get_rest_url_by_path( 'actors/autocomplete' ) );
413 - }
414 -
415 - return $endpoints;
416 397 }
417 398
418 399 /**
419 400 * Returns a user@domain type of identifier for the user.
@@ -424,25 +405,14 @@
424 405 return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
425 406 }
426 407
427 408 /**
428 - * Returns the Liked API endpoint.
429 - *
430 - * @since 8.1.0
431 - *
432 - * @return string The Liked endpoint.
433 - */
434 - public function get_liked() {
435 - return get_rest_url_by_path( \sprintf( 'actors/%d/liked', $this->get__id() ) );
436 - }
437 -
438 - /**
439 409 * Returns the Featured-API-Endpoint.
440 410 *
441 411 * @return string The Featured-Endpoint.
442 412 */
443 413 public function get_featured() {
444 - return get_rest_url_by_path( \sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
414 + return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
445 415 }
446 416
447 417 /**
448 418 * Returns the Featured-Tags-API-Endpoint.
@@ -449,9 +419,9 @@
449 419 *
450 420 * @return string The Featured-Tags-Endpoint.
451 421 */
452 422 public function get_featured_tags() {
453 - return get_rest_url_by_path( \sprintf( 'actors/%d/collections/tags', $this->get__id() ) );
423 + return get_rest_url_by_path( sprintf( 'actors/%d/collections/tags', $this->get__id() ) );
454 424 }
455 425
456 426 /**
457 427 * Returns whether the site is indexable.
@@ -492,9 +462,9 @@
492 462 * @param mixed $value The new value.
493 463 * @return bool True if the attribute was updated, false otherwise.
494 464 */
495 465 public function update_icon( $value ) {
496 - if ( ! \wp_attachment_is_image( $value ) ) {
466 + if ( ! wp_attachment_is_image( $value ) ) {
497 467 return false;
498 468 }
499 469 return \update_option( 'site_icon', $value );
500 470 }
@@ -505,9 +475,9 @@
505 475 * @param mixed $value The new value.
506 476 * @return bool True if the attribute was updated, false otherwise.
507 477 */
508 478 public function update_header( $value ) {
509 - if ( ! \wp_attachment_is_image( $value ) ) {
479 + if ( ! wp_attachment_is_image( $value ) ) {
510 480 return false;
511 481 }
512 482 return \update_option( 'activitypub_header_image', $value );
513 483 }
@@ -527,9 +497,9 @@
527 497 'order' => 'DESC',
528 498 'number' => 10,
529 499 );
530 500
531 - $tags = \get_tags( $args );
501 + $tags = get_tags( $args );
532 502
533 503 foreach ( $tags as $tag ) {
534 504 $hashtags[] = array(
535 505 'type' => 'Hashtag',
@@ -571,11 +541,11 @@
571 541 $this->get_url(),
572 542 $this->get_alternate_url(),
573 543 );
574 544
575 - $also_known_as = \array_merge( $also_known_as, \get_option( 'activitypub_blog_user_also_known_as', array() ) );
545 + $also_known_as = array_merge( $also_known_as, \get_option( 'activitypub_blog_user_also_known_as', array() ) );
576 546
577 - return \array_unique( $also_known_as );
547 + return array_unique( $also_known_as );
578 548 }
579 549
580 550 /**
581 551 * Returns the movedTo.
@@ -585,52 +555,6 @@
585 555 public function get_moved_to() {
586 556 $moved_to = \get_option( 'activitypub_blog_user_moved_to' );
587 557
588 558 return $moved_to && $moved_to !== $this->get_id() ? $moved_to : null;
589 - }
590 -
591 - /**
592 - * Get the actor-level interaction policy.
593 - *
594 - * Overrides the magic property accessor on Base_Object so that we always
595 - * compute the policy from the current site setting rather than returning a
596 - * cached property value. Currently only emits `canFeature` (FEP-7aa9).
597 - * Driven by the site option `activitypub_default_feature_policy` and
598 - * defaults to denying all featured-collection requests, in line with
599 - * FEP-7aa9's "absence of policy = no consent" rule.
600 - *
601 - * @see https://w3id.org/fep/7aa9
602 - *
603 - * @since 9.0.0
604 - *
605 - * @return array
606 - */
607 - public function get_interaction_policy() {
608 - $policy = array( 'canFeature' => $this->build_can_feature_policy() );
609 -
610 - // Merge with an explicitly set interaction policy, if any.
611 - if ( $this->interaction_policy ) {
612 - $policy = \array_merge( (array) $this->interaction_policy, $policy );
613 - }
614 -
615 - return $policy;
616 - }
617 -
618 - /**
619 - * Build the `canFeature` policy array from the site option.
620 - *
621 - * @return array
622 - */
623 - protected function build_can_feature_policy() {
624 - $policy = \get_option( 'activitypub_default_feature_policy', ACTIVITYPUB_INTERACTION_POLICY_ME );
625 -
626 - switch ( $policy ) {
627 - case ACTIVITYPUB_INTERACTION_POLICY_ANYONE:
628 - return array( 'automaticApproval' => array( 'https://www.w3.org/ns/activitystreams#Public' ) );
629 - case ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS:
630 - return array( 'automaticApproval' => array( $this->get_followers() ) );
631 - case ACTIVITYPUB_INTERACTION_POLICY_ME:
632 - default:
633 - return array( 'automaticApproval' => array( $this->get_id() ) );
634 - }
635 559 }
636 560 }