Add event reminder (=self announcing of event at a specified time gap before the event starts) #58
22 changed files with 567 additions and 13 deletions
|
@ -74,6 +74,11 @@ jobs:
|
|||
if: steps.cache-wordpress.outputs.cache-hit != 'false'
|
||||
run: bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 6.6 false true true true
|
||||
|
||||
- name: Run Feature tests of the ActivityPub Event Bridge
|
||||
run: cd /workspace/Event-Federation/wordpress-activitypub-event-bridge/ && ./vendor/bin/phpunit --filter=reminder
|
||||
env:
|
||||
PHP_VERSION: ${{ matrix.php-version }}
|
||||
|
||||
- name: Run Integration tests for The Events Calendar
|
||||
run: cd /workspace/Event-Federation/wordpress-activitypub-event-bridge/ && ./vendor/bin/phpunit --filter=the_events_calendar
|
||||
env:
|
||||
|
|
8
build/reminder/block.json
Normal file
8
build/reminder/block.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "reminder",
|
||||
"title": "Reminder Plugin: not a block, but block.json is very useful.",
|
||||
"category": "widgets",
|
||||
"icon": "admin-comments",
|
||||
"keywords": [],
|
||||
"editorScript": "file:./plugin.js"
|
||||
}
|
1
build/reminder/plugin.asset.php
Normal file
1
build/reminder/plugin.asset.php
Normal file
|
@ -0,0 +1 @@
|
|||
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-i18n', 'wp-plugins'), 'version' => 'd491284dfb7e5078a777');
|
1
build/reminder/plugin.js
Normal file
1
build/reminder/plugin.js
Normal file
|
@ -0,0 +1 @@
|
|||
(()=>{"use strict";const e=window.wp.editor,t=window.wp.plugins,i=window.wp.components,n=window.wp.data,a=window.wp.coreData,r=window.wp.i18n,d=window.ReactJSXRuntime,p=activityPubEventBridge.reminderTypeGap;(0,t.registerPlugin)("activitypub-event-bridge-reminder",{render:()=>{const t=(0,n.useSelect)((e=>e("core/editor").getCurrentPostType()),[]),[_,b]=(0,a.useEntityProp)("postType",t,"meta"),u=_?.activitypub_event_bridge_reminder_time_gap?_?.activitypub_event_bridge_reminder_time_gap:p;return(0,d.jsx)(e.PluginDocumentSettingPanel,{name:"activitypub",title:(0,r.__)("Send reminder before event's start","activitypub"),children:(0,d.jsx)(i.SelectControl,{label:(0,r.__)("Time gap","activitypub"),value:u,options:[{label:(0,r.__)("Disabled","activitypub-event-bridge"),value:0},{label:(0,r.__)("6 hours","activitypub-event-bridge"),value:21600},{label:(0,r.__)("1 day","activitypub-event-bridge"),value:86400},{label:(0,r.__)("3 days","activitypub-event-bridge"),value:259200},{label:(0,r.__)("1 week","activitypub-event-bridge"),value:604800}],onChange:e=>{b({..._,activitypub_event_bridge_reminder_time_gap:e})},__nextHasNoMarginBottom:!0})})}})})();
|
|
@ -57,8 +57,9 @@
|
|||
],
|
||||
"test-debug": [
|
||||
"@prepare-test",
|
||||
"@test-eventin"
|
||||
"@test-wp-event-manager"
|
||||
],
|
||||
"test-features": "phpunit --filter=reminder",
|
||||
"test-vs-event-list": "phpunit --filter=vs_event_list",
|
||||
"test-the-events-calendar": "phpunit --filter=the_events_calendar",
|
||||
"test-gatherpress": "phpunit --filter=gatherpress",
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace ActivityPub_Event_Bridge\Activitypub\Transformer;
|
|||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity\Activity;
|
||||
use Activitypub\Activity\Extended_Object\Event as Event_Object;
|
||||
use Activitypub\Activity\Extended_Object\Place;
|
||||
use Activitypub\Transformer\Post;
|
||||
|
@ -148,7 +149,7 @@ 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.
|
||||
|
@ -376,4 +377,19 @@ abstract class Event extends Post {
|
|||
|
||||
return $activitypub_object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an activity for announcing itself.
|
||||
*
|
||||
* @return Activity The Activity.
|
||||
*/
|
||||
public function to_announce_self_activity() {
|
||||
$activity = new Activity();
|
||||
$activity->set_type( 'Announce' );
|
||||
|
||||
// Pre-fill the Activity with data (for example cc and to).
|
||||
$activity->set_object( $this->get_id() );
|
||||
|
||||
return $activity;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ final class GatherPress extends Event {
|
|||
/**
|
||||
* Get the end time from the event object.
|
||||
*/
|
||||
protected function get_start_time(): string {
|
||||
public function get_start_time(): string {
|
||||
return $this->gp_event->get_datetime_start( 'Y-m-d\TH:i:s\Z' );
|
||||
}
|
||||
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ final class VS_Event_List extends Event_Transformer {
|
|||
/**
|
||||
* Get the end time from the events metadata.
|
||||
*/
|
||||
protected function get_start_time(): string {
|
||||
public function get_start_time(): string {
|
||||
$start_time = get_post_meta( $this->wp_object->ID, 'event-start-date', true );
|
||||
return \gmdate( 'Y-m-d\TH:i:s\Z', $start_time );
|
||||
}
|
||||
|
|
194
includes/class-reminder.php
Normal file
194
includes/class-reminder.php
Normal file
|
@ -0,0 +1,194 @@
|
|||
<?php
|
||||
/**
|
||||
* General settings class.
|
||||
*
|
||||
* This file contains the General class definition, which handles the "General" settings
|
||||
* page for the ActivityPub Event Extension Plugin, providing options for configuring various general settings.
|
||||
*
|
||||
* @package ActivityPub_Event_Bridge
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
namespace ActivityPub_Event_Bridge;
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
||||
|
||||
use Activitypub\Activity_Dispatcher;
|
||||
use Activitypub\Transformer\Factory as Transformer_Factory;
|
||||
use ActivityPub_Event_Bridge\Setup;
|
||||
use ActivityPub_Event_Bridge\Activitypub\Transformer\Event as Event_Transformer;
|
||||
use DateTime;
|
||||
|
||||
use function Activitypub\is_user_disabled;
|
||||
|
||||
/**
|
||||
* Adds automatic announcing or sending of reminders before the events start time.
|
||||
*/
|
||||
class Reminder {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks.
|
||||
*/
|
||||
public static function init() {
|
||||
// Post transitions.
|
||||
\add_action( 'transition_post_status', array( self::class, 'maybe_schedule_event_reminder' ), 33, 3 );
|
||||
\add_action( 'delete_post', array( self::class, 'unschedule_event_reminder' ), 33, 1 );
|
||||
|
||||
// Send an event reminder.
|
||||
\add_action( 'activitypub_event_bridge_send_event_reminder', array( self::class, 'send_event_reminder' ), 10, 1 );
|
||||
|
||||
// Load the block which allows overriding the reminder time for an individual event in the post settings.
|
||||
\add_action( 'enqueue_block_editor_assets', array( self::class, 'enqueue_editor_assets' ) );
|
||||
|
||||
// Register the post-meta which stores per-event overrides of the side-wide default of the reminder time gap.
|
||||
\add_action( 'init', array( self::class, 'register_postmeta' ), 11 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register post meta for controlling whether and when a reminder is scheduled for an individual event.
|
||||
*/
|
||||
public static function register_postmeta() {
|
||||
$ap_post_types = \get_post_types_by_support( 'activitypub' );
|
||||
foreach ( $ap_post_types as $post_type ) {
|
||||
\register_post_meta(
|
||||
$post_type,
|
||||
'activitypub_event_bridge_reminder_time_gap',
|
||||
array(
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'integer',
|
||||
'sanitize_callback' => 'absint',
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the block editor assets.
|
||||
*/
|
||||
public static function enqueue_editor_assets() {
|
||||
// Check for our supported post types.
|
||||
$current_screen = \get_current_screen();
|
||||
$event_post_types = Setup::get_instance()->get_active_event_plugins_post_types();
|
||||
if ( ! $current_screen || ! in_array( $current_screen->post_type, $event_post_types, true ) ) {
|
||||
return;
|
||||
}
|
||||
$asset_data = include ACTIVITYPUB_EVENT_BRIDGE_PLUGIN_DIR . 'build/reminder/plugin.asset.php';
|
||||
$plugin_url = plugins_url( 'build/reminder/plugin.js', ACTIVITYPUB_EVENT_BRIDGE_PLUGIN_FILE );
|
||||
wp_enqueue_script( 'activitypub-event-bridge-reminder', $plugin_url, $asset_data['dependencies'], $asset_data['version'], true );
|
||||
|
||||
// Pass the the default site wide time gap option to the settings block on the events edit page.
|
||||
wp_localize_script(
|
||||
'activitypub-event-bridge-reminder',
|
||||
'activityPubEventBridge',
|
||||
array(
|
||||
'reminderTypeGap' => \get_option( 'activitypub_event_bridge_reminder_time_gap', 0 ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule Activities.
|
||||
*
|
||||
* @param string $new_status New post status.
|
||||
* @param string $old_status Old post status.
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public static function maybe_schedule_event_reminder( $new_status, $old_status, $post ): void {
|
||||
// Re-Check that we got a valid post.
|
||||
$post = get_post( $post );
|
||||
|
||||
if ( ! $post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// At first always unschedule the reminder for this event, it will be added again, in case.
|
||||
self::unschedule_event_reminder( $post->ID );
|
||||
|
||||
// Do not set reminders if post is password protected.
|
||||
if ( \post_password_required( $post ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only schedule an reminder for event post types.
|
||||
if ( ! Setup::get_instance()->is_post_type_event_of_active_event_plugin( $post->post_type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not schedule a reminder if the event is not published.
|
||||
if ( 'publish' !== $new_status ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// See if a reminder time gap is set for the event individually in the events post-meta.
|
||||
$reminder_time_gap = (int) get_post_meta( $post->ID, 'activitypub_event_bridge_reminder_time_gap', true );
|
||||
|
||||
// If not fallback to the global reminder time gap.
|
||||
if ( ! $reminder_time_gap ) {
|
||||
$reminder_time_gap = \get_option( 'activitypub_event_bridge_reminder_time_gap', 0 );
|
||||
}
|
||||
|
||||
// Any non positive integer means that this feature is not active for this event post.
|
||||
if ( 0 === $reminder_time_gap || ! is_int( $reminder_time_gap ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get start time of the event.
|
||||
$event_transformer = Transformer_Factory::get_transformer( $post );
|
||||
|
||||
if ( \is_wp_error( $event_transformer ) || ! $event_transformer instanceof Event_Transformer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$start_time = $event_transformer->get_start_time();
|
||||
$start_datetime = new DateTime( $start_time );
|
||||
$start_timestamp = $start_datetime->getTimestamp();
|
||||
|
||||
// Get the time when the reminder of the event's start should be sent.
|
||||
$schedule_time = $start_timestamp - $reminder_time_gap;
|
||||
|
||||
// If the reminder time has already passed "now" skip it.
|
||||
if ( $schedule_time < \time() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// All checks passed: schedule a single event which will trigger the sending of the reminder for this event post.
|
||||
\wp_schedule_single_event( $schedule_time, 'activitypub_event_bridge_send_event_reminder', array( $post->ID ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unschedule the event reminder.
|
||||
*
|
||||
* @param int $post_id The WordPress post ID of the event post.
|
||||
*/
|
||||
public static function unschedule_event_reminder( $post_id ): void {
|
||||
\wp_clear_scheduled_hook( 'activitypub_event_bridge_send_event_reminder', array( $post_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reminder for an event post.
|
||||
*
|
||||
* This currently sends an Announce activity.
|
||||
*
|
||||
* @param int $post_id The WordPress post ID of the event post.
|
||||
*/
|
||||
public static function send_event_reminder( $post_id ): void {
|
||||
$post = \get_post( $post_id );
|
||||
|
||||
$transformer = Transformer_Factory::get_transformer( $post );
|
||||
|
||||
if ( \is_wp_error( $transformer ) || ! $transformer instanceof Event_Transformer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user_id = $transformer->get_wp_user_id();
|
||||
|
||||
if ( $user_id > 0 && is_user_disabled( $user_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = $transformer->to_announce_self_activity( 'Announce' );
|
||||
|
||||
Activity_Dispatcher::send_activity_to_followers( $activity, $user_id, $post );
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@ class Settings {
|
|||
'activitypub_event_bridge_default_event_category',
|
||||
array(
|
||||
'type' => 'string',
|
||||
'description' => \__( 'Define your own custom post template', 'activitypub' ),
|
||||
'description' => \__( 'Default standardized federated event category.s', 'activitypub' ),
|
||||
'show_in_rest' => true,
|
||||
'default' => self::DEFAULT_EVENT_CATEGORY,
|
||||
'sanitize_callback' => array( self::class, 'sanitize_mapped_event_category' ),
|
||||
|
@ -56,11 +56,22 @@ class Settings {
|
|||
'activitypub_event_bridge_event_category_mappings',
|
||||
array(
|
||||
'type' => 'array',
|
||||
'description' => \__( 'Define your own custom post template', 'activitypub' ),
|
||||
'description' => \__( 'Category mappings to standardized federated event categories.', 'activitypub' ),
|
||||
'default' => array(),
|
||||
'sanitize_callback' => array( self::class, 'sanitize_event_category_mappings' ),
|
||||
)
|
||||
);
|
||||
|
||||
\register_setting(
|
||||
'activitypub-event-bridge',
|
||||
'activitypub_event_bridge_reminder_time_gap',
|
||||
array(
|
||||
'type' => 'array',
|
||||
'description' => \__( 'Time gap in seconds when a reminder is triggered that the event is about to start.', 'activitypub' ),
|
||||
'default' => 0, // Zero leads to this feature being deactivated.
|
||||
'sanitize_callback' => 'absint',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,7 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore
|
|||
use ActivityPub_Event_Bridge\Admin\Event_Plugin_Admin_Notices;
|
||||
use ActivityPub_Event_Bridge\Admin\General_Admin_Notices;
|
||||
use ActivityPub_Event_Bridge\Admin\Settings_Page;
|
||||
use ActivityPub_Event_Bridge\Reminder;
|
||||
use ActivityPub_Event_Bridge\Plugins\Event_Plugin;
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
|
@ -118,6 +119,38 @@ class Setup {
|
|||
return $this->active_event_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter function for the active event plugins post types.
|
||||
*
|
||||
* @return array List of event post types of the active event plugins.
|
||||
*/
|
||||
public function get_active_event_plugins_post_types() {
|
||||
$post_types = array();
|
||||
foreach ( $this->active_event_plugins as $event_plugin ) {
|
||||
$post_types[] = $event_plugin->get_post_type();
|
||||
}
|
||||
|
||||
return $post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check whether a post type is an event post type of an active event plugin.
|
||||
*
|
||||
* @param string $post_type The post type.
|
||||
*
|
||||
* @return bool True if it is an event post type.
|
||||
*/
|
||||
public function is_post_type_event_of_active_event_plugin( $post_type ) {
|
||||
foreach ( $this->active_event_plugins as $event_plugin ) {
|
||||
if ( $post_type === $event_plugin->get_post_type() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds all the classes for the supported event plugins.
|
||||
*
|
||||
|
@ -186,6 +219,8 @@ class Setup {
|
|||
return;
|
||||
}
|
||||
|
||||
add_action( 'init', array( Reminder::class, 'init' ) );
|
||||
|
||||
add_filter( 'activitypub_transformer', array( $this, 'register_activitypub_event_transformer' ), 10, 3 );
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,8 @@ abstract class Event_Plugin {
|
|||
|
||||
/**
|
||||
* Returns the Activitypub transformer for the event plugins event post type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_activitypub_event_transformer_class(): string {
|
||||
return str_replace( 'Plugins', 'Activitypub\Transformer', static::class );
|
||||
|
|
19
package.json
Executable file
19
package.json
Executable file
|
@ -0,0 +1,19 @@
|
|||
|
||||
{
|
||||
"name": "activitypub-poll",
|
||||
"version": "0.1.0",
|
||||
"author": {
|
||||
"name": "André Menrath",
|
||||
"web": "https://graz.social/@linos"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "wp-scripts start",
|
||||
"build": "wp-scripts build",
|
||||
"readme": "grunt wp_readme_to_markdown"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wordpress/scripts": "^30.0.2",
|
||||
"grunt-wp-readme-to-markdown": "^2.0.1",
|
||||
"classnames": "^2.3.2"
|
||||
}
|
||||
}
|
|
@ -26,6 +26,12 @@
|
|||
<!-- Exclude the Node Modules directory. -->
|
||||
<exclude-pattern>/node_modules/*</exclude-pattern>
|
||||
|
||||
<!-- Exclude Javascript files. -->
|
||||
<exclude-pattern>*.js</exclude-pattern>
|
||||
|
||||
<!-- Exclude build assets from js blocks. -->
|
||||
<exclude-pattern>/build/*/*asset.php</exclude-pattern>
|
||||
|
||||
<!-- Exclude minified Javascript files. -->
|
||||
<exclude-pattern>*.min.js</exclude-pattern>
|
||||
|
||||
|
|
9
src/reminder/block.json
Normal file
9
src/reminder/block.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "reminder",
|
||||
"title": "Reminder Plugin: not a block, but block.json is very useful.",
|
||||
"category": "widgets",
|
||||
"icon": "admin-comments",
|
||||
"keywords": [
|
||||
],
|
||||
"editorScript": "file:./plugin.js"
|
||||
}
|
43
src/reminder/plugin.js
Normal file
43
src/reminder/plugin.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
import { PluginDocumentSettingPanel } from '@wordpress/editor';
|
||||
import { registerPlugin } from '@wordpress/plugins';
|
||||
import { SelectControl } from '@wordpress/components';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { useEntityProp } from '@wordpress/core-data';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
const reminderTimeGapDefault = activityPubEventBridge.reminderTypeGap;
|
||||
|
||||
const Reminder = () => {
|
||||
const postType = useSelect(
|
||||
( select ) => select( 'core/editor' ).getCurrentPostType(),
|
||||
[]
|
||||
);
|
||||
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
|
||||
|
||||
const reminderTimeGap = meta?.activitypub_event_bridge_reminder_time_gap ? meta?.activitypub_event_bridge_reminder_time_gap : reminderTimeGapDefault;
|
||||
|
||||
return (
|
||||
<PluginDocumentSettingPanel
|
||||
name="activitypub"
|
||||
title={ __( 'Send reminder before event\'s start', 'activitypub' ) }
|
||||
>
|
||||
<SelectControl
|
||||
label={ __( 'Time gap', 'activitypub' ) }
|
||||
value={ reminderTimeGap }
|
||||
options={ [
|
||||
{ label: __( 'Disabled', 'activitypub-event-bridge' ), value: 0 },
|
||||
{ label: __( '6 hours', 'activitypub-event-bridge' ), value: 21600 },
|
||||
{ label: __( '1 day', 'activitypub-event-bridge' ), value: 86400 },
|
||||
{ label: __( '3 days', 'activitypub-event-bridge' ), value: 259200 },
|
||||
{ label: __( '1 week', 'activitypub-event-bridge' ), value: 604800 }
|
||||
] }
|
||||
onChange={ ( value ) => {
|
||||
setMeta( { ...meta, activitypub_event_bridge_reminder_time_gap: value } );
|
||||
} }
|
||||
__nextHasNoMarginBottom
|
||||
/>
|
||||
</PluginDocumentSettingPanel>
|
||||
);
|
||||
}
|
||||
|
||||
registerPlugin( 'activitypub-event-bridge-reminder', { render: Reminder } );
|
|
@ -29,6 +29,15 @@ require_once ACTIVITYPUB_EVENT_BRIDGE_PLUGIN_DIR . '/includes/event-categories.p
|
|||
|
||||
$selected_default_event_category = \get_option( 'activitypub_event_bridge_default_event_category', 'MEETING' );
|
||||
$current_category_mapping = \get_option( 'activitypub_event_bridge_event_category_mappings', array() );
|
||||
$reminder_time_gap = \get_option( 'activitypub_event_bridge_reminder_time_gap', 0 );
|
||||
|
||||
$reminder_time_gap_choices = array(
|
||||
0 => __( 'Disabled', 'activitypub-event-bridge' ),
|
||||
HOUR_IN_SECONDS * 6 => __( '6 hours', 'activitypub-event-bridge' ),
|
||||
DAY_IN_SECONDS => __( '1 day', 'activitypub-event-bridge' ),
|
||||
DAY_IN_SECONDS * 3 => __( '3 days', 'activitypub-event-bridge' ),
|
||||
WEEK_IN_SECONDS => __( '1 week', 'activitypub-event-bridge' ),
|
||||
)
|
||||
?>
|
||||
|
||||
<div class="activitypub-settings-header">
|
||||
|
@ -98,6 +107,17 @@ $current_category_mapping = \get_option( 'activitypub_event_bridge_event_
|
|||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="box">
|
||||
<h2> <?php esc_html_e( 'Send reminder before event', 'activitypub-event-bridge' ); ?> </h2>
|
||||
<p> <?php esc_html_e( 'Specify a time interval before the event starts to trigger a reminder. This reminder automatically boosts the event, making it reappear in users\' timelines at the defined time before the event to increase visibility just before the event begins.', 'activitypub-event-bridge' ); ?> </p>
|
||||
<select id="activitypub_event_bridge_reminder_time_gap" name="activitypub_event_bridge_reminder_time_gap">';
|
||||
<?php
|
||||
foreach ( $reminder_time_gap_choices as $value => $label ) {
|
||||
echo '<option value="' . esc_attr( $value ) . '" ' . selected( $reminder_time_gap, $value, false ) . '>' . esc_html( $label ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<?php \submit_button(); ?>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -50,9 +50,6 @@ function _manually_load_plugin() {
|
|||
$plugin_file = null;
|
||||
// See if we want to run integration tests for a specific event-plugin.
|
||||
switch ( $activitypub_event_extension_integration_filter ) {
|
||||
case 'the_events_calendar':
|
||||
$plugin_file = 'the-events-calendar/the-events-calendar.php';
|
||||
break;
|
||||
case 'vs_event_list':
|
||||
$plugin_file = 'very-simple-event-list/vsel.php';
|
||||
break;
|
||||
|
@ -68,6 +65,9 @@ function _manually_load_plugin() {
|
|||
case 'wp_event_manager':
|
||||
$plugin_file = 'wp-event-manager/wp-event-manager.php';
|
||||
break;
|
||||
default:
|
||||
// By default we test other stuff using The Events Calendar.
|
||||
$plugin_file = 'the-events-calendar/the-events-calendar.php';
|
||||
}
|
||||
|
||||
if ( $plugin_file ) {
|
||||
|
|
|
@ -16,7 +16,7 @@ class Test_Events_Manager extends WP_UnitTestCase {
|
|||
parent::set_up();
|
||||
|
||||
if ( ! class_exists( 'EM_Events' ) ) {
|
||||
self::markTestSkipped( 'VS Event List plugin is not active.' );
|
||||
self::markTestSkipped( 'Events Manager plugin is not active.' );
|
||||
}
|
||||
|
||||
// For tests allow every user to create new events.
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* Class SampleTest
|
||||
* Tests for GatherPress.
|
||||
*
|
||||
* @package ActivityPub_Event_Bridge
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sample test case.
|
||||
* Test class for testing the GatherPress integration.
|
||||
*/
|
||||
class Test_GatherPress extends WP_UnitTestCase {
|
||||
/**
|
||||
|
|
183
tests/test-class-reminder.php
Normal file
183
tests/test-class-reminder.php
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
/**
|
||||
* Test for Reminder class.
|
||||
*
|
||||
* @package ActivityPub_Event_Bridge
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test class for testing the scheduling of reminder Activities.
|
||||
*/
|
||||
class Test_Reminder extends WP_UnitTestCase {
|
||||
/**
|
||||
* Mockup events of certain complexity.
|
||||
*/
|
||||
public const MOCKUP_VENUE = array(
|
||||
'venue' => 'Minimal Venue',
|
||||
'status' => 'publish',
|
||||
);
|
||||
|
||||
public const MOCKUP_EVENT = array(
|
||||
'title' => 'My Event',
|
||||
'content' => 'Come to my event!',
|
||||
'start_date' => '+10 days 15:00:00',
|
||||
'duration' => HOUR_IN_SECONDS,
|
||||
'status' => 'publish',
|
||||
);
|
||||
|
||||
/**
|
||||
* Override the setup function, so that tests don't run if the Events Calendar is not active.
|
||||
*/
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
|
||||
if ( ! class_exists( '\Tribe__Events__Main' ) ) {
|
||||
self::markTestSkipped( 'The Events Calendar is not active.' );
|
||||
}
|
||||
|
||||
// For tests allow every user to create new events.
|
||||
update_option( 'dbem_events_anonymous_submissions', true );
|
||||
|
||||
// Make sure that ActivityPub support is enabled for Events Manager.
|
||||
$aec = \ActivityPub_Event_Bridge\Setup::get_instance();
|
||||
$aec->activate_activitypub_support_for_active_event_plugins();
|
||||
|
||||
// Delete all posts afterwards.
|
||||
_delete_all_posts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that with the default reminder setting (time-gap is zero) no reminder event is scheduled.
|
||||
*/
|
||||
public function test_event_reminder_not_being_scheduled_by_default() {
|
||||
// Create a The Events Calendar Event.
|
||||
$wp_object = tribe_events()
|
||||
->set_args( self::MOCKUP_EVENT )
|
||||
->create();
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) );
|
||||
|
||||
$this->assertEquals( false, $scheduled_event );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that with a side-wide option the reminder is scheduled.
|
||||
*/
|
||||
public function test_event_reminder_scheduled_with_site_wide_option() {
|
||||
\update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS );
|
||||
// Create a The Events Calendar Event.
|
||||
$wp_object = tribe_events()
|
||||
->set_args( self::MOCKUP_EVENT )
|
||||
->create();
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) );
|
||||
|
||||
$this->assertNotEquals( false, $scheduled_event );
|
||||
$this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS, $scheduled_event->timestamp );
|
||||
$this->assertEquals( false, $scheduled_event->schedule );
|
||||
$this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a specific event can override the side-wide reminder default.
|
||||
*/
|
||||
public function test_event_reminder_scheduled_with_per_event_override() {
|
||||
\update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS );
|
||||
|
||||
// Create a The Events Calendar Event.
|
||||
$wp_object = tribe_events()
|
||||
->set_args(
|
||||
array_merge(
|
||||
self::MOCKUP_EVENT,
|
||||
array( 'activitypub_event_bridge_reminder_time_gap' => DAY_IN_SECONDS * 3 ),
|
||||
)
|
||||
)
|
||||
->create();
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) );
|
||||
|
||||
$this->assertNotEquals( false, $scheduled_event );
|
||||
$this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS * 3, $scheduled_event->timestamp );
|
||||
$this->assertEquals( false, $scheduled_event->schedule );
|
||||
$this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook );
|
||||
|
||||
// Now update the option once more to see if the schedule got updated too.
|
||||
$post_id = array_key_first(
|
||||
tribe_events( $wp_object->ID )
|
||||
->set_args(
|
||||
array( 'activitypub_event_bridge_reminder_time_gap' => HOUR_IN_SECONDS ),
|
||||
)
|
||||
->save()
|
||||
);
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $post_id ) );
|
||||
$this->assertNotEquals( false, $scheduled_event );
|
||||
$this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - HOUR_IN_SECONDS, $scheduled_event->timestamp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the scheduled reminder is removed when the event is deleted.
|
||||
*/
|
||||
public function test_event_reminder_deleted_event() {
|
||||
\update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS );
|
||||
|
||||
// Create a The Events Calendar Event.
|
||||
$wp_object = tribe_events()
|
||||
->set_args(
|
||||
array_merge(
|
||||
self::MOCKUP_EVENT,
|
||||
array( 'activitypub_event_bridge_reminder_time_gap' => DAY_IN_SECONDS * 3 ),
|
||||
)
|
||||
)
|
||||
->create();
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) );
|
||||
|
||||
$this->assertNotEquals( false, $scheduled_event );
|
||||
$this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS * 3, $scheduled_event->timestamp );
|
||||
$this->assertEquals( false, $scheduled_event->schedule );
|
||||
$this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook );
|
||||
|
||||
// Now delete the event.
|
||||
tribe_events( $wp_object->ID )->delete();
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) );
|
||||
$this->assertEquals( false, $scheduled_event );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the scheduled reminder is removed when the event is moved to trash.
|
||||
*/
|
||||
public function test_event_reminder_event_moved_to_trash() {
|
||||
\update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS );
|
||||
|
||||
// Create a The Events Calendar Event.
|
||||
$wp_object = tribe_events()
|
||||
->set_args(
|
||||
array_merge(
|
||||
self::MOCKUP_EVENT,
|
||||
array( 'activitypub_event_bridge_reminder_time_gap' => DAY_IN_SECONDS * 3 ),
|
||||
)
|
||||
)
|
||||
->create();
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) );
|
||||
|
||||
$this->assertNotEquals( false, $scheduled_event );
|
||||
$this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS * 3, $scheduled_event->timestamp );
|
||||
$this->assertEquals( false, $scheduled_event->schedule );
|
||||
$this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook );
|
||||
|
||||
// Now move the event to the trash.
|
||||
$post_id = array_key_first(
|
||||
tribe_events( $wp_object->ID )
|
||||
->set_args(
|
||||
array( 'post_status' => 'trash' ),
|
||||
)
|
||||
->save()
|
||||
);
|
||||
|
||||
$scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) );
|
||||
$this->assertEquals( false, $scheduled_event );
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue