diff --git a/activitypub-event-bridge.php b/activitypub-event-bridge.php
index 961af39..0276072 100644
--- a/activitypub-event-bridge.php
+++ b/activitypub-event-bridge.php
@@ -3,7 +3,7 @@
* Plugin Name: ActivityPub Event Bridge
* Description: Integrating popular event plugins with the ActivityPub plugin.
* Plugin URI: https://event-federation.eu/
- * Version: 0.2.1
+ * Version: 0.2.1.4
* Author: André Menrath
* Author URI: https://graz.social/@linos
* Text Domain: activitypub-event-bridge
@@ -27,6 +27,8 @@ define( 'ACTIVITYPUB_EVENT_BRIDGE_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'ACTIVITYPUB_EVENT_BRIDGE_PLUGIN_VERSION', current( get_file_data( __FILE__, array( 'Version' ), 'plugin' ) ) );
define( 'ACTIVITYPUB_EVENT_BRIDGE_DOMAIN', 'activitypub-event-bridge' );
define( 'ACTIVITYPUB_EVENT_BRIDGE_ACTIVITYPUB_PLUGIN_MIN_VERSION', '3.2.2' );
+define( 'ACTIVITYPUB_EVENT_BRIDGE_CUSTOM_SUMMARY', "
\n - [ap_start_time]
\n - [ap_end_time]
\n - [ap_location]
\n
\n[ap_hashcats][ap_hashtags]" );
+define( 'ACTIVITYPUB_EVENT_BRIDGE_DEFAULT_SUMMARY_TYPE', 'preset' );
// Include and register the autoloader class for automatic loading of plugin classes.
require_once ACTIVITYPUB_EVENT_BRIDGE_PLUGIN_DIR . '/includes/class-autoloader.php';
diff --git a/assets/css/activitypub-event-bridge-admin.css b/assets/css/activitypub-event-bridge-admin.css
index c89ec6e..043082f 100644
--- a/assets/css/activitypub-event-bridge-admin.css
+++ b/assets/css/activitypub-event-bridge-admin.css
@@ -177,3 +177,7 @@ code.activitypub-event-bridge-settings-example-url {
overflow-x: auto;
word-break: break-all;
}
+
+#activitypub_summary_type_custom-details {
+ display: none;
+}
diff --git a/assets/js/activitypub-event-bridge-admin.js b/assets/js/activitypub-event-bridge-admin.js
index bf00a1c..4716ec8 100644
--- a/assets/js/activitypub-event-bridge-admin.js
+++ b/assets/js/activitypub-event-bridge-admin.js
@@ -11,4 +11,23 @@ jQuery( function( $ ) {
$( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', false );
}
} );
+
+ // Function to toggle visibility of custom details based on selected radio button.
+ function toggleCustomDetailsForSummary() {
+ if ($("#activitypub_summary_type_custom").is(':checked')) {
+ $("#activitypub_summary_type_custom-details").show();
+ } else {
+ $("#activitypub_summary_type_custom-details").hide();
+ }
+ }
+
+ // Run the toggle function on page load.
+ $(document).ready(function() {
+ toggleCustomDetailsForSummary(); // Set the correct state on load.
+
+ // Listen for changes on the radio buttons
+ $("input[name=activitypub_summary_type]").change(function() {
+ toggleCustomDetailsForSummary(); // Update visibility on change.
+ });
+ });
} );
diff --git a/includes/activitypub/transformer/class-event.php b/includes/activitypub/transformer/class-event.php
index babf2b9..6d742cd 100644
--- a/includes/activitypub/transformer/class-event.php
+++ b/includes/activitypub/transformer/class-event.php
@@ -14,6 +14,8 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
use Activitypub\Activity\Extended_Object\Event as Event_Object;
use Activitypub\Activity\Extended_Object\Place;
use Activitypub\Transformer\Post;
+use ActivityPub_Event_Bridge\Event_Shortcodes;
+
use DateTime;
/**
@@ -148,14 +150,14 @@ abstract class Event extends Post {
*
* This is mandatory and must be implemented in the final event transformer class.
*/
- abstract protected function get_start_time(): string;
+ abstract public function get_start_time(): string;
/**
* Get the end time.
*
* This is not mandatory and therefore just return null by default.
*/
- protected function get_end_time(): ?string {
+ public function get_end_time(): ?string {
return null;
}
@@ -164,14 +166,14 @@ abstract class Event extends Post {
*
* This should be overridden in the actual event transformer.
*/
- protected function get_location(): ?Place {
+ public function get_location(): ?Place {
return null;
}
/**
* Default value for the event status.
*/
- protected function get_status(): ?string {
+ public function get_status(): ?string {
return 'CONFIRMED';
}
@@ -255,6 +257,44 @@ abstract class Event extends Post {
return '';
}
+
+
+ /**
+ * Get the summary.
+ */
+ public function get_summary(): ?string {
+ if ( 'preset' === get_option( 'activitypub_summary_type', 'preset' ) ) {
+ return $this->get_preset_summary();
+ }
+
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
+ $post = $this->wp_object;
+ $summary = $this->get_event_summary_template();
+
+ // It seems that shortcodes are only applied to published posts.
+ if ( is_preview() ) {
+ $post->post_status = 'publish';
+ }
+
+ // Register our shortcodes just in time.
+ Event_Shortcodes::register();
+ // Fill in the shortcodes.
+ \setup_postdata( $post );
+ $summary = \do_shortcode( $summary );
+ \wp_reset_postdata();
+
+ $summary = \wpautop( $summary );
+ $summary = \preg_replace( '/[\n\r\t]/', '', $summary );
+ $summary = \trim( $summary );
+
+ $summary = \apply_filters( 'activitypub_event_bridge_the_summary', $summary, $post );
+
+ // Don't need these anymore, should never appear in a post.
+ Event_Shortcodes::unregister();
+
+ return $summary;
+ }
+
/**
* Create a custom summary.
*
@@ -263,7 +303,7 @@ abstract class Event extends Post {
*
* @return string $summary The custom event summary.
*/
- public function get_summary(): ?string {
+ public function get_preset_summary(): ?string {
add_filter( 'activitypub_object_content_template', array( self::class, 'remove_ap_permalink_from_template' ), 2, 2 );
$excerpt = $this->retrieve_excerpt();
// BeforeFirstRelease: decide whether this should be a admin setting.
@@ -308,6 +348,18 @@ abstract class Event extends Post {
return $summary;
}
+ /**
+ * Gets the template to use to generate the summary of the ActivityStreams representation of an event post.
+ *
+ * @return string The Template.
+ */
+ protected function get_event_summary_template() {
+ $summary = \get_option( 'activitypub_event_bridge_custom_summary', ACTIVITYPUB_EVENT_BRIDGE_CUSTOM_SUMMARY );
+ $template = $summary ?? ACTIVITYPUB_EVENT_BRIDGE_CUSTOM_SUMMARY;
+
+ return apply_filters( 'activitypub_event_bridge_summary_template', $template, $this->wp_object );
+ }
+
/**
* By default set the timezone of the WordPress site.
*
diff --git a/includes/activitypub/transformer/class-the-events-calendar.php b/includes/activitypub/transformer/class-the-events-calendar.php
index f50fa29..80ac52e 100644
--- a/includes/activitypub/transformer/class-the-events-calendar.php
+++ b/includes/activitypub/transformer/class-the-events-calendar.php
@@ -72,7 +72,7 @@ final class The_Events_Calendar extends Event {
/**
* Get the end time from the event object.
*/
- protected function get_end_time(): ?string {
+ public function get_end_time(): ?string {
if ( empty( $this->tribe_event->end_date ) ) {
return null;
}
@@ -83,7 +83,7 @@ final class The_Events_Calendar extends Event {
/**
* Get the end time from the event object.
*/
- protected function get_start_time(): string {
+ public function get_start_time(): string {
$date = date_create( $this->tribe_event->start_date, wp_timezone() );
return \gmdate( 'Y-m-d\TH:i:s\Z', $date->getTimestamp() );
}
diff --git a/includes/class-event-shortcodes.php b/includes/class-event-shortcodes.php
new file mode 100644
index 0000000..611150f
--- /dev/null
+++ b/includes/class-event-shortcodes.php
@@ -0,0 +1,253 @@
+getTimestamp();
+ $datetime_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
+ return wp_date( $datetime_format, $start_timestamp );
+ }
+
+ /**
+ * Generates output for the 'apeb_start_time' shortcode.
+ *
+ * @param ?array $atts The shortcodes attributes.
+ *
+ * @return string The formatted start date and time of the event.
+ */
+ public static function start_time( $atts ) {
+ $transformer = self::get_transformer();
+
+ if ( ! $transformer ) {
+ return '';
+ }
+
+ $args = shortcode_atts(
+ array(
+ 'icon' => 'true',
+ 'title' => 'true',
+ ),
+ $atts,
+ 'ap_start_time'
+ );
+
+ $args['icon'] = filter_var( $args['icon'], FILTER_VALIDATE_BOOLEAN );
+ $args['title'] = filter_var( $args['title'], FILTER_VALIDATE_BOOLEAN );
+
+ $start_timestamp = $transformer->get_start_time();
+
+ if ( ! $start_timestamp ) {
+ return '';
+ }
+
+ $start_time = array();
+
+ if ( $args['icon'] ) {
+ $start_time[] = '🗓️';
+ }
+
+ if ( $args['title'] ) {
+ $start_time[] = __( 'Start', 'activitypub-event-bridge' ) . ':';
+ }
+
+ $start_time[] = self::format_time( $start_timestamp );
+
+ $start_time = implode( ' ', $start_time );
+
+ return $start_time;
+ }
+
+ /**
+ * Generates output for the 'apeb_end_time' shortcode.
+ *
+ * @param ?array $atts The shortcodes attributes.
+ *
+ * @return string The formatted end date and time of the event.
+ */
+ public static function end_time( $atts ) {
+ $transformer = self::get_transformer();
+
+ if ( ! $transformer ) {
+ return '';
+ }
+
+ $args = shortcode_atts(
+ array(
+ 'icon' => 'true',
+ 'title' => 'true',
+ ),
+ $atts,
+ 'ap_end_time'
+ );
+
+ $args['icon'] = filter_var( $args['icon'], FILTER_VALIDATE_BOOLEAN );
+ $args['title'] = filter_var( $args['title'], FILTER_VALIDATE_BOOLEAN );
+
+ $end_timestamp = $transformer->get_end_time();
+
+ if ( ! $end_timestamp ) {
+ return '';
+ }
+
+ $end_time = array();
+
+ if ( $args['icon'] ) {
+ $end_time[] = '⏳';
+ }
+
+ if ( $args['title'] ) {
+ $end_time[] = __( 'End', 'activitypub-event-bridge' ) . ':';
+ }
+
+ $end_time[] = self::format_time( $end_timestamp );
+
+ $end_time = implode( ' ', $end_time );
+
+ return $end_time;
+ }
+
+ /**
+ * Generates output for the 'apeb_location shortcode.
+ *
+ * @param ?array $atts The shortcodes attributes.
+ *
+ * @return string The formatted location/address of the event.
+ */
+ public static function location( $atts ) {
+ $transformer = self::get_transformer();
+
+ if ( ! $transformer ) {
+ return '';
+ }
+
+ $args = shortcode_atts(
+ array(
+ 'icon' => 'true',
+ 'title' => 'true',
+ 'country' => 'true',
+ 'zip' => 'true',
+ 'city' => 'true',
+ 'street' => 'true',
+ 'name' => 'true',
+ ),
+ $atts,
+ 'ap_location'
+ );
+
+ foreach ( $args as $arg => $value ) {
+ $args[ $arg ] = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
+ }
+
+ $location = $transformer->get_location();
+
+ if ( ! $location ) {
+ return '';
+ }
+
+ $output = array();
+
+ if ( $args['icon'] ) {
+ $output[] = '📍';
+ }
+
+ if ( $args['title'] ) {
+ $output[] = __( 'Location', 'activitypub-event-bridge' ) . ':';
+ }
+
+ $address = $location->get_address();
+
+ if ( $address ) {
+ if ( is_string( $address ) ) {
+ $output[] = $address;
+ }
+ if ( is_array( $address ) ) {
+ if ( $args['name'] && array_key_exists( 'name', $address ) ) {
+ $output[] = $address['name'] . ',';
+ }
+ if ( $args['street'] && array_key_exists( 'streetAddress', $address ) ) {
+ $output[] = $address['streetAddress'] . ',';
+ }
+ if ( $args['zip'] && array_key_exists( 'postalCode', $address ) ) {
+ $output[] = $address['postalCode'];
+ }
+ if ( $args['city'] && array_key_exists( 'addressLocality', $address ) ) {
+ $output[] = $address['addressLocality'] . ',';
+ }
+ if ( $args['country'] && array_key_exists( 'addressCountry', $address ) ) {
+ $output[] = $address['addressCountry'];
+ }
+ }
+ }
+
+ $output = implode( ' ', $output );
+
+ return $output;
+ }
+}
diff --git a/includes/class-settings.php b/includes/class-settings.php
index 6cd7d2e..da1467d 100644
--- a/includes/class-settings.php
+++ b/includes/class-settings.php
@@ -71,6 +71,28 @@ class Settings {
'default' => 1,
)
);
+
+ \register_setting(
+ 'activitypub-event-bridge',
+ 'activitypub_summary_type',
+ array(
+ 'type' => 'string',
+ 'description' => \__( 'Summary type to use for ActivityStreams', 'activitypub-event-bridge' ),
+ 'show_in_rest' => true,
+ 'default' => 'preset',
+ )
+ );
+
+ \register_setting(
+ 'activitypub-event-bridge',
+ 'activitypub_event_bridge_custom_summary',
+ array(
+ 'type' => 'string',
+ 'description' => \__( 'Define your own custom summary template for events', 'activitypub-event-bridge' ),
+ 'show_in_rest' => true,
+ 'default' => ACTIVITYPUB_EVENT_BRIDGE_CUSTOM_SUMMARY,
+ )
+ );
}
/**
diff --git a/templates/settings.php b/templates/settings.php
index 309590f..e9390d1 100644
--- a/templates/settings.php
+++ b/templates/settings.php
@@ -42,6 +42,52 @@ $current_category_mapping = \get_option( 'activitypub_event_bridge_event_