PluginProbe
ActivityPub / 8.0.2
ActivityPub v8.0.2
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 -122 9.2.08.0.2 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( \home_url( '/@' . $this->get_preferred_username() ) );
98 97 }
99 98
100 99 return \add_query_arg( 'author', $this->_id, \home_url( '/' ) );
101 100 }
@@ -169,9 +168,9 @@
169 168 *
170 169 * @return string The User-Url.
171 170 */
172 171 public function get_alternate_url() {
173 - return \esc_url_raw( \trailingslashit( \get_home_url() ) );
172 + return \esc_url( \trailingslashit( get_home_url() ) );
174 173 }
175 174
176 175 /**
177 176 * Generate a default Username.
@@ -191,9 +190,9 @@
191 190 * without the 'www.' prefix.
192 191 *
193 192 * @param string $host The default username (site's host name).
194 193 */
195 - return \apply_filters( 'activitypub_default_blog_username', $host );
194 + return apply_filters( 'activitypub_default_blog_username', $host );
196 195 }
197 196
198 197 /**
199 198 * Get the preferred Username.
@@ -215,9 +214,34 @@
215 214 *
216 215 * @return string[] The User icon.
217 216 */
218 217 public function get_icon() {
219 - return site_icon();
218 + // Try site_logo, falling back to site_icon, first.
219 + $icon_id = get_option( 'site_icon' );
220 +
221 + // Try custom logo second.
222 + if ( ! $icon_id ) {
223 + $icon_id = get_theme_mod( 'custom_logo' );
224 + }
225 +
226 + $icon_url = false;
227 +
228 + if ( $icon_id ) {
229 + $icon = wp_get_attachment_image_src( $icon_id, 'full' );
230 + if ( $icon ) {
231 + $icon_url = $icon[0];
232 + }
233 + }
234 +
235 + if ( ! $icon_url ) {
236 + // Fallback to default icon.
237 + $icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE );
238 + }
239 +
240 + return array(
241 + 'type' => 'Image',
242 + 'url' => esc_url( $icon_url ),
243 + );
220 244 }
221 245
222 246 /**
223 247 * Get the User-Header-Image.
@@ -224,9 +248,9 @@
224 248 *
225 249 * @return string[]|null The User-Header-Image.
226 250 */
227 251 public function get_image() {
228 - $header_image = \get_option( 'activitypub_header_image' );
252 + $header_image = get_option( 'activitypub_header_image' );
229 253 $image_url = null;
230 254
231 255 if ( $header_image ) {
232 256 $image_url = \wp_get_attachment_url( $header_image );
@@ -238,9 +262,9 @@
238 262
239 263 if ( $image_url ) {
240 264 return array(
241 265 'type' => 'Image',
242 - 'url' => \esc_url_raw( $image_url ),
266 + 'url' => esc_url( $image_url ),
243 267 );
244 268 }
245 269
246 270 return null;
@@ -251,46 +275,23 @@
251 275 *
252 276 * @return string The published date.
253 277 */
254 278 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(
279 + $first_post = new \WP_Query(
263 280 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 - ),
281 + 'orderby' => 'date',
282 + 'order' => 'ASC',
283 + 'number' => 1,
279 284 )
280 285 );
281 286
282 - if ( ! empty( $first_federated->posts[0] ) ) {
283 - $time = \strtotime( $first_federated->posts[0]->post_date_gmt );
287 + if ( ! empty( $first_post->posts[0] ) ) {
288 + $time = \strtotime( $first_post->posts[0]->post_date_gmt );
284 289 } else {
285 290 $time = \time();
286 291 }
287 292
288 - $published = \gmdate( ACTIVITYPUB_DATE_TIME_RFC3339, $time );
289 -
290 - \update_option( 'activitypub_blog_published', $published, false );
291 -
292 - return $published;
293 + return \gmdate( ACTIVITYPUB_DATE_TIME_RFC3339, $time );
293 294 }
294 295
295 296 /**
296 297 * Get the canonical URL.
@@ -358,9 +359,9 @@
358 359 *
359 360 * @return string The Inbox-Endpoint.
360 361 */
361 362 public function get_inbox() {
362 - return get_rest_url_by_path( \sprintf( 'actors/%d/inbox', $this->get__id() ) );
363 + return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) );
363 364 }
364 365
365 366 /**
366 367 * Returns the Outbox-API-Endpoint.
@@ -367,9 +368,9 @@
367 368 *
368 369 * @return string The Outbox-Endpoint.
369 370 */
370 371 public function get_outbox() {
371 - return get_rest_url_by_path( \sprintf( 'actors/%d/outbox', $this->get__id() ) );
372 + return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) );
372 373 }
373 374
374 375 /**
375 376 * Returns the Followers-API-Endpoint.
@@ -376,9 +377,9 @@
376 377 *
377 378 * @return string The Followers-Endpoint.
378 379 */
379 380 public function get_followers() {
380 - return get_rest_url_by_path( \sprintf( 'actors/%d/followers', $this->get__id() ) );
381 + return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) );
381 382 }
382 383
383 384 /**
384 385 * Returns the Following-API-Endpoint.
@@ -385,9 +386,9 @@
385 386 *
386 387 * @return string The Following-Endpoint.
387 388 */
388 389 public function get_following() {
389 - return get_rest_url_by_path( \sprintf( 'actors/%d/following', $this->get__id() ) );
390 + return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) );
390 391 }
391 392
392 393 /**
393 394 * Returns endpoints.
@@ -394,26 +395,11 @@
394 395 *
395 396 * @return string[]|null The endpoints.
396 397 */
397 398 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' ),
399 + return array(
400 + 'sharedInbox' => get_rest_url_by_path( 'inbox' ),
405 401 );
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 402 }
417 403
418 404 /**
419 405 * Returns a user@domain type of identifier for the user.
@@ -424,25 +410,14 @@
424 410 return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
425 411 }
426 412
427 413 /**
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 414 * Returns the Featured-API-Endpoint.
440 415 *
441 416 * @return string The Featured-Endpoint.
442 417 */
443 418 public function get_featured() {
444 - return get_rest_url_by_path( \sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
419 + return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
445 420 }
446 421
447 422 /**
448 423 * Returns the Featured-Tags-API-Endpoint.
@@ -449,9 +424,9 @@
449 424 *
450 425 * @return string The Featured-Tags-Endpoint.
451 426 */
452 427 public function get_featured_tags() {
453 - return get_rest_url_by_path( \sprintf( 'actors/%d/collections/tags', $this->get__id() ) );
428 + return get_rest_url_by_path( sprintf( 'actors/%d/collections/tags', $this->get__id() ) );
454 429 }
455 430
456 431 /**
457 432 * Returns whether the site is indexable.
@@ -492,9 +467,9 @@
492 467 * @param mixed $value The new value.
493 468 * @return bool True if the attribute was updated, false otherwise.
494 469 */
495 470 public function update_icon( $value ) {
496 - if ( ! \wp_attachment_is_image( $value ) ) {
471 + if ( ! wp_attachment_is_image( $value ) ) {
497 472 return false;
498 473 }
499 474 return \update_option( 'site_icon', $value );
500 475 }
@@ -505,9 +480,9 @@
505 480 * @param mixed $value The new value.
506 481 * @return bool True if the attribute was updated, false otherwise.
507 482 */
508 483 public function update_header( $value ) {
509 - if ( ! \wp_attachment_is_image( $value ) ) {
484 + if ( ! wp_attachment_is_image( $value ) ) {
510 485 return false;
511 486 }
512 487 return \update_option( 'activitypub_header_image', $value );
513 488 }
@@ -527,9 +502,9 @@
527 502 'order' => 'DESC',
528 503 'number' => 10,
529 504 );
530 505
531 - $tags = \get_tags( $args );
506 + $tags = get_tags( $args );
532 507
533 508 foreach ( $tags as $tag ) {
534 509 $hashtags[] = array(
535 510 'type' => 'Hashtag',
@@ -571,11 +546,11 @@
571 546 $this->get_url(),
572 547 $this->get_alternate_url(),
573 548 );
574 549
575 - $also_known_as = \array_merge( $also_known_as, \get_option( 'activitypub_blog_user_also_known_as', array() ) );
550 + $also_known_as = array_merge( $also_known_as, \get_option( 'activitypub_blog_user_also_known_as', array() ) );
576 551
577 - return \array_unique( $also_known_as );
552 + return array_unique( $also_known_as );
578 553 }
579 554
580 555 /**
581 556 * Returns the movedTo.
@@ -585,52 +560,6 @@
585 560 public function get_moved_to() {
586 561 $moved_to = \get_option( 'activitypub_blog_user_moved_to' );
587 562
588 563 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 564 }
636 565 }