PluginProbe
ActivityPub / 7.0.0
ActivityPub v7.0.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-generic-object.php

class-generic-object.php in ActivityPub 7.0.0, at includes/activity/class-generic-object.php

399 lines 12.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Generic Object.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Activity;
9
10 use function Activitypub\camel_to_snake_case;
11 use function Activitypub\snake_to_camel_case;
12
13 /**
14 * Generic Object.
15 *
16 * This class is used to create Generic Objects.
17 * It is used to create objects that might be unknown by the plugin but
18 * conform to the ActivityStreams vocabulary.
19 *
20 * @since 5.3.0
21 *
22 * @method string|null get_actor() Gets one or more entities that performed or are expected to perform the activity.
23 * @method string[]|null get_also_known_as() Gets the also known as property of the object.
24 * @method string|null get_attributed_to() Gets the entity attributed as the original author.
25 * @method array[]|null get_attachment() Gets the attachment property of the object.
26 * @method string[]|null get_cc() Gets the secondary recipients of the object.
27 * @method string|null get_content() Gets the content property of the object.
28 * @method string[]|null get_endpoints() Gets the endpoint property of the object.
29 * @method string[]|null get_icon() Gets the icon property of the object.
30 * @method string|null get_id() Gets the object's unique global identifier.
31 * @method string[]|null get_image() Gets the image property of the object.
32 * @method string[]|string|null get_in_reply_to() Gets the objects this object is in reply to.
33 * @method string|null get_inbox() Gets the inbox property of the object.
34 * @method string|null get_name() Gets the natural language name of the object.
35 * @method Base_Object|string|null get_object() Gets the direct object of the activity.
36 * @method string|null get_preferred_username() Gets the preferred username of the object.
37 * @method string|null get_published() Gets the date and time the object was published in ISO 8601 format.
38 * @method string|null get_summary() Gets the natural language summary of the object.
39 * @method array[]|null get_tag() Gets the tag property of the object.
40 * @method string[]|string|null get_to() Gets the primary recipients of the object.
41 * @method string get_type() Gets the type of the object.
42 * @method string|null get_updated() Gets the date and time the object was updated in ISO 8601 format.
43 * @method string|null get_url() Gets the URL of the object.
44 *
45 * @method string|string[] add_cc( string|array $cc ) Adds one or more entities to the secondary audience of the object.
46 * @method string|string[] add_to( string|array $to ) Adds one or more entities to the primary audience of the object.
47 *
48 * @method Base_Object set_actor( string|array $actor ) Sets one or more entities that performed the activity.
49 * @method Base_Object set_attachment( array $attachment ) Sets the attachment property of the object.
50 * @method Base_Object set_attributed_to( string $attributed_to ) Sets the entity attributed as the original author.
51 * @method Base_Object set_cc( array|string $cc ) Sets the secondary recipients of the object.
52 * @method Base_Object set_content( string $content ) Sets the content property of the object.
53 * @method Base_Object set_content_map( array $content_map ) Sets the content property of the object.
54 * @method Base_Object set_icon( array $icon ) Sets the icon property of the object.
55 * @method Base_Object set_id( string $id ) Sets the object's unique global identifier.
56 * @method Base_Object set_image( array $image ) Sets the image property of the object.
57 * @method Base_Object set_name( string $name ) Sets the natural language name of the object.
58 * @method Base_Object set_origin( string $origin ) Sets the origin property of the object.
59 * @method Base_Object set_published( string $published ) Sets the date and time the object was published in ISO 8601 format.
60 * @method Base_Object set_sensitive( bool $sensitive ) Sets the sensitive property of the object.
61 * @method Base_Object set_summary( string $summary ) Sets the natural language summary of the object.
62 * @method Base_Object set_summary_map( array|null $summary_map ) Sets the summary property of the object.
63 * @method Base_Object set_target( string $target ) Sets the target property of the object.
64 * @method Base_Object set_to( array|string $to ) Sets the primary recipients of the object.
65 * @method Base_Object set_type( string $type ) Sets the type of the object.
66 * @method Base_Object set_updated( string $updated ) Sets the date and time the object was updated in ISO 8601 format.
67 * @method Base_Object set_url( string $url ) Sets the URL of the object.
68 */
69 #[\AllowDynamicProperties]
70 class Generic_Object {
71 /**
72 * The JSON-LD context for the object.
73 *
74 * @var array
75 */
76 const JSON_LD_CONTEXT = array(
77 'https://www.w3.org/ns/activitystreams',
78 );
79
80 /**
81 * The object's unique global identifier
82 *
83 * @see https://www.w3.org/TR/activitypub/#obj-id
84 *
85 * @var string
86 */
87 protected $id;
88
89 /**
90 * Magic function, to transform the object to string.
91 *
92 * @return string The object id.
93 */
94 public function __toString() {
95 return $this->to_string();
96 }
97
98 /**
99 * Function to transform the object to string.
100 *
101 * @return string The object id.
102 */
103 public function to_string() {
104 return $this->get_id();
105 }
106
107 /**
108 * Magic function to implement getter and setter.
109 *
110 * @param string $method The method name.
111 * @param string $params The method params.
112 *
113 * @return mixed
114 */
115 public function __call( $method, $params ) {
116 $var = \strtolower( \substr( $method, 4 ) );
117
118 if ( \strncasecmp( $method, 'get', 3 ) === 0 ) {
119 if ( ! $this->has( $var ) ) {
120 return null;
121 }
122
123 return $this->$var;
124 }
125
126 if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
127 return $this->set( $var, $params[0] );
128 }
129
130 if ( \strncasecmp( $method, 'add', 3 ) === 0 ) {
131 return $this->add( $var, $params[0] );
132 }
133
134 return null;
135 }
136
137 /**
138 * Generic getter.
139 *
140 * @param string $key The key to get.
141 *
142 * @return mixed The value.
143 */
144 public function get( $key ) {
145 return call_user_func( array( $this, 'get_' . $key ) );
146 }
147
148 /**
149 * Generic setter.
150 *
151 * @param string $key The key to set.
152 * @param string $value The value to set.
153 *
154 * @return mixed The value.
155 */
156 public function set( $key, $value ) {
157 $this->$key = $value;
158
159 return $this;
160 }
161
162 /**
163 * Generic adder.
164 *
165 * @param string $key The key to set.
166 * @param mixed $value The value to add.
167 *
168 * @return mixed|void The value.
169 */
170 public function add( $key, $value ) {
171 if ( empty( $value ) ) {
172 return;
173 }
174
175 if ( ! isset( $this->$key ) ) {
176 $this->$key = array();
177 }
178
179 if ( is_string( $this->$key ) ) {
180 $this->$key = array( $this->$key );
181 }
182
183 $attributes = $this->$key;
184
185 if ( is_array( $value ) ) {
186 $attributes = array_merge( $attributes, $value );
187 } else {
188 $attributes[] = $value;
189 }
190
191 $this->$key = array_unique( $attributes );
192
193 return $this->$key;
194 }
195
196 /**
197 * Check if the object has a key
198 *
199 * @param string $key The key to check.
200 *
201 * @return boolean True if the object has the key.
202 */
203 public function has( $key ) {
204 return property_exists( $this, $key );
205 }
206
207 /**
208 * Convert JSON input to an array.
209 *
210 * @param string $json The JSON string.
211 *
212 * @return Generic_Object|\WP_Error An Object built from the JSON string or WP_Error when it's not a JSON string.
213 */
214 public static function init_from_json( $json ) {
215 $array = \json_decode( $json, true );
216
217 if ( ! is_array( $array ) ) {
218 return new \WP_Error( 'invalid_json', __( 'Invalid JSON', 'activitypub' ), array( 'status' => 400 ) );
219 }
220
221 return self::init_from_array( $array );
222 }
223
224 /**
225 * Convert input array to a Base_Object.
226 *
227 * @param array $data The object array.
228 *
229 * @return Generic_Object|\WP_Error An Object built from the input array or WP_Error when it's not an array.
230 */
231 public static function init_from_array( $data ) {
232 if ( ! is_array( $data ) ) {
233 return new \WP_Error( 'invalid_array', __( 'Invalid array', 'activitypub' ), array( 'status' => 400 ) );
234 }
235
236 $object = new static();
237 $object->from_array( $data );
238
239 return $object;
240 }
241
242 /**
243 * Convert JSON input to an array and pre-fill the object.
244 *
245 * @param array $data The array.
246 */
247 public function from_array( $data ) {
248 foreach ( $data as $key => $value ) {
249 if ( null !== $value ) {
250 $key = camel_to_snake_case( $key );
251 call_user_func( array( $this, 'set_' . $key ), $value );
252 }
253 }
254 }
255
256 /**
257 * Convert JSON input to an array and pre-fill the object.
258 *
259 * @param string $json The JSON string.
260 */
261 public function from_json( $json ) {
262 $array = \json_decode( $json, true );
263
264 $this->from_array( $array );
265 }
266
267 /**
268 * Convert Object to an array.
269 *
270 * It tries to get the object attributes if they exist
271 * and falls back to the getters. Empty values are ignored.
272 *
273 * @param bool $include_json_ld_context Whether to include the JSON-LD context. Default true.
274 *
275 * @return array An array built from the Object.
276 */
277 public function to_array( $include_json_ld_context = true ) {
278 $array = array();
279 $vars = get_object_vars( $this );
280
281 foreach ( $vars as $key => $value ) {
282 if ( \is_wp_error( $value ) ) {
283 continue;
284 }
285
286 // Ignore all _prefixed keys.
287 if ( '_' === substr( $key, 0, 1 ) ) {
288 continue;
289 }
290
291 // If value is empty, try to get it from a getter.
292 if ( ! $value ) {
293 $value = call_user_func( array( $this, 'get_' . $key ) );
294 }
295
296 if ( is_object( $value ) ) {
297 $value = $value->to_array( false );
298 }
299
300 if ( is_array( $value ) && $this->is_namespaced( $key ) ) {
301 foreach ( $value as $sub_key => $sub_value ) {
302 $array[ snake_to_camel_case( $key ) . ':' . snake_to_camel_case( $sub_key ) ] = $sub_value;
303 }
304 } elseif ( isset( $value ) ) {
305 $array[ snake_to_camel_case( $key ) ] = $value;
306 }
307 }
308
309 if ( $include_json_ld_context ) {
310 // Get JsonLD context and move it to '@context' at the top.
311 $array = array_merge( array( '@context' => $this->get_json_ld_context() ), $array );
312 }
313
314 $class = new \ReflectionClass( $this );
315 $class = strtolower( $class->getShortName() );
316
317 /**
318 * Filter the array of the ActivityPub object.
319 *
320 * @param array $array The array of the ActivityPub object.
321 * @param string $class The class of the ActivityPub object.
322 * @param string $id The ID of the ActivityPub object.
323 * @param Generic_Object $object The ActivityPub object.
324 *
325 * @return array The filtered array of the ActivityPub object.
326 */
327 $array = \apply_filters( 'activitypub_activity_object_array', $array, $class, $this->id, $this );
328
329 /**
330 * Filter the array of the ActivityPub object by class.
331 *
332 * @param array $array The array of the ActivityPub object.
333 * @param string $id The ID of the ActivityPub object.
334 * @param Generic_Object $object The ActivityPub object.
335 *
336 * @return array The filtered array of the ActivityPub object.
337 */
338 return \apply_filters( "activitypub_activity_{$class}_object_array", $array, $this->id, $this );
339 }
340
341 /**
342 * Convert Object to JSON.
343 *
344 * @param bool $include_json_ld_context Whether to include the JSON-LD context. Default true.
345 *
346 * @return string The JSON string.
347 */
348 public function to_json( $include_json_ld_context = true ) {
349 $array = $this->to_array( $include_json_ld_context );
350 $options = \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT | \JSON_UNESCAPED_SLASHES;
351
352 /**
353 * Options to be passed to json_encode().
354 *
355 * @param int $options The current options flags.
356 */
357 $options = \apply_filters( 'activitypub_json_encode_options', $options );
358
359 return \wp_json_encode( $array, $options );
360 }
361
362 /**
363 * Returns the keys of the object vars.
364 *
365 * @return array The keys of the object vars.
366 */
367 public function get_object_var_keys() {
368 return \array_keys( \get_object_vars( $this ) );
369 }
370
371 /**
372 * Returns the JSON-LD context of this object.
373 *
374 * @return array $context A compacted JSON-LD context for the ActivityPub object.
375 */
376 public function get_json_ld_context() {
377 return static::JSON_LD_CONTEXT;
378 }
379
380 /**
381 * Checks if an attribute is in a namespace.
382 *
383 * @param string $attribute The attribute to check.
384 *
385 * @return bool Whether the attribute is namespaced.
386 */
387 private function is_namespaced( $attribute ) {
388 $namespaces = array();
389
390 foreach ( static::JSON_LD_CONTEXT as $context ) {
391 if ( is_array( $context ) ) {
392 $namespaces = \array_merge( $namespaces, $context );
393 }
394 }
395
396 return isset( $namespaces[ $attribute ] ) && \wp_http_validate_url( $namespaces[ $attribute ] );
397 }
398 }
399