PluginProbe
ActivityPub / 3.2.3
ActivityPub v3.2.3
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 3.2.3, at includes/model/class-blog.php

431 lines 8.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Activitypub\Model;
3
4 use WP_Query;
5 use WP_Error;
6
7 use Activitypub\Signature;
8 use Activitypub\Activity\Actor;
9 use Activitypub\Collection\Users;
10 use Activitypub\Collection\Extra_Fields;
11
12 use function Activitypub\esc_hashtag;
13 use function Activitypub\is_single_user;
14 use function Activitypub\is_blog_public;
15 use function Activitypub\is_user_disabled;
16 use function Activitypub\get_rest_url_by_path;
17
18 class Blog extends Actor {
19 /**
20 * The Featured-Posts.
21 *
22 * @see https://docs.joinmastodon.org/spec/activitypub/#featured
23 *
24 * @context {
25 * "@id": "http://joinmastodon.org/ns#featured",
26 * "@type": "@id"
27 * }
28 *
29 * @var string
30 */
31 protected $featured;
32
33 /**
34 * Moderators endpoint.
35 *
36 * @see https://join-lemmy.org/docs/contributors/05-federation.html
37 *
38 * @var string
39 */
40 protected $moderators;
41
42 /**
43 * The User-ID
44 *
45 * @var int
46 */
47 protected $_id = Users::BLOG_USER_ID; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
48
49 /**
50 * If the User is indexable.
51 *
52 * @context http://joinmastodon.org/ns#indexable
53 *
54 * @var boolean
55 */
56 protected $indexable;
57
58 /**
59 * The WebFinger Resource.
60 *
61 * @var string<url>
62 */
63 protected $webfinger;
64
65 /**
66 * If the User is discoverable.
67 *
68 * @see https://docs.joinmastodon.org/spec/activitypub/#discoverable
69 *
70 * @context http://joinmastodon.org/ns#discoverable
71 *
72 * @var boolean
73 */
74 protected $discoverable;
75
76 /**
77 * Restrict posting to mods
78 *
79 * @see https://join-lemmy.org/docs/contributors/05-federation.html
80 *
81 * @var boolean
82 */
83 protected $posting_restricted_to_mods;
84
85 public function get_manually_approves_followers() {
86 return false;
87 }
88
89 public function get_discoverable() {
90 return true;
91 }
92
93 /**
94 * Get the User-ID.
95 *
96 * @return string The User-ID.
97 */
98 public function get_id() {
99 return $this->get_url();
100 }
101
102 /**
103 * Get the type of the object.
104 *
105 * If the Blog is in "single user" mode, return "Person" insted of "Group".
106 *
107 * @return string The type of the object.
108 */
109 public function get_type() {
110 if ( is_single_user() ) {
111 return 'Person';
112 } else {
113 return 'Group';
114 }
115 }
116
117 /**
118 * Get the User-Name.
119 *
120 * @return string The User-Name.
121 */
122 public function get_name() {
123 return \wp_strip_all_tags(
124 \html_entity_decode(
125 \get_bloginfo( 'name' ),
126 \ENT_QUOTES,
127 'UTF-8'
128 )
129 );
130 }
131
132 /**
133 * Get the User-Description.
134 *
135 * @return string The User-Description.
136 */
137 public function get_summary() {
138 $summary = \get_option( 'activitypub_blog_description', null );
139
140 if ( ! $summary ) {
141 $summary = \get_bloginfo( 'description' );
142 }
143
144 return \wpautop(
145 \wp_kses(
146 $summary,
147 'default'
148 )
149 );
150 }
151
152 /**
153 * Get the User-Url.
154 *
155 * @return string The User-Url.
156 */
157 public function get_url() {
158 return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
159 }
160
161 /**
162 * Get blog's homepage URL.
163 *
164 * @return string The User-Url.
165 */
166 public function get_alternate_url() {
167 return \esc_url( \trailingslashit( get_home_url() ) );
168 }
169
170 /**
171 * Generate a default Username.
172 *
173 * @return string The auto-generated Username.
174 */
175 public static function get_default_username() {
176 // check if domain host has a subdomain
177 $host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST );
178 $host = \preg_replace( '/^www\./i', '', $host );
179
180 /**
181 * Filter the default blog username.
182 *
183 * @param string $host The default username.
184 */
185 return apply_filters( 'activitypub_default_blog_username', $host );
186 }
187
188 /**
189 * Get the preferred User-Name.
190 *
191 * @return string The User-Name.
192 */
193 public function get_preferred_username() {
194 $username = \get_option( 'activitypub_blog_identifier' );
195
196 if ( $username ) {
197 return $username;
198 }
199
200 return self::get_default_username();
201 }
202
203 /**
204 * Get the User-Icon.
205 *
206 * @return array The User-Icon.
207 */
208 public function get_icon() {
209 // try site icon first
210 $icon_id = get_option( 'site_icon' );
211
212 // try custom logo second
213 if ( ! $icon_id ) {
214 $icon_id = get_theme_mod( 'custom_logo' );
215 }
216
217 $icon_url = false;
218
219 if ( $icon_id ) {
220 $icon = wp_get_attachment_image_src( $icon_id, 'full' );
221 if ( $icon ) {
222 $icon_url = $icon[0];
223 }
224 }
225
226 if ( ! $icon_url ) {
227 // fallback to default icon
228 $icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE );
229 }
230
231 return array(
232 'type' => 'Image',
233 'url' => esc_url( $icon_url ),
234 );
235 }
236
237 /**
238 * Get the User-Header-Image.
239 *
240 * @return array|null The User-Header-Image.
241 */
242 public function get_image() {
243 $header_image = get_option( 'activitypub_header_image' );
244 $image_url = null;
245
246 if ( $header_image ) {
247 $image_url = \wp_get_attachment_url( $header_image );
248 }
249
250 if ( ! $image_url && \has_header_image() ) {
251 $image_url = \get_header_image();
252 }
253
254 if ( $image_url ) {
255 return array(
256 'type' => 'Image',
257 'url' => esc_url( $image_url ),
258 );
259 }
260
261 return null;
262 }
263
264 public function get_published() {
265 $first_post = new WP_Query(
266 array(
267 'orderby' => 'date',
268 'order' => 'ASC',
269 'number' => 1,
270 )
271 );
272
273 if ( ! empty( $first_post->posts[0] ) ) {
274 $time = \strtotime( $first_post->posts[0]->post_date_gmt );
275 } else {
276 $time = \time();
277 }
278
279 return \gmdate( 'Y-m-d\TH:i:s\Z', $time );
280 }
281
282 public function get_canonical_url() {
283 return \home_url();
284 }
285
286 public function get_moderators() {
287 if ( is_single_user() || 'Group' !== $this->get_type() ) {
288 return null;
289 }
290
291 return get_rest_url_by_path( 'collections/moderators' );
292 }
293
294 public function get_attributed_to() {
295 if ( is_single_user() || 'Group' !== $this->get_type() ) {
296 return null;
297 }
298
299 return get_rest_url_by_path( 'collections/moderators' );
300 }
301
302 public function get_public_key() {
303 return array(
304 'id' => $this->get_id() . '#main-key',
305 'owner' => $this->get_id(),
306 'publicKeyPem' => Signature::get_public_key_for( $this->get__id() ),
307 );
308 }
309
310 public function get_posting_restricted_to_mods() {
311 if ( 'Group' === $this->get_type() ) {
312 return true;
313 }
314
315 return null;
316 }
317
318 /**
319 * Returns the Inbox-API-Endpoint.
320 *
321 * @return string The Inbox-Endpoint.
322 */
323 public function get_inbox() {
324 return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) );
325 }
326
327 /**
328 * Returns the Outbox-API-Endpoint.
329 *
330 * @return string The Outbox-Endpoint.
331 */
332 public function get_outbox() {
333 return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) );
334 }
335
336 /**
337 * Returns the Followers-API-Endpoint.
338 *
339 * @return string The Followers-Endpoint.
340 */
341 public function get_followers() {
342 return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) );
343 }
344
345 /**
346 * Returns the Following-API-Endpoint.
347 *
348 * @return string The Following-Endpoint.
349 */
350 public function get_following() {
351 return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) );
352 }
353
354 public function get_endpoints() {
355 $endpoints = null;
356
357 if ( ACTIVITYPUB_SHARED_INBOX_FEATURE ) {
358 $endpoints = array(
359 'sharedInbox' => get_rest_url_by_path( 'inbox' ),
360 );
361 }
362
363 return $endpoints;
364 }
365
366 /**
367 * Returns a user@domain type of identifier for the user.
368 *
369 * @return string The Webfinger-Identifier.
370 */
371 public function get_webfinger() {
372 return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
373 }
374
375 /**
376 * Returns the Featured-API-Endpoint.
377 *
378 * @return string The Featured-Endpoint.
379 */
380 public function get_featured() {
381 return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
382 }
383
384 public function get_indexable() {
385 if ( is_blog_public() ) {
386 return true;
387 } else {
388 return false;
389 }
390 }
391
392 /**
393 * Get the User-Hashtags.
394 *
395 * @see https://docs.joinmastodon.org/spec/activitypub/#Hashtag
396 *
397 * @return array The User-Hashtags.
398 */
399 public function get_tag() {
400 $hashtags = array();
401
402 $args = array(
403 'orderby' => 'count',
404 'order' => 'DESC',
405 'number' => 10,
406 );
407
408 $tags = get_tags( $args );
409
410 foreach ( $tags as $tag ) {
411 $hashtags[] = array(
412 'type' => 'Hashtag',
413 'href' => \get_tag_link( $tag->term_id ),
414 'name' => esc_hashtag( $tag->name ),
415 );
416 }
417
418 return $hashtags;
419 }
420
421 /**
422 * Extend the User-Output with Attachments.
423 *
424 * @return array The extended User-Output.
425 */
426 public function get_attachment() {
427 $extra_fields = Extra_Fields::get_actor_fields( $this->_id );
428 return Extra_Fields::fields_to_attachments( $extra_fields );
429 }
430 }
431