PluginProbe
ActivityPub / 1.2.0
ActivityPub v1.2.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 1.2.0, at includes/activity/class-base-object.php

679 lines 15.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
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 * A Collection containing objects considered to be responses to
259 * this object.
260 *
261 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-replies
262 *
263 * @var string
264 * | Collection
265 * | Link
266 * | null
267 */
268 protected $replies;
269
270 /**
271 * The date and time describing the actual or expected starting time
272 * of the object.
273 * When used with an Activity object, for instance, the startTime
274 * property specifies the moment the activity began
275 * or is scheduled to begin.
276 *
277 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-starttime
278 *
279 * @var string|null xsd:dateTime
280 */
281 protected $start_time;
282
283 /**
284 * A natural language summarization of the object encoded as HTML.
285 * Multiple language tagged summaries MAY be provided.
286 *
287 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
288 *
289 * @var string
290 * | ObjectType
291 * | Link
292 * | null
293 */
294 protected $summary;
295
296 /**
297 * The content MAY be expressed using multiple language-tagged
298 * values.
299 *
300 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
301 *
302 * @var array<string>|null
303 */
304 protected $summary_map;
305
306 /**
307 * One or more "tags" that have been associated with an objects.
308 * A tag can be any kind of Object.
309 * The key difference between attachment and tag is that the former
310 * implies association by inclusion, while the latter implies
311 * associated by reference.
312 *
313 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tag
314 *
315 * @var string
316 * | ObjectType
317 * | Link
318 * | array<ObjectType>
319 * | array<Link>
320 * | null
321 */
322 protected $tag;
323
324 /**
325 * The date and time at which the object was updated
326 *
327 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-updated
328 *
329 * @var string|null xsd:dateTime
330 */
331 protected $updated;
332
333 /**
334 * One or more links to representations of the object.
335 *
336 * @var string
337 * | array<string>
338 * | Link
339 * | array<Link>
340 * | null
341 */
342 protected $url;
343
344 /**
345 * An entity considered to be part of the public primary audience
346 * of an Object
347 *
348 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to
349 *
350 * @var string
351 * | ObjectType
352 * | Link
353 * | array<ObjectType>
354 * | array<Link>
355 * | null
356 */
357 protected $to;
358
359 /**
360 * An Object that is part of the private primary audience of this
361 * Object.
362 *
363 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bto
364 *
365 * @var string
366 * | ObjectType
367 * | Link
368 * | array<ObjectType>
369 * | array<Link>
370 * | null
371 */
372 protected $bto;
373
374 /**
375 * An Object that is part of the public secondary audience of this
376 * Object.
377 *
378 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-cc
379 *
380 * @var string
381 * | ObjectType
382 * | Link
383 * | array<ObjectType>
384 * | array<Link>
385 * | null
386 */
387 protected $cc;
388
389 /**
390 * One or more Objects that are part of the private secondary
391 * audience of this Object.
392 *
393 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bcc
394 *
395 * @var string
396 * | ObjectType
397 * | Link
398 * | array<ObjectType>
399 * | array<Link>
400 * | null
401 */
402 protected $bcc;
403
404 /**
405 * The MIME media type of the value of the content property.
406 * If not specified, the content property is assumed to contain
407 * text/html content.
408 *
409 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-mediatype
410 *
411 * @var string|null
412 */
413 protected $media_type;
414
415 /**
416 * When the object describes a time-bound resource, such as an audio
417 * or video, a meeting, etc, the duration property indicates the
418 * object's approximate duration.
419 * The value MUST be expressed as an xsd:duration as defined by
420 * xmlschema11-2, section 3.3.6 (e.g. a period of 5 seconds is
421 * represented as "PT5S").
422 *
423 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
424 *
425 * @var string|null
426 */
427 protected $duration;
428
429 /**
430 * Intended to convey some sort of source from which the content
431 * markup was derived, as a form of provenance, or to support
432 * future editing by clients.
433 *
434 * @see https://www.w3.org/TR/activitypub/#source-property
435 *
436 * @var ObjectType
437 */
438 protected $source;
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 $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 $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
676 return \wp_json_encode( $array, \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT );
677 }
678 }
679