PluginProbe
ActivityPub / 5.7.0
ActivityPub v5.7.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 / handler / class-delete.php

class-delete.php in ActivityPub 5.7.0, at includes/handler/class-delete.php

197 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Delete handler file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Handler;
9
10 use WP_REST_Request;
11 use Activitypub\Http;
12 use Activitypub\Collection\Followers;
13 use Activitypub\Collection\Interactions;
14
15 use function Activitypub\object_to_uri;
16
17 /**
18 * Handles Delete requests.
19 */
20 class Delete {
21 /**
22 * Initialize the class, registering WordPress hooks.
23 */
24 public static function init() {
25 \add_action( 'activitypub_inbox_delete', array( self::class, 'handle_delete' ) );
26 \add_filter( 'activitypub_defer_signature_verification', array( self::class, 'defer_signature_verification' ), 10, 2 );
27 \add_action( 'activitypub_delete_actor_interactions', array( self::class, 'delete_interactions' ) );
28 \add_filter( 'activitypub_get_outbox_activity', array( self::class, 'outbox_activity' ) );
29 }
30
31 /**
32 * Handles "Delete" requests.
33 *
34 * @param array $activity The delete activity.
35 */
36 public static function handle_delete( $activity ) {
37 $object_type = isset( $activity['object']['type'] ) ? $activity['object']['type'] : '';
38
39 switch ( $object_type ) {
40 /*
41 * Actor Types.
42 *
43 * @see https://www.w3.org/TR/activitystreams-vocabulary/#actor-types
44 */
45 case 'Person':
46 case 'Group':
47 case 'Organization':
48 case 'Service':
49 case 'Application':
50 self::maybe_delete_follower( $activity );
51 break;
52
53 /*
54 * Object and Link Types.
55 *
56 * @see https://www.w3.org/TR/activitystreams-vocabulary/#object-types
57 */
58 case 'Note':
59 case 'Article':
60 case 'Image':
61 case 'Audio':
62 case 'Video':
63 case 'Event':
64 case 'Document':
65 self::maybe_delete_interaction( $activity );
66 break;
67
68 /*
69 * Tombstone Type.
70 *
71 * @see: https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tombstone
72 */
73 case 'Tombstone':
74 self::maybe_delete_interaction( $activity );
75 break;
76
77 /*
78 * Minimal Activity.
79 *
80 * @see https://www.w3.org/TR/activitystreams-core/#example-1
81 */
82 default:
83 // Ignore non Minimal Activities.
84 if ( ! is_string( $activity['object'] ) ) {
85 return;
86 }
87
88 // Check if Object is an Actor.
89 if ( $activity['actor'] === $activity['object'] ) {
90 self::maybe_delete_follower( $activity );
91 } else { // Assume an interaction otherwise.
92 self::maybe_delete_interaction( $activity );
93 }
94 // Maybe handle Delete Activity for other Object Types.
95 break;
96 }
97 }
98
99 /**
100 * Delete a Follower if Actor-URL is a Tombstone.
101 *
102 * @param array $activity The delete activity.
103 */
104 public static function maybe_delete_follower( $activity ) {
105 /* @var \Activitypub\Model\Follower $follower Follower object. */
106 $follower = Followers::get_follower_by_actor( $activity['actor'] );
107
108 // Verify that Actor is deleted.
109 if ( $follower && Http::is_tombstone( $activity['actor'] ) ) {
110 $follower->delete();
111 self::maybe_delete_interactions( $activity );
112 }
113 }
114
115 /**
116 * Delete Reactions if Actor-URL is a Tombstone.
117 *
118 * @param array $activity The delete activity.
119 */
120 public static function maybe_delete_interactions( $activity ) {
121 // Verify that Actor is deleted.
122 if ( Http::is_tombstone( $activity['actor'] ) ) {
123 \wp_schedule_single_event(
124 \time(),
125 'activitypub_delete_actor_interactions',
126 array( $activity['actor'] )
127 );
128 }
129 }
130
131 /**
132 * Delete comments from an Actor.
133 *
134 * @param string $actor The URL of the actor whose comments to delete.
135 */
136 public static function delete_interactions( $actor ) {
137 $comments = Interactions::get_interactions_by_actor( $actor );
138
139 foreach ( $comments as $comment ) {
140 wp_delete_comment( $comment, true );
141 }
142 }
143
144 /**
145 * Delete a Reaction if URL is a Tombstone.
146 *
147 * @param array $activity The delete activity.
148 */
149 public static function maybe_delete_interaction( $activity ) {
150 if ( is_array( $activity['object'] ) ) {
151 $id = $activity['object']['id'];
152 } else {
153 $id = $activity['object'];
154 }
155
156 $comments = Interactions::get_interaction_by_id( $id );
157
158 if ( $comments && Http::is_tombstone( $id ) ) {
159 foreach ( $comments as $comment ) {
160 wp_delete_comment( $comment->comment_ID, true );
161 }
162 }
163 }
164
165 /**
166 * Defer signature verification for `Delete` requests.
167 *
168 * @param bool $defer Whether to defer signature verification.
169 * @param WP_REST_Request $request The request object.
170 *
171 * @return bool Whether to defer signature verification.
172 */
173 public static function defer_signature_verification( $defer, $request ) {
174 $json = $request->get_json_params();
175
176 if ( isset( $json['type'] ) && 'Delete' === $json['type'] ) {
177 return true;
178 }
179
180 return false;
181 }
182
183 /**
184 * Set the object to the object ID.
185 *
186 * @param \Activitypub\Activity\Activity $activity The Activity object.
187 * @return \Activitypub\Activity\Activity The filtered Activity object.
188 */
189 public static function outbox_activity( $activity ) {
190 if ( 'Delete' === $activity->get_type() ) {
191 $activity->set_object( object_to_uri( $activity->get_object() ) );
192 }
193
194 return $activity;
195 }
196 }
197