A simple Gutenberg-first event management plugin that integrates with WooCommerce Box Office.
If you want to install this plugin, DON'T DOWNLOAD THIS REPO. You can download the latest stable version from the releases page or just click here.
Simple Events uses Composer, a dependency manager for PHP. Visit the official Composer download instructions to install Composer.
Then, run:
composer install
Run npm install to install all the Node.js dependencies.
Below you will find some information on how to run scripts.
- Use to compile and run the block in development mode.
- Watches for any changes and reports back any errors in your code.
- Use to build production code for your block inside
buildfolder. - Runs once and reports back the gzip file sizes of the produced code.
Tests run inside a Dockerized WordPress environment powered by @wordpress/env.
- Docker must be running
- Dependencies installed (
composer install&&npm install)
npx wp-env start
npm run test:php
This executes PHPUnit inside the tests WordPress container. Tests live in tests/phpunit/ and must extend WP_UnitTestCase. Test files should end in Test.php.
npx wp-env stop
This must be enabled in the settings before they are shown.
Change the previous link text (defaults to
<< {Event Title})
add_filter('se_event_previous_link_text', function( string $link_text, WP_Post $event ) {
return "Previous Event ({$event->post_title})";
}, 10, 2);Change the next link text (defaults to
{Event Title} >>)
add_filter('se_event_next_link_text', function( string $link_text, WP_Post $event ) {
return "Next Event ({$event->post_title})";
}, 10, 2);Change the link text to the calendar if page set in settings, if not set in settings will not show. (defaults to
View Full Calendar)
add_filter('se_event_calendar_link_text', function( string $link_text ) {
return "View Full Calendar";
}, 10, 1);add_filter( 'simple_events_calendar_day_events', function( array $day_events, DateTime $date, int $start_timestamp, int $end_timestamp ) {
$unique_events = array();
$seen_keys = array();
foreach ( $day_events as $event ) {
if ( ! is_object( $event ) || ! isset( $event->ID, $event->event_start_date, $event->event_end_date ) ) {
$unique_events[] = $event;
continue;
}
$key = implode(
'|',
array(
(string) $event->ID,
$event->event_start_date instanceof DateTime ? $event->event_start_date->format( 'U' ) : '',
$event->event_end_date instanceof DateTime ? $event->event_end_date->format( 'U' ) : '',
)
);
if ( isset( $seen_keys[ $key ] ) ) {
continue;
}
$seen_keys[ $key ] = true;
$unique_events[] = $event;
}
return $unique_events;
}, 10, 4 );When the cron task runs to update the event start date to a future date if its passed and future dates exist.
add_filter('se_event_update_query_dates_interval', function( int $interval ) {
return 'hourly'; // Please use the WP Cron intervals: https://developer.wordpress.org/reference/functions/wp_get_schedules/
}, 10, 1);add_filter('se_event_update_dates_search_range', function( int $age ) {
return 48 * HOUR_IN_SECONDS; // The number of days to check for events that are older than this.
}, 10, 1);It is possible to skip and event from being updated by adding a filter to the event.
add_filter('se_event_update_query_dates_skip', function( bool $skip, intget $event ) {
// Skip the event if it is a specific event.
if ( $event === 1234 ) {
return true;
}
return $skip;
}, 10, 2);When an event has been updated, the se_event_updated_query_dates is fired.
add_action('se_event_updated_query_dates', function( int $event_id ) {
// Do something with the event.
}, 10, 2);add_filter('se_calendar_export_query_args', function( array $args ) {
// Modify the query arguments for calendar export
$args['posts_per_page'] = 50; // Export more events
return $args;
}, 10, 1);add_filter('se_calendar_export_event_location', function( $location_object, int $event_id, array $event_date ) {
// Modify the location object in iCal export
// $location_object is an Eluceo\iCal\Domain\ValueObject\Location object
// You can create a new Location object with additional details
$venue = get_post_meta( $event_id, 'se_event_venue', true );
$full_address = $location_object->getValue();
if ( ! empty( $venue ) ) {
$full_address = $venue . ', ' . $full_address;
}
return new \Eluceo\iCal\Domain\ValueObject\Location( $full_address );
}, 10, 3);add_filter('se_calendar_export_event', function( $event, int $event_id, array $event_date ) {
// Modify individual event before adding to calendar
// $event is an Eluceo\iCal\Domain\Entity\Event object
return $event;
}, 10, 3);add_filter('se_calendar_export_calendar', function( $calendar, array $events ) {
// Modify the calendar object before rendering
// $calendar is an Eluceo\iCal\Domain\Entity\Calendar object
return $calendar;
}, 10, 2);add_filter('se_calendar_export_rendered', function( string $ical_content ) {
// Modify the final iCal text output before sending
return $ical_content;
}, 10, 1);The simple-events/tickets/all route returns all published ticket products for the block's picker, capped so the cached payload stays a sane size.
add_filter('se_ticket_products_all_limit', function( int $limit ) {
return 5000; // Default 2000.
}, 10, 1);The WP_Query arguments behind that route, for sites that need to narrow which ticket products the picker offers rather than just how many. Unfiltered, the arguments are unchanged.
add_filter('se_ticket_products_all_query_args', function( array $args ) {
$args['post__not_in'] = array( 123, 456 );
return $args;
}, 10, 1);The result is cached site-wide in the se_ticket_products_all transient for up to an hour, so a callback whose output varies per user or per request will have one editor's list served to all the others. Overriding posts_per_page here defeats the payload bound that se_ticket_products_all_limit enforces.
Simple plugin to add a focal point control to the featured post image.
If you want to use this plugin extension, you can find it at https://github.com/a8cteam51/bamberg-ua/tree/trunk/mu-plugins/team51-focal-point
Copy the team51-focal-point folder to your mu-plugins directory.
- Event Tickets block: added the
se_ticket_products_all_query_argsfilter, so a site can modify the query behind the picker's ticket list and narrow which products are offered rather than only capping how many.
- Event Tickets block: the "Add existing tickets" picker now loads the whole ticket catalogue in a single request to a new lightweight
simple-events/tickets/allREST route instead of one request per 25 products, and searching filters client-side with no further requests. Results are cached in a transient that is flushed whenever a product is saved, trashed or deleted, so newly created tickets appear in the picker immediately. Also fixes the picker never including tickets already attached to the event.
- Security: the
migrate-all-eventsREST route, both settings-page ajax handlers and the event-dates sync and read routes now check an appropriate capability, and the ajax handlers check a nonce. Previously they could be reached without one. Sites should update. - Event dates: removing the Event Info block, migrating, or syncing dates no longer destroys data — the 1.0.0 to 2.0.0 migration is idempotent, dates mirror their event's status, and a sync creates and updates before deleting.
- Archives and calendar: fixed category filtering and the event-date query cost on archives, incorrect header dates, month flags at year boundaries, date grouping, mobile navigation labels, and events spanning midnight or enclosing the visible grid. Calendar event details are now keyboard accessible.
- Editor: fixed changing the timezone discarding every other event setting, "Revert Changes" leaving the wrong timestamps, a failed date fetch silently showing no dates, the Migrate Events button failing on plain permalinks, and lost focus while typing in ticket fields.
- Internationalisation: the plugin now loads its text domain and ships a translation template.
- Improves the calendar event query process to reduce the number of queries and improve performance on sites with large numbers of events. Adds customisable colours to the calendars loading skeleton. Fixes a bug where events which are not published can still leak into calendar or next/previous queries.
- Calendar grid alignment: fixed month grid date placement when WordPress Week Starts On is set to Sunday (or any
start_of_weekother than Monday). Dates and events now appear under the correct weekday column.
- Calendar loading UX: added a loading skeleton while calendar month requests are in flight.
- Calendar mobile interaction: fixed day selection logic on mobile breakpoints when themes customize hidden/mobile display rules.
- Calendar navigation: added a "Show Months in Order" option for sequential month navigation (defaults to off for existing blocks).
- Loop Event Info block: added a configurable HTML wrapper element (
div/p/h1–h6), per-block date and time format overrides, and a query offset control. - Query Loop Events: the block-editor preview now matches the published front-end for every feed order. Previously, with "Newest to Oldest" the editor preview showed the oldest events while the front-end showed the newest.
- Removed a redundant query cache-buster that wrote a timestamp into post content on every change.
- Added Playwright end-to-end tests (run in CI) covering the event-dates save flow, the Query Loop editor/front-end parity, and the Loop Event Info rendering options.