Skip to content

Commit a7f70b0

Browse files
pfefferleobenland
andauthored
Add interaction policy and quoting controls to ActivityPub (#2207)
Co-authored-by: Konstantin Obenland <[email protected]>
1 parent 35b5390 commit a7f70b0

File tree

15 files changed

+381
-54
lines changed

15 files changed

+381
-54
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: added
3+
4+
Added a setting to control who can quote your posts.

FEDERATION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The WordPress plugin largely follows ActivityPub's server-to-server specificatio
88
- [WebFinger](https://www.w3.org/community/reports/socialcg/CG-FINAL-apwf-20240608/)
99
- [HTTP Signatures](https://swicg.github.io/activitypub-http-signature/)
1010
- [NodeInfo](https://nodeinfo.diaspora.software/)
11+
- [Interaction Policy](https://docs.gotosocial.org/en/latest/federation/interaction_policy/)
1112

1213
## Supported FEPs
1314

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?php return array('dependencies' => array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'b0197fe6abf861a22382');
1+
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-components', 'wp-core-data', 'wp-data', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'faa910495b60327c9360');

build/editor-plugin/plugin.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

includes/activity/class-activity.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class Activity extends Base_Object {
102102
*
103103
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-target
104104
*
105-
* @var string|array
105+
* @var string|array|null
106106
*/
107107
protected $target;
108108

@@ -114,7 +114,7 @@ class Activity extends Base_Object {
114114
*
115115
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-result
116116
*
117-
* @var string|Base_Object
117+
* @var string|Base_Object|null
118118
*/
119119
protected $result;
120120

@@ -126,7 +126,7 @@ class Activity extends Base_Object {
126126
*
127127
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-replies
128128
*
129-
* @var array
129+
* @var array|null
130130
*/
131131
protected $replies;
132132

@@ -140,7 +140,7 @@ class Activity extends Base_Object {
140140
*
141141
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-origin
142142
*
143-
* @var string|array
143+
* @var string|array|null
144144
*/
145145
protected $origin;
146146

@@ -150,7 +150,7 @@ class Activity extends Base_Object {
150150
*
151151
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-instrument
152152
*
153-
* @var string|array
153+
* @var string|array|null
154154
*/
155155
protected $instrument;
156156

@@ -221,6 +221,10 @@ public function pre_fill_activity_from_object() {
221221
$this->set( 'in_reply_to', $object->get_in_reply_to() );
222222
}
223223

224+
if ( $object->get_interaction_policy() && ! $this->get_interaction_policy() ) {
225+
$this->set( 'interaction_policy', $object->get_interaction_policy() );
226+
}
227+
224228
if ( $object->get_id() && ! $this->get_id() ) {
225229
$id = strtok( $object->get_id(), '#' );
226230
if ( $object->get_updated() ) {
@@ -240,7 +244,7 @@ public function pre_fill_activity_from_object() {
240244
* @return array $context A compacted JSON-LD context.
241245
*/
242246
public function get_json_ld_context() {
243-
if ( $this->object instanceof Base_Object ) {
247+
if ( \is_object( $this->object ) ) {
244248
$class = get_class( $this->object );
245249
if ( $class && $class::JSON_LD_CONTEXT ) {
246250
// Without php 5.6 support this could be just: 'return $this->object::JSON_LD_CONTEXT;'.

includes/activity/class-actor.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ class Actor extends Base_Object {
201201
*
202202
* @context as:manuallyApprovesFollowers
203203
*
204-
* @var boolean
204+
* @var boolean|null
205205
*/
206206
protected $manually_approves_followers = false;
207207

@@ -211,7 +211,7 @@ class Actor extends Base_Object {
211211
*
212212
* @see https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/
213213
*
214-
* @var array
214+
* @var array|null
215215
*/
216216
protected $attribution_domains = null;
217217

@@ -225,7 +225,7 @@ class Actor extends Base_Object {
225225
/**
226226
* The alsoKnownAs of the actor.
227227
*
228-
* @var array
228+
* @var array|null
229229
*/
230230
protected $also_known_as;
231231

@@ -239,7 +239,7 @@ class Actor extends Base_Object {
239239
* "@type": "@id"
240240
* }
241241
*
242-
* @var string
242+
* @var string|null
243243
*/
244244
protected $featured;
245245

@@ -253,7 +253,7 @@ class Actor extends Base_Object {
253253
* "@type": "@id"
254254
* }
255255
*
256-
* @var string
256+
* @var string|null
257257
*/
258258
protected $featured_tags;
259259

@@ -264,7 +264,7 @@ class Actor extends Base_Object {
264264
*
265265
* @context http://joinmastodon.org/ns#discoverable
266266
*
267-
* @var boolean
267+
* @var boolean|null
268268
*/
269269
protected $discoverable;
270270

@@ -275,7 +275,7 @@ class Actor extends Base_Object {
275275
*
276276
* @context http://joinmastodon.org/ns#indexable
277277
*
278-
* @var boolean
278+
* @var boolean|null
279279
*/
280280
protected $indexable;
281281

@@ -284,7 +284,7 @@ class Actor extends Base_Object {
284284
*
285285
* @see https://codeberg.org/fediverse/fep/src/branch/main/fep/2c59/fep-2c59.md
286286
*
287-
* @var string
287+
* @var string|null
288288
*/
289289
protected $webfinger;
290290

@@ -293,7 +293,7 @@ class Actor extends Base_Object {
293293
*
294294
* @see https://join-lemmy.org/docs/contributors/05-federation.html
295295
*
296-
* @var string
296+
* @var string|null
297297
*/
298298
protected $moderators;
299299

@@ -302,7 +302,7 @@ class Actor extends Base_Object {
302302
*
303303
* @see https://join-lemmy.org/docs/contributors/05-federation.html
304304
*
305-
* @var boolean
305+
* @var boolean|null
306306
*/
307307
protected $posting_restricted_to_mods;
308308

@@ -311,7 +311,7 @@ class Actor extends Base_Object {
311311
*
312312
* @see https://codeberg.org/fediverse/fep/src/branch/main/fep/844e/fep-844e.md
313313
*
314-
* @var array
314+
* @var array|null
315315
*/
316316
protected $implements;
317317

@@ -320,7 +320,7 @@ class Actor extends Base_Object {
320320
*
321321
* @see https://litepub.social/
322322
*
323-
* @var boolean
323+
* @var boolean|null
324324
*/
325325
protected $invisible = null;
326326
}

includes/activity/class-base-object.php

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,42 @@ class Base_Object extends Generic_Object {
3030
const JSON_LD_CONTEXT = array(
3131
'https://www.w3.org/ns/activitystreams',
3232
array(
33-
'Hashtag' => 'as:Hashtag',
34-
'sensitive' => 'as:sensitive',
35-
'dcterms' => 'http://purl.org/dc/terms/',
33+
'Hashtag' => 'as:Hashtag',
34+
'sensitive' => 'as:sensitive',
35+
'dcterms' => 'http://purl.org/dc/terms/',
36+
'gts' => 'https://gotosocial.org/ns#',
37+
'interactionPolicy' => array(
38+
'@id' => 'gts:interactionPolicy',
39+
'@type' => '@id',
40+
),
41+
'canQuote' => array(
42+
'@id' => 'gts:canQuote',
43+
'@type' => '@id',
44+
),
45+
'canReply' => array(
46+
'@id' => 'gts:canReply',
47+
'@type' => '@id',
48+
),
49+
'canLike' => array(
50+
'@id' => 'gts:canLike',
51+
'@type' => '@id',
52+
),
53+
'canAnnounce' => array(
54+
'@id' => 'gts:canAnnounce',
55+
'@type' => '@id',
56+
),
57+
'automaticApproval' => array(
58+
'@id' => 'gts:automaticApproval',
59+
'@type' => '@id',
60+
),
61+
'manualApproval' => array(
62+
'@id' => 'gts:manualApproval',
63+
'@type' => '@id',
64+
),
65+
'always' => array(
66+
'@id' => 'gts:always',
67+
'@type' => '@id',
68+
),
3669
),
3770
);
3871

@@ -372,7 +405,7 @@ class Base_Object extends Generic_Object {
372405
*
373406
* @see https://www.w3.org/TR/activitypub/#source-property
374407
*
375-
* @var array
408+
* @var array|null
376409
*/
377410
protected $source;
378411

@@ -392,7 +425,7 @@ class Base_Object extends Generic_Object {
392425
*
393426
* @see https://www.w3.org/TR/activitypub/#likes
394427
*
395-
* @var array
428+
* @var array|null
396429
*/
397430
protected $likes;
398431

@@ -402,7 +435,7 @@ class Base_Object extends Generic_Object {
402435
*
403436
* @see https://www.w3.org/TR/activitypub/#shares
404437
*
405-
* @var array
438+
* @var array|null
406439
*/
407440
protected $shares;
408441

@@ -413,7 +446,7 @@ class Base_Object extends Generic_Object {
413446
*
414447
* @see https://docs.joinmastodon.org/spec/activitypub/#sensitive
415448
*
416-
* @var boolean
449+
* @var boolean|null
417450
*/
418451
protected $sensitive;
419452

@@ -423,10 +456,23 @@ class Base_Object extends Generic_Object {
423456
* @see https://codeberg.org/fediverse/fep/src/branch/main/fep/b2b8/fep-b2b8.md#sensitive
424457
* @see https://www.dublincore.org/specifications/dublin-core/dcmi-terms/
425458
*
426-
* @var array
459+
* @var array|null
427460
*/
428461
protected $dcterms;
429462

463+
/**
464+
* Interaction policy is an attempt to limit the harmful effects of unwanted replies and
465+
* other interactions on a user's posts (e.g., "reply guys").
466+
*
467+
* It is also used by Mastodon to limit the ability to quote posts.
468+
*
469+
* @see https://docs.gotosocial.org/en/latest/federation/interaction_policy/
470+
* @see https://blog.joinmastodon.org/2025/09/introducing-quote-posts/
471+
*
472+
* @var array|null
473+
*/
474+
protected $interaction_policy;
475+
430476
/**
431477
* Generic getter.
432478
*

0 commit comments

Comments
 (0)