WIP: Add Event Sources Logic (ActivityPub follows) #86
23 changed files with 716 additions and 526 deletions
|
@ -28,10 +28,10 @@ First you need to add some basic information about your event plugin. Just creat
|
|||
final class My_Event_Plugin extends Event_Plugin {
|
||||
```
|
||||
|
||||
Then you need to tell the Event Bridge for ActivityPub about that class by adding it to the `EVENT_PLUGIN_CLASSES` constant in the `includes/setup.php` file:
|
||||
Then you need to tell the Event Bridge for ActivityPub about that class by adding it to the `EVENT_PLUGIN_INTEGRATIONS` constant in the `includes/setup.php` file:
|
||||
|
||||
```php
|
||||
private const EVENT_PLUGIN_CLASSES = array(
|
||||
private const EVENT_PLUGIN_INTEGRATIONS = array(
|
||||
...
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\My_Event_Plugin',
|
||||
);
|
||||
|
|
|
@ -31,6 +31,7 @@ class Event_Sources {
|
|||
*/
|
||||
public static function init() {
|
||||
self::register_post_type();
|
||||
\add_filter( 'allowed_redirect_hosts', array( self::class, 'add_event_sources_hosts_to_allowed_redirect_hosts' ) );
|
||||
\add_action( 'event_bridge_for_activitypub_follow', array( self::class, 'activitypub_follow_actor' ), 10, 1 );
|
||||
\add_action( 'event_bridge_for_activitypub_unfollow', array( self::class, 'activitypub_unfollow_actor' ), 10, 1 );
|
||||
}
|
||||
|
|
|
@ -50,13 +50,12 @@ class Update {
|
|||
return;
|
||||
}
|
||||
|
||||
$transmogrifier_class = Setup::get_transmogrifier();
|
||||
$transmogrifier = Setup::get_transmogrifier();
|
||||
|
||||
if ( ! $transmogrifier_class ) {
|
||||
if ( ! $transmogrifier ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transmogrifier = new $transmogrifier_class( $activity['object'] );
|
||||
$transmogrifier->save();
|
||||
$transmogrifier->save( $activity['object'] );
|
||||
}
|
||||
}
|
||||
|
|
339
includes/activitypub/transmogrifier/class-base.php
Normal file
339
includes/activitypub/transmogrifier/class-base.php
Normal file
|
@ -0,0 +1,339 @@
|
|||
<?php
|
||||
/**
|
||||
* Base class with common functions for transforming an ActivityPub Event object to a WordPress object.
|
||||
*
|
||||
* @package Event_Bridge_For_ActivityPub
|
||||
* @since 1.0.0
|
||||
* @license AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace Event_Bridge_For_ActivityPub\Activitypub\Transmogrifier;
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use WP_Error;
|
||||
|
||||
use function Activitypub\sanitize_url;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
/**
|
||||
* Base class with common functions for transforming an ActivityPub Event object to a WordPress object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
abstract class Base {
|
||||
/**
|
||||
* The current GatherPress Event object.
|
||||
*
|
||||
* @var Event
|
||||
*/
|
||||
protected $activitypub_event;
|
||||
|
||||
/**
|
||||
* Internal function to actually save the event.
|
||||
*/
|
||||
abstract protected function save_event();
|
||||
|
||||
/**
|
||||
* Save the ActivityPub event object as GatherPress Event.
|
||||
*
|
||||
* @param array $activitypub_event The ActivityPub event as associative array.
|
||||
*/
|
||||
public function save( $activitypub_event ) {
|
||||
$activitypub_event = Event::init_from_array( $activitypub_event );
|
||||
|
||||
if ( is_wp_error( $activitypub_event ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activitypub_event = $activitypub_event;
|
||||
$this->save_event();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post.
|
||||
*/
|
||||
protected function get_post_id_from_activitypub_id() {
|
||||
global $wpdb;
|
||||
return $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT ID FROM $wpdb->posts WHERE guid=%s",
|
||||
esc_sql( $this->activitypub_event->get_id() )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a time string if it is according to the ActivityPub specification.
|
||||
*
|
||||
* @param string $time_string The time string.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_valid_activitypub_time_string( $time_string ) {
|
||||
// Try to create a DateTime object from the input string.
|
||||
try {
|
||||
$date = new DateTime( $time_string );
|
||||
} catch ( Exception $e ) {
|
||||
// If parsing fails, it's not valid.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure the timezone is correctly formatted (e.g., 'Z' or a valid offset).
|
||||
$timezone = $date->getTimezone();
|
||||
$formatted_timezone = $timezone->getName();
|
||||
|
||||
// Return true only if the time string includes 'Z' or a valid timezone offset.
|
||||
$valid = 'Z' === $formatted_timezone || preg_match( '/^[+-]\d{2}:\d{2}$/ ', $formatted_timezone );
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image URL and alt-text of an ActivityPub object.
|
||||
*
|
||||
* @param array $data The ActivityPub object as ann associative array.
|
||||
* @return ?array Array containing the images URL and alt-text.
|
||||
*/
|
||||
private static function extract_image_alt_and_url( $data ) {
|
||||
$image = array(
|
||||
'url' => null,
|
||||
'alt' => null,
|
||||
);
|
||||
|
||||
// Check whether it is already simple.
|
||||
if ( ! $data || is_string( $data ) ) {
|
||||
$image['url'] = $data;
|
||||
return $image;
|
||||
}
|
||||
|
||||
if ( ! isset( $data['type'] ) ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
if ( ! in_array( $data['type'], array( 'Document', 'Image' ), true ) ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
if ( isset( $data['url'] ) ) {
|
||||
$image['url'] = $data['url'];
|
||||
} elseif ( isset( $data['id'] ) ) {
|
||||
$image['id'] = $data['id'];
|
||||
}
|
||||
|
||||
if ( isset( $data['name'] ) ) {
|
||||
$image['alt'] = $data['name'];
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the featured image.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_featured_image() {
|
||||
$event = $this->activitypub_event;
|
||||
$image = $event->get_image();
|
||||
if ( $image ) {
|
||||
return self::extract_image_alt_and_url( $image );
|
||||
}
|
||||
$attachment = $event->get_attachment();
|
||||
if ( is_array( $attachment ) && ! empty( $attachment ) ) {
|
||||
$supported_types = array( 'Image', 'Document' );
|
||||
$match = null;
|
||||
|
||||
foreach ( $attachment as $item ) {
|
||||
if ( in_array( $item['type'], $supported_types, true ) ) {
|
||||
$match = $item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$attachment = $match;
|
||||
}
|
||||
return self::extract_image_alt_and_url( $attachment );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an image URL return an attachment ID. Image will be side-loaded into the media library if it doesn't exist.
|
||||
*
|
||||
* Forked from https://gist.github.com/kingkool68/a66d2df7835a8869625282faa78b489a.
|
||||
*
|
||||
* @param int $post_id The post ID where the image will be set as featured image.
|
||||
* @param string $url The image URL to maybe sideload.
|
||||
* @uses media_sideload_image
|
||||
* @return string|int|WP_Error
|
||||
*/
|
||||
protected static function maybe_sideload_image( $post_id, $url = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
// Include necessary WordPress file for media handling.
|
||||
if ( ! function_exists( 'media_sideload_image' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
}
|
||||
|
||||
// Check to see if the URL has already been fetched, if so return the attachment ID.
|
||||
$attachment_id = $wpdb->get_var(
|
||||
$wpdb->prepare( "SELECT `post_id` FROM {$wpdb->postmeta} WHERE `meta_key` = '_source_url' AND `meta_value` = %s", sanitize_url( $url ) )
|
||||
);
|
||||
if ( ! empty( $attachment_id ) ) {
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
$attachment_id = $wpdb->get_var(
|
||||
$wpdb->prepare( "SELECT `ID` FROM {$wpdb->posts} WHERE guid=%s", $url )
|
||||
);
|
||||
if ( ! empty( $attachment_id ) ) {
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
// If the URL doesn't exist, sideload it to the media library.
|
||||
return media_sideload_image( sanitize_url( $url ), $post_id, sanitize_url( $url ), 'id' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sideload an image_url set it as featured image and add the alt-text.
|
||||
*
|
||||
* @param int $post_id The post ID where the image will be set as featured image.
|
||||
* @param string $image_url The image URL.
|
||||
* @param string $alt_text The alt-text of the image.
|
||||
* @return int The attachment ID
|
||||
*/
|
||||
protected static function set_featured_image_with_alt( $post_id, $image_url, $alt_text = '' ) {
|
||||
// Maybe sideload the image or get the Attachment ID of an existing one.
|
||||
$image_id = self::maybe_sideload_image( $post_id, $image_url );
|
||||
|
||||
if ( is_wp_error( $image_id ) ) {
|
||||
// Handle the error.
|
||||
return $image_id;
|
||||
}
|
||||
|
||||
// Set the image as the featured image for the post.
|
||||
set_post_thumbnail( $post_id, $image_id );
|
||||
|
||||
// Update the alt text.
|
||||
if ( ! empty( $alt_text ) ) {
|
||||
update_post_meta( $image_id, '_wp_attachment_image_alt', sanitize_text_field( $alt_text ) );
|
||||
}
|
||||
|
||||
return $image_id; // Return the attachment ID for further use if needed.
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a PostalAddress to a string.
|
||||
*
|
||||
* @link https://schema.org/PostalAddress
|
||||
*
|
||||
* @param array $postal_address The PostalAddress as an associative array.
|
||||
* @return string
|
||||
*/
|
||||
private static function postal_address_to_string( $postal_address ) {
|
||||
if ( ! is_array( $postal_address ) || 'PostalAddress' !== $postal_address['type'] ) {
|
||||
_doing_it_wrong(
|
||||
__METHOD__,
|
||||
'The parameter postal_address must be an associate array like schema.org/PostalAddress.',
|
||||
esc_html( EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_VERSION )
|
||||
);
|
||||
}
|
||||
|
||||
$address = array();
|
||||
|
||||
$known_attributes = array(
|
||||
'streetAddress',
|
||||
'postalCode',
|
||||
'addressLocality',
|
||||
'addressState',
|
||||
'addressCountry',
|
||||
);
|
||||
|
||||
foreach ( $known_attributes as $attribute ) {
|
||||
if ( isset( $postal_address[ $attribute ] ) && is_string( $postal_address[ $attribute ] ) ) {
|
||||
$address[] = $postal_address[ $attribute ];
|
||||
}
|
||||
}
|
||||
|
||||
$address_string = implode( ' ,', $address );
|
||||
|
||||
return $address_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an address to a string.
|
||||
*
|
||||
* @param mixed $address The address as an object, string or associative array.
|
||||
* @return string
|
||||
*/
|
||||
protected static function address_to_string( $address ) {
|
||||
if ( is_string( $address ) ) {
|
||||
return $address;
|
||||
}
|
||||
|
||||
if ( is_object( $address ) ) {
|
||||
$address = (array) $address;
|
||||
}
|
||||
|
||||
if ( ! is_array( $address ) || ! isset( $address['type'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( 'PostalAddress' === $address['type'] ) {
|
||||
return self::postal_address_to_string( $address );
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the ActivityPub event object as GatherPress event.
|
||||
*/
|
||||
public function delete() {
|
||||
$post_id = $this->get_post_id_from_activitypub_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 ) {
|
||||
wp_delete_attachment( $thumbnail_id, true );
|
||||
}
|
||||
|
||||
wp_delete_post( $post_id, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of revisions to keep.
|
||||
*
|
||||
* @return int The number of revisions to keep.
|
||||
*/
|
||||
public static function revisions_to_keep() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the online event link.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
protected function get_online_event_link_from_attachments() {
|
||||
$attachments = $this->activitypub_event->get_attachment();
|
||||
|
||||
if ( ! is_array( $attachments ) || empty( $attachments ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $attachments as $attachment ) {
|
||||
if ( array_key_exists( 'type', $attachment ) && 'Link' === $attachment['type'] && isset( $attachment['href'] ) ) {
|
||||
return $attachment['href'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,10 +11,7 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Activitypub\Transmogrifier;
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use WP_Error;
|
||||
|
||||
use function Activitypub\sanitize_url;
|
||||
|
||||
|
@ -30,224 +27,7 @@ use GatherPress\Core\Event as GatherPress_Event;
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class GatherPress {
|
||||
/**
|
||||
* The current GatherPress Event object.
|
||||
*
|
||||
* @var Event
|
||||
*/
|
||||
protected $activitypub_event;
|
||||
|
||||
/**
|
||||
* Extend the constructor, to also set the GatherPress objects.
|
||||
*
|
||||
* This is a special class object form The Events Calendar which
|
||||
* has a lot of useful functions, we make use of our getter functions.
|
||||
*
|
||||
* @param array $activitypub_event The ActivityPub Event as associative array.
|
||||
*/
|
||||
public function __construct( $activitypub_event ) {
|
||||
$activitypub_event = Event::init_from_array( $activitypub_event );
|
||||
|
||||
if ( is_wp_error( $activitypub_event ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activitypub_event = $activitypub_event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a time string if it is according to the ActivityPub specification.
|
||||
*
|
||||
* @param string $time_string The time string.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_valid_activitypub_time_string( $time_string ) {
|
||||
// Try to create a DateTime object from the input string.
|
||||
try {
|
||||
$date = new DateTime( $time_string );
|
||||
} catch ( Exception $e ) {
|
||||
// If parsing fails, it's not valid.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure the timezone is correctly formatted (e.g., 'Z' or a valid offset).
|
||||
$timezone = $date->getTimezone();
|
||||
$formatted_timezone = $timezone->getName();
|
||||
|
||||
// Return true only if the time string includes 'Z' or a valid timezone offset.
|
||||
$valid = 'Z' === $formatted_timezone || preg_match( '/^[+-]\d{2}:\d{2}$/ ', $formatted_timezone );
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of Post IDs of events that have ended.
|
||||
*
|
||||
* @param int $cache_retention_period Additional time buffer in seconds.
|
||||
* @return int[]
|
||||
*/
|
||||
public static function get_past_events( $cache_retention_period = 0 ) {
|
||||
global $wpdb;
|
||||
|
||||
$time_limit = gmdate( 'Y-m-d H:i:s', time() - $cache_retention_period );
|
||||
|
||||
$results = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
"SELECT post_id FROM {$wpdb->prefix}gatherpress_events WHERE datetime_end < %s",
|
||||
$time_limit
|
||||
)
|
||||
);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post.
|
||||
*/
|
||||
private function get_post_id_from_activitypub_id() {
|
||||
global $wpdb;
|
||||
return $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT ID FROM $wpdb->posts WHERE guid=%s",
|
||||
esc_sql( $this->activitypub_event->get_id() )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image URL and alt-text of an ActivityPub object.
|
||||
*
|
||||
* @param array $data The ActivityPub object as ann associative array.
|
||||
* @return ?array Array containing the images URL and alt-text.
|
||||
*/
|
||||
private static function extract_image_alt_and_url( $data ) {
|
||||
$image = array(
|
||||
'url' => null,
|
||||
'alt' => null,
|
||||
);
|
||||
|
||||
// Check whether it is already simple.
|
||||
if ( ! $data || is_string( $data ) ) {
|
||||
$image['url'] = $data;
|
||||
return $image;
|
||||
}
|
||||
|
||||
if ( ! isset( $data['type'] ) ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
if ( ! in_array( $data['type'], array( 'Document', 'Image' ), true ) ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
if ( isset( $data['url'] ) ) {
|
||||
$image['url'] = $data['url'];
|
||||
} elseif ( isset( $data['id'] ) ) {
|
||||
$image['id'] = $data['id'];
|
||||
}
|
||||
|
||||
if ( isset( $data['name'] ) ) {
|
||||
$image['alt'] = $data['name'];
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the featured image.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_featured_image() {
|
||||
$event = $this->activitypub_event;
|
||||
$image = $event->get_image();
|
||||
if ( $image ) {
|
||||
return self::extract_image_alt_and_url( $image );
|
||||
}
|
||||
$attachment = $event->get_attachment();
|
||||
if ( is_array( $attachment ) && ! empty( $attachment ) ) {
|
||||
$supported_types = array( 'Image', 'Document' );
|
||||
$match = null;
|
||||
|
||||
foreach ( $attachment as $item ) {
|
||||
if ( in_array( $item['type'], $supported_types, true ) ) {
|
||||
$match = $item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$attachment = $match;
|
||||
}
|
||||
return self::extract_image_alt_and_url( $attachment );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an image URL return an attachment ID. Image will be side-loaded into the media library if it doesn't exist.
|
||||
*
|
||||
* Forked from https://gist.github.com/kingkool68/a66d2df7835a8869625282faa78b489a.
|
||||
*
|
||||
* @param int $post_id The post ID where the image will be set as featured image.
|
||||
* @param string $url The image URL to maybe sideload.
|
||||
* @uses media_sideload_image
|
||||
* @return string|int|WP_Error
|
||||
*/
|
||||
public static function maybe_sideload_image( $post_id, $url = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
// Include necessary WordPress file for media handling.
|
||||
if ( ! function_exists( 'media_sideload_image' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
}
|
||||
|
||||
// Check to see if the URL has already been fetched, if so return the attachment ID.
|
||||
$attachment_id = $wpdb->get_var(
|
||||
$wpdb->prepare( "SELECT `post_id` FROM {$wpdb->postmeta} WHERE `meta_key` = '_source_url' AND `meta_value` = %s", sanitize_url( $url ) )
|
||||
);
|
||||
if ( ! empty( $attachment_id ) ) {
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
$attachment_id = $wpdb->get_var(
|
||||
$wpdb->prepare( "SELECT `ID` FROM {$wpdb->posts} WHERE guid=%s", $url )
|
||||
);
|
||||
if ( ! empty( $attachment_id ) ) {
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
// If the URL doesn't exist, sideload it to the media library.
|
||||
return media_sideload_image( sanitize_url( $url ), $post_id, sanitize_url( $url ), 'id' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sideload an image_url set it as featured image and add the alt-text.
|
||||
*
|
||||
* @param int $post_id The post ID where the image will be set as featured image.
|
||||
* @param string $image_url The image URL.
|
||||
* @param string $alt_text The alt-text of the image.
|
||||
* @return int The attachment ID
|
||||
*/
|
||||
private static function set_featured_image_with_alt( $post_id, $image_url, $alt_text = '' ) {
|
||||
// Maybe sideload the image or get the Attachment ID of an existing one.
|
||||
$image_id = self::maybe_sideload_image( $post_id, $image_url );
|
||||
|
||||
if ( is_wp_error( $image_id ) ) {
|
||||
// Handle the error.
|
||||
return $image_id;
|
||||
}
|
||||
|
||||
// Set the image as the featured image for the post.
|
||||
set_post_thumbnail( $post_id, $image_id );
|
||||
|
||||
// Update the alt text.
|
||||
if ( ! empty( $alt_text ) ) {
|
||||
update_post_meta( $image_id, '_wp_attachment_image_alt', sanitize_text_field( $alt_text ) );
|
||||
}
|
||||
|
||||
return $image_id; // Return the attachment ID for further use if needed.
|
||||
}
|
||||
|
||||
class GatherPress extends Base {
|
||||
/**
|
||||
* Add tags to post.
|
||||
*
|
||||
|
@ -271,94 +51,12 @@ class GatherPress {
|
|||
|
||||
// Add the tags as terms to the post.
|
||||
if ( ! empty( $tag_names ) ) {
|
||||
wp_set_object_terms( $post_id, $tag_names, 'gatherpress_topic', true ); // 'true' appends to existing terms.
|
||||
wp_set_object_terms( $post_id, $tag_names, 'gatherpress_topic', true );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the online event link.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
protected function get_online_event_link_from_attachments() {
|
||||
$attachments = $this->activitypub_event->get_attachment();
|
||||
|
||||
if ( ! is_array( $attachments ) || empty( $attachments ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $attachments as $attachment ) {
|
||||
if ( array_key_exists( 'type', $attachment ) && 'Link' === $attachment['type'] && isset( $attachment['href'] ) ) {
|
||||
return $attachment['href'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a PostalAddress to a string.
|
||||
*
|
||||
* @link https://schema.org/PostalAddress
|
||||
*
|
||||
* @param array $postal_address The PostalAddress as an associative array.
|
||||
* @return string
|
||||
*/
|
||||
protected static function postal_address_to_string( $postal_address ) {
|
||||
if ( ! is_array( $postal_address ) || 'PostalAddress' !== $postal_address['type'] ) {
|
||||
_doing_it_wrong(
|
||||
__METHOD__,
|
||||
'The parameter postal_address must be an associate array like schema.org/PostalAddress.',
|
||||
esc_html( EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_VERSION )
|
||||
);
|
||||
}
|
||||
|
||||
$address = array();
|
||||
|
||||
$known_attributes = array(
|
||||
'streetAddress',
|
||||
'postalCode',
|
||||
'addressLocality',
|
||||
'addressState',
|
||||
'addressCountry',
|
||||
);
|
||||
|
||||
foreach ( $known_attributes as $attribute ) {
|
||||
if ( isset( $postal_address[ $attribute ] ) && is_string( $postal_address[ $attribute ] ) ) {
|
||||
$address[] = $postal_address[ $attribute ];
|
||||
}
|
||||
}
|
||||
|
||||
$address_string = implode( ' ,', $address );
|
||||
|
||||
return $address_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an address to a string.
|
||||
*
|
||||
* @param mixed $address The address as an object, string or associative array.
|
||||
* @return string
|
||||
*/
|
||||
protected static function address_to_string( $address ) {
|
||||
if ( is_string( $address ) ) {
|
||||
return $address;
|
||||
}
|
||||
|
||||
if ( is_object( $address ) ) {
|
||||
$address = (array) $address;
|
||||
}
|
||||
|
||||
if ( ! is_array( $address ) || ! isset( $address['type'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( 'PostalAddress' === $address['type'] ) {
|
||||
return self::postal_address_to_string( $address );
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add venue.
|
||||
*
|
||||
|
@ -421,8 +119,10 @@ class GatherPress {
|
|||
|
||||
/**
|
||||
* Save the ActivityPub event object as GatherPress Event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save() {
|
||||
protected function save_event(): void {
|
||||
// Limit this as a safety measure.
|
||||
add_filter( 'wp_revisions_to_keep', array( self::class, 'revisions_to_keep' ) );
|
||||
|
||||
|
@ -483,36 +183,4 @@ class GatherPress {
|
|||
// Limit this as a safety measure.
|
||||
remove_filter( 'wp_revisions_to_keep', array( self::class, 'revisions_to_keep' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the ActivityPub event object as GatherPress event.
|
||||
*/
|
||||
public function delete() {
|
||||
$post_id = $this->get_post_id_from_activitypub_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 ) {
|
||||
wp_delete_attachment( $thumbnail_id, true );
|
||||
}
|
||||
|
||||
wp_delete_post( $post_id, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of revisions to keep.
|
||||
*
|
||||
* @return int The number of revisions to keep.
|
||||
*/
|
||||
public static function revisions_to_keep() {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* ActivityPub Transmogrify for the The Events Calendar event plugin.
|
||||
*
|
||||
* Handles converting incoming external ActivityPub events to The Events Calendar Events.
|
||||
*
|
||||
* @package Event_Bridge_For_ActivityPub
|
||||
* @since 1.0.0
|
||||
* @license AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace Event_Bridge_For_ActivityPub\Activitypub\Transmogrifier;
|
||||
|
||||
use DateTime;
|
||||
|
||||
use function Activitypub\sanitize_url;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use GatherPress\Core\Event as GatherPress_Event;
|
||||
|
||||
/**
|
||||
* ActivityPub Transmogrifier for the GatherPress event plugin.
|
||||
*
|
||||
* Handles converting incoming external ActivityPub events to GatherPress Events.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class The_Events_Calendar extends Base {
|
||||
/**
|
||||
* Get a list of Post IDs of events that have ended.
|
||||
*
|
||||
* @param int $cache_retention_period Additional time buffer in seconds.
|
||||
* @return ?array
|
||||
*/
|
||||
public static function get_past_events( $cache_retention_period = 0 ): ?array {
|
||||
unset( $cache_retention_period );
|
||||
|
||||
$results = array();
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the ActivityPub event object as GatherPress Event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save_event(): void {
|
||||
// Limit this as a safety measure.
|
||||
add_filter( 'wp_revisions_to_keep', array( self::class, 'revisions_to_keep' ) );
|
||||
|
||||
$this->get_post_id_from_activitypub_id();
|
||||
|
||||
// Limit this as a safety measure.
|
||||
remove_filter( 'wp_revisions_to_keep', array( self::class, 'revisions_to_keep' ) );
|
||||
}
|
||||
}
|
|
@ -97,7 +97,7 @@ class Health_Check {
|
|||
// Call the transformer Factory.
|
||||
$transformer = Transformer_Factory::get_transformer( $event_posts[0] );
|
||||
// Check that we got the right transformer.
|
||||
$desired_transformer_class = $event_plugin::get_activitypub_event_transformer_class();
|
||||
$desired_transformer_class = $event_plugin::get_activitypub_event_transformer( $event_posts[0] );
|
||||
if ( $transformer instanceof $desired_transformer_class ) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ use Event_Bridge_For_ActivityPub\ActivityPub\Model\Event_Source;
|
|||
use Event_Bridge_For_ActivityPub\Event_Sources;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources as Event_Source_Collection;
|
||||
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin;
|
||||
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin_Integration;
|
||||
use Event_Bridge_For_ActivityPub\Integrations\Feature_Event_Sources;
|
||||
use Event_Bridge_For_ActivityPub\Setup;
|
||||
|
||||
/**
|
||||
|
@ -171,15 +173,15 @@ class Settings_Page {
|
|||
case 'settings':
|
||||
$event_terms = array();
|
||||
|
||||
foreach ( $event_plugins as $event_plugin ) {
|
||||
$event_terms = array_merge( $event_terms, self::get_event_terms( $event_plugin ) );
|
||||
foreach ( $event_plugins as $event_plugin_integration ) {
|
||||
$event_terms = array_merge( $event_terms, self::get_event_terms( $event_plugin_integration ) );
|
||||
}
|
||||
|
||||
$supports_event_sources = array();
|
||||
|
||||
foreach ( $event_plugins as $event_plugin ) {
|
||||
if ( $event_plugin->supports_event_sources() ) {
|
||||
$supports_event_sources[ $event_plugin::class ] = $event_plugin->get_plugin_name();
|
||||
foreach ( $event_plugins as $event_plugin_integration ) {
|
||||
if ( $event_plugin_integration instanceof Feature_Event_Sources && $event_plugin_integration instanceof Event_Plugin_Integration ) {
|
||||
$supports_event_sources[ $event_plugin_integration::class ] = $event_plugin_integration::get_plugin_name();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Admin;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\Event_Sources;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
|
@ -59,7 +61,7 @@ class User_Interface {
|
|||
*/
|
||||
public static function row_actions( $actions, $post ) {
|
||||
// check if the post is enabled for ActivityPub.
|
||||
if ( ! self::post_is_external_event_post( $post ) ) {
|
||||
if ( ! Event_Sources::is_cached_external_event_post( $post ) ) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
|
@ -72,19 +74,6 @@ class User_Interface {
|
|||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a post is both an event post and external (from ActivityPub federation).
|
||||
*
|
||||
* @param WP_Post $post The post.
|
||||
* @return bool
|
||||
*/
|
||||
private static function post_is_external_event_post( $post ) {
|
||||
if ( 'gatherpress_event' !== $post->post_type ) {
|
||||
return false;
|
||||
}
|
||||
return str_starts_with( $post->guid, 'https://ga.lan' ) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the user capabilities so that nobody can edit external events.
|
||||
*
|
||||
|
@ -99,7 +88,7 @@ class User_Interface {
|
|||
if ( 'edit_post' === $cap && isset( $args[0] ) ) {
|
||||
$post_id = $args[0];
|
||||
$post = get_post( $post_id );
|
||||
if ( $post && self::post_is_external_event_post( $post ) ) {
|
||||
if ( $post && Event_Sources::is_cached_external_event_post( $post ) ) {
|
||||
// Deny editing by returning 'do_not_allow'.
|
||||
return array( 'do_not_allow' );
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ namespace Event_Bridge_For_ActivityPub;
|
|||
use Activitypub\Model\Blog;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources as Event_Sources_Collection;
|
||||
use Event_Bridge_For_ActivityPub\Activitypub\Transmogrifier\GatherPress;
|
||||
use Event_Bridge_For_ActivityPub\Activitypub\Handler;
|
||||
use Event_Bridge_For_ActivityPub\Admin\User_Interface;
|
||||
|
||||
|
||||
use function Activitypub\get_remote_metadata_by_actor;
|
||||
use function Activitypub\is_activitypub_request;
|
||||
|
@ -22,6 +25,22 @@ use function Activitypub\is_activitypub_request;
|
|||
* @package Event_Bridge_For_ActivityPub
|
||||
*/
|
||||
class Event_Sources {
|
||||
/**
|
||||
* Init.
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'init', array( Event_Sources_Collection::class, 'init' ) );
|
||||
\add_action( 'activitypub_register_handlers', array( Handler::class, 'register_handlers' ) );
|
||||
\add_action( 'admin_init', array( User_Interface::class, 'init' ) );
|
||||
\add_filter( 'activitypub_is_post_disabled', array( self::class, 'is_cached_external_post' ), 10, 2 );
|
||||
if ( ! \wp_next_scheduled( 'event_bridge_for_activitypub_event_sources_clear_cache' ) ) {
|
||||
\wp_schedule_event( time(), 'daily', 'event_bridge_for_activitypub_event_sources_clear_cache' );
|
||||
}
|
||||
\add_action( 'event_bridge_for_activitypub_event_sources_clear_cache', array( self::class, 'clear_cache' ) );
|
||||
\add_filter( 'activitypub_rest_following', array( self::class, 'add_event_sources_to_following_collection' ), 10, 2 );
|
||||
\add_filter( 'template_include', array( self::class, 'redirect_activitypub_requests_for_cached_external_events' ), 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get metadata of ActivityPub Actor by ID/URL.
|
||||
*
|
||||
|
@ -88,10 +107,7 @@ class Event_Sources {
|
|||
if ( $disabled || ! $post ) {
|
||||
return $disabled;
|
||||
}
|
||||
if ( ! str_starts_with( \get_site_url(), $post->guid ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return ! self::is_cached_external_event_post( $post );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,13 +117,10 @@ class Event_Sources {
|
|||
* @return bool
|
||||
*/
|
||||
public static function is_cached_external_event_post( $post ): bool {
|
||||
if ( 'gatherpress_event' !== $post->post_type ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! str_starts_with( \get_site_url(), $post->guid ) ) {
|
||||
if ( get_post_meta( $post->id, 'event_bridge_for_activitypub_is_cached', true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace Event_Bridge_For_ActivityPub;
|
|||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use Event_Bridge_For_ActivityPub\Integrations\Feature_Event_Sources;
|
||||
|
||||
/**
|
||||
* Class responsible for the ActivityPui Event Extension related Settings.
|
||||
|
@ -155,7 +156,7 @@ class Settings {
|
|||
|
||||
$valid_options = array();
|
||||
foreach ( $active_event_plugins as $active_event_plugin ) {
|
||||
if ( $active_event_plugin->supports_event_sources() ) {
|
||||
if ( $active_event_plugin instanceof Feature_Event_Sources ) {
|
||||
$full_class = $active_event_plugin::class;
|
||||
$valid_options[] = substr( $full_class, strrpos( $full_class, '\\' ) + 1 );
|
||||
}
|
||||
|
|
|
@ -15,14 +15,14 @@ namespace Event_Bridge_For_ActivityPub;
|
|||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources as Event_Sources_Collection;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Handler;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\Base as Transmogrifier_Base;
|
||||
use Event_Bridge_For_ActivityPub\Admin\Event_Plugin_Admin_Notices;
|
||||
use Event_Bridge_For_ActivityPub\Admin\General_Admin_Notices;
|
||||
use Event_Bridge_For_ActivityPub\Admin\Health_Check;
|
||||
use Event_Bridge_For_ActivityPub\Admin\Settings_Page;
|
||||
use Event_Bridge_For_ActivityPub\Admin\User_Interface;
|
||||
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin;
|
||||
use Event_Bridge_For_ActivityPub\Integrations\Feature_Event_Sources;
|
||||
|
||||
use function Activitypub\is_user_type_disabled;
|
||||
|
||||
|
@ -127,16 +127,16 @@ class Setup {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
private const EVENT_PLUGIN_CLASSES = array(
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\Events_Manager',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\GatherPress',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\The_Events_Calendar',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\VS_Event_List',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\WP_Event_Manager',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\Eventin',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\Modern_Events_Calendar_Lite',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\EventPrime',
|
||||
'\Event_Bridge_For_ActivityPub\Integrations\Event_Organiser',
|
||||
private const EVENT_PLUGIN_INTEGRATIONS = array(
|
||||
\Event_Bridge_For_ActivityPub\Integrations\Events_Manager::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\GatherPress::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\The_Events_Calendar::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\VS_Event_List::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\WP_Event_Manager::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\Eventin::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\Modern_Events_Calendar_Lite::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\EventPrime::class,
|
||||
\Event_Bridge_For_ActivityPub\Integrations\Event_Organiser::class,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -169,13 +169,18 @@ class Setup {
|
|||
$all_plugins = array_merge( get_plugins(), get_mu_plugins() );
|
||||
|
||||
$active_event_plugins = array();
|
||||
foreach ( self::EVENT_PLUGIN_CLASSES as $event_plugin_class ) {
|
||||
$event_plugin_file = call_user_func( array( $event_plugin_class, 'get_relative_plugin_file' ) );
|
||||
foreach ( self::EVENT_PLUGIN_INTEGRATIONS as $event_plugin_integration ) {
|
||||
// Get the filename of the main plugin file of the event plugin (relative to the plugin dir).
|
||||
$event_plugin_file = $event_plugin_integration::get_relative_plugin_file();
|
||||
|
||||
// This check should not be needed, but does not hurt.
|
||||
if ( ! $event_plugin_file ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if plugin is present on disk and is activated.
|
||||
if ( array_key_exists( $event_plugin_file, $all_plugins ) && \is_plugin_active( $event_plugin_file ) ) {
|
||||
$active_event_plugins[ $event_plugin_file ] = new $event_plugin_class();
|
||||
$active_event_plugins[ $event_plugin_file ] = new $event_plugin_integration();
|
||||
}
|
||||
}
|
||||
set_transient( 'event_bridge_for_activitypub_active_event_plugins', $active_event_plugins );
|
||||
|
@ -191,12 +196,9 @@ class Setup {
|
|||
public static function detect_event_plugins_supporting_event_sources(): array {
|
||||
$plugins_supporting_event_sources = array();
|
||||
|
||||
foreach ( self::EVENT_PLUGIN_CLASSES as $event_plugin_class ) {
|
||||
if ( ! class_exists( $event_plugin_class ) || ! method_exists( $event_plugin_class, 'get_plugin_file' ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( call_user_func( array( $event_plugin_class, 'supports_event_sources' ) ) ) {
|
||||
$plugins_supporting_event_sources[] = new $event_plugin_class();
|
||||
foreach ( self::EVENT_PLUGIN_INTEGRATIONS as $event_plugin_integration ) {
|
||||
if ( $event_plugin_integration instanceof Feature_Event_Sources ) {
|
||||
$plugins_supporting_event_sources[] = new $event_plugin_integration();
|
||||
}
|
||||
}
|
||||
return $plugins_supporting_event_sources;
|
||||
|
@ -241,39 +243,8 @@ class Setup {
|
|||
}
|
||||
|
||||
if ( ! is_user_type_disabled( 'blog' ) && get_option( 'event_bridge_for_activitypub_event_sources_active' ) ) {
|
||||
add_action( 'init', array( Event_Sources_Collection::class, 'init' ) );
|
||||
add_action( 'activitypub_register_handlers', array( Handler::class, 'register_handlers' ) );
|
||||
add_action( 'admin_init', array( User_Interface::class, 'init' ) );
|
||||
add_filter( 'allowed_redirect_hosts', array( Event_Sources_Collection::class, 'add_event_sources_hosts_to_allowed_redirect_hosts' ) );
|
||||
add_filter( 'activitypub_is_post_disabled', array( Event_Sources::class, 'is_cached_external_post' ), 10, 2 );
|
||||
if ( ! wp_next_scheduled( 'event_bridge_for_activitypub_event_sources_clear_cache' ) ) {
|
||||
wp_schedule_event( time(), 'daily', 'event_bridge_for_activitypub_event_sources_clear_cache' );
|
||||
}
|
||||
|
||||
add_action( 'event_bridge_for_activitypub_event_sources_clear_cache', array( Event_Sources::class, 'clear_cache' ) );
|
||||
add_filter( 'activitypub_rest_following', array( Event_Sources::class, 'add_event_sources_to_following_collection' ), 10, 2 );
|
||||
add_filter(
|
||||
'gatherpress_force_online_event_link',
|
||||
function ( $force_online_event_link ) {
|
||||
// Get the current post object.
|
||||
$post = get_post();
|
||||
|
||||
// Check if we are in a valid context and the post type is 'gatherpress'.
|
||||
if ( $post && 'gatherpress_event' === $post->post_type ) {
|
||||
// Add your custom logic here to decide whether to force the link.
|
||||
// For example, force it only if a specific meta field exists.
|
||||
if ( get_post_meta( $post->ID, 'event_bridge_for_activitypub_is_cached', true ) ) {
|
||||
return true; // Force the online event link.
|
||||
}
|
||||
}
|
||||
|
||||
return $force_online_event_link; // Default behavior.
|
||||
},
|
||||
10,
|
||||
1
|
||||
);
|
||||
Event_Sources::init();
|
||||
}
|
||||
\add_filter( 'template_include', array( \Event_Bridge_For_ActivityPub\Event_Sources::class, 'redirect_activitypub_requests_for_cached_external_events' ), 100 );
|
||||
add_filter( 'activitypub_transformer', array( $this, 'register_activitypub_event_transformer' ), 10, 3 );
|
||||
}
|
||||
|
||||
|
@ -348,10 +319,7 @@ class Setup {
|
|||
// Get the transformer for a specific event plugins event-post type.
|
||||
foreach ( $this->active_event_plugins as $event_plugin ) {
|
||||
if ( $wp_object->post_type === $event_plugin->get_post_type() ) {
|
||||
$transformer_class = $event_plugin::get_activitypub_event_transformer_class();
|
||||
if ( class_exists( $transformer_class ) ) {
|
||||
return new $transformer_class( $wp_object, $event_plugin::get_event_category_taxonomy() );
|
||||
}
|
||||
return $event_plugin::get_activitypub_event_transformer( $wp_object, $event_plugin::get_event_category_taxonomy() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,9 +384,9 @@ class Setup {
|
|||
/**
|
||||
* Get the transmogrifier class.
|
||||
*
|
||||
* Retrieves the appropriate transmogrifier class based on the active event plugin.
|
||||
* Retrieves the appropriate transmogrifier class based on the active event plugins and settings.
|
||||
*
|
||||
* @return string|null The transmogrifier class name or null if not available.
|
||||
* @return Transmogrifier_Base|null The transmogrifier class name or null if not available.
|
||||
*/
|
||||
public static function get_transmogrifier() {
|
||||
// Retrieve singleton instance.
|
||||
|
@ -428,7 +396,7 @@ class Setup {
|
|||
$event_sources_active = (bool) get_option( 'event_bridge_for_activitypub_event_sources_active', false );
|
||||
$event_plugin = get_option( 'event_bridge_for_activitypub_plugin_used_for_event_source_feature', '' );
|
||||
|
||||
// Bail out if event sources are not active or no plugin is specified.
|
||||
// Exit if event sources are not active or no plugin is specified.
|
||||
if ( ! $event_sources_active || empty( $event_plugin ) ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -439,12 +407,12 @@ class Setup {
|
|||
// Loop through active plugins to find a match.
|
||||
foreach ( $active_event_plugins as $active_event_plugin ) {
|
||||
// Retrieve the class name of the active plugin.
|
||||
$active_plugin_class = get_class( $active_event_plugin );
|
||||
$active_plugin_class_name = get_class( $active_event_plugin );
|
||||
|
||||
// Check if the active plugin class name contains the specified event plugin name.
|
||||
if ( false !== strpos( $active_plugin_class, $event_plugin ) ) {
|
||||
if ( false !== strpos( $active_plugin_class_name, $event_plugin ) ) {
|
||||
// Return the transmogrifier class provided by the plugin.
|
||||
return $active_event_plugin->get_transmogrifier_class();
|
||||
return $active_event_plugin->get_transmogrifier();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\Event_Organiser as Event_Organiser_Transformer;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
|
@ -21,7 +23,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Event_Organiser extends Event_Plugin {
|
||||
final class Event_Organiser extends Event_Plugin_Integration {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -49,15 +51,6 @@ final class Event_Organiser extends Event_Plugin {
|
|||
return array( 'event-organiser' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_activitypub_transformer_class_name(): string {
|
||||
return 'Event_Organiser';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the taxonomy used for the plugin's event categories.
|
||||
*
|
||||
|
@ -66,4 +59,14 @@ final class Event_Organiser extends Event_Plugin {
|
|||
public static function get_event_category_taxonomy(): string {
|
||||
return 'event-category';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer for a Event_Organiser event post.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return Event_Organiser_Transformer
|
||||
*/
|
||||
public static function get_activitypub_event_transformer( $post ): Event_Organiser_Transformer {
|
||||
return new Event_Organiser_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\Activitypub\Transformer\Event as Event_Transformer;
|
||||
use Event_Bridge_For_ActivityPub\Activitypub\Transformer\Event as ActivityPub_Event_Transformer;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
require_once EVENT_BRIDGE_FOR_ACTIVITYPUB_PLUGIN_DIR . 'includes/integrations/interface-feature-event-sources.php';
|
||||
|
||||
/**
|
||||
* Interface for a supported event plugin.
|
||||
*
|
||||
|
@ -23,7 +25,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
abstract class Event_Plugin {
|
||||
abstract class Event_Plugin_Integration {
|
||||
/**
|
||||
* Returns the plugin file relative to the plugins dir.
|
||||
*
|
||||
|
@ -45,6 +47,14 @@ abstract class Event_Plugin {
|
|||
*/
|
||||
abstract public static function get_event_category_taxonomy(): string;
|
||||
|
||||
/**
|
||||
* Returns the Activitypub transformer for the event plugins event post type.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return ActivityPub_Event_Transformer
|
||||
*/
|
||||
abstract public static function get_activitypub_event_transformer( $post ): ActivityPub_Event_Transformer;
|
||||
|
||||
/**
|
||||
* Returns the IDs of the admin pages of the plugin.
|
||||
*
|
||||
|
@ -54,19 +64,10 @@ abstract class Event_Plugin {
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* By default event sources are not supported by an event plugin integration.
|
||||
*
|
||||
* @return bool True if event sources are supported.
|
||||
*/
|
||||
public static function supports_event_sources(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugins name from the main plugin-file's top-level-file-comment.
|
||||
*/
|
||||
final public static function get_plugin_name(): string {
|
||||
public static function get_plugin_name(): string {
|
||||
$all_plugins = array_merge( get_plugins(), get_mu_plugins() );
|
||||
if ( isset( $all_plugins[ static::get_relative_plugin_file() ]['Name'] ) ) {
|
||||
return $all_plugins[ static::get_relative_plugin_file() ]['Name'];
|
||||
|
@ -88,21 +89,4 @@ abstract class Event_Plugin {
|
|||
|
||||
return $is_event_plugins_edit_page || $is_event_plugins_settings_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Activitypub transformer for the event plugins event post type.
|
||||
*/
|
||||
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 ( ! static::supports_event_sources() ) {
|
||||
return null;
|
||||
}
|
||||
return str_replace( 'Integrations', 'Activitypub\Transmogrifier', static::class );
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\Eventin as Eventin_Transformer;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
|
@ -21,7 +23,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Eventin extends Event_plugin {
|
||||
final class Eventin extends Event_Plugin_Integration {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -57,4 +59,14 @@ final class Eventin extends Event_plugin {
|
|||
public static function get_event_category_taxonomy(): string {
|
||||
return 'etn_category';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer for a Eventin event post.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return Eventin_Transformer
|
||||
*/
|
||||
public static function get_activitypub_event_transformer( $post ): Eventin_Transformer {
|
||||
return new Eventin_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\EventPrime as EventPrime_Transformer;
|
||||
|
||||
use Activitypub\Signature;
|
||||
use Eventprime_Basic_Functions;
|
||||
|
||||
|
@ -20,7 +22,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class EventPrime extends Event_Plugin {
|
||||
final class EventPrime extends Event_Plugin_Integration {
|
||||
/**
|
||||
* Add filter for the template inclusion.
|
||||
*/
|
||||
|
@ -56,12 +58,13 @@ final class EventPrime extends Event_Plugin {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer class.
|
||||
* Returns the ActivityPub transformer for a EventPrime event post.
|
||||
*
|
||||
* @return string
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return EventPrime_Transformer
|
||||
*/
|
||||
public static function get_activitypub_transformer_class_name(): string {
|
||||
return 'EventPrime';
|
||||
public static function get_activitypub_event_transformer( $post ): EventPrime_Transformer {
|
||||
return new EventPrime_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\Events_Manager as Events_Manager_Transformer;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
|
@ -21,7 +23,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Events_Manager extends Event_Plugin {
|
||||
final class Events_Manager extends Event_Plugin_Integration {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -57,4 +59,14 @@ final class Events_Manager extends Event_Plugin {
|
|||
public static function get_event_category_taxonomy(): string {
|
||||
return defined( 'EM_TAXONOMY_CATEGORY' ) ? constant( 'EM_TAXONOMY_CATEGORY' ) : 'event-categories';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer for a Events_Manager event post.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return Events_Manager_Transformer
|
||||
*/
|
||||
public static function get_activitypub_event_transformer( $post ): Events_Manager_Transformer {
|
||||
return new Events_Manager_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\GatherPress as GatherPress_Transformer;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\GatherPress as GatherPress_Transmogrifier;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
|
@ -21,7 +24,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class GatherPress extends Event_Plugin {
|
||||
final class GatherPress extends Event_Plugin_Integration implements Feature_Event_Sources {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -49,15 +52,6 @@ final class GatherPress extends Event_Plugin {
|
|||
return array( class_exists( '\GatherPress\Core\Utility' ) ? \GatherPress\Core\Utility::prefix_key( 'general' ) : 'gatherpress_general' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_activitypub_transformer_class_name(): string {
|
||||
return 'GatherPress';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the taxonomy used for the plugin's event categories.
|
||||
*
|
||||
|
@ -68,11 +62,67 @@ final class GatherPress extends Event_Plugin {
|
|||
}
|
||||
|
||||
/**
|
||||
* GatherPress supports the Event Sources feature.
|
||||
* Returns the ActivityPub transformer for a GatherPress event post.
|
||||
*
|
||||
* @return bool True if event sources are supported.
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return GatherPress_Transformer
|
||||
*/
|
||||
public static function supports_event_sources(): bool {
|
||||
return true;
|
||||
public static function get_activitypub_event_transformer( $post ): GatherPress_Transformer {
|
||||
return new GatherPress_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Transmogrifier for GatherPress.
|
||||
*/
|
||||
public static function get_transmogrifier(): GatherPress_Transmogrifier {
|
||||
return new GatherPress_Transmogrifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of Post IDs of events that have ended.
|
||||
*
|
||||
* @param int $ended_before_time Filter: only get events that ended before that datetime as unix-time.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_cached_remote_events( $ended_before_time ): array {
|
||||
global $wpdb;
|
||||
|
||||
$ended_before_time_string = gmdate( 'Y-m-d H:i:s', $ended_before_time );
|
||||
|
||||
$results = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
"SELECT post_id FROM {$wpdb->prefix}gatherpress_events WHERE datetime_end < %s",
|
||||
$ended_before_time_string
|
||||
)
|
||||
);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init function.
|
||||
*/
|
||||
public static function init() {
|
||||
\add_filter(
|
||||
'gatherpress_force_online_event_link',
|
||||
function ( $force_online_event_link ) {
|
||||
// Get the current post object.
|
||||
$post = get_post();
|
||||
|
||||
// Check if we are in a valid context and the post type is 'gatherpress'.
|
||||
if ( $post && 'gatherpress_event' === $post->post_type ) {
|
||||
// Add your custom logic here to decide whether to force the link.
|
||||
// For example, force it only if a specific meta field exists.
|
||||
if ( get_post_meta( $post->ID, 'event_bridge_for_activitypub_is_cached', true ) ) {
|
||||
return true; // Force the online event link.
|
||||
}
|
||||
}
|
||||
|
||||
return $force_online_event_link; // Default behavior.
|
||||
},
|
||||
10,
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\Modern_Events_Calendar_Lite as Modern_Events_Calendar_Lite_Transformer;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
|
@ -21,7 +23,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Modern_Events_Calendar_Lite extends Event_plugin {
|
||||
final class Modern_Events_Calendar_Lite extends Event_Plugin_Integration {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -58,4 +60,14 @@ final class Modern_Events_Calendar_Lite extends Event_plugin {
|
|||
public static function get_event_category_taxonomy(): string {
|
||||
return 'mec_category';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer for a Modern_Events_Calendar_Lite event post.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return Modern_Events_Calendar_Lite_Transformer
|
||||
*/
|
||||
public static function get_activitypub_event_transformer( $post ): Modern_Events_Calendar_Lite_Transformer {
|
||||
return new Modern_Events_Calendar_Lite_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\The_Events_Calendar as The_Events_Calendar_Transformer;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\The_Events_Calendar as The_Events_Calendar_Transmogrifier;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
|
@ -21,7 +24,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class The_Events_Calendar extends Event_plugin {
|
||||
final class The_Events_Calendar extends Event_plugin_Integration implements Feature_Event_Sources {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -40,6 +43,25 @@ final class The_Events_Calendar extends Event_plugin {
|
|||
return class_exists( '\Tribe__Events__Main' ) ? \Tribe__Events__Main::POSTTYPE : 'tribe_event';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the taxonomy used for the plugin's event categories.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_event_category_taxonomy(): string {
|
||||
return class_exists( '\Tribe__Events__Main' ) ? \Tribe__Events__Main::TAXONOMY : 'tribe_events_cat';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer for a The_Events_Calendar event post.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return The_Events_Calendar_Transformer
|
||||
*/
|
||||
public static function get_activitypub_event_transformer( $post ): The_Events_Calendar_Transformer {
|
||||
return new The_Events_Calendar_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IDs of the admin pages of the plugin.
|
||||
*
|
||||
|
@ -55,11 +77,20 @@ final class The_Events_Calendar extends Event_plugin {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the taxonomy used for the plugin's event categories.
|
||||
*
|
||||
* @return string
|
||||
* Returns the Transmogrifier for The_Events_Calendar.
|
||||
*/
|
||||
public static function get_event_category_taxonomy(): string {
|
||||
return class_exists( '\Tribe__Events__Main' ) ? \Tribe__Events__Main::TAXONOMY : 'tribe_events_cat';
|
||||
public static function get_transmogrifier(): The_Events_Calendar_Transmogrifier {
|
||||
return new The_Events_Calendar_Transmogrifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of Post IDs of events that have ended.
|
||||
*
|
||||
* @param int $ended_before_time Filter: only get events that ended before that datetime as unix-time.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_cached_remote_events( $ended_before_time ): array {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\Event_Plugins;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\VS_Event_List as VS_Event_List_Transformer;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
@ -24,7 +24,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class VS_Event_List extends Event_Plugin {
|
||||
final class VS_Event_List extends Event_Plugin_Integration {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -52,15 +52,6 @@ final class VS_Event_List extends Event_Plugin {
|
|||
return array( 'settings_page_vsel' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_activitypub_transformer_class_name(): string {
|
||||
return 'VS_Event';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the taxonomy used for the plugin's event categories.
|
||||
*
|
||||
|
@ -69,4 +60,14 @@ final class VS_Event_List extends Event_Plugin {
|
|||
public static function get_event_category_taxonomy(): string {
|
||||
return 'event_cat';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer for a VS_Event_List event post.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return VS_Event_List_Transformer
|
||||
*/
|
||||
public static function get_activitypub_event_transformer( $post ): VS_Event_List_Transformer {
|
||||
return new VS_Event_List_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\Integrations\Event_Plugin;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transformer\WP_Event_Manager as WP_Event_Manager_Transformer;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
@ -24,7 +24,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class WP_Event_Manager extends Event_Plugin {
|
||||
final class WP_Event_Manager extends Event_Plugin_Integration {
|
||||
/**
|
||||
* Returns the full plugin file.
|
||||
*
|
||||
|
@ -52,15 +52,6 @@ final class WP_Event_Manager extends Event_Plugin {
|
|||
return array( 'event-manager-settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_activitypub_transformer_class_name(): string {
|
||||
return 'WP_Event_Manager';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the taxonomy used for the plugin's event categories.
|
||||
*
|
||||
|
@ -69,4 +60,14 @@ final class WP_Event_Manager extends Event_Plugin {
|
|||
public static function get_event_category_taxonomy(): string {
|
||||
return 'event_listing_category';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub transformer for a WP_Event_Manager event post.
|
||||
*
|
||||
* @param WP_Post $post The WordPress post object of the Event.
|
||||
* @return WP_Event_Manager_Transformer
|
||||
*/
|
||||
public static function get_activitypub_event_transformer( $post ): WP_Event_Manager_Transformer {
|
||||
return new WP_Event_Manager_Transformer( $post, self::get_event_category_taxonomy() );
|
||||
}
|
||||
}
|
||||
|
|
42
includes/integrations/interface-feature-event-sources.php
Normal file
42
includes/integrations/interface-feature-event-sources.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
/**
|
||||
* Interface for defining supported Event Plugins.
|
||||
*
|
||||
* Basic information that each supported event needs for this plugin to work.
|
||||
*
|
||||
* @package Event_Bridge_For_ActivityPub
|
||||
* @since 1.0.0
|
||||
* @license AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace Event_Bridge_For_ActivityPub\Integrations;
|
||||
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\Base as Transmogrifier;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
/**
|
||||
* Interface for an event plugin integration that supports the Event Sources feature.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface Feature_Event_Sources {
|
||||
/**
|
||||
* Returns the plugin file relative to the plugins dir.
|
||||
*
|
||||
* @return Transmogrifier
|
||||
*/
|
||||
public static function get_transmogrifier(): Transmogrifier;
|
||||
|
||||
/**
|
||||
* Retrieves a list of post IDs for cached remote events that have ended.
|
||||
*
|
||||
* Filters the events to include only those that ended before the specified timestamp.
|
||||
*
|
||||
* @param int $ended_before_time Unix timestamp. Only events ending before this time will be included.
|
||||
*
|
||||
* @return int[] List of post IDs for events that match the criteria.
|
||||
*/
|
||||
public static function get_cached_remote_events( $ended_before_time ): array;
|
||||
}
|
Loading…
Reference in a new issue