cleanup and drafting up activitypub follow/unfollow api
Some checks failed
PHP Code Checker / PHP Code Checker (pull_request) Failing after 45s
PHPUnit / PHPUnit – PHP 7.4 (pull_request) Successful in 1m2s
PHPUnit / PHPUnit – PHP 8.0 (pull_request) Successful in 1m1s
PHPUnit / PHPUnit – PHP 8.1 (pull_request) Successful in 1m2s
PHPUnit / PHPUnit – PHP 8.2 (pull_request) Successful in 1m2s
PHPUnit / PHPUnit – PHP 8.3 (pull_request) Successful in 1m4s
PHPUnit / PHPUnit – PHP 8.4 (pull_request) Successful in 1m6s
Some checks failed
PHP Code Checker / PHP Code Checker (pull_request) Failing after 45s
PHPUnit / PHPUnit – PHP 7.4 (pull_request) Successful in 1m2s
PHPUnit / PHPUnit – PHP 8.0 (pull_request) Successful in 1m1s
PHPUnit / PHPUnit – PHP 8.1 (pull_request) Successful in 1m2s
PHPUnit / PHPUnit – PHP 8.2 (pull_request) Successful in 1m2s
PHPUnit / PHPUnit – PHP 8.3 (pull_request) Successful in 1m4s
PHPUnit / PHPUnit – PHP 8.4 (pull_request) Successful in 1m6s
This commit is contained in:
parent
1eda885719
commit
d77cdf1430
6 changed files with 178 additions and 83 deletions
|
@ -92,6 +92,16 @@ class Event_Sources {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
\register_post_meta(
|
||||||
|
self::POST_TYPE,
|
||||||
|
'activitypub_inbox',
|
||||||
|
array(
|
||||||
|
'type' => 'string',
|
||||||
|
'single' => true,
|
||||||
|
'sanitize_callback' => 'sanitize_url',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
\register_post_meta(
|
\register_post_meta(
|
||||||
self::POST_TYPE,
|
self::POST_TYPE,
|
||||||
'event_source_utilize_announces',
|
'event_source_utilize_announces',
|
||||||
|
@ -229,4 +239,140 @@ class Event_Sources {
|
||||||
$post_id = Event_Source::get_wp_post_from_activitypub_actor_id( $event_source );
|
$post_id = Event_Source::get_wp_post_from_activitypub_actor_id( $event_source );
|
||||||
return wp_delete_post( $post_id, true );
|
return wp_delete_post( $post_id, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a hook to run async.
|
||||||
|
*
|
||||||
|
* @param string $hook The hook name.
|
||||||
|
* @param array $args The arguments to pass to the hook.
|
||||||
|
* @param string $unqueue_hook Optional a hook to unschedule before queuing.
|
||||||
|
* @return void|bool Whether the hook was queued.
|
||||||
|
*/
|
||||||
|
public static function queue( $hook, $args, $unqueue_hook = null ) {
|
||||||
|
if ( $unqueue_hook ) {
|
||||||
|
$hook_timestamp = wp_next_scheduled( $unqueue_hook, $args );
|
||||||
|
if ( $hook_timestamp ) {
|
||||||
|
wp_unschedule_event( $hook_timestamp, $unqueue_hook, $args );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wp_next_scheduled( $hook, $args ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return \wp_schedule_single_event( \time(), $hook, $args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare to follow an ActivityPub actor via a scheduled event.
|
||||||
|
*
|
||||||
|
* @param string $actor The ActivityPub actor.
|
||||||
|
*
|
||||||
|
* @return bool|WP_Error Whether the event was queued.
|
||||||
|
*/
|
||||||
|
public static function queue_follow_actor( $actor ) {
|
||||||
|
$queued = self::queue(
|
||||||
|
'event_bridge_for_activitypub_follow',
|
||||||
|
$actor,
|
||||||
|
'event_bridge_for_activitypub_unfollow'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $queued;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Follow an ActivityPub actor via the Application user.
|
||||||
|
*
|
||||||
|
* @param string $actor_id The ID/URL of the Actor.
|
||||||
|
*/
|
||||||
|
public static function activitypub_follow_actor( $actor_id ) {
|
||||||
|
$post_id = Event_Source::get_wp_post_from_activitypub_actor_id( $actor_id );
|
||||||
|
|
||||||
|
if ( ! $post_id ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$actor = Event_Source::init_from_cpt( get_post( $post_id ) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $actor ) ) {
|
||||||
|
return $actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inbox = $actor->get_shared_inbox();
|
||||||
|
$to = $actor->get_id();
|
||||||
|
|
||||||
|
$application = new \Activitypub\Model\Application();
|
||||||
|
|
||||||
|
$activity = new \Activitypub\Activity\Activity();
|
||||||
|
$activity->set_type( 'Follow' );
|
||||||
|
$activity->set_to( null );
|
||||||
|
$activity->set_cc( null );
|
||||||
|
$activity->set_actor( $application->get_id() );
|
||||||
|
$activity->set_object( $to );
|
||||||
|
$activity->set_id( $actor . '#follow-' . \preg_replace( '~^https?://~', '', $to ) );
|
||||||
|
$activity = $activity->to_json();
|
||||||
|
\Activitypub\safe_remote_post( $inbox, $activity, \Activitypub\Collection\Actors::APPLICATION_USER_ID );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare to unfollow an actor via a scheduled event.
|
||||||
|
*
|
||||||
|
* @param string $actor The ActivityPub actor ID.
|
||||||
|
*
|
||||||
|
* @return bool|WP_Error Whether the event was queued.
|
||||||
|
*/
|
||||||
|
public static function queue_unfollow_actor( $actor ) {
|
||||||
|
$queued = self::queue(
|
||||||
|
'event_bridge_for_activitypub_unfollow',
|
||||||
|
$actor,
|
||||||
|
'event_bridge_for_activitypub_follow'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $queued;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unfollow an ActivityPub actor.
|
||||||
|
*
|
||||||
|
* @param string $actor_id The ActivityPub actor ID.
|
||||||
|
*/
|
||||||
|
public static function activitypub_unfollow_actor( $actor_id ) {
|
||||||
|
$post_id = Event_Source::get_wp_post_from_activitypub_actor_id( $actor_id );
|
||||||
|
|
||||||
|
if ( ! $post_id ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$actor = Event_Source::init_from_cpt( get_post( $post_id ) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $actor ) ) {
|
||||||
|
return $actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inbox = $actor->get_shared_inbox();
|
||||||
|
$to = $actor->get_id();
|
||||||
|
|
||||||
|
$application = new \Activitypub\Model\Application();
|
||||||
|
|
||||||
|
if ( is_wp_error( $inbox ) ) {
|
||||||
|
return $inbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
$activity = new \Activitypub\Activity\Activity();
|
||||||
|
$activity->set_type( 'Undo' );
|
||||||
|
$activity->set_to( null );
|
||||||
|
$activity->set_cc( null );
|
||||||
|
$activity->set_actor( $application->get_id() );
|
||||||
|
$activity->set_object(
|
||||||
|
array(
|
||||||
|
'type' => 'Follow',
|
||||||
|
'actor' => $actor,
|
||||||
|
'object' => $to,
|
||||||
|
'id' => $to,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$activity->set_id( $actor . '#unfollow-' . \preg_replace( '~^https?://~', '', $to ) );
|
||||||
|
$activity = $activity->to_json();
|
||||||
|
\Activitypub\safe_remote_post( $inbox, $activity, \Activitypub\Collection\Actors::APPLICATION_USER_ID );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Model;
|
namespace Event_Bridge_For_ActivityPub\ActivityPub\Model;
|
||||||
|
|
||||||
use Activitypub\Activity\Actor;
|
use Activitypub\Activity\Actor;
|
||||||
use Activitypub\Webfinger;
|
|
||||||
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources;
|
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources;
|
||||||
use WP_Error;
|
use WP_Error;
|
||||||
|
|
||||||
|
@ -118,6 +117,32 @@ class Event_Source extends Actor {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the post meta.
|
||||||
|
*/
|
||||||
|
protected function get_post_meta_input() {
|
||||||
|
$meta_input = array();
|
||||||
|
$meta_input['activitypub_inbox'] = $this->get_shared_inbox();
|
||||||
|
$meta_input['activitypub_actor_json'] = $this->to_json();
|
||||||
|
|
||||||
|
return $meta_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the shared inbox, with a fallback to the inbox.
|
||||||
|
*
|
||||||
|
* @return string|null The URL to the shared inbox, the inbox or null.
|
||||||
|
*/
|
||||||
|
public function get_shared_inbox() {
|
||||||
|
if ( ! empty( $this->get_endpoints()['sharedInbox'] ) ) {
|
||||||
|
return $this->get_endpoints()['sharedInbox'];
|
||||||
|
} elseif ( ! empty( $this->get_inbox() ) ) {
|
||||||
|
return $this->get_inbox();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the current Event Source object to Database within custom post type.
|
* Save the current Event Source object to Database within custom post type.
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,11 +9,8 @@ namespace Event_Bridge_For_ActivityPub;
|
||||||
|
|
||||||
use Activitypub\Activity\Extended_Object\Event;
|
use Activitypub\Activity\Extended_Object\Event;
|
||||||
use Activitypub\Collection\Actors;
|
use Activitypub\Collection\Actors;
|
||||||
use Activitypub\Http;
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
use function Activitypub\get_remote_metadata_by_actor;
|
use function Activitypub\get_remote_metadata_by_actor;
|
||||||
use function register_post_type;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for handling and saving the ActivityPub event sources (i.e. follows).
|
* Class for handling and saving the ActivityPub event sources (i.e. follows).
|
||||||
|
@ -30,83 +27,9 @@ class Event_Sources {
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
\add_action( 'init', array( $this, 'register_post_meta' ) );
|
|
||||||
|
|
||||||
\add_action( 'activitypub_inbox', array( $this, 'handle_activitypub_inbox' ), 15, 3 );
|
\add_action( 'activitypub_inbox', array( $this, 'handle_activitypub_inbox' ), 15, 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the post type used to store the external event sources (i.e., followed ActivityPub actors).
|
|
||||||
*/
|
|
||||||
public static function register_post_type() {
|
|
||||||
register_post_type(
|
|
||||||
self::POST_TYPE,
|
|
||||||
array(
|
|
||||||
'labels' => array(
|
|
||||||
'name' => _x( 'Event Sources', 'post_type plural name', 'activitypub' ),
|
|
||||||
'singular_name' => _x( 'Event Source', 'post_type single name', 'activitypub' ),
|
|
||||||
),
|
|
||||||
'public' => false,
|
|
||||||
'hierarchical' => false,
|
|
||||||
'rewrite' => false,
|
|
||||||
'query_var' => false,
|
|
||||||
'delete_with_user' => false,
|
|
||||||
'can_export' => true,
|
|
||||||
'supports' => array(),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
\register_post_meta(
|
|
||||||
self::POST_TYPE,
|
|
||||||
'activitypub_inbox',
|
|
||||||
array(
|
|
||||||
'type' => 'string',
|
|
||||||
'single' => true,
|
|
||||||
'sanitize_callback' => 'sanitize_url',
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
\register_post_meta(
|
|
||||||
self::POST_TYPE,
|
|
||||||
'activitypub_errors',
|
|
||||||
array(
|
|
||||||
'type' => 'string',
|
|
||||||
'single' => false,
|
|
||||||
'sanitize_callback' => function ( $value ) {
|
|
||||||
if ( ! is_string( $value ) ) {
|
|
||||||
throw new Exception( 'Error message is no valid string' );
|
|
||||||
}
|
|
||||||
|
|
||||||
return esc_sql( $value );
|
|
||||||
},
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
\register_post_meta(
|
|
||||||
self::POST_TYPE,
|
|
||||||
'activitypub_user_id',
|
|
||||||
array(
|
|
||||||
'type' => 'string',
|
|
||||||
'single' => false,
|
|
||||||
'sanitize_callback' => function ( $value ) {
|
|
||||||
return esc_sql( $value );
|
|
||||||
},
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
\register_post_meta(
|
|
||||||
self::POST_TYPE,
|
|
||||||
'activitypub_actor_json',
|
|
||||||
array(
|
|
||||||
'type' => 'string',
|
|
||||||
'single' => true,
|
|
||||||
'sanitize_callback' => function ( $value ) {
|
|
||||||
return sanitize_text_field( $value );
|
|
||||||
},
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the ActivityPub Inbox.
|
* Handle the ActivityPub Inbox.
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,6 +20,7 @@ use Event_Bridge_For_ActivityPub\Admin\General_Admin_Notices;
|
||||||
use Event_Bridge_For_ActivityPub\Admin\Health_Check;
|
use Event_Bridge_For_ActivityPub\Admin\Health_Check;
|
||||||
use Event_Bridge_For_ActivityPub\Admin\Settings_Page;
|
use Event_Bridge_For_ActivityPub\Admin\Settings_Page;
|
||||||
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin;
|
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin;
|
||||||
|
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources as Event_Sources_Collection;
|
||||||
|
|
||||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||||
|
|
||||||
|
@ -183,7 +184,7 @@ class Setup {
|
||||||
}
|
}
|
||||||
|
|
||||||
add_action( 'init', array( Health_Check::class, 'init' ) );
|
add_action( 'init', array( Health_Check::class, 'init' ) );
|
||||||
add_action( 'init', array( Event_Sources::class, 'register_post_type' ) );
|
add_action( 'init', array( Event_Sources_Collection::class, 'register_post_type' ) );
|
||||||
|
|
||||||
// Check if the minimum required version of the ActivityPub plugin is installed.
|
// Check if the minimum required version of the ActivityPub plugin is installed.
|
||||||
if ( ! version_compare( $this->activitypub_plugin_version, EVENT_BRIDGE_FOR_ACTIVITYPUB_ACTIVITYPUB_PLUGIN_MIN_VERSION ) ) {
|
if ( ! version_compare( $this->activitypub_plugin_version, EVENT_BRIDGE_FOR_ACTIVITYPUB_ACTIVITYPUB_PLUGIN_MIN_VERSION ) ) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ $table = new \Event_Bridge_For_ActivityPub\Table\Event_Sources();
|
||||||
|
|
||||||
<!-- Button that triggers ThickBox -->
|
<!-- Button that triggers ThickBox -->
|
||||||
<a href="#TB_inline?width=600&height=400&inlineId=Event_Bridge_For_ActivityPub_add_new_source" class="thickbox button button-primary">
|
<a href="#TB_inline?width=600&height=400&inlineId=Event_Bridge_For_ActivityPub_add_new_source" class="thickbox button button-primary">
|
||||||
<?php esc_html_e( 'Add new', 'event-bridge-for-activitypub' ); ?>
|
<?php esc_html_e( 'Add Event Source', 'event-bridge-for-activitypub' ); ?>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- ThickBox content (hidden initially) -->
|
<!-- ThickBox content (hidden initially) -->
|
||||||
|
@ -37,8 +37,8 @@ $table = new \Event_Bridge_For_ActivityPub\Table\Event_Sources();
|
||||||
<p> <?php esc_html_e( 'Here you can enter either a Fediverse handle (@username@example.social), URL of an ActivityPub Account (https://example.social/user/username) or instance URL.', 'event-bridge-for-activitypub' ); ?> </p>
|
<p> <?php esc_html_e( 'Here you can enter either a Fediverse handle (@username@example.social), URL of an ActivityPub Account (https://example.social/user/username) or instance URL.', 'event-bridge-for-activitypub' ); ?> </p>
|
||||||
<form method="post" action="options.php">
|
<form method="post" action="options.php">
|
||||||
<?php \settings_fields( 'event-bridge-for-activitypub-event-sources' ); ?>
|
<?php \settings_fields( 'event-bridge-for-activitypub-event-sources' ); ?>
|
||||||
<input type="text" name="event_bridge_for_activitypub_event_source" id="event_bridge_for_activitypub_event_source" value="test">
|
<input type="text" name="event_bridge_for_activitypub_event_source" id="event_bridge_for_activitypub_event_source" value="">
|
||||||
<?php \submit_button(); ?>
|
<?php \submit_button( __( 'Add Event Source', 'event-bridge-for-activitypub' ) ); ?>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue