Compare commits
6 commits
main
...
refactorin
Author | SHA1 | Date | |
---|---|---|---|
30acc30caf | |||
e0afda10e2 | |||
4b9dbbef06 | |||
9eebf588ab | |||
735926745b | |||
1232aaf4bc |
14 changed files with 615 additions and 419 deletions
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Plugin Name: ActivityPub Event Extensions
|
* Plugin Name: ActivityPub Event Extensions
|
||||||
* Description: Custom ActivityPub Transformers and Integretions for common Event Plugins
|
* Description: Custom ActivityPub Transformers and Integrations for common Event Plugins
|
||||||
* Plugin URI: https://event-federation.eu/
|
* Plugin URI: https://event-federation.eu/
|
||||||
* Version: 1.0.0
|
* Version: 1.0.0
|
||||||
* Author: André Menrath
|
* Author: André Menrath
|
||||||
|
@ -9,90 +9,52 @@
|
||||||
* Text Domain: activitypub-event-extensions
|
* Text Domain: activitypub-event-extensions
|
||||||
* License: AGPL-3.0-or-later
|
* License: AGPL-3.0-or-later
|
||||||
*
|
*
|
||||||
* ActivityPub tested up to: 2.2.0
|
* ActivityPub tested up to: 2.4.0
|
||||||
*
|
*
|
||||||
* @package activitypub-event-extensions
|
* @package activitypub-event-extensions
|
||||||
* @license AGPL-3.0-or-later
|
* @license AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
// Exit if accessed directly.
|
||||||
exit; // Exit if accessed directly.
|
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
define( 'ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_VERSION', '1.0.0' );
|
||||||
* Add the custom transformers for the events of several WordPress event plugins.
|
|
||||||
*/
|
|
||||||
add_filter(
|
|
||||||
'activitypub_transformer',
|
|
||||||
function( $transformer, $wp_object, $object_class ) {
|
|
||||||
if ( 'WP_Post' != $object_class ) {
|
|
||||||
return $transformer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
define( 'ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||||||
* VS Event List
|
define( 'ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
|
||||||
* @see https://wordpress.org/plugins/very-simple-event-list/
|
define( 'ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_FILE', plugin_dir_path( __FILE__ ) . '/' . basename( __FILE__ ) );
|
||||||
*/
|
define( 'ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||||||
if ( class_exists( 'vsel_widget' ) && $wp_object->post_type === 'event' ) {
|
|
||||||
require_once __DIR__ . '/includes/activitypub/transformer/class-vs-event.php';
|
|
||||||
return new \VS_Event( $wp_object );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Include and register the autoloader class for automatic loading of plugin classes.
|
||||||
* Events manager
|
require_once ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_DIR . '/includes/class-autoloader.php';
|
||||||
* @see https://wordpress.org/plugins/events-manager/
|
Activitypub_Event_Extensions\Autoloader::register();
|
||||||
*/
|
|
||||||
if ( class_exists( 'EM_Events' ) && $wp_object->post_type === 'event' ) {
|
|
||||||
require_once __DIR__ . '/includes/activitypub/transformer/class-events-manager.php';
|
|
||||||
return new \Events_Manager( $wp_object );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Initialize the plugin.
|
||||||
* Events manager
|
Activitypub_Event_Extensions\Setup::get_instance();
|
||||||
* @see https://wordpress.org/plugins/events-manager/
|
|
||||||
*/
|
|
||||||
if ( class_exists( 'GatherPress\Core\Event' ) && $wp_object->post_type === 'gp_event' ) {
|
|
||||||
require_once __DIR__ . '/includes/activitypub/transformer/class-gatherpress.php';
|
|
||||||
return new \GatherPress( $wp_object );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the default transformer.
|
|
||||||
|
|
||||||
return $transformer;
|
|
||||||
},
|
|
||||||
10,
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activate the plugin.
|
|
||||||
*/
|
|
||||||
function activitypub_event_extensions_activate() {
|
|
||||||
// Don't allow plugin activation, when the ActivityPub plugin is not activated yet.
|
|
||||||
if( ! class_exists( 'ActivtiyPub' ) ) {
|
|
||||||
deactivate_plugins( plugin_basename( __FILE__ ) );
|
|
||||||
wp_die( __( 'Please install and Activate ActivityPub.', 'activitypub-event-extensions' ), 'Plugin dependency check', array( 'back_link' => true ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_activation_hook( __FILE__, 'activitypub_event_extensions_activate' );
|
|
||||||
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// require_once __DIR__ . '/admin/class-admin-notices.php';
|
|
||||||
// new \Admin_Notices();
|
// For local development purposes: TODO. Remove everything after here.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a filter for http_request_host_is_external
|
* Add a filter for http_request_host_is_external
|
||||||
*
|
*
|
||||||
* TODO: Remove this.
|
* TODO: Remove this for release.
|
||||||
*
|
*
|
||||||
* @todo This filter is temporary code needed to do local testing.
|
* @todo This filter is temporary code needed to do local testing.
|
||||||
*/
|
*/
|
||||||
add_filter( 'http_request_host_is_external', 'custom_http_request_host_is_external', 10, 3 );
|
add_filter( 'http_request_host_is_external', 'custom_http_request_host_is_external', 10, 3 );
|
||||||
|
|
||||||
// Your custom callback function
|
/**
|
||||||
|
* Add a filter for http_request_host_is_external
|
||||||
|
*
|
||||||
|
* TODO: Remove this for release.
|
||||||
|
*
|
||||||
|
* @todo This filter is temporary code needed to do local testing.
|
||||||
|
*/
|
||||||
function custom_http_request_host_is_external( $is_external, $host, $url ) {
|
function custom_http_request_host_is_external( $is_external, $host, $url ) {
|
||||||
$is_external = true;
|
$is_external = true;
|
||||||
|
|
||||||
|
@ -102,7 +64,7 @@ function custom_http_request_host_is_external( $is_external, $host, $url ) {
|
||||||
/**
|
/**
|
||||||
* Don't verify ssl certs for testing.
|
* Don't verify ssl certs for testing.
|
||||||
*
|
*
|
||||||
* TODO: Remove this.
|
* TODO: Remove this for release.
|
||||||
*
|
*
|
||||||
* @todo This filter is temporary code needed to do local testing.
|
* @todo This filter is temporary code needed to do local testing.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Admin Notices for guiding to proper configuration of ActivityPub with event plugins.
|
|
||||||
*
|
|
||||||
* @package activity-event-transformers
|
|
||||||
* @license AGPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO: Modularize after we know what we want.
|
|
||||||
class Admin_Notices {
|
|
||||||
const VSEL_PLUGIN_FILE = 'very-simple-event-list/vsel.php';
|
|
||||||
const VSEL_POST_TYPE = 'event';
|
|
||||||
const EVENTS_MANAGER_PLUGIN_FILE = 'events-manager/events-manager.php';
|
|
||||||
const EVENTS_MANAGER_POTS_TYPE = 'event';
|
|
||||||
const TRIBE_POST_TYPE = 'tribe_events';
|
|
||||||
const TRIBE_PLUGIN_FILE = 'the-events-calendar/the-events-calendar.php';
|
|
||||||
const ACTIVITYPUB_PLUGIN_FILE = 'activitypub/activitypub.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add actions and filters.
|
|
||||||
*/
|
|
||||||
public function __construct() {
|
|
||||||
add_action( 'admin_init', array( self::class, 'check_for_admin_notices' ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the conditions for admin notices
|
|
||||||
*
|
|
||||||
* These should mainly improve usability.
|
|
||||||
*/
|
|
||||||
public static function check_for_admin_notices() {
|
|
||||||
|
|
||||||
if ( is_admin() && is_plugin_active( self::ACTIVITYPUB_PLUGIN_FILE ) ) {
|
|
||||||
// Check for VSEL
|
|
||||||
if ( is_plugin_active( self::VSEL_PLUGIN_FILE ) && self::post_type_is_not_activitypub_enabled( self::VSEL_POST_TYPE ) ) {
|
|
||||||
add_action( 'admin_notices', array( self::class, 'vsel_admin_notices' ) );
|
|
||||||
}
|
|
||||||
// Check for Events Manager
|
|
||||||
if ( is_plugin_active( self::EVENTS_MANAGER_PLUGIN_FILE ) && self::post_type_is_not_activitypub_enabled( self::EVENTS_MANAGER_POTS_TYPE ) ) {
|
|
||||||
add_action( 'admin_notices', array( self::class, 'events_manager_admin_notices' ) );
|
|
||||||
}
|
|
||||||
// Check for The Events Calendar
|
|
||||||
if ( is_plugin_active( self::TRIBE_PLUGIN_FILE ) && self::post_type_is_not_activitypub_enabled( self::TRIBE_POST_TYPE ) ) {
|
|
||||||
add_action( 'admin_notices', array( self::class, 'the_events_calendar_admin_notices' ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if ActivityPub is enabled for the custom post type of the event plugin.
|
|
||||||
*
|
|
||||||
* @param string $post_type The post type of the event plugin.
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private static function post_type_is_not_activitypub_enabled( $post_type ) {
|
|
||||||
return ! in_array( $post_type, get_option( 'activitypub_support_post_types' ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether to do any admin notices for VSEL
|
|
||||||
*/
|
|
||||||
public static function vsel_admin_notices() {
|
|
||||||
$is_vsel_edit_page = isset( $_GET['post_type'] ) && $_GET['post_type'] === self::VSEL_POST_TYPE;
|
|
||||||
$is_vsel_settings_page = strpos( $_SERVER['REQUEST_URI'], '/wp-admin/options-general.php?page=vsel' ) !== false;
|
|
||||||
$is_vsel_page = $is_vsel_edit_page || $is_vsel_settings_page;
|
|
||||||
if ( $is_vsel_page ) {
|
|
||||||
self::do_admin_notice_post_type_not_activitypub_enabled( self::VSEL_PLUGIN_FILE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether to do any admin notices for Events Manager
|
|
||||||
*/
|
|
||||||
public static function events_manager_admin_notices() {
|
|
||||||
$is_events_manager_page = isset( $_GET['post_type'] ) && $_GET['post_type'] === self::EVENTS_MANAGER_POTS_TYPE;
|
|
||||||
if ( $is_events_manager_page ) {
|
|
||||||
self::do_admin_notice_post_type_not_activitypub_enabled( self::EVENTS_MANAGER_PLUGIN_FILE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether to do any admin notices for The Events Calendar
|
|
||||||
*/
|
|
||||||
public static function the_events_calendar_admin_notices() {
|
|
||||||
$is_events_manager_page = isset( $_GET['post_type'] ) && $_GET['post_type'] === self::TRIBE_POST_TYPE;
|
|
||||||
if ( $is_events_manager_page ) {
|
|
||||||
self::do_admin_notice_post_type_not_activitypub_enabled( self::TRIBE_PLUGIN_FILE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print admin notice that the current post type is not enabled in the ActivityPub plugin.
|
|
||||||
*/
|
|
||||||
private static function do_admin_notice_post_type_not_activitypub_enabled( $event_plugin_file ) {
|
|
||||||
$vsel_plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $event_plugin_file );
|
|
||||||
$activitypub_plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . self::ACTIVITYPUB_PLUGIN_FILE );
|
|
||||||
$notice = sprintf(
|
|
||||||
_x(
|
|
||||||
'You have installed the %1$s plugin, but the event post type of %2$s is not enabled in the <a href="%3$s">%1$s settings</a>.',
|
|
||||||
'admin notice',
|
|
||||||
'your-text-domain'
|
|
||||||
),
|
|
||||||
$activitypub_plugin_data['Name'],
|
|
||||||
$vsel_plugin_data['Name'],
|
|
||||||
admin_url( 'options-general.php?page=activitypub&tab=settings' )
|
|
||||||
);
|
|
||||||
wp_admin_notice(
|
|
||||||
$notice,
|
|
||||||
array(
|
|
||||||
'type' => 'warning',
|
|
||||||
'dismissible' => true,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Handling Event Joins.
|
|
||||||
*
|
|
||||||
* @package activitypub-event-extensions
|
|
||||||
*/
|
|
79
includes/activitypub/transformer/class-event.php
Normal file
79
includes/activitypub/transformer/class-event.php
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Replace the default ActivityPub Transformer
|
||||||
|
*
|
||||||
|
* @package activity-event-transformers
|
||||||
|
* @license AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Activitypub_Event_Extensions\Activitypub\Transformer;
|
||||||
|
|
||||||
|
use Activitypub\Activity\Extended_Object\Event as Event_Object;
|
||||||
|
use Activitypub\Model\Blog;
|
||||||
|
use Activitypub\Transformer\Post;
|
||||||
|
|
||||||
|
use function Activitypub\get_rest_url_by_path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base transformer for WordPress event post types to ActivityPub events.
|
||||||
|
*/
|
||||||
|
class Event extends Post {
|
||||||
|
/**
|
||||||
|
* Returns the User-URL of the Author of the Post.
|
||||||
|
*
|
||||||
|
* If `single_user` mode is enabled, the URL of the Blog-User is returned.
|
||||||
|
*
|
||||||
|
* @return string The User-URL.
|
||||||
|
*/
|
||||||
|
protected function get_attributed_to() {
|
||||||
|
$blog = new Blog();
|
||||||
|
return $blog->get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ActivityStreams 2.0 Object-Type for an Event.
|
||||||
|
*
|
||||||
|
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-event
|
||||||
|
*
|
||||||
|
* @return string The Event Object-Type.
|
||||||
|
*/
|
||||||
|
protected function get_object_type() {
|
||||||
|
return 'Event';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic function that converts an WP-Event object to an ActivityPub-Event object.
|
||||||
|
*
|
||||||
|
* @return Event_Object
|
||||||
|
*/
|
||||||
|
public function to_object() {
|
||||||
|
$activitypub_object = new Event_Object();
|
||||||
|
$activitypub_object = $this->transform_object_properties( $activitypub_object );
|
||||||
|
|
||||||
|
$published = \strtotime( $this->wp_object->post_date_gmt );
|
||||||
|
|
||||||
|
$activitypub_object->set_published( \gmdate( 'Y-m-d\TH:i:s\Z', $published ) );
|
||||||
|
|
||||||
|
$updated = \strtotime( $this->wp_object->post_modified_gmt );
|
||||||
|
|
||||||
|
if ( $updated > $published ) {
|
||||||
|
$activitypub_object->set_updated( \gmdate( 'Y-m-d\TH:i:s\Z', $updated ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$activitypub_object->set_content_map(
|
||||||
|
array(
|
||||||
|
$this->get_locale() => $this->get_content(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$path = sprintf( 'actors/%d/followers', intval( $this->wp_object->post_author ) );
|
||||||
|
|
||||||
|
$activitypub_object->set_to(
|
||||||
|
array(
|
||||||
|
'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
get_rest_url_by_path( $path ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $activitypub_object;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,11 +7,10 @@
|
||||||
* @license AGPL-3.0-or-later
|
* @license AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Activitypub_Event_Extensions\Activitypub\Transformer\Event as Event_Transformer;
|
||||||
use EM_Event;
|
use EM_Event;
|
||||||
use Activitypub\Activity\Extended_Object\Event;
|
use Activitypub\Activity\Extended_Object\Event;
|
||||||
use Activitypub\Activity\Extended_Object\Place;
|
use Activitypub\Activity\Extended_Object\Place;
|
||||||
use Activitypub\Transformer\Post;
|
|
||||||
|
|
||||||
use function Activitypub\esc_hashtag;
|
use function Activitypub\esc_hashtag;
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
@ -25,7 +24,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
class Events_Manager extends Post {
|
class Events_Manager extends Event_Transformer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the EM_Event object.
|
* Holds the EM_Event object.
|
||||||
|
@ -44,7 +43,6 @@ class Events_Manager extends Post {
|
||||||
* @return string Widget name.
|
* @return string Widget name.
|
||||||
*/
|
*/
|
||||||
public function get_transformer_name() {
|
public function get_transformer_name() {
|
||||||
|
|
||||||
return 'activitypub-event-transformers/events-manager';
|
return 'activitypub-event-transformers/events-manager';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +56,6 @@ class Events_Manager extends Post {
|
||||||
* @return string Widget title.
|
* @return string Widget title.
|
||||||
*/
|
*/
|
||||||
public function get_transformer_label() {
|
public function get_transformer_label() {
|
||||||
|
|
||||||
return 'Events Manager';
|
return 'Events Manager';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +69,6 @@ class Events_Manager extends Post {
|
||||||
* @return array Widget categories.
|
* @return array Widget categories.
|
||||||
*/
|
*/
|
||||||
public static function get_supported_post_types() {
|
public static function get_supported_post_types() {
|
||||||
|
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,23 +80,19 @@ class Events_Manager extends Post {
|
||||||
* @return string The Event Object-Type.
|
* @return string The Event Object-Type.
|
||||||
*/
|
*/
|
||||||
protected function get_type() {
|
protected function get_type() {
|
||||||
|
|
||||||
return 'Event';
|
return 'Event';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get_is_online() {
|
protected function get_is_online() {
|
||||||
|
|
||||||
return 'url' === $this->em_event->event_location_type;
|
return 'url' === $this->em_event->event_location_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the event location.
|
* Get the event location.
|
||||||
*
|
*
|
||||||
* @param int $post_id The WordPress post ID.
|
|
||||||
* @return array The Place.
|
* @return array The Place.
|
||||||
*/
|
*/
|
||||||
public function get_location() {
|
public function get_location() {
|
||||||
|
|
||||||
if ( 'url' === $this->em_event->event_location_type ) {
|
if ( 'url' === $this->em_event->event_location_type ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +124,6 @@ class Events_Manager extends Post {
|
||||||
* Get the end time from the events metadata.
|
* Get the end time from the events metadata.
|
||||||
*/
|
*/
|
||||||
protected function get_end_time() {
|
protected function get_end_time() {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +131,6 @@ class Events_Manager extends Post {
|
||||||
* Get the end time from the events metadata.
|
* Get the end time from the events metadata.
|
||||||
*/
|
*/
|
||||||
protected function get_start_time() {
|
protected function get_start_time() {
|
||||||
|
|
||||||
$date_string = $this->em_event->event_start_date;
|
$date_string = $this->em_event->event_start_date;
|
||||||
$time_string = $this->em_event->event_start_time;
|
$time_string = $this->em_event->event_start_time;
|
||||||
$timezone_string = $this->em_event->event_timezone;
|
$timezone_string = $this->em_event->event_timezone;
|
||||||
|
@ -157,7 +147,6 @@ class Events_Manager extends Post {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get_maximum_attendee_capacity() {
|
protected function get_maximum_attendee_capacity() {
|
||||||
|
|
||||||
return $this->em_event->event_spaces;
|
return $this->em_event->event_spaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,25 +154,21 @@ class Events_Manager extends Post {
|
||||||
* @todo decide whether to include pending bookings or not!
|
* @todo decide whether to include pending bookings or not!
|
||||||
*/
|
*/
|
||||||
protected function get_remaining_attendee_capacity() {
|
protected function get_remaining_attendee_capacity() {
|
||||||
|
|
||||||
$em_bookings = $this->em_event->get_bookings()->get_bookings();
|
$em_bookings = $this->em_event->get_bookings()->get_bookings();
|
||||||
$remaining_attendee_capacity = $this->em_event->event_spaces - count( $em_bookings->bookings );
|
$remaining_attendee_capacity = $this->em_event->event_spaces - count( $em_bookings->bookings );
|
||||||
return $remaining_attendee_capacity;
|
return $remaining_attendee_capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get_participant_count() {
|
protected function get_participant_count() {
|
||||||
|
|
||||||
$em_bookings = $this->em_event->get_bookings()->get_bookings();
|
$em_bookings = $this->em_event->get_bookings()->get_bookings();
|
||||||
return count( $em_bookings->bookings );
|
return count( $em_bookings->bookings );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get_content() {
|
protected function get_content() {
|
||||||
|
|
||||||
return $this->wp_object->post_content;
|
return $this->wp_object->post_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get_summary() {
|
protected function get_summary() {
|
||||||
|
|
||||||
if ( $this->em_event->post_excerpt ) {
|
if ( $this->em_event->post_excerpt ) {
|
||||||
$excerpt = $this->em_event->post_excerpt;
|
$excerpt = $this->em_event->post_excerpt;
|
||||||
} else {
|
} else {
|
||||||
|
@ -202,7 +187,6 @@ class Events_Manager extends Post {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private function get_event_link_attachment() {
|
private function get_event_link_attachment() {
|
||||||
|
|
||||||
$event_link_url = $this->em_event->event_location->data['url'];
|
$event_link_url = $this->em_event->event_location->data['url'];
|
||||||
$event_link_text = $this->em_event->event_location->data['text'];
|
$event_link_text = $this->em_event->event_location->data['text'];
|
||||||
return array(
|
return array(
|
||||||
|
@ -218,7 +202,7 @@ class Events_Manager extends Post {
|
||||||
* Overrides/extends the get_attachments function to also add the event Link.
|
* Overrides/extends the get_attachments function to also add the event Link.
|
||||||
*/
|
*/
|
||||||
protected function get_attachment() {
|
protected function get_attachment() {
|
||||||
// Get attachments via parent function
|
// Get attachments via parent function.
|
||||||
$attachments = parent::get_attachment();
|
$attachments = parent::get_attachment();
|
||||||
|
|
||||||
// The first attachment is the featured image, make sure it is compatible with Mobilizon.
|
// The first attachment is the featured image, make sure it is compatible with Mobilizon.
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use Activitypub\Transformer\Post;
|
use Activitypub\Transformer\Post;
|
||||||
use Activitypub\Model\Blog_user;
|
use Activitypub\Model\Blog_user;
|
||||||
use Activitypub\Activity\Extended_Object\Event;
|
use Activitypub\Activity\Extended_Object\Event as Event_Object;
|
||||||
use Activitypub\Activity\Extended_Object\Place;
|
use Activitypub\Activity\Extended_Object\Place;
|
||||||
use GatherPress\Core\Event as GatherPress_Event;
|
use GatherPress\Core\Event as GatherPress_Event;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
class GatherPress extends Post {
|
class GatherPress extends Post {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The target transformet ActivityPub Event object.
|
* The target ActivityPub Event object of the transformer.
|
||||||
*
|
*
|
||||||
* @var Event
|
* @var Event
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityPub Tribe Transformer
|
* ActivityPub Tribe Transformer
|
||||||
*
|
*
|
||||||
|
@ -7,20 +6,22 @@
|
||||||
* @license AGPL-3.0-or-later
|
* @license AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace Activitypub_Event_Extensions\Activitypub\Transformer;
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
exit; // Exit if accessed directly.
|
exit; // Exit if accessed directly.
|
||||||
}
|
}
|
||||||
|
|
||||||
use Activitypub\Transformer\Post;
|
use Activitypub_Event_Extensions\Activitypub\Transformer\Event;
|
||||||
use Activitypub\Activity\Extended_Object\Event;
|
|
||||||
use Activitypub\Activity\Extended_Object\Place;
|
use Activitypub\Activity\Extended_Object\Place;
|
||||||
|
use WP_Error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityPub Tribe Transformer
|
* ActivityPub Tribe Transformer
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
class Tribe extends Post {
|
class Tribe extends Event {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Tribe Event object.
|
* The Tribe Event object.
|
||||||
|
@ -40,69 +41,14 @@ class Tribe extends Post {
|
||||||
// $this->tribe_event = tribe_get_event( $wp_post->ID );
|
// $this->tribe_event = tribe_get_event( $wp_post->ID );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
|
||||||
* Get widget name.
|
|
||||||
*
|
|
||||||
* Retrieve oEmbed widget name.
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
* @access public
|
|
||||||
* @return string Widget name.
|
|
||||||
*/
|
|
||||||
public function get_name() {
|
|
||||||
|
|
||||||
return 'activitypub-event-transformers/tribe';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get widget title.
|
|
||||||
*
|
|
||||||
* Retrieve Transformer title.
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
* @access public
|
|
||||||
* @return string Widget title.
|
|
||||||
*/
|
|
||||||
public function get_label() {
|
|
||||||
|
|
||||||
return 'The Events Calendar';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the ActivityStreams 2.0 Object-Type for an Event.
|
|
||||||
*
|
|
||||||
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-event
|
|
||||||
*
|
|
||||||
* @return string The Event Object-Type.
|
|
||||||
*/
|
|
||||||
protected function get_object_type() {
|
|
||||||
|
|
||||||
return 'Event';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get supported post types.
|
|
||||||
*
|
|
||||||
* Retrieve the list of supported WordPress post types this transformer widget can handle.
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
* @access public
|
|
||||||
* @return array Widget categories.
|
|
||||||
*/
|
|
||||||
public static function get_supported_post_types() {
|
|
||||||
|
|
||||||
return array( 'tribe_events' );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get tribe category of wp_post
|
* Get tribe category of wp_post
|
||||||
*
|
*
|
||||||
* @return string|null tribe category if it exists
|
* @return string|null tribe category if it exists
|
||||||
*/
|
*/
|
||||||
public function get_tribe_category() {
|
public function get_tribe_category() {
|
||||||
// todo make it possible that one event can have multiple categories?
|
// TODO: make it possible that one event can have multiple categories?
|
||||||
|
// Using cat_slugs isn't the best way to do this, don't know if it's a good idea.
|
||||||
// using cat_slugs isn't 100% nice way to do this, don't know if it's a good idea
|
|
||||||
$categories = tribe_get_event_cat_slugs( $this->wp_object->ID );
|
$categories = tribe_get_event_cat_slugs( $this->wp_object->ID );
|
||||||
|
|
||||||
if ( count( $categories ) === 0 ) {
|
if ( count( $categories ) === 0 ) {
|
||||||
|
@ -123,7 +69,7 @@ class Tribe extends Post {
|
||||||
return 'CANCELLED';
|
return 'CANCELLED';
|
||||||
}
|
}
|
||||||
if ( 'postponed' === $this->tribe_event->event_status ) {
|
if ( 'postponed' === $this->tribe_event->event_status ) {
|
||||||
return 'CANCELLED'; // this will be reflected in the cancelled reason
|
return 'CANCELLED'; // This will be reflected in the cancelled reason.
|
||||||
}
|
}
|
||||||
if ( '' === $this->tribe_event->event_status ) {
|
if ( '' === $this->tribe_event->event_status ) {
|
||||||
return 'CONFIRMED';
|
return 'CONFIRMED';
|
||||||
|
@ -142,12 +88,12 @@ class Tribe extends Post {
|
||||||
protected function get_content() {
|
protected function get_content() {
|
||||||
|
|
||||||
$content = parent::get_content();
|
$content = parent::get_content();
|
||||||
// todo remove link at the end of the content
|
// TODO: remove link at the end of the content.
|
||||||
|
|
||||||
// todo add organizer
|
// TODO: add organizer
|
||||||
// $this->tribe_event->organizers[0]
|
// $this->tribe_event->organizers[0].
|
||||||
|
|
||||||
// todo add Canclled reason in the content (maybe at the end)
|
// TODO: do add Cancelled reason in the content (maybe at the end).
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
@ -155,11 +101,12 @@ class Tribe extends Post {
|
||||||
/**
|
/**
|
||||||
* Get the event location.
|
* Get the event location.
|
||||||
*
|
*
|
||||||
* @param int $post_id The WordPress post ID.
|
|
||||||
* @returns array The Place.
|
* @returns array The Place.
|
||||||
*/
|
*/
|
||||||
public function get_event_location() {
|
public function get_event_location() {
|
||||||
/*
|
/*
|
||||||
|
This is how the Tribe event looks like:
|
||||||
|
TODO: Remove this comment.
|
||||||
'post_title' => 'testvenue',
|
'post_title' => 'testvenue',
|
||||||
'post_name' => 'testvenue',
|
'post_name' => 'testvenue',
|
||||||
'guid' => 'http://localhost/venue/testvenue/',
|
'guid' => 'http://localhost/venue/testvenue/',
|
||||||
|
@ -184,6 +131,6 @@ class Tribe extends Post {
|
||||||
$venue->address . "\n" .
|
$venue->address . "\n" .
|
||||||
$venue->zip . ', ' . $venue->city . "\n" .
|
$venue->zip . ', ' . $venue->city . "\n" .
|
||||||
$venue->country
|
$venue->country
|
||||||
); // todo add checks that everything exists here (lol)
|
); // TODO: add checks that everything exists here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityPub Transformer for the plugin Very Simple Event List.
|
* ActivityPub Transformer for the plugin Very Simple Event List.
|
||||||
*
|
*
|
||||||
|
@ -7,11 +6,14 @@
|
||||||
* @license AGPL-3.0-or-later
|
* @license AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Activitypub\Transformer\Post;
|
namespace Activitypub_Event_Extensions\Activitypub\Transformer;
|
||||||
use Activitypub\Model\Blog_user;
|
|
||||||
|
use Activitypub_Event_Extensions\Activitypub\Transformer\Event as Event_Transformer;
|
||||||
|
use Activitypub\Model\Blog;
|
||||||
use Activitypub\Activity\Extended_Object\Event;
|
use Activitypub\Activity\Extended_Object\Event;
|
||||||
use Activitypub\Activity\Extended_Object\Place;
|
use Activitypub\Activity\Extended_Object\Place;
|
||||||
|
|
||||||
|
use WP_Error;
|
||||||
use function Activitypub\get_rest_url_by_path;
|
use function Activitypub\get_rest_url_by_path;
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
@ -23,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
class VS_Event extends Post {
|
class VS_Event extends Event_Transformer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The target transformet ActivityPub Event object.
|
* The target transformet ActivityPub Event object.
|
||||||
|
@ -89,7 +91,6 @@ class VS_Event extends Post {
|
||||||
/**
|
/**
|
||||||
* Get the event location.
|
* Get the event location.
|
||||||
*
|
*
|
||||||
* @param int $post_id The WordPress post ID.
|
|
||||||
* @return array The Place.
|
* @return array The Place.
|
||||||
*/
|
*/
|
||||||
public function get_location() {
|
public function get_location() {
|
||||||
|
@ -148,7 +149,7 @@ class VS_Event extends Post {
|
||||||
}
|
}
|
||||||
$event_link = $this->get_event_link();
|
$event_link = $this->get_event_link();
|
||||||
if ( $event_link ) {
|
if ( $event_link ) {
|
||||||
$attachments[] = $this->get_event_link();
|
$attachments[] = $event_link;
|
||||||
}
|
}
|
||||||
return $attachments;
|
return $attachments;
|
||||||
}
|
}
|
||||||
|
@ -159,62 +160,9 @@ class VS_Event extends Post {
|
||||||
* @return string $category
|
* @return string $category
|
||||||
*/
|
*/
|
||||||
protected function get_category() {
|
protected function get_category() {
|
||||||
|
|
||||||
$post_categories = wp_get_post_terms( $this->wp_object->ID, 'event_cat' );
|
|
||||||
|
|
||||||
if ( empty( $post_categories ) ) {
|
|
||||||
return 'MEETING';
|
return 'MEETING';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare an array to store all category information for comparison.
|
|
||||||
$category_info = array();
|
|
||||||
|
|
||||||
// Extract relevant category information (name, slug, description) from the categories array.
|
|
||||||
foreach ( $post_categories as $category ) {
|
|
||||||
$category_info[] = strtolower( $category->name );
|
|
||||||
$category_info[] = strtolower( $category->slug );
|
|
||||||
$category_info[] = strtolower( $category->description );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert mobilizon categories to lowercase for case-insensitive comparison.
|
|
||||||
$mobilizon_categories = array_map( 'strtolower', Event::DEFAULT_EVENT_CATEGORIES );
|
|
||||||
|
|
||||||
// Initialize variables to track the best match.
|
|
||||||
$best_mobilizon_category_match = '';
|
|
||||||
$best_match_length = 0;
|
|
||||||
|
|
||||||
// Check for the best match.
|
|
||||||
foreach ( $mobilizon_categories as $mobilizon_category ) {
|
|
||||||
foreach ( $category_info as $category ) {
|
|
||||||
foreach ( explode( '_', $mobilizon_category ) as $mobilizon_category_slice ) {
|
|
||||||
if ( stripos( $category, $mobilizon_category_slice ) !== false ) {
|
|
||||||
// Check if the current match is longer than the previous best match.
|
|
||||||
$current_match_legnth = strlen( $mobilizon_category_slice );
|
|
||||||
if ( $current_match_legnth > $best_match_length ) {
|
|
||||||
$best_mobilizon_category_match = $mobilizon_category;
|
|
||||||
$best_match_length = $current_match_legnth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( '' != $best_mobilizon_category_match ) ? strtoupper( $best_mobilizon_category_match ) : 'MEETING';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the User-URL of the Author of the Post.
|
|
||||||
*
|
|
||||||
* If `single_user` mode is enabled, the URL of the Blog-User is returned.
|
|
||||||
*
|
|
||||||
* @return string The User-URL.
|
|
||||||
*/
|
|
||||||
protected function get_attributed_to() {
|
|
||||||
|
|
||||||
$user = new Blog_User();
|
|
||||||
return $user->get_url();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a custom summary.
|
* Create a custom summary.
|
||||||
*
|
*
|
||||||
|
@ -224,7 +172,6 @@ class VS_Event extends Post {
|
||||||
* @return string $summary The custom event summary.
|
* @return string $summary The custom event summary.
|
||||||
*/
|
*/
|
||||||
public function get_summary() {
|
public function get_summary() {
|
||||||
|
|
||||||
if ( $this->wp_object->excerpt ) {
|
if ( $this->wp_object->excerpt ) {
|
||||||
$excerpt = $this->wp_object->post_excerpt;
|
$excerpt = $this->wp_object->post_excerpt;
|
||||||
} elseif ( get_post_meta( $this->wp_object->ID, 'event-summary', true ) ) {
|
} elseif ( get_post_meta( $this->wp_object->ID, 'event-summary', true ) ) {
|
||||||
|
@ -315,7 +262,8 @@ class VS_Event extends Post {
|
||||||
->set_in_language( $this->get_locale() )
|
->set_in_language( $this->get_locale() )
|
||||||
->set_actor( get_rest_url_by_path( 'application' ) )
|
->set_actor( get_rest_url_by_path( 'application' ) )
|
||||||
->set_to( array( 'https://www.w3.org/ns/activitystreams#Public' ) )
|
->set_to( array( 'https://www.w3.org/ns/activitystreams#Public' ) )
|
||||||
->set_location();
|
->set_location()
|
||||||
|
->set_id();
|
||||||
return $this->ap_object;
|
return $this->ap_object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
93
includes/admin/class-event-plugin-admin-notices.php
Normal file
93
includes/admin/class-event-plugin-admin-notices.php
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class responsible for Event Plugin related admin notices.
|
||||||
|
*
|
||||||
|
* Notices for guiding to proper configuration of ActivityPub with event plugins.
|
||||||
|
*
|
||||||
|
* @package Activitypub_Event_Extensions
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Activitypub_Event_Extensions\Admin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible for Event Plugin related admin notices.
|
||||||
|
*
|
||||||
|
* Notices for guiding to proper configuration of ActivityPub with event plugins.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class Event_Plugin_Admin_Notices {
|
||||||
|
/**
|
||||||
|
* Information about the event plugin.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $event_plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds admin notices to an active supported event plugin.
|
||||||
|
*
|
||||||
|
* @param array $event_plugin Information about the activate event plugin.
|
||||||
|
*/
|
||||||
|
public function __construct( $event_plugin ) {
|
||||||
|
$this->event_plugin = $event_plugin;
|
||||||
|
if ( $this->event_post_type_is_not_activitypub_enabled() ) {
|
||||||
|
add_action( 'admin_notices', array( $this, 'admin_notice_activitypub_not_enabled_for_post_type' ), 10, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if ActivityPub is enabled for the custom post type of the event plugin.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function event_post_type_is_not_activitypub_enabled() {
|
||||||
|
return ! in_array( $this->event_plugin['post_type'], get_option( 'activitypub_support_post_types', array() ), true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the admin notices for the plugins.
|
||||||
|
*/
|
||||||
|
public function admin_notice_activitypub_not_enabled_for_post_type() {
|
||||||
|
// Get the current page.
|
||||||
|
$screen = get_current_screen();
|
||||||
|
// Check if we are on a edit page for the event, or on the settings page of the event plugin.
|
||||||
|
$is_event_plugins_edit_page = 'edit' === $screen->base && $this->event_plugin['post_type'] === $screen->post_type;
|
||||||
|
$is_event_plugins_settings_page = $this->event_plugin['settings_page_id'] === $screen->id;
|
||||||
|
|
||||||
|
if ( $is_event_plugins_edit_page || $is_event_plugins_settings_page ) {
|
||||||
|
$this->do_admin_notice_post_type_not_activitypub_enabled( $this->event_plugin['plugin_file'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print admin notice that the current post type is not enabled in the ActivityPub plugin.
|
||||||
|
*
|
||||||
|
* @param string $event_plugin_file The event plugin file path.
|
||||||
|
*/
|
||||||
|
private function do_admin_notice_post_type_not_activitypub_enabled( $event_plugin_file ) {
|
||||||
|
$event_plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $event_plugin_file );
|
||||||
|
$activitypub_plugin_data = get_plugin_data( ACTIVITYPUB_PLUGIN_FILE );
|
||||||
|
$notice = sprintf(
|
||||||
|
/* translators: 1: the name of the event plugin a admin notice is shown. 2: The name of the ActivityPub plugin. */
|
||||||
|
_x(
|
||||||
|
'You have installed the <i>%1$s</i> plugin, but the event post type of the plugin <i>%2$s</i> is <b>not enabled</b> in the <a href="%3$s">%1$s settings</a>.',
|
||||||
|
'admin notice',
|
||||||
|
'activitypub-event-extensions'
|
||||||
|
),
|
||||||
|
esc_html( $activitypub_plugin_data['Name'] ),
|
||||||
|
esc_html( $event_plugin_data['Name'] ),
|
||||||
|
admin_url( 'options-general.php?page=activitypub&tab=settings' )
|
||||||
|
);
|
||||||
|
$allowed_html = array(
|
||||||
|
'a' => array(
|
||||||
|
'href' => true,
|
||||||
|
'title' => true,
|
||||||
|
),
|
||||||
|
'b' => array(),
|
||||||
|
'i' => array(),
|
||||||
|
);
|
||||||
|
echo '<div class="notice notice-warning is-dismissible"><p>' . \wp_kses( $notice, $allowed_html ) . '</p></div>';
|
||||||
|
}
|
||||||
|
}
|
73
includes/admin/class-general-admin-notices.php
Normal file
73
includes/admin/class-general-admin-notices.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class responsible for Event Plugin related admin notices.
|
||||||
|
*
|
||||||
|
* Notices for guiding to proper configuration of ActivityPub with event plugins.
|
||||||
|
*
|
||||||
|
* @package Activitypub_Event_Extensions
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Activitypub_Event_Extensions\Admin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible for Event Plugin related admin notices.
|
||||||
|
*
|
||||||
|
* Notices for guiding to proper configuration of ActivityPub with event plugins.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class General_Admin_Notices {
|
||||||
|
/**
|
||||||
|
* Warning if the plugin is Active and the ActivityPub plugin is not.
|
||||||
|
*/
|
||||||
|
public static function do_admin_notice_activitypub_plugin_not_enabled() {
|
||||||
|
$activitypub_plugin_url = 'https://wordpress.org/plugins/activitypub/';
|
||||||
|
|
||||||
|
$notice = sprintf(
|
||||||
|
/* translators: 1: the name of the event plugin a admin notice is shown. 2: The name of the ActivityPub plugin. */
|
||||||
|
_x(
|
||||||
|
'For the ActivityPub Event Extensions to work, you will need to install and activate the <a href="%1$s">ActivityPub</a> plugin.',
|
||||||
|
'admin notice',
|
||||||
|
'activitypub-event-extensions'
|
||||||
|
),
|
||||||
|
esc_html( $activitypub_plugin_url ),
|
||||||
|
admin_url( 'options-general.php?page=activitypub&tab=settings' )
|
||||||
|
);
|
||||||
|
$allowed_html = array(
|
||||||
|
'a' => array(
|
||||||
|
'href' => true,
|
||||||
|
'title' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
echo '<div class="notice notice-warning"><p>' . \wp_kses( $notice, $allowed_html ) . '</p></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning that no supported event plugin can be found.
|
||||||
|
*/
|
||||||
|
public static function do_admin_notice_no_supported_event_plugin_active() {
|
||||||
|
$supported_event_plugins_url = 'https://code.event-federation.eu/Event-Federation/wordpress-activitypub-event-extensions#events-plugin-that-will-be-supported-at-first';
|
||||||
|
|
||||||
|
$notice = sprintf(
|
||||||
|
/* translators: 1: the name of the event plugin a admin notice is shown. 2: The name of the ActivityPub plugin. */
|
||||||
|
_x(
|
||||||
|
'The Plugin <i>ActivityPub Event Extensions</i> is of no use, because you do not have installed and activated a supported Event Plugin.
|
||||||
|
<br> For a list of supported Event Plugins see <a href="%1$s">here</a>.',
|
||||||
|
'admin notice',
|
||||||
|
'activitypub-event-extensions'
|
||||||
|
),
|
||||||
|
esc_html( $supported_event_plugins_url ),
|
||||||
|
admin_url( 'options-general.php?page=activitypub&tab=settings' )
|
||||||
|
);
|
||||||
|
$allowed_html = array(
|
||||||
|
'a' => array(
|
||||||
|
'href' => true,
|
||||||
|
'title' => true,
|
||||||
|
),
|
||||||
|
'br',
|
||||||
|
'i',
|
||||||
|
);
|
||||||
|
echo '<div class="notice notice-warning"><p>' . \wp_kses( $notice, $allowed_html ) . '</p></div>';
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,67 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapping of WordPress Terms(Tags) to known Event Categories
|
|
||||||
*
|
|
||||||
* @package activity-event-transformers
|
|
||||||
* @license AGPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( ! defined( 'ABSPATH' ) ) {
|
|
||||||
exit; // Exit if accessed directly.
|
|
||||||
}
|
|
||||||
|
|
||||||
use Activitypub\Activity\Extended_Object\Event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ActivityPub Tribe Transformer
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
class Category_Mapper {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static function to do the Mapping
|
|
||||||
**/
|
|
||||||
public static function map( $post_categories ) {
|
|
||||||
|
|
||||||
if ( empty( $post_categories ) ) {
|
|
||||||
return 'MEETING';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare an array to store all category information for comparison.
|
|
||||||
$category_info = array();
|
|
||||||
|
|
||||||
// Extract relevant category information (name, slug, description) from the categories array.
|
|
||||||
foreach ( $post_categories as $category ) {
|
|
||||||
$category_info[] = strtolower( $category->name );
|
|
||||||
$category_info[] = strtolower( $category->slug );
|
|
||||||
$category_info[] = strtolower( $category->description );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert mobilizon categories to lowercase for case-insensitive comparison.
|
|
||||||
$mobilizon_categories = array_map( 'strtolower', Event::DEFAULT_EVENT_CATEGORIES );
|
|
||||||
|
|
||||||
// Initialize variables to track the best match.
|
|
||||||
$best_mobilizon_category_match = '';
|
|
||||||
$best_match_length = 0;
|
|
||||||
|
|
||||||
// Check for the best match.
|
|
||||||
foreach ( $mobilizon_categories as $mobilizon_category ) {
|
|
||||||
foreach ( $category_info as $category ) {
|
|
||||||
foreach ( explode( '_', $mobilizon_category ) as $mobilizon_category_slice ) {
|
|
||||||
if ( stripos( $category, $mobilizon_category_slice ) !== false ) {
|
|
||||||
// Check if the current match is longer than the previous best match.
|
|
||||||
$current_match_legnth = strlen( $mobilizon_category_slice );
|
|
||||||
if ( $current_match_legnth > $best_match_length ) {
|
|
||||||
$best_mobilizon_category_match = $mobilizon_category;
|
|
||||||
$best_match_length = $current_match_legnth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( '' != $best_mobilizon_category_match ) ? strtoupper( $best_mobilizon_category_match ) : 'MEETING';
|
|
||||||
}
|
|
||||||
}
|
|
66
includes/class-autoloader.php
Normal file
66
includes/class-autoloader.php
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class responsible for autoloading ActivityPub Event Extensions class files.
|
||||||
|
*
|
||||||
|
* The Autoloader class is responsible for automatically loading class files as needed
|
||||||
|
* to ensure a clean and organized codebase. It maps class names to their corresponding
|
||||||
|
* file locations within the GatherPress plugin.
|
||||||
|
*
|
||||||
|
* @package Activitypub_Event_Extensions
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Activitypub_Event_Extensions;
|
||||||
|
|
||||||
|
// Exit if accessed directly.
|
||||||
|
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Autoloader.
|
||||||
|
*
|
||||||
|
* This class is responsible for automatic loading of classes and namespaces.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class Autoloader {
|
||||||
|
/**
|
||||||
|
* Register method for autoloader.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function register(): void {
|
||||||
|
spl_autoload_register(
|
||||||
|
function ( $full_class ) {
|
||||||
|
$base_dir = ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_DIR . '/includes/';
|
||||||
|
$base = 'Activitypub_Event_Extensions\\';
|
||||||
|
|
||||||
|
if ( strncmp( $full_class, $base, strlen( $base ) ) === 0 ) {
|
||||||
|
$maybe_uppercase = str_replace( $base, '', $full_class );
|
||||||
|
$class = strtolower( $maybe_uppercase );
|
||||||
|
// All classes should be capitalized. If this is instead looking for a lowercase method, we ignore that.
|
||||||
|
if ( $maybe_uppercase === $class ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( false !== strpos( $class, '\\' ) ) {
|
||||||
|
$parts = explode( '\\', $class );
|
||||||
|
$class = array_pop( $parts );
|
||||||
|
$sub_dir = strtr( implode( '/', $parts ), '_', '-' );
|
||||||
|
$base_dir = $base_dir . $sub_dir . '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = 'class-' . strtr( $class, '_', '-' );
|
||||||
|
$file = $base_dir . $filename . '.php';
|
||||||
|
|
||||||
|
if ( file_exists( $file ) && is_readable( $file ) ) {
|
||||||
|
require_once $file;
|
||||||
|
} else {
|
||||||
|
\wp_die( sprintf( esc_html( 'Required class not found or not readable: %s' ), esc_html( $full_class ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
0
includes/class-settings.php
Normal file
0
includes/class-settings.php
Normal file
232
includes/class-setup.php
Normal file
232
includes/class-setup.php
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class responsible for initializing ActivityPub Event Extensions.
|
||||||
|
*
|
||||||
|
* The setup class provides function for checking if this plugin should be activated.
|
||||||
|
* It detects supported event plugins and provides all setup hooks and filters.
|
||||||
|
*
|
||||||
|
* @package Activitypub_Event_Extensions
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Activitypub_Event_Extensions;
|
||||||
|
|
||||||
|
use Activitypub_Event_Extensions\Admin\General_Admin_Notices;
|
||||||
|
use Activitypub_Event_Extensions\Admin\Event_Plugin_Admin_Notices;
|
||||||
|
|
||||||
|
// Exit if accessed directly.
|
||||||
|
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||||
|
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Setup.
|
||||||
|
*
|
||||||
|
* This class is responsible for initializing ActivityPub Event Extensions.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class Setup {
|
||||||
|
const SUPPORTED_EVENT_PLUGINS = array(
|
||||||
|
'events_manager' => array(
|
||||||
|
'plugin_file' => 'events-manager/events-manager.php',
|
||||||
|
'post_type' => 'event',
|
||||||
|
'settings_page' => 'options-general.php?page=vsel',
|
||||||
|
'transformer_class' => 'Events_Manager',
|
||||||
|
),
|
||||||
|
'gatherpress' => array(
|
||||||
|
'plugin_file' => 'gatherpress/gatherpress.php',
|
||||||
|
'post_type' => 'gatherpress_event',
|
||||||
|
'transformer_class' => 'GatherPress',
|
||||||
|
'settings_page_id' => 'gatherpress_general',
|
||||||
|
),
|
||||||
|
'the_events_calendar' => array(
|
||||||
|
'plugin_file' => 'the-events-calendar/the-events-calendar.php',
|
||||||
|
'post_type' => 'tribe_events',
|
||||||
|
'transformer_class' => 'Tribe',
|
||||||
|
'settings_page_id' => 'tribe_general',
|
||||||
|
),
|
||||||
|
'vsel' => array(
|
||||||
|
'plugin_file' => 'very-simple-event-list/vsel.php',
|
||||||
|
'post_type' => 'event',
|
||||||
|
'settings_page_id' => 'settings_page_vsel',
|
||||||
|
'transformer_class' => 'VS_Event',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep the information whether the ActivityPub plugin is active.
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
protected $activitypub_plugin_is_active = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds an array of the currently activated supported event plugins.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $active_event_plugins = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the Setup class.
|
||||||
|
*
|
||||||
|
* Initializes and sets up various components of the plugin.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected function __construct() {
|
||||||
|
$this->activitypub_plugin_is_active = is_plugin_active( 'activitypub/activitypub.php' );
|
||||||
|
$this->active_event_plugins = self::detect_supported_event_plugins();
|
||||||
|
$this->setup_hooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The single instance of the class.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
* @var ?self|null The instance of the class.
|
||||||
|
*/
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the instance of the Singleton class.
|
||||||
|
*
|
||||||
|
* If an instance does not exist, it creates one; otherwise, it returns the existing instance.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*
|
||||||
|
* @return self The instance of the class.
|
||||||
|
*/
|
||||||
|
public static function get_instance(): self {
|
||||||
|
if ( null === self::$instance ) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that checks for supported activated event plugins.
|
||||||
|
*
|
||||||
|
* @return array List of supported event plugins as keys from the SUPPORTED_EVENT_PLUGINS const.
|
||||||
|
*/
|
||||||
|
public static function detect_supported_event_plugins(): array {
|
||||||
|
$active_event_plugins = array();
|
||||||
|
foreach ( self::SUPPORTED_EVENT_PLUGINS as $event_plugin_key => $event_plugin ) {
|
||||||
|
if ( \is_plugin_active( $event_plugin['plugin_file'] ) ) {
|
||||||
|
$active_event_plugins[ $event_plugin_key ] = $event_plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $active_event_plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up hooks for various purposes.
|
||||||
|
*
|
||||||
|
* This method adds hooks for different purposes as needed.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function setup_hooks(): void {
|
||||||
|
register_activation_hook( ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_FILE, array( $this, 'activate' ) );
|
||||||
|
|
||||||
|
add_action( 'admin_init', array( $this, 'do_admin_notices' ) );
|
||||||
|
|
||||||
|
// If we don't have any active event plugins, or the ActivityPub plugin is not enabled, abort here.
|
||||||
|
if ( empty( $this->active_event_plugins ) || ! $this->activitypub_plugin_is_active ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'activitypub_transformer', array( $this, 'register_activitypub_event_transformer' ), 10, 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires the initialization of admin notices for all active supported event plugins.s
|
||||||
|
*/
|
||||||
|
public function do_admin_notices(): void {
|
||||||
|
foreach ( $this->active_event_plugins as $event_plugin ) {
|
||||||
|
new Event_Plugin_Admin_Notices( $event_plugin );
|
||||||
|
}
|
||||||
|
if ( ! $this->activitypub_plugin_is_active ) {
|
||||||
|
add_action( 'admin_notices', array( new General_Admin_Notices(), 'do_admin_notice_activitypub_plugin_not_enabled' ), 10, 1 );
|
||||||
|
}
|
||||||
|
if ( empty( $this->active_event_plugins ) ) {
|
||||||
|
add_action( 'admin_notices', array( new General_Admin_Notices(), 'do_admin_notice_no_supported_event_plugin_active' ), 10, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the custom transformers for the events of several WordPress event plugins.
|
||||||
|
*
|
||||||
|
* @param Activitypub\Transformer\Base $transformer The transformer to use.
|
||||||
|
* @param mixed $wp_object The WordPress object to transform.
|
||||||
|
* @param string $object_class The class of the object to transform.
|
||||||
|
*
|
||||||
|
* @return \Activitypub\Transformer\Base|null
|
||||||
|
*/
|
||||||
|
public function register_activitypub_event_transformer( $transformer, $wp_object, $object_class ): \Activitypub\Transformer\Base|null {
|
||||||
|
// If the current WordPress object is not a post (e.g., a WP_Comment), don't change the transformer.
|
||||||
|
if ( 'WP_Post' !== $object_class ) {
|
||||||
|
return $transformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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['post_type'] ) {
|
||||||
|
$transformer_class = 'Activitypub_Event_Extensions\Activitypub\Transformer\\' . $event_plugin['transformer_class'];
|
||||||
|
return new $transformer_class( $wp_object );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the default transformer.
|
||||||
|
return $transformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates the ActivityPub Event Extensions plugin.
|
||||||
|
*
|
||||||
|
* This method handles the activation of the ActivityPub Event Extensions plugin.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function activate() {
|
||||||
|
// Don't allow plugin activation, when the ActivityPub plugin is not activated yet.
|
||||||
|
if ( ! $this->activitypub_plugin_is_active ) {
|
||||||
|
deactivate_plugins( plugin_basename( ACTIVITYPUB_EVENT_EXTENSIONS_PLUGIN_FILE ) );
|
||||||
|
$notice = sprintf(
|
||||||
|
/* translators: 1: the name of the event plugin a admin notice is shown. 2: The name of the ActivityPub plugin. */
|
||||||
|
_x(
|
||||||
|
'To use this plugin install and activate the <a href="%1$s">%2$s</a> plugin first.',
|
||||||
|
'admin notice',
|
||||||
|
'activitypub-event-extensions'
|
||||||
|
),
|
||||||
|
esc_html( 'https://wordpress.org/plugins/activitypub' ),
|
||||||
|
esc_html( 'ActivityPub' )
|
||||||
|
);
|
||||||
|
$allowed_html = array(
|
||||||
|
'a' => array(
|
||||||
|
'href' => true,
|
||||||
|
'title' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
wp_die(
|
||||||
|
wp_kses( $notice, $allowed_html ),
|
||||||
|
'Plugin dependency check',
|
||||||
|
array( 'back_link' => true ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// If someone installs this plugin, we simply enable ActivityPub support for the event post type, without asking.
|
||||||
|
$activitypub_supported_post_types = get_option( 'activitypub_support_post_types', array() );
|
||||||
|
foreach ( $this->active_event_plugins as $event_plugin ) {
|
||||||
|
if ( ! in_array( $event_plugin['post_type'], $activitypub_supported_post_types, true ) ) {
|
||||||
|
$activitypub_supported_post_types[] = $event_plugin['post_type'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update_option( 'activitypub_support_post_types', $activitypub_supported_post_types );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue