updated plugin Event Bridge for ActivityPub version 1.3.0
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources;
|
||||
@ -48,9 +48,18 @@ abstract class Base {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add hook to insert post meta to flag post as remote and remember where we received it from.
|
||||
$add_origin_post_meta_callback = function ( $post_id ) use ( $event_source_post_id ): void {
|
||||
self::add_origin_post_meta( $post_id, $event_source_post_id );
|
||||
};
|
||||
\add_action( 'wp_after_insert_post', $add_origin_post_meta_callback, 10, 1 );
|
||||
|
||||
// Pass the saving to the actual Transmogrifier implementation.
|
||||
$post_id = static::save_event( $activitypub_event, $event_source_post_id );
|
||||
|
||||
// Remove hook added above.
|
||||
\remove_action( 'wp_after_insert_post', $add_origin_post_meta_callback, 10 );
|
||||
|
||||
// Post processing: Logging and marking the imported event's origin.
|
||||
$event_activitypub_id = $activitypub_event->get_id();
|
||||
$event_source_activitypub_id = \get_the_guid( $event_source_post_id );
|
||||
@ -60,9 +69,6 @@ abstract class Base {
|
||||
'event_bridge_for_activitypub_write_log',
|
||||
array( "[ACTIVITYPUB] Processed incoming event {$event_activitypub_id} from {$event_source_activitypub_id}" )
|
||||
);
|
||||
// Use post meta to remember who we received this event from.
|
||||
\update_post_meta( $post_id, '_event_bridge_for_activitypub_event_source', absint( $event_source_post_id ) );
|
||||
\update_post_meta( $post_id, 'activitypub_content_visibility', defined( 'ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL' ) ? constant( 'ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL' ) : '' );
|
||||
} else {
|
||||
\do_action(
|
||||
'event_bridge_for_activitypub_write_log',
|
||||
@ -71,6 +77,20 @@ abstract class Base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert post meta to remember who we received an event from.
|
||||
*
|
||||
* @param int $post_id The WordPress post ID of the event itself.
|
||||
* @param int $event_source_post_id The WordPress post ID of the event source custom post type.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function add_origin_post_meta( $post_id, $event_source_post_id ): void {
|
||||
// Use post meta to remember who we received this event from.
|
||||
\update_post_meta( $post_id, '_event_bridge_for_activitypub_event_source', absint( $event_source_post_id ) );
|
||||
\update_post_meta( $post_id, 'activitypub_content_visibility', defined( 'ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL' ) ? constant( 'ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL' ) : '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a local event in WordPress that is a cached remote one.
|
||||
*
|
||||
@ -129,6 +149,8 @@ abstract class Base {
|
||||
*/
|
||||
protected static function get_post_id_from_activitypub_id( $activitypub_id ): int {
|
||||
global $wpdb;
|
||||
|
||||
// phpcs:disable WordPress.DB.DirectDatabaseQuery
|
||||
return (int) $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT ID FROM $wpdb->posts WHERE guid=%s",
|
||||
@ -227,15 +249,13 @@ abstract class Base {
|
||||
|
||||
// Include necessary WordPress file for media handling.
|
||||
if ( ! function_exists( 'media_sideload_image' ) ) {
|
||||
// @phpstan-ignore-next-line
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
// @phpstan-ignore-next-line
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
// @phpstan-ignore-next-line
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
}
|
||||
|
||||
// Check to see if the URL has already been fetched, if so return the attachment ID.
|
||||
// phpcs:disable WordPress.DB.DirectDatabaseQuery
|
||||
$attachment_id = $wpdb->get_var(
|
||||
$wpdb->prepare( "SELECT `post_id` FROM {$wpdb->postmeta} WHERE `meta_key` = '_source_url' AND `meta_value` = %s", $url )
|
||||
);
|
||||
@ -243,6 +263,7 @@ abstract class Base {
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.DB.DirectDatabaseQuery
|
||||
$attachment_id = $wpdb->get_var(
|
||||
$wpdb->prepare( "SELECT `ID` FROM {$wpdb->posts} WHERE guid=%s", $url )
|
||||
);
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use Activitypub\Activity\Extended_Object\Place;
|
||||
@ -40,7 +40,7 @@ class GatherPress extends Base {
|
||||
$tags_array = $event->get_tag();
|
||||
|
||||
// Ensure the input is valid.
|
||||
if ( empty( $tags_array ) || ! is_array( $tags_array ) || ! $post_id ) {
|
||||
if ( empty( $tags_array ) || ! $post_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use Activitypub\Activity\Extended_Object\Place;
|
||||
@ -43,19 +43,18 @@ class The_Events_Calendar extends Base {
|
||||
add_filter( 'wp_revisions_to_keep', array( self::class, 'revisions_to_keep' ) );
|
||||
|
||||
$post_id = self::get_post_id_from_activitypub_id( $activitypub_event->get_id() );
|
||||
$duration = self::get_duration( $activitypub_event );
|
||||
$venue_id = self::add_venue( $activitypub_event, $event_source_post_id );
|
||||
$organizer_id = self::add_organizer( $activitypub_event );
|
||||
|
||||
$args = array(
|
||||
'title' => $activitypub_event->get_name(),
|
||||
'content' => $activitypub_event->get_content() ?? '',
|
||||
'start_date' => gmdate( 'Y-m-d H:i:s', strtotime( $activitypub_event->get_start_time() ) ),
|
||||
'duration' => $duration,
|
||||
'status' => 'publish',
|
||||
'guid' => $activitypub_event->get_id(),
|
||||
'title' => $activitypub_event->get_name(),
|
||||
'content' => $activitypub_event->get_content() ?? '',
|
||||
'status' => 'publish',
|
||||
'guid' => $activitypub_event->get_id(),
|
||||
);
|
||||
|
||||
$args = self::enrich_event_args_with_date_info( $args, $activitypub_event );
|
||||
|
||||
if ( $venue_id ) {
|
||||
$args['venue'] = $venue_id;
|
||||
$args['VenueID'] = $venue_id;
|
||||
@ -103,6 +102,33 @@ class The_Events_Calendar extends Base {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich event arguments with normalized start date and timezone.
|
||||
*
|
||||
* @param array $args Existing event arguments.
|
||||
* @param Event $activitypub_event The ActivityPub event as associative array.
|
||||
* @return array Modified $args array including 'start_date' and 'timezone' and 'duration'.
|
||||
*/
|
||||
private static function enrich_event_args_with_date_info( $args, $activitypub_event ): array {
|
||||
$start_time_str = $activitypub_event->get_start_time();
|
||||
$timezone_string = $activitypub_event->get_timezone();
|
||||
|
||||
$start_time = new \DateTime( $start_time_str );
|
||||
|
||||
if ( empty( $timezone_string ) ) {
|
||||
$timezone_string = 'UTC';
|
||||
}
|
||||
|
||||
$start_time->setTimezone( new \DateTimeZone( $timezone_string ) );
|
||||
|
||||
$args['timezone'] = $timezone_string;
|
||||
$args['start_date'] = $start_time->format( 'Y-m-d H:i:s' );
|
||||
$args['duration'] = self::get_duration( $activitypub_event );
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Map an ActivityStreams Place to the Events Calendar venue.
|
||||
*
|
||||
@ -148,6 +174,14 @@ class The_Events_Calendar extends Base {
|
||||
$args['guid'] = $location['id'];
|
||||
}
|
||||
|
||||
if ( isset( $location['latitude'] ) ) {
|
||||
$args['latitude'] = $location['latitude'];
|
||||
}
|
||||
|
||||
if ( isset( $location['longitude'] ) ) {
|
||||
$args['longitude'] = $location['longitude'];
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
@ -210,7 +244,6 @@ class The_Events_Calendar extends Base {
|
||||
$results = $tribe_venue->search( $location['name'] )->all();
|
||||
|
||||
foreach ( $results as $potential_matching_post_id ) {
|
||||
// @phpstan-ignore-next-line
|
||||
if ( $potential_matching_post_id instanceof \WP_Post ) {
|
||||
$potential_matching_post_id = $potential_matching_post_id->ID;
|
||||
}
|
||||
@ -251,6 +284,13 @@ class The_Events_Calendar extends Base {
|
||||
// This might likely change, because of FEP-8a8e.
|
||||
$actor = $activitypub_event->get_attributed_to();
|
||||
|
||||
/**
|
||||
* Allow filtering of incoming organizer.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
$actor = \apply_filters( 'event_bridge_for_activitypub_remote_organizer', $actor, $activitypub_event );
|
||||
|
||||
if ( is_null( $actor ) ) {
|
||||
return false;
|
||||
}
|
||||
@ -270,6 +310,7 @@ class The_Events_Calendar extends Base {
|
||||
'website' => $event_source->get_url(),
|
||||
'excerpt' => $event_source->get_summary(),
|
||||
'post_parent' => $event_source->get__id(), // Maybe just use post meta too here.
|
||||
'post_status' => 'publish',
|
||||
);
|
||||
|
||||
if ( $event_source->get_published() ) {
|
||||
@ -334,7 +375,7 @@ class The_Events_Calendar extends Base {
|
||||
$tags_array = $activitypub_event->get_tag();
|
||||
|
||||
// Ensure the input is valid.
|
||||
if ( empty( $tags_array ) || ! is_array( $tags_array ) || ! $post_id ) {
|
||||
if ( empty( $tags_array ) || ! $post_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use Activitypub\Activity\Extended_Object\Place;
|
||||
@ -77,7 +77,7 @@ class VS_Event_List extends Base {
|
||||
$tags_array = $activitypub_event->get_tag();
|
||||
|
||||
// Ensure the input is valid.
|
||||
if ( empty( $tags_array ) || ! is_array( $tags_array ) || ! $post_id ) {
|
||||
if ( empty( $tags_array ) || ! $post_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\Helper;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity\Extended_Object\Event;
|
||||
use Activitypub\Activity\Extended_Object\Place;
|
||||
@ -67,6 +67,10 @@ class Sanitizer {
|
||||
$event->set_end_time( \sanitize_text_field( $data['endTime'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['timezone'] ) && in_array( $data['timezone'], \DateTimeZone::listIdentifiers(), true ) ) {
|
||||
$event->set_timezone( \sanitize_text_field( $data['timezone'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['published'] ) ) {
|
||||
$event->set_published( \sanitize_text_field( $data['published'] ) );
|
||||
}
|
||||
@ -177,6 +181,17 @@ class Sanitizer {
|
||||
return array_is_list( $arr );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize an validate a float.
|
||||
*
|
||||
* @param mixed $value The input value.
|
||||
* @return float|null
|
||||
*/
|
||||
private static function validate_and_sanitize_float( $value ) {
|
||||
$sanitized = filter_var( $value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
|
||||
return is_numeric( $sanitized ) ? (float) $sanitized : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert input array to an Location.
|
||||
*
|
||||
@ -189,9 +204,18 @@ class Sanitizer {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the array is a list, work with the first item.
|
||||
if ( array_key_exists( 0, $data ) ) {
|
||||
$data = $data[0];
|
||||
// If the array is a list, search for the first item with 'type' === 'Place'.
|
||||
if ( self::array_is_list( $data ) ) {
|
||||
foreach ( $data as $item ) {
|
||||
if ( is_array( $item ) && ( 'Place' === ( $item['type'] ?? null ) ) ) {
|
||||
$data = $item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isset( $data['type'] ) || 'Place' !== $data['type'] ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$place = new Place();
|
||||
@ -204,6 +228,14 @@ class Sanitizer {
|
||||
$place->set_id( \sanitize_url( $data['id'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['latitude'] ) ) {
|
||||
$place->set_latitude( self::validate_and_sanitize_float( $data['latitude'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['longitude'] ) ) {
|
||||
$place->set_longitude( self::validate_and_sanitize_float( $data['longitude'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['url'] ) ) {
|
||||
$place->set_url( \sanitize_url( $data['url'] ) );
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\Helper;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
/**
|
||||
* Extending the Tribe Events API to allow setting of the guid.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\Helper;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
/**
|
||||
* Extending the Organizer Venue API to allow setting of the guid.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
namespace Event_Bridge_For_ActivityPub\ActivityPub\Transmogrifier\Helper;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
\defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
/**
|
||||
* Extending the Tribe Venue API to allow setting of the guid.
|
||||
@ -29,6 +29,30 @@ class The_Events_Calendar_Venue_Repository extends \Tribe__Events__Repositories_
|
||||
'comment_count',
|
||||
);
|
||||
|
||||
/**
|
||||
* Tribe__Events__Repositories__Venue constructor.
|
||||
*
|
||||
* Add aliases for longitude an latitude.
|
||||
*
|
||||
* @since 4.9
|
||||
* @since 6.10.1 Added `show_map` and `show_map_link` aliases.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
// Add venue specific aliases.
|
||||
$this->update_fields_aliases = array_merge(
|
||||
$this->update_fields_aliases,
|
||||
array(
|
||||
'latitude' => '_VenueLat',
|
||||
'longitude' => '_VenueLng',
|
||||
)
|
||||
);
|
||||
|
||||
$this->add_simple_meta_schema_entry( 'latitude', '_VenueLat' );
|
||||
$this->add_simple_meta_schema_entry( 'longitude', '_VenueLng' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current key can be updated by this repository or not.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user