PluginProbe
ActivityPub / 5.3.1
ActivityPub v5.3.1
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 / model / class-blog.php

class-blog.php in ActivityPub 5.3.1, at includes/model/class-blog.php

556 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Blog model file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Model;
9
10 use WP_Query;
11
12 use Activitypub\Signature;
13 use Activitypub\Activity\Actor;
14 use Activitypub\Collection\Actors;
15 use Activitypub\Collection\Extra_Fields;
16
17 use function Activitypub\esc_hashtag;
18 use function Activitypub\is_single_user;
19 use function Activitypub\is_blog_public;
20 use function Activitypub\get_rest_url_by_path;
21 use function Activitypub\get_attribution_domains;
22
23 /**
24 * Blog class.
25 *
26 * @method int get__id() Gets the internal user ID for the blog (always returns BLOG_USER_ID).
27 */
28 class Blog extends Actor {
29 /**
30 * The Featured-Posts.
31 *
32 * @see https://docs.joinmastodon.org/spec/activitypub/#featured
33 *
34 * @context {
35 * "@id": "http://joinmastodon.org/ns#featured",
36 * "@type": "@id"
37 * }
38 *
39 * @var string
40 */
41 protected $featured;
42
43 /**
44 * Moderators endpoint.
45 *
46 * @see https://join-lemmy.org/docs/contributors/05-federation.html
47 *
48 * @var string
49 */
50 protected $moderators;
51
52 /**
53 * The User-ID
54 *
55 * @var int
56 */
57 protected $_id = Actors::BLOG_USER_ID; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
58
59 /**
60 * If the User is indexable.
61 *
62 * @context http://joinmastodon.org/ns#indexable
63 *
64 * @var boolean
65 */
66 protected $indexable;
67
68 /**
69 * The WebFinger Resource.
70 *
71 * @var string
72 */
73 protected $webfinger;
74
75 /**
76 * Whether the User is discoverable.
77 *
78 * @see https://docs.joinmastodon.org/spec/activitypub/#discoverable
79 *
80 * @context http://joinmastodon.org/ns#discoverable
81 *
82 * @var boolean
83 */
84 protected $discoverable;
85
86 /**
87 * Restrict posting to mods.
88 *
89 * @see https://join-lemmy.org/docs/contributors/05-federation.html
90 *
91 * @var boolean
92 */
93 protected $posting_restricted_to_mods;
94
95 /**
96 * Whether the User manually approves followers.
97 *
98 * @return false
99 */
100 public function get_manually_approves_followers() {
101 return false;
102 }
103
104 /**
105 * Whether the User is discoverable.
106 *
107 * @return boolean
108 */
109 public function get_discoverable() {
110 return true;
111 }
112
113 /**
114 * Get the User ID.
115 *
116 * @return string The User ID.
117 */
118 public function get_id() {
119 $permalink = \get_option( 'activitypub_use_permalink_as_id_for_blog', false );
120
121 if ( $permalink ) {
122 return $this->get_url();
123 }
124
125 return \add_query_arg( 'author', $this->_id, \trailingslashit( \home_url() ) );
126 }
127
128 /**
129 * Get the type of the object.
130 *
131 * If the Blog is in "single user" mode, return "Person" insted of "Group".
132 *
133 * @return string The type of the object.
134 */
135 public function get_type() {
136 if ( is_single_user() ) {
137 return 'Person';
138 } else {
139 return 'Group';
140 }
141 }
142
143 /**
144 * Get the Username.
145 *
146 * @return string The Username.
147 */
148 public function get_name() {
149 return \wp_strip_all_tags(
150 \html_entity_decode(
151 \get_bloginfo( 'name' ),
152 \ENT_QUOTES,
153 'UTF-8'
154 )
155 );
156 }
157
158 /**
159 * Get the User description.
160 *
161 * @return string The User description.
162 */
163 public function get_summary() {
164 $summary = \get_option( 'activitypub_blog_description', null );
165
166 if ( ! $summary ) {
167 $summary = \get_bloginfo( 'description' );
168 }
169
170 return \wpautop(
171 \wp_kses(
172 $summary,
173 'default'
174 )
175 );
176 }
177
178 /**
179 * Get the User url.
180 *
181 * @return string The User url.
182 */
183 public function get_url() {
184 return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
185 }
186
187 /**
188 * Get blog's homepage URL.
189 *
190 * @return string The User-Url.
191 */
192 public function get_alternate_url() {
193 return \esc_url( \trailingslashit( get_home_url() ) );
194 }
195
196 /**
197 * Generate a default Username.
198 *
199 * @return string The auto-generated Username.
200 */
201 public static function get_default_username() {
202 // Check if domain host has a subdomain.
203 $host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST );
204 $host = \preg_replace( '/^www\./i', '', $host );
205
206 /**
207 * Filters the default blog username.
208 *
209 * This filter allows developers to modify the default username that is
210 * generated for the blog, which by default is the site's host name
211 * without the 'www.' prefix.
212 *
213 * @param string $host The default username (site's host name).
214 */
215 return apply_filters( 'activitypub_default_blog_username', $host );
216 }
217
218 /**
219 * Get the preferred Username.
220 *
221 * @return string The Username.
222 */
223 public function get_preferred_username() {
224 $username = \get_option( 'activitypub_blog_identifier' );
225
226 if ( $username ) {
227 return $username;
228 }
229
230 return self::get_default_username();
231 }
232
233 /**
234 * Get the User icon.
235 *
236 * @return array The User icon.
237 */
238 public function get_icon() {
239 // Try site_logo, falling back to site_icon, first.
240 $icon_id = get_option( 'site_icon' );
241
242 // Try custom logo second.
243 if ( ! $icon_id ) {
244 $icon_id = get_theme_mod( 'custom_logo' );
245 }
246
247 $icon_url = false;
248
249 if ( $icon_id ) {
250 $icon = wp_get_attachment_image_src( $icon_id, 'full' );
251 if ( $icon ) {
252 $icon_url = $icon[0];
253 }
254 }
255
256 if ( ! $icon_url ) {
257 // Fallback to default icon.
258 $icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE );
259 }
260
261 return array(
262 'type' => 'Image',
263 'url' => esc_url( $icon_url ),
264 );
265 }
266
267 /**
268 * Get the User-Header-Image.
269 *
270 * @return array|null The User-Header-Image.
271 */
272 public function get_image() {
273 $header_image = get_option( 'activitypub_header_image' );
274 $image_url = null;
275
276 if ( $header_image ) {
277 $image_url = \wp_get_attachment_url( $header_image );
278 }
279
280 if ( ! $image_url && \has_header_image() ) {
281 $image_url = \get_header_image();
282 }
283
284 if ( $image_url ) {
285 return array(
286 'type' => 'Image',
287 'url' => esc_url( $image_url ),
288 );
289 }
290
291 return null;
292 }
293
294 /**
295 * Get the published date.
296 *
297 * @return string The published date.
298 */
299 public function get_published() {
300 $first_post = new WP_Query(
301 array(
302 'orderby' => 'date',
303 'order' => 'ASC',
304 'number' => 1,
305 )
306 );
307
308 if ( ! empty( $first_post->posts[0] ) ) {
309 $time = \strtotime( $first_post->posts[0]->post_date_gmt );
310 } else {
311 $time = \time();
312 }
313
314 return \gmdate( 'Y-m-d\TH:i:s\Z', $time );
315 }
316
317 /**
318 * Get the canonical URL.
319 *
320 * @return string|null The canonical URL.
321 */
322 public function get_canonical_url() {
323 return \home_url();
324 }
325
326 /**
327 * Get the Moderators endpoint.
328 *
329 * @return string|null The Moderators endpoint.
330 */
331 public function get_moderators() {
332 if ( is_single_user() || 'Group' !== $this->get_type() ) {
333 return null;
334 }
335
336 return get_rest_url_by_path( 'collections/moderators' );
337 }
338
339 /**
340 * Get attributedTo value.
341 *
342 * @return string|null The attributedTo value.
343 */
344 public function get_attributed_to() {
345 if ( is_single_user() || 'Group' !== $this->get_type() ) {
346 return null;
347 }
348
349 return get_rest_url_by_path( 'collections/moderators' );
350 }
351
352 /**
353 * Get the public key information.
354 *
355 * @return array The public key.
356 */
357 public function get_public_key() {
358 return array(
359 'id' => $this->get_id() . '#main-key',
360 'owner' => $this->get_id(),
361 'publicKeyPem' => Signature::get_public_key_for( $this->get__id() ),
362 );
363 }
364
365 /**
366 * Returns whether posting is restricted to mods.
367 *
368 * @return bool|null True if posting is restricted to mods, null if not applicable.
369 */
370 public function get_posting_restricted_to_mods() {
371 if ( 'Group' === $this->get_type() ) {
372 return true;
373 }
374
375 return null;
376 }
377
378 /**
379 * Returns the Inbox-API-Endpoint.
380 *
381 * @return string The Inbox-Endpoint.
382 */
383 public function get_inbox() {
384 return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) );
385 }
386
387 /**
388 * Returns the Outbox-API-Endpoint.
389 *
390 * @return string The Outbox-Endpoint.
391 */
392 public function get_outbox() {
393 return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) );
394 }
395
396 /**
397 * Returns the Followers-API-Endpoint.
398 *
399 * @return string The Followers-Endpoint.
400 */
401 public function get_followers() {
402 return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) );
403 }
404
405 /**
406 * Returns the Following-API-Endpoint.
407 *
408 * @return string The Following-Endpoint.
409 */
410 public function get_following() {
411 return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) );
412 }
413
414 /**
415 * Returns endpoints.
416 *
417 * @return array|null The endpoints.
418 */
419 public function get_endpoints() {
420 $endpoints = null;
421
422 if ( ACTIVITYPUB_SHARED_INBOX_FEATURE ) {
423 $endpoints = array(
424 'sharedInbox' => get_rest_url_by_path( 'inbox' ),
425 );
426 }
427
428 return $endpoints;
429 }
430
431 /**
432 * Returns a user@domain type of identifier for the user.
433 *
434 * @return string The Webfinger-Identifier.
435 */
436 public function get_webfinger() {
437 return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
438 }
439
440 /**
441 * Returns the Featured-API-Endpoint.
442 *
443 * @return string The Featured-Endpoint.
444 */
445 public function get_featured() {
446 return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
447 }
448
449 /**
450 * Returns whether the site is indexable.
451 *
452 * @return bool Whether the site is indexable.
453 */
454 public function get_indexable() {
455 if ( is_blog_public() ) {
456 return true;
457 } else {
458 return false;
459 }
460 }
461
462 /**
463 * Update the Username.
464 *
465 * @param mixed $value The new value.
466 * @return bool True if the attribute was updated, false otherwise.
467 */
468 public function update_name( $value ) {
469 return \update_option( 'blogname', $value );
470 }
471
472 /**
473 * Update the User description.
474 *
475 * @param mixed $value The new value.
476 * @return bool True if the attribute was updated, false otherwise.
477 */
478 public function update_summary( $value ) {
479 return \update_option( 'blogdescription', $value );
480 }
481
482 /**
483 * Update the User icon.
484 *
485 * @param mixed $value The new value.
486 * @return bool True if the attribute was updated, false otherwise.
487 */
488 public function update_icon( $value ) {
489 if ( ! wp_attachment_is_image( $value ) ) {
490 return false;
491 }
492 return \update_option( 'site_icon', $value );
493 }
494
495 /**
496 * Update the User-Header-Image.
497 *
498 * @param mixed $value The new value.
499 * @return bool True if the attribute was updated, false otherwise.
500 */
501 public function update_header( $value ) {
502 if ( ! wp_attachment_is_image( $value ) ) {
503 return false;
504 }
505 return \update_option( 'activitypub_header_image', $value );
506 }
507
508 /**
509 * Get the User - Hashtags.
510 *
511 * @see https://docs.joinmastodon.org/spec/activitypub/#Hashtag
512 *
513 * @return array The User - Hashtags.
514 */
515 public function get_tag() {
516 $hashtags = array();
517
518 $args = array(
519 'orderby' => 'count',
520 'order' => 'DESC',
521 'number' => 10,
522 );
523
524 $tags = get_tags( $args );
525
526 foreach ( $tags as $tag ) {
527 $hashtags[] = array(
528 'type' => 'Hashtag',
529 'href' => \get_tag_link( $tag->term_id ),
530 'name' => esc_hashtag( $tag->name ),
531 );
532 }
533
534 return $hashtags;
535 }
536
537 /**
538 * Extend the User-Output with Attachments.
539 *
540 * @return array The extended User-Output.
541 */
542 public function get_attachment() {
543 $extra_fields = Extra_Fields::get_actor_fields( $this->_id );
544 return Extra_Fields::fields_to_attachments( $extra_fields );
545 }
546
547 /**
548 * Returns the website hosts allowed to credit this blog.
549 *
550 * @return array|null The attribution domains or null if not found.
551 */
552 public function get_attribution_domains() {
553 return get_attribution_domains();
554 }
555 }
556