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

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

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