PluginProbe
ActivityPub / 3.2.4
ActivityPub v3.2.4
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/activity/class-base-object.php +311 -271 8.2.13.2.4 View file →
@@ -2,16 +2,19 @@
2 2 /**
3 3 * Inspired by the PHP ActivityPub Library by @Landrok
4 4 *
5 5 * @link https://github.com/landrok/activitypub
6 - *
7 - * @package Activitypub
8 6 */
9 7
10 8 namespace Activitypub\Activity;
11 9
12 -use Activitypub\Activity\Extended_Object\Place;
10 +use WP_Error;
11 +use ReflectionClass;
12 +use DateTime;
13 13
14 +use function Activitypub\camel_to_snake_case;
15 +use function Activitypub\snake_to_camel_case;
16 +
14 17 /**
15 18 * Base_Object is an implementation of one of the
16 19 * Activity Streams Core Types.
17 20 *
@@ -21,176 +24,27 @@
21 24 * Note: Object is a reserved keyword in PHP. It has been suffixed with
22 25 * 'Base_' for this reason.
23 26 *
24 27 * @see https://www.w3.org/TR/activitystreams-core/#object
25 - *
26 - * @method array|string|null get_attachment() Gets the attachment property of the object.
27 - * @method array|string|null get_attributed_to() Gets the entity attributed as the original author.
28 - * @method string|null get_audience() Gets the total population of entities for which the object can be considered relevant.
29 - * @method string[]|string|null get_bcc() Gets the private secondary audience of the object.
30 - * @method string[]|string|null get_bto() Gets the private primary audience of the object.
31 - * @method string[]|string|null get_cc() Gets the secondary recipients of the object.
32 - * @method string|null get_content() Gets the content property of the object.
33 - * @method string[]|null get_content_map() Gets the content map property of the object.
34 - * @method string|null get_context() Gets the context within which the object exists.
35 - * @method array|null get_dcterms() Gets the Dublin Core terms property of the object.
36 - * @method string|null get_duration() Gets the duration property of time-bound resources.
37 - * @method string|null get_end_time() Gets the date and time describing the ending time of the object.
38 - * @method string|null get_generator() Gets the entity that generated the object.
39 - * @method string[]|null get_icon() Gets the icon property of the object.
40 - * @method string|null get_id() Gets the object's unique global identifier.
41 - * @method string[]|null get_image() Gets the image property of the object.
42 - * @method string[]|string|null get_in_reply_to() Gets the objects this object is in reply to.
43 - * @method array|null get_interaction_policy() Gets the interaction policy property of the object.
44 - * @method array|null get_likes() Gets the collection of likes for this object.
45 - * @method array|string|null|Place get_location() Gets the physical or logical locations associated with the object.
46 - * @method string|null get_media_type() Gets the MIME media type of the content property.
47 - * @method string|null get_name() Gets the natural language name of the object.
48 - * @method string[]|null get_name_map() Gets the name map property of the object.
49 - * @method string|null get_preview() Gets the entity that provides a preview of this object.
50 - * @method string|null get_published() Gets the date and time the object was published in ISO 8601 format.
51 - * @method string|null get_quote() Gets the quote property of the object (FEP-044f).
52 - * @method string|null get_quote_url() Gets the quoteUrl property of the object.
53 - * @method string|null get_quote_uri() Gets the quoteUri property of the object.
54 - * @method string|null get__misskey_quote() Gets the _misskey_quote property of the object.
55 - * @method string|array|null get_replies() Gets the collection of responses to this object.
56 - * @method bool|null get_sensitive() Gets the sensitive property of the object.
57 - * @method array|null get_shares() Gets the collection of shares for this object.
58 - * @method array|null get_source() Gets the source property indicating content markup derivation.
59 - * @method string|null get_start_time() Gets the date and time describing the starting time of the object.
60 - * @method string|null get_summary() Gets the natural language summary of the object.
61 - * @method string[]|null get_summary_map() Gets the summary map property of the object.
62 - * @method array[]|null get_tag() Gets the tag property of the object.
63 - * @method string[]|string|null get_to() Gets the primary recipients of the object.
64 - * @method string get_type() Gets the type of the object.
65 - * @method string|null get_updated() Gets the date and time the object was updated in ISO 8601 format.
66 - * @method string|null get_url() Gets the URL of the object.
67 - * @method string|null get_former_type() Gets the former type of a Tombstone object.
68 - * @method string|null get_deleted() Gets the date and time the object was deleted in ISO 8601 format.
69 - *
70 - * @method string|string[] add_cc( string|array $cc ) Adds one or more entities to the secondary audience of the object.
71 - * @method string|string[] add_to( string|array $to ) Adds one or more entities to the primary audience of the object.
72 - *
73 - * @method Base_Object set_attachment( array $attachment ) Sets the attachment property of the object.
74 - * @method Base_Object set_attributed_to( string $attributed_to ) Sets the entity attributed as the original author.
75 - * @method Base_Object set_audience( string $audience ) Sets the total population of entities for which the object can be considered relevant.
76 - * @method Base_Object set_bcc( array|string $bcc ) Sets the private secondary audience of the object.
77 - * @method Base_Object set_bto( array|string $bto ) Sets the private primary audience of the object.
78 - * @method Base_Object set_cc( array|string $cc ) Sets the secondary recipients of the object.
79 - * @method Base_Object set_content( string $content ) Sets the content property of the object.
80 - * @method Base_Object set_content_map( array $content_map ) Sets the content property of the object.
81 - * @method Base_Object set_context( string $context ) Sets the context within which the object exists.
82 - * @method Base_Object set_dcterms( array $dcterms ) Sets the Dublin Core terms property of the object.
83 - * @method Base_Object set_duration( string $duration ) Sets the duration property of time-bound resources.
84 - * @method Base_Object set_end_time( string $end_time ) Sets the date and time describing the ending time of the object.
85 - * @method Base_Object set_generator( string $generator ) Sets the entity that generated the object.
86 - * @method Base_Object set_icon( array $icon ) Sets the icon property of the object.
87 - * @method Base_Object set_id( string $id ) Sets the object's unique global identifier.
88 - * @method Base_Object set_image( array $image ) Sets the image property of the object.
89 - * @method Base_Object set_in_reply_to( string|string[] $in_reply_to ) Sets the is in reply to property of the object.
90 - * @method Base_Object set_interaction_policy( array|null $policy ) Sets the interaction policy property of the object.
91 - * @method Base_Object set_likes( array $likes ) Sets the collection of likes for this object.
92 - * @method Base_Object set_location( array|string|Place $location ) Sets the physical or logical locations associated with the object.
93 - * @method Base_Object set_media_type( string $media_type ) Sets the MIME media type of the content property.
94 - * @method Base_Object set_name( string $name ) Sets the natural language name of the object.
95 - * @method Base_Object set_name_map( array|null $name_map ) Sets the name map property of the object.
96 - * @method Base_Object set_preview( string $preview ) Sets the entity that provides a preview of this object.
97 - * @method Base_Object set_published( string|null $published ) Sets the date and time the object was published in ISO 8601 format.
98 - * @method Base_Object set_quote( string $quote ) Sets the quote property of the object (FEP-044f).
99 - * @method Base_Object set_quote_url( string $quote_url ) Sets the quoteUrl property of the object.
100 - * @method Base_Object set_quote_uri( string $quote_uri ) Sets the quoteUri property of the object.
101 - * @method Base_Object set__misskey_quote( mixed $misskey_quote ) Sets the _misskey_quote property of the object.
102 - * @method Base_Object set_replies( string|array $replies ) Sets the collection of responses to this object.
103 - * @method Base_Object set_sensitive( bool|null $sensitive ) Sets the sensitive property of the object.
104 - * @method Base_Object set_shares( array $shares ) Sets the collection of shares for this object.
105 - * @method Base_Object set_source( array $source ) Sets the source property indicating content markup derivation.
106 - * @method Base_Object set_start_time( string $start_time ) Sets the date and time describing the starting time of the object.
107 - * @method Base_Object set_summary( string $summary ) Sets the natural language summary of the object.
108 - * @method Base_Object set_summary_map( array|null $summary_map ) Sets the summary property of the object.
109 - * @method Base_Object set_tag( array|null $tag ) Sets the tag property of the object.
110 - * @method Base_Object set_to( string|string[] $to ) Sets the primary recipients of the object.
111 - * @method Base_Object set_type( string $type ) Sets the type of the object.
112 - * @method Base_Object set_updated( string $updated ) Sets the date and time the object was updated in ISO 8601 format.
113 - * @method Base_Object set_url( string $url ) Sets the URL of the object.
114 - * @method Base_Object set_former_type( string $former_type ) Sets the former type of a Tombstone object.
115 - * @method Base_Object set_deleted( string $deleted ) Sets the date and time the object was deleted in ISO 8601 format.
116 28 */
117 -class Base_Object extends Generic_Object {
118 - /**
119 - * The JSON-LD context for the object.
120 - *
121 - * @var array
122 - */
29 +class Base_Object {
123 30 const JSON_LD_CONTEXT = array(
124 31 'https://www.w3.org/ns/activitystreams',
125 32 array(
126 - 'Hashtag' => 'as:Hashtag',
127 - 'sensitive' => 'as:sensitive',
128 - 'dcterms' => 'http://purl.org/dc/terms/',
129 - 'gts' => 'https://gotosocial.org/ns#',
130 - 'schema' => 'http://schema.org/',
131 - 'exifData' => 'schema:exifData',
132 - 'PropertyValue' => 'schema:PropertyValue',
133 - 'interactionPolicy' => array(
134 - '@id' => 'gts:interactionPolicy',
135 - '@type' => '@id',
136 - ),
137 - 'canQuote' => array(
138 - '@id' => 'gts:canQuote',
139 - '@type' => '@id',
140 - ),
141 - 'canReply' => array(
142 - '@id' => 'gts:canReply',
143 - '@type' => '@id',
144 - ),
145 - 'canLike' => array(
146 - '@id' => 'gts:canLike',
147 - '@type' => '@id',
148 - ),
149 - 'canAnnounce' => array(
150 - '@id' => 'gts:canAnnounce',
151 - '@type' => '@id',
152 - ),
153 - 'automaticApproval' => array(
154 - '@id' => 'gts:automaticApproval',
155 - '@type' => '@id',
156 - ),
157 - 'manualApproval' => array(
158 - '@id' => 'gts:manualApproval',
159 - '@type' => '@id',
160 - ),
161 - 'always' => array(
162 - '@id' => 'gts:always',
163 - '@type' => '@id',
164 - ),
33 + 'Hashtag' => 'as:Hashtag',
165 34 ),
166 35 );
167 36
168 37 /**
169 - * The default types for Objects.
38 + * The object's unique global identifier
170 39 *
171 - * @see https://www.w3.org/TR/activitystreams-vocabulary/#object-types
40 + * @see https://www.w3.org/TR/activitypub/#obj-id
172 41 *
173 - * @var array
42 + * @var string
174 43 */
175 - const TYPES = array(
176 - 'Article',
177 - 'Audio',
178 - 'Document',
179 - 'Event',
180 - 'Image',
181 - 'Note',
182 - 'Page',
183 - 'Place',
184 - 'Profile',
185 - 'Relationship',
186 - 'Tombstone',
187 - 'Video',
188 - );
44 + protected $id;
189 45
190 46 /**
191 - * The type of the object.
192 - *
193 47 * @var string
194 48 */
195 49 protected $type = 'Object';
196 50
@@ -201,9 +55,14 @@
201 55 * similar to attachments in email.
202 56 *
203 57 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attachment
204 58 *
205 - * @var string|null
59 + * @var string
60 + * | ObjectType
61 + * | Link
62 + * | array<ObjectType>
63 + * | array<Link>
64 + * | null
206 65 */
207 66 protected $attachment;
208 67
209 68 /**
@@ -212,19 +71,29 @@
212 71 * object might be attributed to the completion of another activity.
213 72 *
214 73 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attributedto
215 74 *
216 - * @var string|null
75 + * @var string
76 + * | ObjectType
77 + * | Link
78 + * | array<ObjectType>
79 + * | array<Link>
80 + * | null
217 81 */
218 82 protected $attributed_to;
219 83
220 84 /**
221 85 * One or more entities that represent the total population of
222 - * entities for which the object can be considered to be relevant.
86 + * entities for which the object can considered to be relevant.
223 87 *
224 88 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audience
225 89 *
226 - * @var string|null
90 + * @var string
91 + * | ObjectType
92 + * | Link
93 + * | array<ObjectType>
94 + * | array<Link>
95 + * | null
227 96 */
228 97 protected $audience;
229 98
230 99 /**
@@ -252,9 +121,12 @@
252 121 * project or event.
253 122 *
254 123 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context
255 124 *
256 - * @var string|null
125 + * @var string
126 + * | ObjectType
127 + * | Link
128 + * | null
257 129 */
258 130 protected $context;
259 131
260 132 /**
@@ -267,27 +139,8 @@
267 139 */
268 140 protected $content_map;
269 141
270 142 /**
271 - * The date and time at which the object was deleted.
272 - *
273 - * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-deleted
274 - *
275 - * @var string|null
276 - */
277 - protected $deleted;
278 -
279 - /**
280 - * The former type of the object. Used in Tombstone objects to
281 - * indicate the type of the object prior to deletion.
282 - *
283 - * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-formertype
284 - *
285 - * @var string|null
286 - */
287 - protected $former_type;
288 -
289 - /**
290 143 * A simple, human-readable, plain-text name for the object.
291 144 * HTML markup MUST NOT be included.
292 145 *
293 146 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-name
@@ -332,9 +185,14 @@
332 185 * at a small size.
333 186 *
334 187 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-icon
335 188 *
336 - * @var string|array|null
189 + * @var string
190 + * | Image
191 + * | Link
192 + * | array<Image>
193 + * | array<Link>
194 + * | null
337 195 */
338 196 protected $icon;
339 197
340 198 /**
@@ -343,9 +201,14 @@
343 201 * or display size limitations assumed.
344 202 *
345 203 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-image-term
346 204 *
347 - * @var string|array|null
205 + * @var string
206 + * | Image
207 + * | Link
208 + * | array<Image>
209 + * | array<Link>
210 + * | null
348 211 */
349 212 protected $image;
350 213
351 214 /**
@@ -353,9 +216,14 @@
353 216 * response.
354 217 *
355 218 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-inreplyto
356 219 *
357 - * @var string|null
220 + * @var string
221 + * | ObjectType
222 + * | Link
223 + * | array<ObjectType>
224 + * | array<Link>
225 + * | null
358 226 */
359 227 protected $in_reply_to;
360 228
361 229 /**
@@ -363,9 +231,14 @@
363 231 * object.
364 232 *
365 233 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-location
366 234 *
367 - * @var string|null|Place
235 + * @var string
236 + * | ObjectType
237 + * | Link
238 + * | array<ObjectType>
239 + * | array<Link>
240 + * | null
368 241 */
369 242 protected $location;
370 243
371 244 /**
@@ -372,9 +245,12 @@
372 245 * An entity that provides a preview of this object.
373 246 *
374 247 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-preview
375 248 *
376 - * @var string|null
249 + * @var string
250 + * | ObjectType
251 + * | Link
252 + * | null
377 253 */
378 254 protected $preview;
379 255
380 256 /**
@@ -404,9 +280,12 @@
404 280 * Multiple language tagged summaries MAY be provided.
405 281 *
406 282 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
407 283 *
408 - * @var string|null
284 + * @var string
285 + * | ObjectType
286 + * | Link
287 + * | null
409 288 */
410 289 protected $summary;
411 290
412 291 /**
@@ -414,9 +293,9 @@
414 293 * values.
415 294 *
416 295 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
417 296 *
418 - * @var string[]|null
297 + * @var array<string>|null
419 298 */
420 299 protected $summary_map;
421 300
422 301 /**
@@ -427,9 +306,14 @@
427 306 * associated by reference.
428 307 *
429 308 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tag
430 309 *
431 - * @var string|null
310 + * @var string
311 + * | ObjectType
312 + * | Link
313 + * | array<ObjectType>
314 + * | array<Link>
315 + * | null
432 316 */
433 317 protected $tag;
434 318
435 319 /**
@@ -443,9 +327,13 @@
443 327
444 328 /**
445 329 * One or more links to representations of the object.
446 330 *
447 - * @var string|null
331 + * @var string
332 + * | array<string>
333 + * | Link
334 + * | array<Link>
335 + * | null
448 336 */
449 337 protected $url;
450 338
451 339 /**
@@ -453,9 +341,14 @@
453 341 * of an Object
454 342 *
455 343 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to
456 344 *
457 - * @var string|array|null
345 + * @var string
346 + * | ObjectType
347 + * | Link
348 + * | array<ObjectType>
349 + * | array<Link>
350 + * | null
458 351 */
459 352 protected $to;
460 353
461 354 /**
@@ -463,9 +356,14 @@
463 356 * Object.
464 357 *
465 358 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bto
466 359 *
467 - * @var string|array|null
360 + * @var string
361 + * | ObjectType
362 + * | Link
363 + * | array<ObjectType>
364 + * | array<Link>
365 + * | null
468 366 */
469 367 protected $bto;
470 368
471 369 /**
@@ -473,9 +371,14 @@
473 371 * Object.
474 372 *
475 373 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-cc
476 374 *
477 - * @var string|array|null
375 + * @var string
376 + * | ObjectType
377 + * | Link
378 + * | array<ObjectType>
379 + * | array<Link>
380 + * | null
478 381 */
479 382 protected $cc;
480 383
481 384 /**
@@ -483,9 +386,14 @@
483 386 * audience of this Object.
484 387 *
485 388 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bcc
486 389 *
487 - * @var string|array|null
390 + * @var string
391 + * | ObjectType
392 + * | Link
393 + * | array<ObjectType>
394 + * | array<Link>
395 + * | null
488 396 */
489 397 protected $bcc;
490 398
491 399 /**
@@ -500,11 +408,11 @@
500 408 protected $media_type;
501 409
502 410 /**
503 411 * When the object describes a time-bound resource, such as an audio
504 - * or video, a meeting, etc., the duration property indicates the
412 + * or video, a meeting, etc, the duration property indicates the
505 413 * object's approximate duration.
506 - * The value MUST be expressed as a xsd:duration as defined by
414 + * The value MUST be expressed as an xsd:duration as defined by
507 415 * xmlschema11-2, section 3.3.6 (e.g. a period of 5 seconds is
508 416 * represented as "PT5S").
509 417 *
510 418 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
@@ -519,9 +427,9 @@
519 427 * future editing by clients.
520 428 *
521 429 * @see https://www.w3.org/TR/activitypub/#source-property
522 430 *
523 - * @var array|null
431 + * @var ObjectType
524 432 */
525 433 protected $source;
526 434
527 435 /**
@@ -529,146 +437,278 @@
529 437 * this object.
530 438 *
531 439 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-replies
532 440 *
533 - * @var string|array|null
441 + * @var string
442 + * | Collection
443 + * | Link
444 + * | null
534 445 */
535 446 protected $replies;
536 447
537 448 /**
538 - * A Collection containing objects considered to be likes for
539 - * this object.
449 + * Magic function to implement getter and setter
540 450 *
541 - * @see https://www.w3.org/TR/activitypub/#likes
451 + * @param string $method The method name.
452 + * @param string $params The method params.
542 453 *
543 - * @var array|null
454 + * @return void
544 455 */
545 - protected $likes;
456 + public function __call( $method, $params ) {
457 + $var = \strtolower( \substr( $method, 4 ) );
546 458
459 + if ( \strncasecmp( $method, 'get', 3 ) === 0 ) {
460 + if ( ! $this->has( $var ) ) {
461 + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
462 + }
463 +
464 + return $this->$var;
465 + }
466 +
467 + if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
468 + return $this->set( $var, $params[0] );
469 + }
470 +
471 + if ( \strncasecmp( $method, 'add', 3 ) === 0 ) {
472 + $this->add( $var, $params[0] );
473 + }
474 + }
475 +
547 476 /**
548 - * A Collection containing objects considered to be shares for
549 - * this object.
477 + * Magic function, to transform the object to string.
550 478 *
551 - * @see https://www.w3.org/TR/activitypub/#shares
479 + * @return string The object id.
480 + */
481 + public function __toString() {
482 + return $this->to_string();
483 + }
484 +
485 + /**
486 + * Function to transform the object to string.
552 487 *
553 - * @var array|null
488 + * @return string The object id.
554 489 */
555 - protected $shares;
490 + public function to_string() {
491 + return $this->get_id();
492 + }
556 493
557 494 /**
558 - * Used to mark an object as containing sensitive content.
559 - * Mastodon displays a content warning, requiring users to click
560 - * through to view the content.
495 + * Generic getter.
561 496 *
562 - * @see https://docs.joinmastodon.org/spec/activitypub/#sensitive
497 + * @param string $key The key to get.
563 498 *
564 - * @var boolean|null
499 + * @return mixed The value.
565 500 */
566 - protected $sensitive;
501 + public function get( $key ) {
502 + if ( ! $this->has( $key ) ) {
503 + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
504 + }
567 505
506 + return call_user_func( array( $this, 'get_' . $key ) );
507 + }
508 +
568 509 /**
569 - * The dcterms namespace.
510 + * Check if the object has a key
570 511 *
571 - * @see https://codeberg.org/fediverse/fep/src/branch/main/fep/b2b8/fep-b2b8.md#sensitive
572 - * @see https://www.dublincore.org/specifications/dublin-core/dcmi-terms/
512 + * @param string $key The key to check.
573 513 *
574 - * @var array|null
514 + * @return boolean True if the object has the key.
575 515 */
576 - protected $dcterms;
516 + public function has( $key ) {
517 + return property_exists( $this, $key );
518 + }
577 519
578 520 /**
579 - * Interaction policy is an attempt to limit the harmful effects of unwanted replies and
580 - * other interactions on a user's posts (e.g., "reply guys").
521 + * Generic setter.
581 522 *
582 - * It is also used by Mastodon to limit the ability to quote posts.
523 + * @param string $key The key to set.
524 + * @param string $value The value to set.
583 525 *
584 - * @see https://docs.gotosocial.org/en/latest/federation/interaction_policy/
585 - * @see https://blog.joinmastodon.org/2025/09/introducing-quote-posts/
586 - *
587 - * @var array|null
526 + * @return mixed The value.
588 527 */
589 - protected $interaction_policy;
528 + public function set( $key, $value ) {
529 + if ( ! $this->has( $key ) ) {
530 + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
531 + }
590 532
533 + $this->$key = $value;
534 +
535 + return $this;
536 + }
537 +
591 538 /**
592 - * Fediverse Enhancement Proposal 044f: Quote Property
539 + * Generic adder.
593 540 *
594 - * @see https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md
595 - * @see https://w3id.org/fep/044f#quote
541 + * @param string $key The key to set.
542 + * @param mixed $value The value to add.
596 543 *
597 - * @var string|null
544 + * @return mixed The value.
598 545 */
599 - protected $quote;
546 + public function add( $key, $value ) {
547 + if ( ! $this->has( $key ) ) {
548 + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
549 + }
600 550
551 + if ( ! isset( $this->$key ) ) {
552 + $this->$key = array();
553 + }
554 +
555 + $attributes = $this->$key;
556 + $attributes[] = $value;
557 +
558 + $this->$key = $attributes;
559 +
560 + return $this->$key;
561 + }
562 +
601 563 /**
602 - * ActivityStreams quoteUrl property.
564 + * Convert JSON input to an array.
603 565 *
604 - * @see https://www.w3.org/ns/activitystreams#quoteUrl
566 + * @return string The JSON string.
605 567 *
606 - * @var string|null
568 + * @return \Activitypub\Activity\Base_Object An Object built from the JSON string.
607 569 */
608 - protected $quote_url;
570 + public static function init_from_json( $json ) {
571 + $array = \json_decode( $json, true );
609 572
573 + if ( ! is_array( $array ) ) {
574 + $array = array();
575 + }
576 +
577 + return self::init_from_array( $array );
578 + }
579 +
610 580 /**
611 - * Fedibird-specific quoteUri property.
581 + * Convert JSON input to an array.
612 582 *
613 - * @see https://fedibird.com/ns#quoteUri
583 + * @return string The object array.
614 584 *
615 - * @var string|null
585 + * @return \Activitypub\Activity\Base_Object An Object built from the JSON string.
616 586 */
617 - protected $quote_uri;
587 + public static function init_from_array( $array ) {
588 + if ( ! is_array( $array ) ) {
589 + return new WP_Error( 'invalid_array', __( 'Invalid array', 'activitypub' ), array( 'status' => 404 ) );
590 + }
618 591
592 + $object = new static();
593 +
594 + foreach ( $array as $key => $value ) {
595 + $key = camel_to_snake_case( $key );
596 + call_user_func( array( $object, 'set_' . $key ), $value );
597 + }
598 +
599 + return $object;
600 + }
601 +
619 602 /**
620 - * Misskey-specific quote property.
603 + * Convert JSON input to an array and pre-fill the object.
621 604 *
622 - * @see https://misskey-hub.net/ns/#_misskey_quote
605 + * @param string $json The JSON string.
606 + */
607 + public function from_json( $json ) {
608 + $array = \json_decode( $json, true );
609 +
610 + $this->from_array( $array );
611 + }
612 +
613 + /**
614 + * Convert JSON input to an array and pre-fill the object.
623 615 *
624 - * @var string|null
616 + * @param array $array The array.
625 617 */
626 - protected $_misskey_quote; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
618 + public function from_array( $array ) {
619 + foreach ( $array as $key => $value ) {
620 + if ( $value ) {
621 + $key = camel_to_snake_case( $key );
622 + call_user_func( array( $this, 'set_' . $key ), $value );
623 + }
624 + }
625 + }
627 626
628 627 /**
629 - * Generic getter.
628 + * Convert Object to an array.
630 629 *
631 - * @param string $key The key to get.
630 + * It tries to get the object attributes if they exist
631 + * and falls back to the getters. Empty values are ignored.
632 632 *
633 - * @return mixed The value.
633 + * @param bool $include_json_ld_context Whether to include the JSON-LD context. Default true.
634 + *
635 + * @return array An array built from the Object.
634 636 */
635 - public function get( $key ) {
636 - if ( ! $this->has( $key ) ) {
637 - return new \WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
637 + public function to_array( $include_json_ld_context = true ) {
638 + $array = array();
639 + $vars = get_object_vars( $this );
640 +
641 + foreach ( $vars as $key => $value ) {
642 + // ignotre all _prefixed keys.
643 + if ( '_' === substr( $key, 0, 1 ) ) {
644 + continue;
645 + }
646 +
647 + // if value is empty, try to get it from a getter.
648 + if ( ! $value ) {
649 + $value = call_user_func( array( $this, 'get_' . $key ) );
650 + }
651 +
652 + if ( is_object( $value ) ) {
653 + $value = $value->to_array( false );
654 + }
655 +
656 + // if value is still empty, ignore it for the array and continue.
657 + if ( isset( $value ) ) {
658 + $array[ snake_to_camel_case( $key ) ] = $value;
659 + }
638 660 }
639 661
640 - return parent::get( $key );
662 + if ( $include_json_ld_context ) {
663 + // Get JsonLD context and move it to '@context' at the top.
664 + $array = array_merge( array( '@context' => $this->get_json_ld_context() ), $array );
665 + }
666 +
667 + $class = new ReflectionClass( $this );
668 + $class = strtolower( $class->getShortName() );
669 +
670 + $array = \apply_filters( 'activitypub_activity_object_array', $array, $class, $this->id, $this );
671 + $array = \apply_filters( "activitypub_activity_{$class}_object_array", $array, $this->id, $this );
672 +
673 + return $array;
641 674 }
642 675
643 676 /**
644 - * Generic setter.
677 + * Convert Object to JSON.
645 678 *
646 - * @param string $key The key to set.
647 - * @param string $value The value to set.
679 + * @param bool $include_json_ld_context Whether to include the JSON-LD context. Default true.
648 680 *
649 - * @return mixed The value.
681 + * @return string The JSON string.
650 682 */
651 - public function set( $key, $value ) {
652 - if ( ! $this->has( $key ) ) {
653 - return new \WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
654 - }
683 + public function to_json( $include_json_ld_context = true ) {
684 + $array = $this->to_array( $include_json_ld_context );
685 + $options = \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT;
655 686
656 - return parent::set( $key, $value );
687 + /*
688 + * Options to be passed to json_encode()
689 + *
690 + * @param int $options The current options flags
691 + */
692 + $options = \apply_filters( 'activitypub_json_encode_options', $options );
693 +
694 + return \wp_json_encode( $array, $options );
657 695 }
658 696
659 697 /**
660 - * Generic adder.
698 + * Returns the keys of the object vars.
661 699 *
662 - * @param string $key The key to set.
663 - * @param mixed $value The value to add.
700 + * @return array The keys of the object vars.
701 + */
702 + public function get_object_var_keys() {
703 + return \array_keys( \get_object_vars( $this ) );
704 + }
705 +
706 + /**
707 + * Returns the JSON-LD context of this object.
664 708 *
665 - * @return mixed The value.
709 + * @return array $context A compacted JSON-LD context for the ActivityPub object.
666 710 */
667 - public function add( $key, $value ) {
668 - if ( ! $this->has( $key ) ) {
669 - return new \WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
670 - }
671 -
672 - return parent::add( $key, $value );
711 + public function get_json_ld_context() {
712 + return static::JSON_LD_CONTEXT;
673 713 }
674 714 }