PluginProbe
ActivityPub / 2.5.0
ActivityPub v2.5.0
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 / activity / class-base-object.php

class-base-object.php in ActivityPub 2.5.0, at includes/activity/class-base-object.php

715 lines 16.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Inspired by the PHP ActivityPub Library by @Landrok
4 *
5 * @link https://github.com/landrok/activitypub
6 */
7
8 namespace Activitypub\Activity;
9
10 use WP_Error;
11 use ReflectionClass;
12 use DateTime;
13
14 use function Activitypub\camel_to_snake_case;
15 use function Activitypub\snake_to_camel_case;
16
17 /**
18 * Base_Object is an implementation of one of the
19 * Activity Streams Core Types.
20 *
21 * The Object is the primary base type for the Activity Streams
22 * vocabulary.
23 *
24 * Note: Object is a reserved keyword in PHP. It has been suffixed with
25 * 'Base_' for this reason.
26 *
27 * @see https://www.w3.org/TR/activitystreams-core/#object
28 */
29 class Base_Object {
30 const JSON_LD_CONTEXT = array(
31 'https://www.w3.org/ns/activitystreams',
32 array(
33 'Hashtag' => 'as:Hashtag',
34 ),
35 );
36
37 /**
38 * The object's unique global identifier
39 *
40 * @see https://www.w3.org/TR/activitypub/#obj-id
41 *
42 * @var string
43 */
44 protected $id;
45
46 /**
47 * @var string
48 */
49 protected $type = 'Object';
50
51 /**
52 * A resource attached or related to an object that potentially
53 * requires special handling.
54 * The intent is to provide a model that is at least semantically
55 * similar to attachments in email.
56 *
57 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attachment
58 *
59 * @var string
60 * | ObjectType
61 * | Link
62 * | array<ObjectType>
63 * | array<Link>
64 * | null
65 */
66 protected $attachment;
67
68 /**
69 * One or more entities to which this object is attributed.
70 * The attributed entities might not be Actors. For instance, an
71 * object might be attributed to the completion of another activity.
72 *
73 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attributedto
74 *
75 * @var string
76 * | ObjectType
77 * | Link
78 * | array<ObjectType>
79 * | array<Link>
80 * | null
81 */
82 protected $attributed_to;
83
84 /**
85 * One or more entities that represent the total population of
86 * entities for which the object can considered to be relevant.
87 *
88 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audience
89 *
90 * @var string
91 * | ObjectType
92 * | Link
93 * | array<ObjectType>
94 * | array<Link>
95 * | null
96 */
97 protected $audience;
98
99 /**
100 * The content or textual representation of the Object encoded as a
101 * JSON string. By default, the value of content is HTML.
102 * The mediaType property can be used in the object to indicate a
103 * different content type.
104 *
105 * The content MAY be expressed using multiple language-tagged
106 * values.
107 *
108 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-content
109 *
110 * @var string|null
111 */
112 protected $content;
113
114 /**
115 * The context within which the object exists or an activity was
116 * performed.
117 * The notion of "context" used is intentionally vague.
118 * The intended function is to serve as a means of grouping objects
119 * and activities that share a common originating context or
120 * purpose. An example could be all activities relating to a common
121 * project or event.
122 *
123 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context
124 *
125 * @var string
126 * | ObjectType
127 * | Link
128 * | null
129 */
130 protected $context;
131
132 /**
133 * The content MAY be expressed using multiple language-tagged
134 * values.
135 *
136 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-content
137 *
138 * @var array|null
139 */
140 protected $content_map;
141
142 /**
143 * A simple, human-readable, plain-text name for the object.
144 * HTML markup MUST NOT be included.
145 *
146 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-name
147 *
148 * @var string|null xsd:string
149 */
150 protected $name;
151
152 /**
153 * The name MAY be expressed using multiple language-tagged values.
154 *
155 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-name
156 *
157 * @var array|null rdf:langString
158 */
159 protected $name_map;
160
161 /**
162 * The date and time describing the actual or expected ending time
163 * of the object.
164 * When used with an Activity object, for instance, the endTime
165 * property specifies the moment the activity concluded or
166 * is expected to conclude.
167 *
168 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-endtime
169 *
170 * @var string|null
171 */
172 protected $end_time;
173
174 /**
175 * The entity (e.g. an application) that generated the object.
176 *
177 * @var string|null
178 */
179 protected $generator;
180
181 /**
182 * An entity that describes an icon for this object.
183 * The image should have an aspect ratio of one (horizontal)
184 * to one (vertical) and should be suitable for presentation
185 * at a small size.
186 *
187 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-icon
188 *
189 * @var string
190 * | Image
191 * | Link
192 * | array<Image>
193 * | array<Link>
194 * | null
195 */
196 protected $icon;
197
198 /**
199 * An entity that describes an image for this object.
200 * Unlike the icon property, there are no aspect ratio
201 * or display size limitations assumed.
202 *
203 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-image-term
204 *
205 * @var string
206 * | Image
207 * | Link
208 * | array<Image>
209 * | array<Link>
210 * | null
211 */
212 protected $image;
213
214 /**
215 * One or more entities for which this object is considered a
216 * response.
217 *
218 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-inreplyto
219 *
220 * @var string
221 * | ObjectType
222 * | Link
223 * | array<ObjectType>
224 * | array<Link>
225 * | null
226 */
227 protected $in_reply_to;
228
229 /**
230 * One or more physical or logical locations associated with the
231 * object.
232 *
233 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-location
234 *
235 * @var string
236 * | ObjectType
237 * | Link
238 * | array<ObjectType>
239 * | array<Link>
240 * | null
241 */
242 protected $location;
243
244 /**
245 * An entity that provides a preview of this object.
246 *
247 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-preview
248 *
249 * @var string
250 * | ObjectType
251 * | Link
252 * | null
253 */
254 protected $preview;
255
256 /**
257 * The date and time at which the object was published
258 *
259 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-published
260 *
261 * @var string|null xsd:dateTime
262 */
263 protected $published;
264
265 /**
266 * The date and time describing the actual or expected starting time
267 * of the object.
268 * When used with an Activity object, for instance, the startTime
269 * property specifies the moment the activity began
270 * or is scheduled to begin.
271 *
272 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-starttime
273 *
274 * @var string|null xsd:dateTime
275 */
276 protected $start_time;
277
278 /**
279 * A natural language summarization of the object encoded as HTML.
280 * Multiple language tagged summaries MAY be provided.
281 *
282 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
283 *
284 * @var string
285 * | ObjectType
286 * | Link
287 * | null
288 */
289 protected $summary;
290
291 /**
292 * The content MAY be expressed using multiple language-tagged
293 * values.
294 *
295 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
296 *
297 * @var array<string>|null
298 */
299 protected $summary_map;
300
301 /**
302 * One or more "tags" that have been associated with an objects.
303 * A tag can be any kind of Object.
304 * The key difference between attachment and tag is that the former
305 * implies association by inclusion, while the latter implies
306 * associated by reference.
307 *
308 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tag
309 *
310 * @var string
311 * | ObjectType
312 * | Link
313 * | array<ObjectType>
314 * | array<Link>
315 * | null
316 */
317 protected $tag;
318
319 /**
320 * The date and time at which the object was updated
321 *
322 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-updated
323 *
324 * @var string|null xsd:dateTime
325 */
326 protected $updated;
327
328 /**
329 * One or more links to representations of the object.
330 *
331 * @var string
332 * | array<string>
333 * | Link
334 * | array<Link>
335 * | null
336 */
337 protected $url;
338
339 /**
340 * An entity considered to be part of the public primary audience
341 * of an Object
342 *
343 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to
344 *
345 * @var string
346 * | ObjectType
347 * | Link
348 * | array<ObjectType>
349 * | array<Link>
350 * | null
351 */
352 protected $to;
353
354 /**
355 * An Object that is part of the private primary audience of this
356 * Object.
357 *
358 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bto
359 *
360 * @var string
361 * | ObjectType
362 * | Link
363 * | array<ObjectType>
364 * | array<Link>
365 * | null
366 */
367 protected $bto;
368
369 /**
370 * An Object that is part of the public secondary audience of this
371 * Object.
372 *
373 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-cc
374 *
375 * @var string
376 * | ObjectType
377 * | Link
378 * | array<ObjectType>
379 * | array<Link>
380 * | null
381 */
382 protected $cc;
383
384 /**
385 * One or more Objects that are part of the private secondary
386 * audience of this Object.
387 *
388 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bcc
389 *
390 * @var string
391 * | ObjectType
392 * | Link
393 * | array<ObjectType>
394 * | array<Link>
395 * | null
396 */
397 protected $bcc;
398
399 /**
400 * The MIME media type of the value of the content property.
401 * If not specified, the content property is assumed to contain
402 * text/html content.
403 *
404 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-mediatype
405 *
406 * @var string|null
407 */
408 protected $media_type;
409
410 /**
411 * When the object describes a time-bound resource, such as an audio
412 * or video, a meeting, etc, the duration property indicates the
413 * object's approximate duration.
414 * The value MUST be expressed as an xsd:duration as defined by
415 * xmlschema11-2, section 3.3.6 (e.g. a period of 5 seconds is
416 * represented as "PT5S").
417 *
418 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
419 *
420 * @var string|null
421 */
422 protected $duration;
423
424 /**
425 * Intended to convey some sort of source from which the content
426 * markup was derived, as a form of provenance, or to support
427 * future editing by clients.
428 *
429 * @see https://www.w3.org/TR/activitypub/#source-property
430 *
431 * @var ObjectType
432 */
433 protected $source;
434
435 /**
436 * A Collection containing objects considered to be responses to
437 * this object.
438 *
439 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-replies
440 *
441 * @var string
442 * | Collection
443 * | Link
444 * | null
445 */
446 protected $replies;
447
448 /**
449 * Magic function to implement getter and setter
450 *
451 * @param string $method The method name.
452 * @param string $params The method params.
453 *
454 * @return void
455 */
456 public function __call( $method, $params ) {
457 $var = \strtolower( \substr( $method, 4 ) );
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
476 /**
477 * Magic function, to transform the object to string.
478 *
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.
487 *
488 * @return string The object id.
489 */
490 public function to_string() {
491 return $this->get_id();
492 }
493
494 /**
495 * Generic getter.
496 *
497 * @param string $key The key to get.
498 *
499 * @return mixed The value.
500 */
501 public function get( $key ) {
502 if ( ! $this->has( $key ) ) {
503 return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) );
504 }
505
506 return call_user_func( array( $this, 'get_' . $key ) );
507 }
508
509 /**
510 * Check if the object has a key
511 *
512 * @param string $key The key to check.
513 *
514 * @return boolean True if the object has the key.
515 */
516 public function has( $key ) {
517 return property_exists( $this, $key );
518 }
519
520 /**
521 * Generic setter.
522 *
523 * @param string $key The key to set.
524 * @param string $value The value to set.
525 *
526 * @return mixed The value.
527 */
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 }
532
533 $this->$key = $value;
534
535 return $this;
536 }
537
538 /**
539 * Generic adder.
540 *
541 * @param string $key The key to set.
542 * @param mixed $value The value to add.
543 *
544 * @return mixed The value.
545 */
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 }
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
563 /**
564 * Convert JSON input to an array.
565 *
566 * @return string The JSON string.
567 *
568 * @return \Activitypub\Activity\Base_Object An Object built from the JSON string.
569 */
570 public static function init_from_json( $json ) {
571 $array = \json_decode( $json, true );
572
573 if ( ! is_array( $array ) ) {
574 $array = array();
575 }
576
577 return self::init_from_array( $array );
578 }
579
580 /**
581 * Convert JSON input to an array.
582 *
583 * @return string The object array.
584 *
585 * @return \Activitypub\Activity\Base_Object An Object built from the JSON string.
586 */
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 }
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
602 /**
603 * Convert JSON input to an array and pre-fill the object.
604 *
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.
615 *
616 * @param array $array The array.
617 */
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 }
626
627 /**
628 * Convert Object to an array.
629 *
630 * It tries to get the object attributes if they exist
631 * and falls back to the getters. Empty values are ignored.
632 *
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.
636 */
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 }
660 }
661
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;
674 }
675
676 /**
677 * Convert Object to JSON.
678 *
679 * @param bool $include_json_ld_context Whether to include the JSON-LD context. Default true.
680 *
681 * @return string The JSON string.
682 */
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;
686
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 );
695 }
696
697 /**
698 * Returns the keys of the object vars.
699 *
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.
708 *
709 * @return array $context A compacted JSON-LD context for the ActivityPub object.
710 */
711 public function get_json_ld_context() {
712 return static::JSON_LD_CONTEXT;
713 }
714 }
715