Skip to content

Commit f538fea

Browse files
authored
Fix Flag activity object list processing (#2200)
1 parent 87c6a56 commit f538fea

File tree

4 files changed

+131
-46
lines changed

4 files changed

+131
-46
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: fixed
3+
4+
Fix Flag activity object list processing to preserve URL arrays

includes/activity/class-activity.php

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class Activity extends Base_Object {
7575
*
7676
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-object-term
7777
*
78-
* @var string|Base_Object|null
78+
* @var string|Base_Object|array|null
7979
*/
8080
protected $object;
8181

@@ -162,33 +162,17 @@ class Activity extends Base_Object {
162162
*
163163
* @see https://www.w3.org/TR/activitypub/#object-without-create
164164
*
165-
* @param array|string|Base_Object|Activity|Actor|null $data Activity object.
165+
* @param array|string|Base_Object|Activity|Actor|null $data Activity object.
166166
*/
167167
public function set_object( $data ) {
168168
$object = $data;
169169

170170
// Convert array to appropriate object type.
171171
if ( is_array( $data ) ) {
172-
$type = $data['type'] ?? null;
173-
174-
if ( in_array( $type, self::TYPES, true ) ) {
175-
$object = self::init_from_array( $data );
176-
} elseif ( in_array( $type, Actor::TYPES, true ) ) {
177-
$object = Actor::init_from_array( $data );
178-
} elseif ( in_array( $type, Base_Object::TYPES, true ) ) {
179-
switch ( $type ) {
180-
case 'Event':
181-
$object = Event::init_from_array( $data );
182-
break;
183-
case 'Place':
184-
$object = Place::init_from_array( $data );
185-
break;
186-
default:
187-
$object = Base_Object::init_from_array( $data );
188-
break;
189-
}
172+
if ( array_is_list( $data ) ) {
173+
$object = array_map( array( $this, 'maybe_convert_to_object' ), $data );
190174
} else {
191-
$object = Generic_Object::init_from_array( $data );
175+
$object = $this->maybe_convert_to_object( $data );
192176
}
193177
}
194178

@@ -266,4 +250,41 @@ public function get_json_ld_context() {
266250

267251
return static::JSON_LD_CONTEXT;
268252
}
253+
254+
/**
255+
* Convert data to the appropriate object type if it has an ActivityPub type.
256+
*
257+
* @param array|string|Base_Object|Activity|Actor|null $data The data to convert.
258+
*
259+
* @return Activity|Actor|Base_Object|Generic_Object|string|\WP_Error|null The converted object or original data.
260+
*/
261+
private function maybe_convert_to_object( $data ) {
262+
if ( ! is_array( $data ) ) {
263+
return $data;
264+
}
265+
266+
$type = $data['type'] ?? null;
267+
268+
if ( in_array( $type, self::TYPES, true ) ) {
269+
$object = self::init_from_array( $data );
270+
} elseif ( in_array( $type, Actor::TYPES, true ) ) {
271+
$object = Actor::init_from_array( $data );
272+
} elseif ( in_array( $type, Base_Object::TYPES, true ) ) {
273+
switch ( $type ) {
274+
case 'Event':
275+
$object = Event::init_from_array( $data );
276+
break;
277+
case 'Place':
278+
$object = Place::init_from_array( $data );
279+
break;
280+
default:
281+
$object = Base_Object::init_from_array( $data );
282+
break;
283+
}
284+
} else {
285+
$object = Generic_Object::init_from_array( $data );
286+
}
287+
288+
return $object;
289+
}
269290
}

includes/activity/class-generic-object.php

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,31 @@
1919
*
2020
* @since 5.3.0
2121
*
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_content_map() Gets the content map property of the object.
29-
* @method string[]|null get_endpoints() Gets the endpoint property of the object.
30-
* @method string[]|null get_icon() Gets the icon property of the object.
31-
* @method string|null get_id() Gets the object's unique global identifier.
32-
* @method string[]|null get_image() Gets the image property of the object.
33-
* @method string[]|string|null get_in_reply_to() Gets the objects this object is in reply to.
34-
* @method string|null get_inbox() Gets the inbox property of the object.
35-
* @method string|null get_name() Gets the natural language name of the object.
36-
* @method string[]|null get_name_map() Gets the name map property of the object.
37-
* @method Base_Object|string|null get_object() Gets the direct object of the activity.
38-
* @method string|null get_preferred_username() Gets the preferred username of the object.
39-
* @method string|null get_published() Gets the date and time the object was published in ISO 8601 format.
40-
* @method string|null get_summary() Gets the natural language summary of the object.
41-
* @method string[]|null get_summary_map() Gets the summary map property of the object.
42-
* @method array[]|null get_tag() Gets the tag property of the object.
43-
* @method string[]|string|null get_to() Gets the primary recipients of the object.
44-
* @method string get_type() Gets the type of the object.
45-
* @method string|null get_updated() Gets the date and time the object was updated in ISO 8601 format.
46-
* @method string|null get_url() Gets the URL of the object.
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_content_map() Gets the content map property of the object.
29+
* @method string[]|null get_endpoints() Gets the endpoint property of the object.
30+
* @method string[]|null get_icon() Gets the icon property of the object.
31+
* @method string|null get_id() Gets the object's unique global identifier.
32+
* @method string[]|null get_image() Gets the image property of the object.
33+
* @method string[]|string|null get_in_reply_to() Gets the objects this object is in reply to.
34+
* @method string|null get_inbox() Gets the inbox property of the object.
35+
* @method string|null get_name() Gets the natural language name of the object.
36+
* @method string[]|null get_name_map() Gets the name map property of the object.
37+
* @method Base_Object|string|array|null get_object() Gets the direct object of the activity.
38+
* @method string|null get_preferred_username() Gets the preferred username of the object.
39+
* @method string|null get_published() Gets the date and time the object was published in ISO 8601 format.
40+
* @method string|null get_summary() Gets the natural language summary of the object.
41+
* @method string[]|null get_summary_map() Gets the summary map property of the object.
42+
* @method array[]|null get_tag() Gets the tag property of the object.
43+
* @method string[]|string|null get_to() Gets the primary recipients of the object.
44+
* @method string get_type() Gets the type of the object.
45+
* @method string|null get_updated() Gets the date and time the object was updated in ISO 8601 format.
46+
* @method string|null get_url() Gets the URL of the object.
4747
*
4848
* @method string|string[] add_cc( string|array $cc ) Adds one or more entities to the secondary audience of the object.
4949
* @method string|string[] add_to( string|array $to ) Adds one or more entities to the primary audience of the object.

tests/includes/activity/class-test-activity.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,66 @@ public function test_activity_object_id() {
134134
$this->assertTrue( str_starts_with( $activity->get_id(), 'https://example.com/author/123#activity-update-' ) );
135135
}
136136

137+
/**
138+
* Test activity object list.
139+
*
140+
* @see https://docs.joinmastodon.org/spec/activitypub/#Flag
141+
* @covers ::init_from_array
142+
*/
143+
public function test_activity_object_list() {
144+
$object = array(
145+
'https://dummysite.example/?author=0',
146+
'https://dummysite.example/?p=123',
147+
);
148+
$activity = Activity::init_from_array(
149+
array(
150+
'id' => 'https://example.social/activities/123',
151+
'type' => 'Flag',
152+
'actor' => 'https://example.social/actor',
153+
'content' => '',
154+
'object' => $object,
155+
)
156+
);
157+
158+
$this->assertSame( $object, $activity->get_object() );
159+
}
160+
161+
/**
162+
* Test activity object mixed array.
163+
*
164+
* @covers ::init_from_array
165+
*/
166+
public function test_activity_object_mixed_array() {
167+
$activity = Activity::init_from_array(
168+
array(
169+
'@context' => 'https://www.w3.org/ns/activitystreams',
170+
'summary' => 'Sally liked a note',
171+
'type' => 'Like',
172+
'actor' => 'http://sally.example.org',
173+
'object' => array(
174+
'http://example.org/posts/1',
175+
array(
176+
'type' => 'Note',
177+
'summary' => 'A simple note',
178+
'content' => 'That is a tree.',
179+
),
180+
),
181+
)
182+
);
183+
184+
$object = $activity->get_object();
185+
186+
// Should be an array with 2 items.
187+
$this->assertIsArray( $object );
188+
$this->assertCount( 2, $object );
189+
190+
// First item should be the URL string (unchanged).
191+
$this->assertSame( 'http://example.org/posts/1', $object[0] );
192+
193+
// Second item should be a Base_Object (converted from array).
194+
$this->assertInstanceOf( 'Activitypub\Activity\Base_Object', $object[1] );
195+
}
196+
137197
/**
138198
* Test activity object.
139199
*/

0 commit comments

Comments
 (0)