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
← All changes | includes/model/class-user.php +190 -88 2.1.05.3.1 View file →
@@ -1,16 +1,28 @@
1 1 <?php
2 +/**
3 + * User model file.
4 + *
5 + * @package Activitypub
6 + */
7 +
2 8 namespace Activitypub\Model;
3 9
4 -use WP_Query;
5 10 use WP_Error;
6 11 use Activitypub\Signature;
7 -use Activitypub\Collection\Users;
8 12 use Activitypub\Activity\Actor;
13 +use Activitypub\Collection\Extra_Fields;
9 14
15 +use function Activitypub\is_blog_public;
10 16 use function Activitypub\is_user_disabled;
11 17 use function Activitypub\get_rest_url_by_path;
18 +use function Activitypub\get_attribution_domains;
12 19
20 +/**
21 + * User class.
22 + *
23 + * @method int get__id() Gets the WordPress user ID.
24 + */
13 25 class User extends Actor {
14 26 /**
15 27 * The local User-ID (WP_User).
16 28 *
@@ -32,23 +44,10 @@
32 44 */
33 45 protected $featured;
34 46
35 47 /**
36 - * Moderators endpoint.
48 + * Whether the User is discoverable.
37 49 *
38 - * @see https://join-lemmy.org/docs/contributors/05-federation.html
39 - *
40 - * @var string
41 - */
42 - protected $moderators;
43 -
44 - public function get_type() {
45 - return 'Person';
46 - }
47 -
48 - /**
49 - * If the User is discoverable.
50 - *
51 50 * @see https://docs.joinmastodon.org/spec/activitypub/#discoverable
52 51 *
53 52 * @context http://joinmastodon.org/ns#discoverable
54 53 *
@@ -56,9 +55,9 @@
56 55 */
57 56 protected $discoverable = true;
58 57
59 58 /**
60 - * If the User is indexable.
59 + * Whether the User is indexable.
61 60 *
62 61 * @context http://joinmastodon.org/ns#indexable
63 62 *
64 63 * @var boolean
@@ -67,21 +66,28 @@
67 66
68 67 /**
69 68 * The WebFinger Resource.
70 69 *
71 - * @var string<url>
70 + * @var string
72 71 */
73 72 protected $webfinger;
74 73
75 74 /**
76 - * Restrict posting to mods
75 + * The type of the object.
77 76 *
78 - * @see https://join-lemmy.org/docs/contributors/05-federation.html
77 + * @return string The type of the object.
78 + */
79 + public function get_type() {
80 + return 'Person';
81 + }
82 +
83 + /**
84 + * Generate a User object from a WP_User.
79 85 *
80 - * @var boolean
86 + * @param int $user_id The user ID.
87 + *
88 + * @return WP_Error|User The User object or WP_Error if user not found.
81 89 */
82 - protected $posting_restricted_to_mods = null;
83 -
84 90 public static function from_wp_user( $user_id ) {
85 91 if ( is_user_disabled( $user_id ) ) {
86 92 return new WP_Error(
87 93 'activitypub_user_not_found',
@@ -89,9 +95,9 @@
89 95 array( 'status' => 404 )
90 96 );
91 97 }
92 98
93 - $object = new static();
99 + $object = new static();
94 100 $object->_id = $user_id;
95 101
96 102 return $object;
97 103 }
@@ -96,32 +102,38 @@
96 102 return $object;
97 103 }
98 104
99 105 /**
100 - * Get the User-ID.
106 + * Get the user ID.
101 107 *
102 - * @return string The User-ID.
108 + * @return string The user ID.
103 109 */
104 110 public function get_id() {
105 - return $this->get_url();
111 + $permalink = \get_user_option( 'activitypub_use_permalink_as_id', $this->_id );
112 +
113 + if ( '1' === $permalink ) {
114 + return $this->get_url();
115 + }
116 +
117 + return \add_query_arg( 'author', $this->_id, \trailingslashit( \home_url() ) );
106 118 }
107 119
108 120 /**
109 - * Get the User-Name.
121 + * Get the Username.
110 122 *
111 - * @return string The User-Name.
123 + * @return string The Username.
112 124 */
113 125 public function get_name() {
114 - return \esc_attr( \get_the_author_meta( 'display_name', $this->_id ) );
126 + return \get_the_author_meta( 'display_name', $this->_id );
115 127 }
116 128
117 129 /**
118 - * Get the User-Description.
130 + * Get the User description.
119 131 *
120 - * @return string The User-Description.
132 + * @return string The User description.
121 133 */
122 134 public function get_summary() {
123 - $description = get_user_meta( $this->_id, 'activitypub_user_description', true );
135 + $description = get_user_option( 'activitypub_description', $this->_id );
124 136 if ( empty( $description ) ) {
125 137 $description = get_user_meta( $this->_id, 'description', true );
126 138 }
127 139 return \wpautop( \wp_kses( $description, 'default' ) );
@@ -127,11 +139,11 @@
127 139 return \wpautop( \wp_kses( $description, 'default' ) );
128 140 }
129 141
130 142 /**
131 - * Get the User-Url.
143 + * Get the User url.
132 144 *
133 - * @return string The User-Url.
145 + * @return string The User url.
134 146 */
135 147 public function get_url() {
136 148 return \esc_url( \get_author_posts_url( $this->_id ) );
137 149 }
@@ -136,21 +148,39 @@
136 148 return \esc_url( \get_author_posts_url( $this->_id ) );
137 149 }
138 150
139 151 /**
140 - * Returns the User-URL with @-Prefix for the username.
152 + * Returns the User URL with @-Prefix for the username.
141 153 *
142 - * @return string The User-URL with @-Prefix for the username.
154 + * @return string The User URL with @-Prefix for the username.
143 155 */
144 156 public function get_alternate_url() {
145 157 return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() );
146 158 }
147 159
160 + /**
161 + * Get the preferred username.
162 + *
163 + * @return string The preferred username.
164 + */
148 165 public function get_preferred_username() {
149 - return \esc_attr( \get_the_author_meta( 'login', $this->_id ) );
166 + return \get_the_author_meta( 'login', $this->_id );
150 167 }
151 168
169 + /**
170 + * Get the User icon.
171 + *
172 + * @return array The User icon.
173 + */
152 174 public function get_icon() {
175 + $icon = \get_user_option( 'activitypub_icon', $this->_id );
176 + if ( wp_attachment_is_image( $icon ) ) {
177 + return array(
178 + 'type' => 'Image',
179 + 'url' => esc_url( wp_get_attachment_url( $icon ) ),
180 + );
181 + }
182 +
153 183 $icon = \esc_url(
154 184 \get_avatar_url(
155 185 $this->_id,
156 186 array( 'size' => 120 )
@@ -162,14 +192,29 @@
162 192 'url' => $icon,
163 193 );
164 194 }
165 195
196 + /**
197 + * Returns the header image.
198 + *
199 + * @return array|null The header image.
200 + */
166 201 public function get_image() {
167 - if ( \has_header_image() ) {
168 - $image = \esc_url( \get_header_image() );
202 + $header_image = get_user_option( 'activitypub_header_image', $this->_id );
203 + $image_url = null;
204 +
205 + if ( ! $header_image && \has_header_image() ) {
206 + $image_url = \get_header_image();
207 + }
208 +
209 + if ( $header_image ) {
210 + $image_url = \wp_get_attachment_url( $header_image );
211 + }
212 +
213 + if ( $image_url ) {
169 214 return array(
170 215 'type' => 'Image',
171 - 'url' => $image,
216 + 'url' => esc_url( $image_url ),
172 217 );
173 218 }
174 219
175 220 return null;
@@ -174,16 +219,26 @@
174 219
175 220 return null;
176 221 }
177 222
223 + /**
224 + * Returns the date the user was created.
225 + *
226 + * @return false|string The date the user was created.
227 + */
178 228 public function get_published() {
179 229 return \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( \get_the_author_meta( 'registered', $this->_id ) ) );
180 230 }
181 231
232 + /**
233 + * Returns the public key.
234 + *
235 + * @return array The public key.
236 + */
182 237 public function get_public_key() {
183 238 return array(
184 - 'id' => $this->get_id() . '#main-key',
185 - 'owner' => $this->get_id(),
239 + 'id' => $this->get_id() . '#main-key',
240 + 'owner' => $this->get_id(),
186 241 'publicKeyPem' => Signature::get_public_key_for( $this->get__id() ),
187 242 );
188 243 }
189 244
@@ -192,9 +247,9 @@
192 247 *
193 248 * @return string The Inbox-Endpoint.
194 249 */
195 250 public function get_inbox() {
196 - return get_rest_url_by_path( sprintf( 'users/%d/inbox', $this->get__id() ) );
251 + return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) );
197 252 }
198 253
199 254 /**
200 255 * Returns the Outbox-API-Endpoint.
@@ -201,9 +256,9 @@
201 256 *
202 257 * @return string The Outbox-Endpoint.
203 258 */
204 259 public function get_outbox() {
205 - return get_rest_url_by_path( sprintf( 'users/%d/outbox', $this->get__id() ) );
260 + return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) );
206 261 }
207 262
208 263 /**
209 264 * Returns the Followers-API-Endpoint.
@@ -210,9 +265,9 @@
210 265 *
211 266 * @return string The Followers-Endpoint.
212 267 */
213 268 public function get_followers() {
214 - return get_rest_url_by_path( sprintf( 'users/%d/followers', $this->get__id() ) );
269 + return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) );
215 270 }
216 271
217 272 /**
218 273 * Returns the Following-API-Endpoint.
@@ -219,9 +274,9 @@
219 274 *
220 275 * @return string The Following-Endpoint.
221 276 */
222 277 public function get_following() {
223 - return get_rest_url_by_path( sprintf( 'users/%d/following', $this->get__id() ) );
278 + return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) );
224 279 }
225 280
226 281 /**
227 282 * Returns the Featured-API-Endpoint.
@@ -228,11 +283,16 @@
228 283 *
229 284 * @return string The Featured-Endpoint.
230 285 */
231 286 public function get_featured() {
232 - return get_rest_url_by_path( sprintf( 'users/%d/collections/featured', $this->get__id() ) );
287 + return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) );
233 288 }
234 289
290 + /**
291 + * Returns the endpoints.
292 + *
293 + * @return array|null The endpoints.
294 + */
235 295 public function get_endpoints() {
236 296 $endpoints = null;
237 297
238 298 if ( ACTIVITYPUB_SHARED_INBOX_FEATURE ) {
@@ -249,43 +309,10 @@
249 309 *
250 310 * @return array The extended User-Output.
251 311 */
252 312 public function get_attachment() {
253 - $array = array();
254 -
255 - $array[] = array(
256 - 'type' => 'PropertyValue',
257 - 'name' => \__( 'Blog', 'activitypub' ),
258 - 'value' => \html_entity_decode(
259 - '<a rel="me" title="' . \esc_attr( \home_url( '/' ) ) . '" target="_blank" href="' . \home_url( '/' ) . '">' . \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) . '</a>',
260 - \ENT_QUOTES,
261 - 'UTF-8'
262 - ),
263 - );
264 -
265 - $array[] = array(
266 - 'type' => 'PropertyValue',
267 - 'name' => \__( 'Profile', 'activitypub' ),
268 - 'value' => \html_entity_decode(
269 - '<a rel="me" title="' . \esc_attr( \get_author_posts_url( $this->get__id() ) ) . '" target="_blank" href="' . \get_author_posts_url( $this->get__id() ) . '">' . \wp_parse_url( \get_author_posts_url( $this->get__id() ), \PHP_URL_HOST ) . '</a>',
270 - \ENT_QUOTES,
271 - 'UTF-8'
272 - ),
273 - );
274 -
275 - if ( \get_the_author_meta( 'user_url', $this->get__id() ) ) {
276 - $array[] = array(
277 - 'type' => 'PropertyValue',
278 - 'name' => \__( 'Website', 'activitypub' ),
279 - 'value' => \html_entity_decode(
280 - '<a rel="me" title="' . \esc_attr( \get_the_author_meta( 'user_url', $this->get__id() ) ) . '" target="_blank" href="' . \get_the_author_meta( 'user_url', $this->get__id() ) . '">' . \wp_parse_url( \get_the_author_meta( 'user_url', $this->get__id() ), \PHP_URL_HOST ) . '</a>',
281 - \ENT_QUOTES,
282 - 'UTF-8'
283 - ),
284 - );
285 - }
286 -
287 - return $array;
313 + $extra_fields = Extra_Fields::get_actor_fields( $this->_id );
314 + return Extra_Fields::fields_to_attachments( $extra_fields );
288 315 }
289 316
290 317 /**
291 318 * Returns a user@domain type of identifier for the user.
@@ -295,28 +322,103 @@
295 322 public function get_webfinger() {
296 323 return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
297 324 }
298 325
299 - public function get_resource() {
300 - return $this->get_webfinger();
301 - }
302 -
326 + /**
327 + * Returns the canonical URL.
328 + *
329 + * @return string The canonical URL.
330 + */
303 331 public function get_canonical_url() {
304 332 return $this->get_url();
305 333 }
306 334
335 + /**
336 + * Returns the streams.
337 + *
338 + * @return null The streams.
339 + */
307 340 public function get_streams() {
308 341 return null;
309 342 }
310 343
344 + /**
345 + * Returns the tag.
346 + *
347 + * @return array The tag.
348 + */
311 349 public function get_tag() {
312 350 return array();
313 351 }
314 352
353 + /**
354 + * Returns the indexable state.
355 + *
356 + * @return bool Whether the user is indexable.
357 + */
315 358 public function get_indexable() {
316 - if ( \get_option( 'blog_public', 1 ) ) {
359 + if ( is_blog_public() ) {
317 360 return true;
318 361 } else {
319 362 return false;
320 363 }
364 + }
365 +
366 + /**
367 + * Update the username.
368 + *
369 + * @param string $value The new value.
370 + * @return int|WP_Error The updated user ID or WP_Error on failure.
371 + */
372 + public function update_name( $value ) {
373 + $userdata = array(
374 + 'ID' => $this->_id,
375 + 'display_name' => $value,
376 + );
377 + return \wp_update_user( $userdata );
378 + }
379 +
380 + /**
381 + * Update the User description.
382 + *
383 + * @param string $value The new value.
384 + * @return bool True if the attribute was updated, false otherwise.
385 + */
386 + public function update_summary( $value ) {
387 + return \update_user_option( $this->_id, 'activitypub_description', $value );
388 + }
389 +
390 + /**
391 + * Update the User icon.
392 + *
393 + * @param int $value The new value. Should be an attachment ID.
394 + * @return bool True if the attribute was updated, false otherwise.
395 + */
396 + public function update_icon( $value ) {
397 + if ( ! wp_attachment_is_image( $value ) ) {
398 + return false;
399 + }
400 + return update_user_option( $this->_id, 'activitypub_icon', $value );
401 + }
402 +
403 + /**
404 + * Update the User-Header-Image.
405 + *
406 + * @param int $value The new value. Should be an attachment ID.
407 + * @return bool True if the attribute was updated, false otherwise.
408 + */
409 + public function update_header( $value ) {
410 + if ( ! wp_attachment_is_image( $value ) ) {
411 + return false;
412 + }
413 + return \update_user_option( $this->_id, 'activitypub_header_image', $value );
414 + }
415 +
416 + /**
417 + * Returns the website hosts allowed to credit this blog.
418 + *
419 + * @return array|null The attribution domains or null if not found.
420 + */
421 + public function get_attribution_domains() {
422 + return get_attribution_domains();
321 423 }
322 424 }