From addd7dd8a1d170fe4b9ee1b10338acfaa062936d Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 21 Sep 2023 16:26:17 +0200 Subject: [PATCH] better handling when data is missing (#444) * better handling when data is missing * WP_Error: add translation key and status * do not use cache for cleanup and update * better queries --- includes/activity/class-base-object.php | 16 ++++++-- includes/class-scheduler.php | 4 +- includes/collection/class-followers.php | 50 +++++++++++++++++++++++-- includes/functions.php | 11 ++++++ 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/includes/activity/class-base-object.php b/includes/activity/class-base-object.php index 3b6703b..b830229 100644 --- a/includes/activity/class-base-object.php +++ b/includes/activity/class-base-object.php @@ -450,7 +450,7 @@ class Base_Object { if ( \strncasecmp( $method, 'get', 3 ) === 0 ) { if ( ! $this->has( $var ) ) { - return new WP_Error( 'invalid_key', 'Invalid key' ); + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) ); } return $this->$var; @@ -492,7 +492,7 @@ class Base_Object { */ public function get( $key ) { if ( ! $this->has( $key ) ) { - return new WP_Error( 'invalid_key', 'Invalid key' ); + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) ); } return call_user_func( array( $this, 'get_' . $key ) ); @@ -519,7 +519,7 @@ class Base_Object { */ public function set( $key, $value ) { if ( ! $this->has( $key ) ) { - return new WP_Error( 'invalid_key', 'Invalid key' ); + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) ); } $this->$key = $value; @@ -537,7 +537,7 @@ class Base_Object { */ public function add( $key, $value ) { if ( ! $this->has( $key ) ) { - return new WP_Error( 'invalid_key', 'Invalid key' ); + return new WP_Error( 'invalid_key', __( 'Invalid key', 'activitypub' ), array( 'status' => 404 ) ); } if ( ! isset( $this->$key ) ) { @@ -562,6 +562,10 @@ class Base_Object { public static function init_from_json( $json ) { $array = \json_decode( $json, true ); + if ( ! is_array( $array ) ) { + $array = array(); + } + return self::init_from_array( $array ); } @@ -573,6 +577,10 @@ class Base_Object { * @return \Activitypub\Activity\Base_Object An Object built from the JSON string. */ public static function init_from_array( $array ) { + if ( ! is_array( $array ) ) { + return new WP_Error( 'invalid_array', __( 'Invalid array', 'activitypub' ), array( 'status' => 404 ) ); + } + $object = new static(); foreach ( $array as $key => $value ) { diff --git a/includes/class-scheduler.php b/includes/class-scheduler.php index b3eca5d..e7f2bd7 100644 --- a/includes/class-scheduler.php +++ b/includes/class-scheduler.php @@ -108,7 +108,7 @@ class Scheduler { $followers = Followers::get_outdated_followers(); foreach ( $followers as $follower ) { - $meta = get_remote_metadata_by_actor( $follower->get_url(), true ); + $meta = get_remote_metadata_by_actor( $follower->get_url(), false ); if ( empty( $meta ) || ! is_array( $meta ) || is_wp_error( $meta ) ) { Followers::add_error( $follower->get__id(), $meta ); @@ -128,7 +128,7 @@ class Scheduler { $followers = Followers::get_faulty_followers(); foreach ( $followers as $follower ) { - $meta = get_remote_metadata_by_actor( $follower->get_url(), true ); + $meta = get_remote_metadata_by_actor( $follower->get_url(), false ); if ( is_tombstone( $meta ) ) { $follower->delete(); diff --git a/includes/collection/class-followers.php b/includes/collection/class-followers.php index ed7105d..a9fe298 100644 --- a/includes/collection/class-followers.php +++ b/includes/collection/class-followers.php @@ -361,7 +361,17 @@ class Followers { public static function get_all_followers() { $args = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array(), + 'meta_query' => array( + 'relation' => 'AND', + array( + 'key' => 'activitypub_inbox', + 'compare' => 'EXISTS', + ), + array( + 'key' => 'activitypub_actor_json', + 'compare' => 'EXISTS', + ), + ), ); return self::get_followers( null, null, null, $args ); } @@ -380,10 +390,19 @@ class Followers { 'fields' => 'ids', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 'meta_query' => array( + 'relation' => 'AND', array( 'key' => 'activitypub_user_id', 'value' => $user_id, ), + array( + 'key' => 'activitypub_inbox', + 'compare' => 'EXISTS', + ), + array( + 'key' => 'activitypub_actor_json', + 'compare' => 'EXISTS', + ), ), ) ); @@ -413,6 +432,7 @@ class Followers { 'fields' => 'ids', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 'meta_query' => array( + 'relation' => 'AND', array( 'key' => 'activitypub_inbox', 'compare' => 'EXISTS', @@ -421,6 +441,11 @@ class Followers { 'key' => 'activitypub_user_id', 'value' => $user_id, ), + array( + 'key' => 'activitypub_inbox', + 'value' => '', + 'compare' => '!=', + ), ), ) ); @@ -463,7 +488,7 @@ class Followers { 'post_type' => self::POST_TYPE, 'posts_per_page' => $number, 'orderby' => 'modified', - 'order' => 'DESC', + 'order' => 'ASC', 'post_status' => 'any', // 'any' includes 'trash 'date_query' => array( array( @@ -491,16 +516,35 @@ class Followers { * * @return mixed The Term list of Followers, the format depends on $output. */ - public static function get_faulty_followers( $number = 10 ) { + public static function get_faulty_followers( $number = 20 ) { $args = array( 'post_type' => self::POST_TYPE, 'posts_per_page' => $number, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 'meta_query' => array( + 'relation' => 'OR', array( 'key' => 'activitypub_errors', 'compare' => 'EXISTS', ), + array( + 'key' => 'activitypub_inbox', + 'compare' => 'NOT EXISTS', + ), + array( + 'key' => 'activitypub_actor_json', + 'compare' => 'NOT EXISTS', + ), + array( + 'key' => 'activitypub_inbox', + 'value' => '', + 'compare' => '=', + ), + array( + 'key' => 'activitypub_actor_json', + 'value' => '', + 'compare' => '=', + ), ), ); diff --git a/includes/functions.php b/includes/functions.php index 0c3bd87..cafe9a4 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -476,3 +476,14 @@ function site_supports_blocks() { */ return apply_filters( 'activitypub_site_supports_blocks', true ); } + +/** + * Check if data is valid JSON. + * + * @param string $data The data to check. + * + * @return boolean True if the data is JSON, false otherwise. + */ +function is_json( $data ) { + return \is_array( \json_decode( $data, true ) ) ? true : false; +}