WIP: Add Event Sources Logic (ActivityPub follows) #86
11 changed files with 188 additions and 124 deletions
|
@ -26,7 +26,6 @@ class Handler {
|
|||
* Register all ActivityPub handlers.
|
||||
*/
|
||||
public static function register_handlers() {
|
||||
|
||||
Accept::init();
|
||||
Announce::init();
|
||||
Update::init();
|
||||
|
|
|
@ -25,6 +25,15 @@ class Event_Sources {
|
|||
*/
|
||||
const POST_TYPE = 'ebap_event_source';
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*/
|
||||
public static function init() {
|
||||
self::register_post_type();
|
||||
\add_action( 'event_bridge_for_activitypub_follow', array( self::class, 'activitypub_follow_actor' ), 10, 2 );
|
||||
\add_action( 'event_bridge_for_activitypub_unfollow', array( self::class, 'activitypub_unfollow_actor' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the post type used to store the external event sources (i.e., followed ActivityPub actors).
|
||||
*/
|
||||
|
@ -146,6 +155,8 @@ class Event_Sources {
|
|||
return $post_id;
|
||||
}
|
||||
|
||||
self::queue_follow_actor( $actor );
|
||||
|
||||
return $event_source;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
||||
|
||||
use Activitypub\Notification;
|
||||
use Activitypub\Collection\Actors;
|
||||
use Event_Bridge_For_ActivityPub\Setup;
|
||||
|
||||
use function Activitypub\is_activity_public;
|
||||
|
||||
/**
|
||||
* Handle Create requests.
|
||||
|
@ -27,23 +29,32 @@ class Create {
|
|||
/**
|
||||
* Handle "Create" requests.
|
||||
*
|
||||
* @param array $activity The activity object.
|
||||
* @param array $activity The activity-object.
|
||||
* @param int $user_id The id of the local blog-user.
|
||||
*/
|
||||
public static function handle_create( $activity ) {
|
||||
if ( ! isset( $activity['object'] ) ) {
|
||||
public static function handle_create( $activity, $user_id ) {
|
||||
// We only process activities that are target the application user.
|
||||
if ( Actors::APPLICATION_USER_ID !== $user_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$object = Actors::get_by_resource( $activity['object'] );
|
||||
|
||||
if ( ! $object || is_wp_error( $object ) ) {
|
||||
// If we can not find a actor, we handle the `create` activity.
|
||||
// Check if Activity is public or not.
|
||||
if ( ! is_activity_public( $activity ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We only expect `create` activities being answers to follow requests by the application actor.
|
||||
if ( Actors::APPLICATION_USER_ID !== $object->get__id() ) {
|
||||
// Check if an object is set.
|
||||
if ( ! isset( $activity['object']['type'] ) || 'Event' !== isset( $activity['object']['type'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transmogrifier_class = Setup::get_transmogrifier();
|
||||
|
||||
if ( ! $transmogrifier_class ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transmogrifier = new $transmogrifier_class( $activity['object'] );
|
||||
$transmogrifier->create();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
|||
|
||||
use Activitypub\Notification;
|
||||
use Activitypub\Collection\Actors;
|
||||
use Activitypub\Http;
|
||||
|
||||
/**
|
||||
* Handle Update requests.
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* @license AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace Event_Bridge_For_ActivityPub\Activitypub\Transmogrify;
|
||||
namespace Event_Bridge_For_ActivityPub\Activitypub\Transmogrifier;
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use Activitypub\Activity\Extended_Object\Place;
|
||||
|
@ -20,7 +20,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
use GatherPress\Core\Event as GatherPress_Event;
|
||||
|
||||
/**
|
||||
* ActivityPub Transmogrify for the GatherPress event plugin.
|
||||
* ActivityPub Transmogrifier for the GatherPress event plugin.
|
||||
*
|
||||
* Handles converting incoming external ActivityPub events to GatherPress Events.
|
||||
*
|
||||
|
@ -56,6 +56,27 @@ class GatherPress {
|
|||
* Save the ActivityPub event object as GatherPress Event.
|
||||
*/
|
||||
public function save() {
|
||||
// Insert GatherPress Event here.
|
||||
// Insert new GatherPress Event post.
|
||||
$post_id = wp_insert_post(
|
||||
array(
|
||||
'post_title' => $this->activitypub_event->get_name(),
|
||||
'post_type' => 'gatherpress_event',
|
||||
'post_content' => $this->activitypub_event->get_content(),
|
||||
'post_excerpt' => $this->activitypub_event->get_summary(),
|
||||
'post_status' => 'publish',
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! $post_id || is_wp_error( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event = new \GatherPress\Core\Event( $post_id );
|
||||
$params = array(
|
||||
'datetime_start' => $this->activitypub_event->get_start_time(),
|
||||
'datetime_end' => $this->activitypub_event->get_end_time(),
|
||||
'timezone' => $this->activitypub_event->get_timezone(),
|
||||
);
|
||||
$event->save_datetimes( $params );
|
||||
}
|
||||
}
|
|
@ -173,14 +173,6 @@ class Settings_Page {
|
|||
$event_terms = array_merge( $event_terms, self::get_event_terms( $event_plugin ) );
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'slug' => self::SETTINGS_SLUG,
|
||||
'event_terms' => $event_terms,
|
||||
);
|
||||
|
||||
\load_template( EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_DIR . 'templates/settings.php', true, $args );
|
||||
break;
|
||||
case 'event-sources':
|
||||
$supports_event_sources = array();
|
||||
|
||||
foreach ( $event_plugins as $event_plugin ) {
|
||||
|
@ -188,13 +180,19 @@ class Settings_Page {
|
|||
$supports_event_sources[ $event_plugin::class ] = $event_plugin->get_plugin_name();
|
||||
}
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'slug' => self::SETTINGS_SLUG,
|
||||
'event_terms' => $event_terms,
|
||||
'supports_event_sources' => $supports_event_sources,
|
||||
);
|
||||
|
||||
\load_template( EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_DIR . 'templates/settings.php', true, $args );
|
||||
break;
|
||||
case 'event-sources':
|
||||
wp_enqueue_script( 'thickbox' );
|
||||
wp_enqueue_style( 'thickbox' );
|
||||
\load_template( EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_DIR . 'templates/event-sources.php', true, $args );
|
||||
\load_template( EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_DIR . 'templates/event-sources.php', true );
|
||||
break;
|
||||
case 'welcome':
|
||||
default:
|
||||
|
|
|
@ -95,7 +95,7 @@ class Settings {
|
|||
);
|
||||
|
||||
\register_setting(
|
||||
'event-bridge-for-activitypub-event-sources',
|
||||
'event-bridge-for-activitypub',
|
||||
'event_bridge_for_activitypub_event_sources_active',
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
|
@ -106,7 +106,7 @@ class Settings {
|
|||
);
|
||||
|
||||
\register_setting(
|
||||
'event-bridge-for-activitypub-event-sources',
|
||||
'event-bridge-for-activitypub',
|
||||
'event_bridge_for_activitypub_plugin_used_for_event_source_feature',
|
||||
array(
|
||||
'type' => 'array',
|
||||
|
@ -115,6 +115,17 @@ class Settings {
|
|||
'sanitize_callback' => array( self::class, 'sanitize_plugin_used_for_event_sources' ),
|
||||
)
|
||||
);
|
||||
|
||||
\register_setting(
|
||||
'event-bridge-for-activitypub-event-sources',
|
||||
'event_bridge_for_activitypub_event_sources',
|
||||
array(
|
||||
'type' => 'array',
|
||||
'description' => \__( 'Dummy setting', 'event-bridge-for-activitypub' ),
|
||||
'default' => array(),
|
||||
'sanitize_callback' => 'is_array',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -204,13 +204,17 @@ class Setup {
|
|||
}
|
||||
|
||||
add_action( 'init', array( Health_Check::class, 'init' ) );
|
||||
add_action( 'init', array( Event_Sources_Collection::class, 'register_post_type' ) );
|
||||
|
||||
// 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 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( get_option( 'event_bridge_for_activitypub_event_sources_active' ) ) {
|
||||
add_action( 'init', array( Event_Sources_Collection::class, 'init' ) );
|
||||
add_action( 'init', array( Handler::class, 'register_handlers' ) );
|
||||
}
|
||||
|
||||
add_filter( 'activitypub_transformer', array( $this, 'register_activitypub_event_transformer' ), 10, 3 );
|
||||
}
|
||||
|
||||
|
@ -348,4 +352,22 @@ class Setup {
|
|||
|
||||
self::activate_activitypub_support_for_active_event_plugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the transmogrifier.
|
||||
*/
|
||||
public static function get_transmogrifier() {
|
||||
$setup = self::get_instance();
|
||||
|
||||
$event_sources_active = get_option( 'event_bridge_for_activitypub_event_sources_active', false );
|
||||
$event_plugin = get_option( 'event_bridge_for_activitypub_plugin_used_for_event_source_feature', '' );
|
||||
|
||||
if ( ! $event_sources_active || ! $event_plugin ) {
|
||||
return;
|
||||
}
|
||||
$active_event_plugins = $setup->get_active_event_plugins();
|
||||
if ( array_key_exists( $event_plugin, $active_event_plugins ) ) {
|
||||
return $active_event_plugins[ $event_plugin ]->get_transmogrifier_class();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,4 +95,14 @@ abstract class Event_Plugin {
|
|||
public static function get_activitypub_event_transformer_class(): string {
|
||||
return str_replace( 'Integrations', 'Activitypub\Transformer', static::class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class used for transmogrifying an Event (ActivityStreams to Event plugin transformation).
|
||||
*/
|
||||
public static function get_transmogrifier_class(): ?string {
|
||||
if ( ! self::supports_event_sources() ) {
|
||||
return null;
|
||||
}
|
||||
return str_replace( 'Integrations', 'Activitypub\Transmogrifier', static::class );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,105 +17,8 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
'event-sources' => 'active',
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! isset( $args ) || ! array_key_exists( 'supports_event_sources', $args ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event_plugins_supporting_event_sources = $args['supports_event_sources'];
|
||||
|
||||
$selected_plugin = \get_option( 'event_bridge_for_activitypub_plugin_used_for_event_source_feature', '' );
|
||||
$event_sources_active = \get_option( 'event_bridge_for_activitypub_event_sources_active', false );
|
||||
?>
|
||||
|
||||
<div class="event-bridge-for-activitypub-settings event-bridge-for-activitypub-settings-page hide-if-no-js">
|
||||
<div class="box">
|
||||
<h3><?php \esc_html_e( 'Configuration of the Event Sources feature', 'activitypub' ); ?></h3>
|
||||
<?php
|
||||
if ( count( $event_plugins_supporting_event_sources ) ) {
|
||||
?>
|
||||
<form method="post" action="options.php">
|
||||
<?php
|
||||
\settings_fields( 'event-bridge-for-activitypub-event-sources' );
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="event_bridge_for_activitypub_event_sources_active"><?php \esc_html_e( 'Enable External Event Sources', 'event-bridge-for-activitypub' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="event_bridge_for_activitypub_event_sources_active"
|
||||
id="event_bridge_for_activitypub_event_sources_active"
|
||||
aria-describedby="event-sources-description"
|
||||
value="1"
|
||||
<?php echo \checked( $event_sources_active ); ?>
|
||||
>
|
||||
<p id="event-sources-description"><?php esc_html_e( 'Activate this feature to allow your WordPress site to fetch events from external sources via ActivityPub. Once enabled, you can add any ActivityPub account as a source of events. These events will be cached on your site and seamlessly integrated into your existing event calendar, creating a unified view of events from both internal and external sources.', 'event-bridge-for-activitypub' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
if ( $event_sources_active ) {
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="event_bridge_for_activitypub_plugin_used_for_event_source_feature"><?php \esc_html_e( 'Event Plugin', 'event-bridge-for-activitypub' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<select
|
||||
name="event_bridge_for_activitypub_plugin_used_for_event_source_feature"
|
||||
id="event_bridge_for_activitypub_plugin_used_for_event_source_feature"
|
||||
value="gatherpress"
|
||||
aria-describedby="event-sources-used-plugin-description"
|
||||
>
|
||||
<?php
|
||||
foreach ( $event_plugins_supporting_event_sources as $event_plugin ) {
|
||||
echo '<option value="' . esc_attr( $event_plugin ) . '" ' . selected( $selected_plugin, $event_plugin, true ) . '>' . esc_attr( $event_plugin ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<p id="event-sources-used-plugin-description"><?php esc_html_e( 'In case you have multiple event plugins installed you might choose which event plugin is utilized.', 'event-bridge-for-activitypub' ); ?></p>
|
||||
</td>
|
||||
<tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<tbody>
|
||||
</table>
|
||||
<?php
|
||||
\submit_button();
|
||||
?>
|
||||
</form>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<p><?php esc_html_e( 'You do not have an Event Plugin installed that supports this feature', 'event-bridge-for-activitypub' ); ?></p>
|
||||
<p><?php esc_html_e( 'The following Event Plugins are supported:', 'event-bridge-for-activitypub' ); ?></p>
|
||||
<?php
|
||||
$plugins_supporting_event_sources = \Event_Bridge_For_ActivityPub\Setup::detect_event_plugins_supporting_event_sources();
|
||||
echo '<ul class="event_bridge_for_activitypub-list">';
|
||||
foreach ( $plugins_supporting_event_sources as $event_plugin ) {
|
||||
echo '<li>' . esc_attr( $event_plugin->get_plugin_name() ) . '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
return;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
if ( ! $event_sources_active ) {
|
||||
echo '</div>';
|
||||
return;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="wrap event_bridge_for_activitypub-admin-table-container">
|
||||
|
||||
<h2> <?php esc_html_e( 'List of Event Sources', 'event-bridge-for-activitypub' ); ?> </h2>
|
||||
|
|
|
@ -32,6 +32,15 @@ if ( ! current_user_can( 'manage_options' ) ) {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $args ) || ! array_key_exists( 'supports_event_sources', $args ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event_plugins_supporting_event_sources = $args['supports_event_sources'];
|
||||
|
||||
$selected_plugin = \get_option( 'event_bridge_for_activitypub_plugin_used_for_event_source_feature', '' );
|
||||
$event_sources_active = \get_option( 'event_bridge_for_activitypub_event_sources_active', false );
|
||||
|
||||
$event_terms = $args['event_terms'];
|
||||
|
||||
require_once EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_DIR . '/includes/event-categories.php';
|
||||
|
@ -42,7 +51,7 @@ $current_category_mapping = \get_option( 'event_bridge_for_activitypub_ev
|
|||
|
||||
<div class="event-bridge-for-activitypub-settings event-bridge-for-activitypub-settings-page hide-if-no-js">
|
||||
<form method="post" action="options.php">
|
||||
<?php \settings_fields( 'event-bridge-for-activitypub-event-sources' ); ?>
|
||||
<?php \settings_fields( 'event-bridge-for-activitypub' ); ?>
|
||||
<div class="box">
|
||||
<h2> <?php esc_html_e( 'Event Summary Text', 'event-bridge-for-activitypub' ); ?> </h2>
|
||||
<p><?php esc_html_e( 'Many Fediverse applications (e.g., Mastodon) don\'t fully support events, instead they will show a summary text along with the events title and the URL to your Website.', 'event-bridge-for-activitypub' ); ?></p>
|
||||
|
@ -90,6 +99,74 @@ $current_category_mapping = \get_option( 'event_bridge_for_activitypub_ev
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3><?php \esc_html_e( 'Configuration of the Event Sources feature', 'activitypub' ); ?></h3>
|
||||
<?php
|
||||
if ( count( $event_plugins_supporting_event_sources ) ) {
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="event_bridge_for_activitypub_event_sources_active"><?php \esc_html_e( 'Enable External Event Sources', 'event-bridge-for-activitypub' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="event_bridge_for_activitypub_event_sources_active"
|
||||
id="event_bridge_for_activitypub_event_sources_active"
|
||||
aria-describedby="event-sources-description"
|
||||
value="1"
|
||||
<?php echo \checked( $event_sources_active ); ?>
|
||||
>
|
||||
<p id="event-sources-description"><?php esc_html_e( 'Activate this feature to allow your WordPress site to fetch events from external sources via ActivityPub. Once enabled, you can add any ActivityPub account as a source of events. These events will be cached on your site and seamlessly integrated into your existing event calendar, creating a unified view of events from both internal and external sources.', 'event-bridge-for-activitypub' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
if ( $event_sources_active ) {
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="event_bridge_for_activitypub_plugin_used_for_event_source_feature"><?php \esc_html_e( 'Event Plugin', 'event-bridge-for-activitypub' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<select
|
||||
name="event_bridge_for_activitypub_plugin_used_for_event_source_feature"
|
||||
id="event_bridge_for_activitypub_plugin_used_for_event_source_feature"
|
||||
value="gatherpress"
|
||||
aria-describedby="event-sources-used-plugin-description"
|
||||
>
|
||||
<?php
|
||||
foreach ( $event_plugins_supporting_event_sources as $event_plugin ) {
|
||||
echo '<option value="' . esc_attr( $event_plugin ) . '" ' . selected( $selected_plugin, $event_plugin, true ) . '>' . esc_attr( $event_plugin ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<p id="event-sources-used-plugin-description"><?php esc_html_e( 'In case you have multiple event plugins installed you might choose which event plugin is utilized.', 'event-bridge-for-activitypub' ); ?></p>
|
||||
</td>
|
||||
<tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<tbody>
|
||||
</table>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<p><?php esc_html_e( 'You do not have an Event Plugin installed that supports this feature', 'event-bridge-for-activitypub' ); ?></p>
|
||||
<p><?php esc_html_e( 'The following Event Plugins are supported:', 'event-bridge-for-activitypub' ); ?></p>
|
||||
<?php
|
||||
$plugins_supporting_event_sources = \Event_Bridge_For_ActivityPub\Setup::detect_event_plugins_supporting_event_sources();
|
||||
echo '<ul class="event_bridge_for_activitypub-list">';
|
||||
foreach ( $plugins_supporting_event_sources as $event_plugin ) {
|
||||
echo '<li>' . esc_attr( $event_plugin->get_plugin_name() ) . '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
return;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h2> <?php esc_html_e( 'ActivityPub Event Category', 'event-bridge-for-activitypub' ); ?> </h2>
|
||||
<p> <?php esc_html_e( 'To help visitors find events more easily, the community created a set of basic event categories. Please select the category that best matches the majority of the events you organize.', 'event-bridge-for-activitypub' ); ?> </p>
|
||||
|
|
Loading…
Reference in a new issue