PluginProbe
ActivityPub / 7.8.2
ActivityPub v7.8.2
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-activity.php

class-activity.php in ActivityPub 7.8.2, at includes/activity/class-activity.php

315 lines 9.3 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 * @package Activitypub
8 */
9
10 namespace Activitypub\Activity;
11
12 use Activitypub\Activity\Extended_Object\Event;
13 use Activitypub\Activity\Extended_Object\Place;
14
15 /**
16 * \Activitypub\Activity\Activity implements the common
17 * attributes of an Activity.
18 *
19 * @see https://www.w3.org/TR/activitystreams-core/#activities
20 * @see https://www.w3.org/TR/activitystreams-core/#intransitiveactivities
21 *
22 * @method string|array get_actor() Gets one or more entities that performed or are expected to perform the activity.
23 * @method string|array|null get_instrument() Gets one or more objects used in the completion of an Activity.
24 * @method Base_Object|string|array|null get_object() Gets the direct object of the activity.
25 * @method string|string[]|null get_origin() Gets the origin property of the activity.
26 * @method array|null get_replies() Gets the collection of responses to this activity.
27 * @method string|null get_result() Gets the result property of the activity.
28 * @method string|string[]|null get_target() Gets the target property of the activity.
29 *
30 * @method Activity set_actor( string|array $actor ) Sets one or more entities that performed the activity.
31 * @method Activity set_instrument( string|array $instrument ) Sets one or more objects used in the completion of an Activity.
32 * @method Activity set_origin( string|array|null $origin ) Sets the origin property of the activity.
33 * @method Activity set_replies( array $replies ) Sets the collection of responses to this activity.
34 * @method Activity set_result( string|null $result ) Sets the result property of the activity.
35 * @method Activity set_target( string|array|null $target ) Sets the target property of the activity.
36 */
37 class Activity extends Base_Object {
38 const JSON_LD_CONTEXT = array(
39 'https://www.w3.org/ns/activitystreams',
40 array(
41 'toot' => 'http://joinmastodon.org/ns#',
42 'QuoteRequest' => 'toot:QuoteRequest',
43 ),
44 );
45
46 /**
47 * The default types for Activities.
48 *
49 * @see https://www.w3.org/TR/activitystreams-vocabulary/#activity-types
50 *
51 * @var array
52 */
53 const TYPES = array(
54 'Accept',
55 'Add',
56 'Announce',
57 'Arrive',
58 'Block',
59 'Create',
60 'Delete',
61 'Dislike',
62 'Follow',
63 'Flag',
64 'Ignore',
65 'Invite',
66 'Join',
67 'Leave',
68 'Like',
69 'Listen',
70 'Move',
71 'Offer',
72 'QuoteRequest', // @see https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md
73 'Read',
74 'Reject',
75 'Remove',
76 'TentativeAccept',
77 'TentativeReject',
78 'Travel',
79 'Undo',
80 'Update',
81 'View',
82 );
83
84 /**
85 * The type of the object.
86 *
87 * @var string
88 */
89 protected $type = 'Activity';
90
91 /**
92 * Describes the direct object of the activity.
93 * For instance, in the activity "John added a movie to his
94 * wishlist", the object of the activity is the movie added.
95 *
96 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-object-term
97 *
98 * @var string|Base_Object|array|null
99 */
100 protected $object;
101
102 /**
103 * Describes one or more entities that either performed or are
104 * expected to perform the activity.
105 * Any single activity can have multiple actors.
106 * The actor MAY be specified using an indirect Link.
107 *
108 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-actor
109 *
110 * @var string|array
111 */
112 protected $actor;
113
114 /**
115 * The indirect object, or target, of the activity.
116 * The precise meaning of the target is largely dependent on the
117 * type of action being described but will often be the object of
118 * the English preposition "to".
119 * For instance, in the activity "John added a movie to his
120 * wishlist", the target of the activity is John's wishlist.
121 * An activity can have more than one target.
122 *
123 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-target
124 *
125 * @var string|array|null
126 */
127 protected $target;
128
129 /**
130 * Describes the result of the activity.
131 * For instance, if a particular action results in the creation of
132 * a new resource, the result property can be used to describe
133 * that new resource.
134 *
135 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-result
136 *
137 * @var string|Base_Object|null
138 */
139 protected $result;
140
141 /**
142 * Identifies a Collection containing objects considered to be responses
143 * to this object.
144 * WordPress has a strong core system of approving replies. We only include
145 * approved replies here.
146 *
147 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-replies
148 *
149 * @var array|null
150 */
151 protected $replies;
152
153 /**
154 * An indirect object of the activity from which the
155 * activity is directed.
156 * The precise meaning of the origin is the object of the English
157 * preposition "from".
158 * For instance, in the activity "John moved an item to List B
159 * from List A", the origin of the activity is "List A".
160 *
161 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-origin
162 *
163 * @var string|array|null
164 */
165 protected $origin;
166
167 /**
168 * One or more objects used (or to be used) in the completion of an
169 * Activity.
170 *
171 * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-instrument
172 *
173 * @var string|array|null
174 */
175 protected $instrument;
176
177 /**
178 * Set the object and copy Object properties to the Activity.
179 *
180 * Any to, bto, cc, bcc, and audience properties specified on the object
181 * MUST be copied over to the new "Create" activity by the server.
182 *
183 * @see https://www.w3.org/TR/activitypub/#object-without-create
184 *
185 * @param array|string|Base_Object|Activity|Actor|null $data Activity object.
186 */
187 public function set_object( $data ) {
188 $object = $data;
189
190 // Convert array to appropriate object type.
191 if ( is_array( $data ) ) {
192 if ( array_is_list( $data ) ) {
193 $object = array_map( array( $this, 'maybe_convert_to_object' ), $data );
194 } else {
195 $object = $this->maybe_convert_to_object( $data );
196 }
197 }
198
199 $this->set( 'object', $object );
200 $this->pre_fill_activity_from_object();
201 }
202
203 /**
204 * Fills the Activity with the specified activity object.
205 */
206 public function pre_fill_activity_from_object() {
207 $object = $this->get_object();
208
209 // Check if `$object` is a URL and use it to generate an ID then.
210 if ( is_string( $object ) && filter_var( $object, FILTER_VALIDATE_URL ) && ! $this->get_id() ) {
211 $this->set( 'id', $object . '#activity-' . strtolower( $this->get_type() ) . '-' . time() );
212
213 return;
214 }
215
216 // Check if `$object` is an object and copy some properties otherwise do nothing.
217 if ( ! is_object( $object ) ) {
218 return;
219 }
220
221 foreach ( array( 'to', 'bto', 'cc', 'bcc', 'audience' ) as $i ) {
222 $value = $object->get( $i );
223 if ( $value && ! $this->get( $i ) ) {
224 $this->set( $i, $value );
225 }
226 }
227
228 if ( $object->get_published() && ! $this->get_published() ) {
229 $this->set( 'published', $object->get_published() );
230 }
231
232 if ( $object->get_updated() && ! $this->get_updated() ) {
233 $this->set( 'updated', $object->get_updated() );
234 }
235
236 if ( $object->get_attributed_to() && ! $this->get_actor() ) {
237 $this->set( 'actor', $object->get_attributed_to() );
238 }
239
240 if ( $this->get_type() !== 'Announce' && $object->get_in_reply_to() && ! $this->get_in_reply_to() ) {
241 $this->set( 'in_reply_to', $object->get_in_reply_to() );
242 }
243
244 if ( $object->get_interaction_policy() && ! $this->get_interaction_policy() ) {
245 $this->set( 'interaction_policy', $object->get_interaction_policy() );
246 }
247
248 if ( $object->get_id() && ! $this->get_id() ) {
249 $id = strtok( $object->get_id(), '#' );
250 if ( $object->get_updated() ) {
251 $updated = $object->get_updated();
252 } elseif ( $object->get_published() ) {
253 $updated = $object->get_published();
254 } else {
255 $updated = time();
256 }
257 $this->set( 'id', $id . '#activity-' . strtolower( $this->get_type() ) . '-' . $updated );
258 }
259 }
260
261 /**
262 * The context of an Activity is usually just the context of the object it contains.
263 *
264 * @return array $context A compacted JSON-LD context.
265 */
266 public function get_json_ld_context() {
267 if ( \is_object( $this->object ) ) {
268 $class = get_class( $this->object );
269 if ( $class && $class::JSON_LD_CONTEXT ) {
270 // Without php 5.6 support this could be just: 'return $this->object::JSON_LD_CONTEXT;'.
271 return $class::JSON_LD_CONTEXT;
272 }
273 }
274
275 return static::JSON_LD_CONTEXT;
276 }
277
278 /**
279 * Convert data to the appropriate object type if it has an ActivityPub type.
280 *
281 * @param array|string|Base_Object|Activity|Actor|null $data The data to convert.
282 *
283 * @return Activity|Actor|Base_Object|Generic_Object|string|\WP_Error|null The converted object or original data.
284 */
285 private function maybe_convert_to_object( $data ) {
286 if ( ! is_array( $data ) ) {
287 return $data;
288 }
289
290 $type = $data['type'] ?? null;
291
292 if ( in_array( $type, self::TYPES, true ) ) {
293 $object = self::init_from_array( $data );
294 } elseif ( in_array( $type, Actor::TYPES, true ) ) {
295 $object = Actor::init_from_array( $data );
296 } elseif ( in_array( $type, Base_Object::TYPES, true ) ) {
297 switch ( $type ) {
298 case 'Event':
299 $object = Event::init_from_array( $data );
300 break;
301 case 'Place':
302 $object = Place::init_from_array( $data );
303 break;
304 default:
305 $object = Base_Object::init_from_array( $data );
306 break;
307 }
308 } else {
309 $object = Generic_Object::init_from_array( $data );
310 }
311
312 return $object;
313 }
314 }
315