PluginProbe
ActivityPub / 5.5.0
ActivityPub v5.5.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.5.0, at includes/handler/class-delete.php

199 lines 5.0 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 if ( is_array( $comments ) ) {
140 foreach ( $comments as $comment ) {
141 wp_delete_comment( $comment->comment_ID, true );
142 }
143 }
144 }
145
146 /**
147 * Delete a Reaction if URL is a Tombstone.
148 *
149 * @param array $activity The delete activity.
150 */
151 public static function maybe_delete_interaction( $activity ) {
152 if ( is_array( $activity['object'] ) ) {
153 $id = $activity['object']['id'];
154 } else {
155 $id = $activity['object'];
156 }
157
158 $comments = Interactions::get_interaction_by_id( $id );
159
160 if ( $comments && Http::is_tombstone( $id ) ) {
161 foreach ( $comments as $comment ) {
162 wp_delete_comment( $comment->comment_ID, true );
163 }
164 }
165 }
166
167 /**
168 * Defer signature verification for `Delete` requests.
169 *
170 * @param bool $defer Whether to defer signature verification.
171 * @param WP_REST_Request $request The request object.
172 *
173 * @return bool Whether to defer signature verification.
174 */
175 public static function defer_signature_verification( $defer, $request ) {
176 $json = $request->get_json_params();
177
178 if ( isset( $json['type'] ) && 'Delete' === $json['type'] ) {
179 return true;
180 }
181
182 return false;
183 }
184
185 /**
186 * Set the object to the object ID.
187 *
188 * @param \Activitypub\Activity\Activity $activity The Activity object.
189 * @return \Activitypub\Activity\Activity The filtered Activity object.
190 */
191 public static function outbox_activity( $activity ) {
192 if ( 'Delete' === $activity->get_type() ) {
193 $activity->set_object( object_to_uri( $activity->get_object() ) );
194 }
195
196 return $activity;
197 }
198 }
199