Refactor outbox parsing and add some debug logs
Some checks failed
PHP Code Checker / PHP Code Checker (pull_request) Failing after 45s
PHPUnit / PHPUnit – PHP 7.4 (pull_request) Failing after 57s
PHPUnit / PHPUnit – PHP 8.0 (pull_request) Failing after 57s
PHPUnit / PHPUnit – PHP 8.1 (pull_request) Failing after 56s
PHPUnit / PHPUnit – PHP 8.2 (pull_request) Failing after 51s
PHPUnit / PHPUnit – PHP 8.3 (pull_request) Failing after 55s
PHPUnit / PHPUnit – PHP 8.4 (pull_request) Failing after 52s
Some checks failed
PHP Code Checker / PHP Code Checker (pull_request) Failing after 45s
PHPUnit / PHPUnit – PHP 7.4 (pull_request) Failing after 57s
PHPUnit / PHPUnit – PHP 8.0 (pull_request) Failing after 57s
PHPUnit / PHPUnit – PHP 8.1 (pull_request) Failing after 56s
PHPUnit / PHPUnit – PHP 8.2 (pull_request) Failing after 51s
PHPUnit / PHPUnit – PHP 8.3 (pull_request) Failing after 55s
PHPUnit / PHPUnit – PHP 8.4 (pull_request) Failing after 52s
This commit is contained in:
parent
1eec93d342
commit
21d1ee9915
5 changed files with 165 additions and 91 deletions
|
@ -94,6 +94,7 @@ class Event_Source extends Actor {
|
|||
$actor = \json_decode( $actor_json, true );
|
||||
|
||||
if ( ! isset( $actor['outbox'] ) ) {
|
||||
\do_action( 'event_bridge_for_activitypub_write_log', array( "[ACTIVITYPUB] Did not find outbox URL for actor {$actor}" ) );
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,10 +57,56 @@ abstract class Base {
|
|||
|
||||
$post_id = $this->save_event();
|
||||
|
||||
$event_id = $activitypub_event['id'];
|
||||
|
||||
if ( $post_id ) {
|
||||
\do_action(
|
||||
'event_bridge_for_activitypub_write_log',
|
||||
array( "[ACTIVITYPUB] Processed incoming event {$event_id} from {$actor}" )
|
||||
);
|
||||
update_post_meta( $post_id, '_event_bridge_for_activitypub_is_remote_cached', true );
|
||||
update_post_meta( $post_id, '_event_bridge_for_activitypub_event_source', sanitize_url( $actor ) );
|
||||
update_post_meta( $post_id, 'activitypub_content_visibility', constant( 'ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL' ) ?? '' );
|
||||
} else {
|
||||
\do_action(
|
||||
'event_bridge_for_activitypub_write_log',
|
||||
array( "[ACTIVITYPUB] Failed processing incoming event {$event_id} from {$actor}" )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a local event in WordPress that is a cached remote one.
|
||||
*
|
||||
* @param int $activitypub_event_id The ActivityPub events ID.
|
||||
*/
|
||||
public function delete( $activitypub_event_id ) {
|
||||
$post_id = self::get_post_id_from_activitypub_id( $activitypub_event_id );
|
||||
|
||||
if ( ! $post_id ) {
|
||||
\do_action(
|
||||
'event_bridge_for_activitypub_write_log',
|
||||
array( "[ACTIVITYPUB] Received delete for event that is not cached locally {$activitypub_event_id}" )
|
||||
);
|
||||
return new WP_Error(
|
||||
'event_bridge_for_activitypub_remote_event_not_found',
|
||||
\__( 'Remote event not found in cache', 'event-bridge-for-activitypub' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$thumbnail_id = get_post_thumbnail_id( $post_id );
|
||||
|
||||
if ( $thumbnail_id && ! Event_Sources::is_attachment_featured_image( $thumbnail_id ) ) {
|
||||
wp_delete_attachment( $thumbnail_id, true );
|
||||
}
|
||||
|
||||
$result = wp_delete_post( $post_id, true );
|
||||
|
||||
if ( $result ) {
|
||||
\do_action( 'event_bridge_for_activitypub_write_log', array( "[ACTIVITYPUB] Deleted cached event {$activitypub_event_id}" ) );
|
||||
} else {
|
||||
\do_action( 'event_bridge_for_activitypub_write_log', array( "[ACTIVITYPUB] Failed deleting cached event {$activitypub_event_id}" ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,31 +322,6 @@ abstract class Base {
|
|||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a local event in WordPress that is a cached remote one.
|
||||
*
|
||||
* @param int $activitypub_event_id The ActivityPub events ID.
|
||||
*/
|
||||
public function delete( $activitypub_event_id ) {
|
||||
$post_id = self::get_post_id_from_activitypub_id( $activitypub_event_id );
|
||||
|
||||
if ( ! $post_id ) {
|
||||
return new WP_Error(
|
||||
'event_bridge_for_activitypub_remote_event_not_found',
|
||||
\__( 'Remote event not found in cache', 'event-bridge-for-activitypub' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$thumbnail_id = get_post_thumbnail_id( $post_id );
|
||||
|
||||
if ( $thumbnail_id && ! Event_Sources::is_attachment_featured_image( $thumbnail_id ) ) {
|
||||
wp_delete_attachment( $thumbnail_id, true );
|
||||
}
|
||||
|
||||
wp_delete_post( $post_id, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of revisions to keep.
|
||||
*
|
||||
|
|
38
includes/class-debug.php
Normal file
38
includes/class-debug.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* Class file for Debug Class.
|
||||
*
|
||||
* @package Event_Bridge_For_ActivityPub
|
||||
* @since 1.0.0
|
||||
* @license AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace Event_Bridge_For_ActivityPub;
|
||||
|
||||
/**
|
||||
* Debug Class.
|
||||
*
|
||||
* @package Event_Bridge_For_ActivityPub
|
||||
* @since 1.0.0
|
||||
* @license AGPL-3.0-or-later
|
||||
*/
|
||||
class Debug {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks.
|
||||
*/
|
||||
public static function init() {
|
||||
if ( defined( 'WP_DEBUG_LOG' ) && constant( 'WP_DEBUG_LOG' ) ) {
|
||||
\add_action( 'event_bridge_for_activitypub_write_log', array( self::class, 'write_log' ), 10, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a log entry.
|
||||
*
|
||||
* @param mixed $log The log entry.
|
||||
*/
|
||||
public static function write_log( $log ) {
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
||||
\error_log( \print_r( $log, true ) );
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
<?php
|
||||
/**
|
||||
* Class file for parsing an ActivityPub outbox for Events.
|
||||
*
|
||||
* The main external entry function is `backfill_events`.
|
||||
* The function `import_events_from_outbox` is used for delaying the parsing via schedules.
|
||||
*
|
||||
* @package Event_Bridge_For_ActivityPub
|
||||
* @since 1.0.0
|
||||
|
@ -14,6 +17,9 @@ use Event_Bridge_For_ActivityPub\ActivityPub\Model\Event_Source;
|
|||
|
||||
/**
|
||||
* Class for parsing an ActivityPub outbox for Events.
|
||||
*
|
||||
* The main external entry function is `backfill_events`.
|
||||
* The function `import_events_from_outbox` is used for delaying the parsing via schedules.
|
||||
*/
|
||||
class Outbox_Parser {
|
||||
/**
|
||||
|
@ -30,13 +36,81 @@ class Outbox_Parser {
|
|||
\add_action( 'event_bridge_for_activitypub_import_events_from_outbox', array( self::class, 'import_events_from_outbox' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the backfilling of events via the outbox of an ActivityPub actor.
|
||||
*
|
||||
* @param string $actor The ActivityPub ID of the actor which owns the outbox.
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public static function backfill_events( $actor ) {
|
||||
// Initiate parsing of outbox collection.
|
||||
$event_source = Event_Source::get_by_id( $actor );
|
||||
|
||||
if ( ! $event_source ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$outbox_url = $event_source->get_outbox();
|
||||
|
||||
if ( ! $outbox_url ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Schedule the import of events via the outbox.
|
||||
return self::queue_importing_from_outbox( $outbox_url, $actor, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import events from an outbox: OrderedCollection or OrderedCollectionPage.
|
||||
*
|
||||
* @param string $url The url of the current page or outbox.
|
||||
* @param string $actor The ActivityPub ID/URL of the actor that owns the outbox.
|
||||
* @return void
|
||||
*/
|
||||
public static function import_events_from_outbox( $url, $actor ) {
|
||||
$outbox = self::fetch_outbox( $url );
|
||||
|
||||
if ( ! $outbox ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_count = self::get_import_count( $actor );
|
||||
|
||||
if ( $current_count >= self::MAX_EVENTS_TO_IMPORT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Process orderedItems if they exist (non-paginated outbox).
|
||||
if ( isset( $outbox['orderedItems'] ) && is_array( $outbox['orderedItems'] ) ) {
|
||||
$current_count += self::import_events_from_items(
|
||||
$outbox['orderedItems'],
|
||||
$actor,
|
||||
self::MAX_EVENTS_TO_IMPORT - $current_count
|
||||
);
|
||||
}
|
||||
|
||||
self::update_import_count( $actor, $current_count );
|
||||
|
||||
// If the count is already exceeded abort here.
|
||||
if ( $current_count >= self::MAX_EVENTS_TO_IMPORT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get next page and if it exists schedule the import of next page.
|
||||
$pagination_url = self::get_pagination_url( $outbox );
|
||||
|
||||
if ( $pagination_url ) {
|
||||
self::queue_importing_from_outbox( $pagination_url, $actor );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an Activity is of type Update or Create.
|
||||
*
|
||||
* @param array $activity The Activity as associative array.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_create_or_update_activity( $activity ) {
|
||||
private static function is_create_or_update_activity( $activity ) {
|
||||
if ( ! isset( $activity['type'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -95,7 +169,7 @@ class Outbox_Parser {
|
|||
* @param int $limit The limit of how many events to save locally.
|
||||
* @return int The number of saved events (at least attempted).
|
||||
*/
|
||||
public static function import_events_from_items( $items, $actor, $limit = -1 ) {
|
||||
private static function import_events_from_items( $items, $actor, $limit = -1 ) {
|
||||
$events = self::parse_items_for_events( $items, $limit );
|
||||
|
||||
$transmogrifier = Setup::get_transmogrifier();
|
||||
|
@ -125,7 +199,7 @@ class Outbox_Parser {
|
|||
* @param int $delay The delay of the current time in seconds.
|
||||
* @return void
|
||||
*/
|
||||
public static function queue_importing_from_outbox( $url, $actor, $delay = 10 ) {
|
||||
private static function queue_importing_from_outbox( $url, $actor, $delay = 10 ) {
|
||||
$hook = 'event_bridge_for_activitypub_import_events_from_outbox';
|
||||
$args = array( $url, $actor );
|
||||
|
||||
|
@ -136,24 +210,6 @@ class Outbox_Parser {
|
|||
return \wp_schedule_single_event( \time() + $delay, $hook, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the backfilling of events via the outbox of an ActivityPub actor.
|
||||
*
|
||||
* @param string $actor The ActivityPub ID of the actor which owns the outbox.
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public static function backfill_events( $actor ) {
|
||||
// Initiate parsing of outbox collection.
|
||||
$outbox_url = Event_Source::get_by_id( $actor )->get_outbox();
|
||||
|
||||
if ( ! $outbox_url ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Schedule the import of events via the outbox.
|
||||
return self::queue_importing_from_outbox( $outbox_url, $actor, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current import count for the actor.
|
||||
*
|
||||
|
@ -213,49 +269,4 @@ class Outbox_Parser {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import events from an outbox: OrderedCollection or OrderedCollectionPage.
|
||||
*
|
||||
* @param string $url The url of the current page or outbox.
|
||||
* @param string $actor The ActivityPub ID/URL of the actor that owns the outbox.
|
||||
* @return void
|
||||
*/
|
||||
public static function import_events_from_outbox( $url, $actor ) {
|
||||
$outbox = self::fetch_outbox( $url );
|
||||
|
||||
if ( ! $outbox ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_count = self::get_import_count( $actor );
|
||||
|
||||
if ( $current_count >= self::MAX_EVENTS_TO_IMPORT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Process orderedItems if they exist (non-paginated outbox).
|
||||
if ( isset( $outbox['orderedItems'] ) && is_array( $outbox['orderedItems'] ) ) {
|
||||
$current_count += self::import_events_from_items(
|
||||
$outbox['orderedItems'],
|
||||
$actor,
|
||||
self::MAX_EVENTS_TO_IMPORT - $current_count
|
||||
);
|
||||
}
|
||||
|
||||
self::update_import_count( $actor, $current_count );
|
||||
|
||||
// If the count is already exceeded abort here.
|
||||
if ( $current_count >= self::MAX_EVENTS_TO_IMPORT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get next page and if it exists schedule the import of next page.
|
||||
$pagination_url = self::get_pagination_url( $outbox );
|
||||
|
||||
if ( $pagination_url ) {
|
||||
self::queue_importing_from_outbox( $pagination_url, $actor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,6 +269,9 @@ class Setup {
|
|||
Event_Sources::init();
|
||||
}
|
||||
|
||||
// Initialize writing of debug logs.
|
||||
Debug::init();
|
||||
|
||||
// Lastly but most importantly: register the ActivityPub transformers for events to the ActivityPub plugin.
|
||||
add_filter( 'activitypub_transformer', array( $this, 'register_activitypub_event_transformer' ), 10, 3 );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue