PluginProbe
ActivityPub / 0.7.3
ActivityPub v0.7.3
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
← All changes | includes/rest/class-inbox.php +127 -384 1.2.0 → 0.7.3 View file →
@@ -1,18 +1,7 @@
1 1 <?php
2 2 namespace Activitypub\Rest;
3 3
4 -use WP_Error;
5 -use WP_REST_Server;
6 -use WP_REST_Response;
7 -use Activitypub\Activity\Activity;
8 -use Activitypub\Collection\Users as User_Collection;
9 -
10 -use function Activitypub\get_context;
11 -use function Activitypub\url_to_authorid;
12 -use function Activitypub\get_rest_url_by_path;
13 -use function Activitypub\get_remote_metadata_by_actor;
14 -
15 4 /**
16 5 * ActivityPub Inbox REST-Class
17 6 *
18 7 * @author Matthias Pfefferle
@@ -23,11 +12,15 @@
23 12 /**
24 13 * Initialize the class, registering WordPress hooks
25 14 */
26 15 public static function init() {
27 - self::register_routes();
28 -
29 - \add_action( 'activitypub_inbox_create', array( self::class, 'handle_create' ), 10, 2 );
16 + add_action( 'rest_api_init', array( '\Activitypub\Rest\Inbox', 'register_routes' ) );
17 + //add_filter( 'rest_pre_serve_request', array( '\Activitypub\Rest\Inbox', 'serve_request' ), 11, 4 );
18 + add_action( 'activitypub_inbox_follow', array( '\Activitypub\Rest\Inbox', 'handle_follow' ), 10, 2 );
19 + add_action( 'activitypub_inbox_unfollow', array( '\Activitypub\Rest\Inbox', 'handle_unfollow' ), 10, 2 );
20 + //add_action( 'activitypub_inbox_like', array( '\Activitypub\Rest\Inbox', 'handle_reaction' ), 10, 2 );
21 + //add_action( 'activitypub_inbox_announce', array( '\Activitypub\Rest\Inbox', 'handle_reaction' ), 10, 2 );
22 + add_action( 'activitypub_inbox_create', array( '\Activitypub\Rest\Inbox', 'handle_create' ), 10, 2 );
30 23 }
31 24
32 25 /**
33 26 * Register routes
@@ -32,164 +25,98 @@
32 25 /**
33 26 * Register routes
34 27 */
35 28 public static function register_routes() {
36 - \register_rest_route(
37 - ACTIVITYPUB_REST_NAMESPACE,
38 - '/inbox',
39 - array(
29 + register_rest_route(
30 + 'activitypub/1.0', '/inbox', array(
40 31 array(
41 - 'methods' => WP_REST_Server::CREATABLE,
42 - 'callback' => array( self::class, 'shared_inbox_post' ),
43 - 'args' => self::shared_inbox_post_parameters(),
44 - 'permission_callback' => '__return_true',
32 + 'methods' => \WP_REST_Server::EDITABLE,
33 + 'callback' => array( '\Activitypub\Rest\Inbox', 'global_inbox' ),
45 34 ),
46 35 )
47 36 );
48 37
49 - \register_rest_route(
50 - ACTIVITYPUB_REST_NAMESPACE,
51 - '/users/(?P<user_id>[\w\-\.]+)/inbox',
52 - array(
38 + register_rest_route(
39 + 'activitypub/1.0', '/users/(?P<id>\d+)/inbox', array(
53 40 array(
54 - 'methods' => WP_REST_Server::CREATABLE,
55 - 'callback' => array( self::class, 'user_inbox_post' ),
56 - 'args' => self::user_inbox_post_parameters(),
57 - 'permission_callback' => '__return_true',
41 + 'methods' => \WP_REST_Server::EDITABLE,
42 + 'callback' => array( '\Activitypub\Rest\Inbox', 'user_inbox' ),
43 + 'args' => self::request_parameters(),
58 44 ),
59 - array(
60 - 'methods' => WP_REST_Server::READABLE,
61 - 'callback' => array( self::class, 'user_inbox_get' ),
62 - 'args' => self::user_inbox_get_parameters(),
63 - 'permission_callback' => '__return_true',
64 - ),
65 45 )
66 46 );
67 47 }
68 48
69 49 /**
70 - * Renders the user-inbox
50 + * Hooks into the REST API request to verify the signature.
71 51 *
72 - * @param WP_REST_Request $request
73 - * @return WP_REST_Response
52 + * @param bool $served Whether the request has already been served.
53 + * @param WP_HTTP_ResponseInterface $result Result to send to the client. Usually a WP_REST_Response.
54 + * @param WP_REST_Request $request Request used to generate the response.
55 + * @param WP_REST_Server $server Server instance.
56 + *
57 + * @return true
74 58 */
75 - public static function user_inbox_get( $request ) {
76 - $user_id = $request->get_param( 'user_id' );
77 - $user = User_Collection::get_by_various( $user_id );
59 + public static function serve_request( $served, $result, $request, $server ) {
60 + if ( '/activitypub' !== substr( $request->get_route(), 0, 12 ) ) {
61 + return $served;
62 + }
78 63
79 - if ( is_wp_error( $user ) ) {
80 - return $user;
64 + if ( 'POST' !== $request->get_method() ) {
65 + return $served;
81 66 }
82 67
83 - $page = $request->get_param( 'page', 0 );
68 + $signature = $request->get_header( 'signature' );
84 69
85 - /*
86 - * Action triggerd prior to the ActivityPub profile being created and sent to the client
87 - */
88 - \do_action( 'activitypub_rest_inbox_pre' );
70 + if ( ! $signature ) {
71 + return $served;
72 + }
89 73
90 - $json = new \stdClass();
74 + $headers = $request->get_headers();
91 75
92 - $json->{'@context'} = get_context();
93 - $json->id = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user->get__id() ) );
94 - $json->generator = 'http://wordpress.org/?v=' . \get_bloginfo_rss( 'version' );
95 - $json->type = 'OrderedCollectionPage';
96 - $json->partOf = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user->get__id() ) ); // phpcs:ignore
76 + //\Activitypub\Signature::verify_signature( $headers, $key );
97 77
98 - $json->totalItems = 0; // phpcs:ignore
99 -
100 - $json->orderedItems = array(); // phpcs:ignore
101 -
102 - $json->first = $json->partOf; // phpcs:ignore
103 -
104 - // filter output
105 - $json = \apply_filters( 'activitypub_rest_inbox_array', $json );
106 -
107 - /*
108 - * Action triggerd after the ActivityPub profile has been created and sent to the client
109 - */
110 - \do_action( 'activitypub_inbox_post' );
111 -
112 - $rest_response = new WP_REST_Response( $json, 200 );
113 - $rest_response->header( 'Content-Type', 'application/activity+json; charset=' . get_option( 'blog_charset' ) );
114 -
115 - return $rest_response;
78 + return $served;
116 79 }
117 80
118 81 /**
119 - * Handles user-inbox requests
82 + * Renders the user-inbox
120 83 *
121 84 * @param WP_REST_Request $request
122 85 *
123 86 * @return WP_REST_Response
124 87 */
125 - public static function user_inbox_post( $request ) {
126 - $user_id = $request->get_param( 'user_id' );
127 - $user = User_Collection::get_by_various( $user_id );
88 + public static function user_inbox( $request ) {
89 + $author_id = $request->get_param( 'id' );
90 + $author = get_user_by( 'ID', $author_id );
128 91
129 - if ( is_wp_error( $user ) ) {
130 - return $user;
92 + $data = json_decode( $request->get_body(), true );
93 +
94 + $type = 'create';
95 + if ( ! empty( $data['type'] ) ) {
96 + $type = strtolower( $data['type'] );
131 97 }
132 98
133 - $data = $request->get_json_params();
134 - $type = $request->get_param( 'type' );
135 - $type = \strtolower( $type );
99 + if ( ! is_array( $data ) || ! array_key_exists( 'type', $data ) ) {
100 + return new \WP_Error( 'rest_invalid_data', __( 'Invalid payload', 'activitypub' ), array( 'status' => 422 ) );
101 + }
136 102
137 - \do_action( 'activitypub_inbox', $data, $user->get__id(), $type );
138 - \do_action( "activitypub_inbox_{$type}", $data, $user->get__id() );
103 + do_action( 'activitypub_inbox', $data, $author_id, $type );
104 + do_action( "activitypub_inbox_{$type}", $data, $author_id );
139 105
140 - $rest_response = new WP_REST_Response( array(), 202 );
141 - $rest_response->header( 'Content-Type', 'application/activity+json; charset=' . get_option( 'blog_charset' ) );
142 -
143 - return $rest_response;
106 + return new \WP_REST_Response( array(), 202 );
144 107 }
145 108
146 109 /**
147 110 * The shared inbox
148 111 *
149 - * @param WP_REST_Request $request
112 + * @param [type] $request [description]
150 113 *
151 - * @return WP_REST_Response
114 + * @return WP_Error not yet implemented
152 115 */
153 - public static function shared_inbox_post( $request ) {
154 - $data = $request->get_json_params();
155 - $type = $request->get_param( 'type' );
156 - $users = self::extract_recipients( $data );
157 -
158 - if ( ! $users ) {
159 - return new WP_Error(
160 - 'rest_invalid_param',
161 - \__( 'No recipients found', 'activitypub' ),
162 - array(
163 - 'status' => 400,
164 - 'params' => array(
165 - 'to' => \__( 'Please check/validate "to" field', 'activitypub' ),
166 - 'bto' => \__( 'Please check/validate "bto" field', 'activitypub' ),
167 - 'cc' => \__( 'Please check/validate "cc" field', 'activitypub' ),
168 - 'bcc' => \__( 'Please check/validate "bcc" field', 'activitypub' ),
169 - 'audience' => \__( 'Please check/validate "audience" field', 'activitypub' ),
170 - ),
171 - )
172 - );
173 - }
174 -
175 - foreach ( $users as $user ) {
176 - $user = User_Collection::get_by_various( $user );
177 -
178 - if ( is_wp_error( $user ) ) {
179 - continue;
180 - }
181 -
182 - $type = \strtolower( $type );
183 -
184 - \do_action( 'activitypub_inbox', $data, $user->ID, $type );
185 - \do_action( "activitypub_inbox_{$type}", $data, $user->ID );
186 - }
187 -
188 - $rest_response = new WP_REST_Response( array(), 202 );
189 - $rest_response->header( 'Content-Type', 'application/activity+json; charset=' . get_option( 'blog_charset' ) );
190 -
191 - return $rest_response;
116 + public static function global_inbox( $request ) {
117 + // Create the response object
118 + return new \WP_Error( 'rest_not_implemented', __( 'This method is not yet implemented', 'activitypub' ), array( 'status' => 501 ) );
192 119 }
193 120
194 121 /**
195 122 * The supported parameters
@@ -195,9 +122,9 @@
195 122 * The supported parameters
196 123 *
197 124 * @return array list of parameters
198 125 */
199 - public static function user_inbox_get_parameters() {
126 + public static function request_parameters() {
200 127 $params = array();
201 128
202 129 $params['page'] = array(
203 130 'type' => 'integer',
@@ -202,11 +129,11 @@
202 129 $params['page'] = array(
203 130 'type' => 'integer',
204 131 );
205 132
206 - $params['user_id'] = array(
133 + $params['id'] = array(
207 134 'required' => true,
208 - 'type' => 'string',
135 + 'type' => 'integer',
209 136 );
210 137
211 138 return $params;
212 139 }
@@ -211,304 +138,120 @@
211 138 return $params;
212 139 }
213 140
214 141 /**
215 - * The supported parameters
142 + * Handles "Follow" requests
216 143 *
217 - * @return array list of parameters
144 + * @param array $object The activity-object
145 + * @param int $user_id The id of the local blog-user
218 146 */
219 - public static function user_inbox_post_parameters() {
220 - $params = array();
147 + public static function handle_follow( $object, $user_id ) {
148 + if ( ! array_key_exists( 'actor', $object ) ) {
149 + return new \WP_Error( 'activitypub_no_actor', __( 'No "Actor" found', 'activitypub' ), $metadata );
150 + }
221 151
222 - $params['page'] = array(
223 - 'type' => 'integer',
224 - );
152 + // save follower
153 + \Activitypub\Db\Followers::add_follower( $object['actor'], $user_id );
225 154
226 - $params['user_id'] = array(
227 - 'required' => true,
228 - 'type' => 'string',
229 - );
155 + // get inbox
156 + $inbox = \Activitypub\get_inbox_by_actor( $object['actor'] );
230 157
231 - $params['id'] = array(
232 - 'required' => true,
233 - 'sanitize_callback' => 'esc_url_raw',
234 - );
158 + // send "Accept" activity
159 + $activity = new \Activitypub\Activity( 'Accept', \Activitypub\Activity::TYPE_SIMPLE );
160 + $activity->set_object( $object );
161 + $activity->set_actor( get_author_posts_url( $user_id ) );
162 + $activity->set_to( $object['actor'] );
163 + $activity->set_id( get_author_posts_url( $user_id ) . '#follow' . preg_replace( '~^https?://~', '', $object['actor'] ) );
235 164
236 - $params['actor'] = array(
237 - 'required' => true,
238 - 'sanitize_callback' => function( $param, $request, $key ) {
239 - if ( ! \is_string( $param ) ) {
240 - $param = $param['id'];
241 - }
242 - return \esc_url_raw( $param );
243 - },
244 - );
165 + $activity = $activity->to_simple_json();
245 166
246 - $params['type'] = array(
247 - 'required' => true,
248 - //'type' => 'enum',
249 - //'enum' => array( 'Create' ),
250 - //'sanitize_callback' => function( $param, $request, $key ) {
251 - // return \strtolower( $param );
252 - //},
253 - );
254 -
255 - $params['object'] = array(
256 - 'required' => true,
257 - );
258 -
259 - return $params;
167 + $response = \Activitypub\safe_remote_post( $inbox, $activity, $user_id );
260 168 }
261 169
262 170 /**
263 - * The supported parameters
171 + * Handles "Unfollow" requests
264 172 *
265 - * @return array list of parameters
173 + * @param array $object The activity-object
174 + * @param int $user_id The id of the local blog-user
266 175 */
267 - public static function shared_inbox_post_parameters() {
268 - $params = array();
176 + public static function handle_unfollow( $object, $user_id ) {
177 + if ( ! array_key_exists( 'actor', $object ) ) {
178 + return new \WP_Error( 'activitypub_no_actor', __( 'No "Actor" found', 'activitypub' ), $metadata );
179 + }
269 180
270 - $params['page'] = array(
271 - 'type' => 'integer',
272 - );
273 -
274 - $params['id'] = array(
275 - 'required' => true,
276 - 'type' => 'string',
277 - 'sanitize_callback' => 'esc_url_raw',
278 - );
279 -
280 - $params['actor'] = array(
281 - 'required' => true,
282 - //'type' => array( 'object', 'string' ),
283 - 'sanitize_callback' => function( $param, $request, $key ) {
284 - if ( ! \is_string( $param ) ) {
285 - $param = $param['id'];
286 - }
287 - return \esc_url_raw( $param );
288 - },
289 - );
290 -
291 - $params['type'] = array(
292 - 'required' => true,
293 - //'type' => 'enum',
294 - //'enum' => array( 'Create' ),
295 - //'sanitize_callback' => function( $param, $request, $key ) {
296 - // return \strtolower( $param );
297 - //},
298 - );
299 -
300 - $params['object'] = array(
301 - 'required' => true,
302 - //'type' => 'object',
303 - );
304 -
305 - $params['to'] = array(
306 - 'required' => false,
307 - 'sanitize_callback' => function( $param, $request, $key ) {
308 - if ( \is_string( $param ) ) {
309 - $param = array( $param );
310 - }
311 -
312 - return $param;
313 - },
314 - );
315 -
316 - $params['cc'] = array(
317 - 'sanitize_callback' => function( $param, $request, $key ) {
318 - if ( \is_string( $param ) ) {
319 - $param = array( $param );
320 - }
321 -
322 - return $param;
323 - },
324 - );
325 -
326 - $params['bcc'] = array(
327 - 'sanitize_callback' => function( $param, $request, $key ) {
328 - if ( \is_string( $param ) ) {
329 - $param = array( $param );
330 - }
331 -
332 - return $param;
333 - },
334 - );
335 -
336 - return $params;
181 + \Activitypub\Db\Followers::remove_follower( $object['actor'], $user_id );
337 182 }
338 183
339 184 /**
340 - * Handles "Create" requests
185 + * Handles "Unfollow" requests
341 186 *
342 187 * @param array $object The activity-object
343 188 * @param int $user_id The id of the local blog-user
344 189 */
345 - public static function handle_create( $object, $user_id ) {
346 - $meta = get_remote_metadata_by_actor( $object['actor'] );
347 -
348 - if ( ! isset( $object['object']['inReplyTo'] ) ) {
349 - return;
190 + public static function handle_reaction( $object, $user_id ) {
191 + if ( ! array_key_exists( 'actor', $object ) ) {
192 + return new \WP_Error( 'activitypub_no_actor', __( 'No "Actor" found', 'activitypub' ), $metadata );
350 193 }
351 194
352 - // check if Activity is public or not
353 - if ( ! self::is_activity_public( $object ) ) {
354 - // @todo maybe send email
355 - return;
356 - }
195 + $meta = \Activitypub\get_remote_metadata_by_actor( $object['actor'] );
357 196
358 - $comment_post_id = \url_to_postid( $object['object']['inReplyTo'] );
359 -
360 - // save only replys and reactions
361 - if ( ! $comment_post_id ) {
362 - return false;
363 - }
364 -
365 197 $commentdata = array(
366 - 'comment_post_ID' => $comment_post_id,
367 - 'comment_author' => \esc_attr( $meta['name'] ),
368 - 'comment_author_url' => \esc_url_raw( $object['actor'] ),
369 - 'comment_content' => addslashes( \wp_kses( $object['object']['content'], 'pre_comment_content' ) ),
370 - 'comment_type' => 'comment',
198 + 'comment_post_ID' => url_to_postid( $object['object'] ),
199 + 'comment_author' => esc_attr( $meta['name'] ),
371 200 'comment_author_email' => '',
201 + 'comment_author_url' => esc_url_raw( $object['actor'] ),
202 + 'comment_content' => esc_url_raw( $object['actor'] ),
203 + 'comment_type' => esc_attr( strtolower( $object['type'] ) ),
372 204 'comment_parent' => 0,
373 205 'comment_meta' => array(
374 - 'source_url' => \esc_url_raw( $object['object']['url'] ),
375 - 'avatar_url' => \esc_url_raw( $meta['icon']['url'] ),
206 + 'source_url' => esc_url_raw( $object['id'] ),
207 + 'avatar_url' => esc_url_raw( $meta['icon']['url'] ),
376 208 'protocol' => 'activitypub',
377 209 ),
378 210 );
379 211
380 212 // disable flood control
381 - \remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
213 + remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
382 214
383 - // do not require email for AP entries
384 - \add_filter( 'pre_option_require_name_email', '__return_false' );
215 + $state = wp_new_comment( $commentdata, true );
385 216
386 - // No nonce possible for this submission route
387 - \add_filter(
388 - 'akismet_comment_nonce',
389 - function() {
390 - return 'inactive';
391 - }
392 - );
393 -
394 - \add_filter( 'wp_kses_allowed_html', array( self::class, 'allowed_comment_html' ), 10, 2 );
395 -
396 - $state = \wp_new_comment( $commentdata, true );
397 -
398 - \remove_filter( 'wp_kses_allowed_html', array( self::class, 'allowed_comment_html' ) );
399 - \remove_filter( 'pre_option_require_name_email', '__return_false' );
400 -
401 217 // re-add flood control
402 - \add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
403 -
404 - do_action( 'activitypub_handled_create', $object, $user_id, $state, $commentdata );
218 + add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
405 219 }
406 220
407 221 /**
408 - * Extract recipient URLs from Activity object
222 + * Handles "Unfollow" requests
409 223 *
410 - * @param array $data
411 - *
412 - * @return array The list of user URLs
224 + * @param array $object The activity-object
225 + * @param int $user_id The id of the local blog-user
413 226 */
414 - public static function extract_recipients( $data ) {
415 - $recipient_items = array();
416 -
417 - foreach ( array( 'to', 'bto', 'cc', 'bcc', 'audience' ) as $i ) {
418 - if ( array_key_exists( $i, $data ) ) {
419 - if ( is_array( $data[ $i ] ) ) {
420 - $recipient = $data[ $i ];
421 - } else {
422 - $recipient = array( $data[ $i ] );
423 - }
424 - $recipient_items = array_merge( $recipient_items, $recipient );
425 - }
426 -
427 - if ( is_array( $data['object'] ) && array_key_exists( $i, $data['object'] ) ) {
428 - if ( is_array( $data['object'][ $i ] ) ) {
429 - $recipient = $data['object'][ $i ];
430 - } else {
431 - $recipient = array( $data['object'][ $i ] );
432 - }
433 - $recipient_items = array_merge( $recipient_items, $recipient );
434 - }
227 + public static function handle_create( $object, $user_id ) {
228 + if ( ! array_key_exists( 'actor', $object ) ) {
229 + return new \WP_Error( 'activitypub_no_actor', __( 'No "Actor" found', 'activitypub' ), $metadata );
435 230 }
436 231
437 - $recipients = array();
232 + $meta = \Activitypub\get_remote_metadata_by_actor( $object['actor'] );
438 233
439 - // flatten array
440 - foreach ( $recipient_items as $recipient ) {
441 - if ( is_array( $recipient ) ) {
442 - // check if recipient is an object
443 - if ( array_key_exists( 'id', $recipient ) ) {
444 - $recipients[] = $recipient['id'];
445 - }
446 - } else {
447 - $recipients[] = $recipient;
448 - }
449 - }
234 + $commentdata = array(
235 + 'comment_post_ID' => url_to_postid( $object['object']['inReplyTo'] ),
236 + 'comment_author' => esc_attr( $meta['name'] ),
237 + 'comment_author_url' => esc_url_raw( $object['actor'] ),
238 + 'comment_content' => wp_filter_kses( $object['object']['content'] ),
239 + 'comment_type' => '',
240 + 'comment_author_email' => '',
241 + 'comment_parent' => 0,
242 + 'comment_meta' => array(
243 + 'source_url' => esc_url_raw( $object['object']['url'] ),
244 + 'avatar_url' => esc_url_raw( $meta['icon']['url'] ),
245 + 'protocol' => 'activitypub',
246 + ),
247 + );
450 248
451 - return array_unique( $recipients );
452 - }
249 + // disable flood control
250 + remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
453 251
454 - /**
455 - * Get local user recipients
456 - *
457 - * @param array $data
458 - *
459 - * @return array The list of local users
460 - */
461 - public static function get_recipients( $data ) {
462 - $recipients = self::extract_recipients( $data );
463 - $users = array();
252 + $state = wp_new_comment( $commentdata, true );
464 253
465 - foreach ( $recipients as $recipient ) {
466 - $user_id = url_to_authorid( $recipient );
467 -
468 - $user = get_user_by( 'id', $user_id );
469 -
470 - if ( $user ) {
471 - $users[] = $user;
472 - }
473 - }
474 -
475 - return $users;
476 - }
477 -
478 - /**
479 - * Check if passed Activity is Public
480 - *
481 - * @param array $data
482 - * @return boolean
483 - */
484 - public static function is_activity_public( $data ) {
485 - $recipients = self::extract_recipients( $data );
486 -
487 - return in_array( 'https://www.w3.org/ns/activitystreams#Public', $recipients, true );
488 - }
489 -
490 - /**
491 - * Adds line breaks to the list of allowed comment tags.
492 - *
493 - * @param array $allowedtags Allowed HTML tags.
494 - * @param string $context Context.
495 - * @return array Filtered tag list.
496 - */
497 - public static function allowed_comment_html( $allowedtags, $context = '' ) {
498 - if ( 'pre_comment_content' !== $context ) {
499 - // Do nothing.
500 - return $allowedtags;
501 - }
502 -
503 - // Add `p` and `br` to the list of allowed tags.
504 - if ( ! array_key_exists( 'br', $allowedtags ) ) {
505 - $allowedtags['br'] = array();
506 - }
507 -
508 - if ( ! array_key_exists( 'p', $allowedtags ) ) {
509 - $allowedtags['p'] = array();
510 - }
511 -
512 - return $allowedtags;
254 + // re-add flood control
255 + add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
513 256 }
514 257 }