From 130990e45f2de60dbdf0644d6b1570ac44f63796 Mon Sep 17 00:00:00 2001 From: Dominik Schilling Date: Sat, 6 Jun 2026 16:50:02 +0200 Subject: [PATCH] Translation Events: Make event end date optional. Adds an "Ongoing event (no end date)" checkbox so events with no scheduled end (e.g. WordPress Credits Contributions) can be modeled explicitly instead of using a fake far-future end date. Fixes https://meta.trac.wordpress.org/ticket/8280 --- .../assets/css/translation-events.css | 12 ++++ .../assets/js/translation-events.js | 53 +++++++++++++--- .../includes/attendee/attendee-adder.php | 19 +++++- .../includes/event/event-capabilities.php | 11 ++-- .../includes/event/event-form-handler.php | 24 ++++--- .../event/event-repository-cached.php | 5 +- .../includes/event/event-repository.php | 63 +++++++++++-------- .../includes/event/event.php | 30 ++++++--- .../includes/routes/event/rss.php | 4 +- .../templates/event-details.php | 21 ++++--- .../templates/parts/event-form.php | 17 ++++- .../templates/parts/event-list.php | 4 +- .../blocks/event-date/index.php | 3 + .../wporg-gp-translation-events.php | 14 +++-- 14 files changed, 202 insertions(+), 78 deletions(-) diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css index c7a8bb643a..9e64dc5394 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css @@ -19,6 +19,18 @@ margin-top: 1em; } +.translation-event-form .event-end-fields { + display: inline-block; + vertical-align: top; +} + +.translation-event-form label.event-end-open-ended-toggle { + display: block; + width: auto; + margin-top: 0.5em; + font-weight: normal; +} + .translation-event-form #submit-event { margin-left: 10%; width: 30%; diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/js/translation-events.js b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/js/translation-events.js index 5052977ddc..c0fdfee1f6 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/js/translation-events.js +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/js/translation-events.js @@ -8,6 +8,7 @@ selectUserTimezone(); } validateEventDates(); + bindOpenEndedToggle(); convertToUserLocalTime(); setInterval( convertToUserLocalTime, 10000 ); @@ -94,7 +95,9 @@ $( '#event-title' ).val( wordcamp.title.rendered ); $( '#event-description' ).val( wordcamp.content.rendered ); $( '#event-start' ).val( new Date( 1000 * wordcamp['Start Date (YYYY-mm-dd)'] ).toISOString().slice( 0,11 ) + '09:00' ); - $( '#event-end' ).val( new Date( 1000 * wordcamp['End Date (YYYY-mm-dd)'] ).toISOString().slice( 0,11 ) + '18:00' ); + if ( ! $( '#event-is-open-ended' ).is( ':checked' ) ) { + $( '#event-end' ).val( new Date( 1000 * wordcamp['End Date (YYYY-mm-dd)'] ).toISOString().slice( 0,11 ) + '18:00' ); + } $( '#event-timezone' ).val( wordcamp['Event Timezone'] ); } @@ -123,13 +126,16 @@ $gp.notices.error( 'Event start date and time must be set.' ); return; } - if ( '' === $( '#event-end' ).val() ) { - $gp.notices.error( 'Event end date and time must be set.' ); - return; - } - if ( $( '#event-end' ).val() <= $( '#event-start' ).val() ) { - $gp.notices.error( 'Event end date and time must be later than event start date and time.' ); - return; + const isOpenEnded = $( '#event-is-open-ended' ).is( ':checked' ); + if ( ! isOpenEnded ) { + if ( '' === $( '#event-end' ).val() ) { + $gp.notices.error( 'Event end date and time must be set.' ); + return; + } + if ( $( '#event-end' ).val() <= $( '#event-start' ).val() ) { + $gp.notices.error( 'Event end date and time must be later than event start date and time.' ); + return; + } } if ( eventStatus === 'publish' && isDraft ) { const submitPrompt = 'Are you sure you want to publish this event?'; @@ -197,6 +203,37 @@ ); } + function bindOpenEndedToggle() { + const $checkbox = $( '#event-is-open-ended' ); + const $endInput = $( '#event-end' ); + if ( ! $checkbox.length || ! $endInput.length ) { + return; + } + + $checkbox.on( + 'change', + function () { + if ( $checkbox.is( ':checked' ) ) { + $endInput.prop( 'disabled', true ).val( '' ); + return; + } + $endInput.prop( 'disabled', false ); + if ( '' === $endInput.val() ) { + const startVal = $( '#event-start' ).val(); + if ( startVal ) { + const start = new Date( startVal ); + start.setHours( start.getHours() + 1 ); + const pad = ( n ) => String( n ).padStart( 2, '0' ); + $endInput.val( + start.getFullYear() + '-' + pad( start.getMonth() + 1 ) + '-' + pad( start.getDate() ) + + 'T' + pad( start.getHours() ) + ':' + pad( start.getMinutes() ) + ); + } + } + } + ); + } + function validateEventDates() { const startDateTimeInput = $( '#event-start' ); const endDateTimeInput = $( '#event-end' ); diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/attendee/attendee-adder.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/attendee/attendee-adder.php index f510118ab3..925fe8e57c 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/attendee/attendee-adder.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/attendee/attendee-adder.php @@ -5,6 +5,7 @@ use Exception; use Wporg\TranslationEvents\Event\Event; use Wporg\TranslationEvents\Stats\Stats_Listener; +use Wporg\TranslationEvents\Translation_Events; class Attendee_Adder { private Attendee_Repository $attendee_repository; @@ -37,6 +38,20 @@ public function add_to_event( Event $event, Attendee $attendee ): void { private function import_stats( Event $event, Attendee $attendee ): void { global $wpdb, $gp_table_prefix; + + $now = Translation_Events::now(); + $end = $event->end() ? $event->end()->utc() : $now; + $start = $event->start()->utc(); + + // Open-ended events can span arbitrary durations. Cap the lookback to avoid + // a full table scan over `translations` when a new attendee joins. + if ( null === $event->end() ) { + $one_year_ago = $now->modify( '-1 year' ); + if ( $start < $one_year_ago ) { + $start = $one_year_ago; + } + } + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching @@ -57,8 +72,8 @@ private function import_stats( Event $event, Attendee $attendee ): void { 'event_id' => $event->id(), 'action' => Stats_Listener::ACTION_CREATE, 'user_id' => $attendee->user_id(), - 'date_added_after' => $event->start()->utc()->format( 'Y-m-d H:i:s' ), - 'date_added_before' => $event->end()->utc()->format( 'Y-m-d H:i:s' ), + 'date_added_after' => $start->format( 'Y-m-d H:i:s' ), + 'date_added_before' => $end->format( 'Y-m-d H:i:s' ), ), ), ); diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-capabilities.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-capabilities.php index a4abcaea50..ce395ef0b1 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-capabilities.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-capabilities.php @@ -266,8 +266,6 @@ private function has_edit_attendees( WP_User $user, Event $event ): bool { * @return bool */ private function has_edit_field( WP_User $user, Event $event, $cap ): bool { - $event_end_plus_1_hr = $event->end()->modify( '+1 hour' ); - if ( self::EDIT_DESCRIPTION === $cap ) { return true; } @@ -284,10 +282,11 @@ private function has_edit_field( WP_User $user, Event $event, $cap ): bool { return ( self::EDIT_TITLE === $cap || self::EDIT_END === $cap ); } - if ( $event->end()->is_in_the_past() && $this->now < $event_end_plus_1_hr ) { - return ( self::EDIT_TITLE === $cap || self::EDIT_END === $cap ); - } - if ( $event->end()->is_in_the_past() && $this->now > $event_end_plus_1_hr ) { + if ( $event->is_past() ) { + $event_end_plus_1_hr = $event->end()->modify( '+1 hour' ); + if ( $this->now < $event_end_plus_1_hr ) { + return ( self::EDIT_TITLE === $cap || self::EDIT_END === $cap ); + } return ( self::EDIT_DESCRIPTION === $cap ); } diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-form-handler.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-form-handler.php index 56580801e8..a6ac2ede99 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-form-handler.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-form-handler.php @@ -201,10 +201,11 @@ private function parse_form_data( array $data ): Event { // This will be sanitized by sanitize_post which is called in wp_insert_post. // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $description = isset( $data['event_description'] ) ? force_balance_tags( wp_unslash( $data['event_description'] ) ) : ''; - $event_start = isset( $data['event_start'] ) ? sanitize_text_field( wp_unslash( $data['event_start'] ) ) : ''; - $event_end = isset( $data['event_end'] ) ? sanitize_text_field( wp_unslash( $data['event_end'] ) ) : ''; - $event_timezone = isset( $data['event_timezone'] ) ? sanitize_text_field( wp_unslash( $data['event_timezone'] ) ) : ''; - $attendance_mode = isset( $data['event_attendance_mode'] ) ? sanitize_text_field( wp_unslash( $data['event_attendance_mode'] ) ) : 'onsite'; + $event_start = isset( $data['event_start'] ) ? sanitize_text_field( wp_unslash( $data['event_start'] ) ) : ''; + $event_end = isset( $data['event_end'] ) ? sanitize_text_field( wp_unslash( $data['event_end'] ) ) : ''; + $event_is_open_ended = ! empty( $data['event_is_open_ended'] ); + $event_timezone = isset( $data['event_timezone'] ) ? sanitize_text_field( wp_unslash( $data['event_timezone'] ) ) : ''; + $attendance_mode = isset( $data['event_attendance_mode'] ) ? sanitize_text_field( wp_unslash( $data['event_attendance_mode'] ) ) : 'onsite'; $event_status = ''; if ( isset( $data['event_form_action'] ) && in_array( $data['event_form_action'], array( 'draft', 'publish', 'trash' ), true ) ) { @@ -223,16 +224,21 @@ private function parse_form_data( array $data ): Event { throw new InvalidStart(); } - try { - $end = new Event_End_Date( $event_end, $timezone ); - } catch ( Exception $e ) { - throw new InvalidEnd(); + if ( $event_is_open_ended ) { + $end = null; + } else { + try { + $end = new Event_End_Date( $event_end, $timezone ); + } catch ( Exception $e ) { + throw new InvalidEnd(); + } + $end = $end->setTimezone( new DateTimeZone( 'UTC' ) ); } $event = new Event( get_current_user_id(), $start->setTimezone( new DateTimeZone( 'UTC' ) ), - $end->setTimezone( new DateTimeZone( 'UTC' ) ), + $end, $timezone, $event_status, $title, diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository-cached.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository-cached.php index 594f907a4f..8032dd29ea 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository-cached.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository-cached.php @@ -61,7 +61,10 @@ public function get_current_events( int $page = -1, int $page_size = -1 ): Event array_filter( $events, function ( $event ) { - return $event->start() <= $this->now && $this->now <= $event->end(); + if ( $event->start() > $this->now ) { + return false; + } + return null === $event->end() || $this->now <= $event->end(); } ) ); diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository.php index 183220da1c..1bc702a577 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event-repository.php @@ -227,12 +227,7 @@ public function get_current_and_upcoming_events( int $page = - 1, int $page_size $page_size, array( 'meta_query' => array( - array( - 'key' => '_event_end', - 'value' => $this->now->format( 'Y-m-d H:i:s' ), - 'compare' => '>', - 'type' => 'DATETIME', - ), + $this->meta_query_end_after_or_unbounded( $this->now ), ), 'meta_key' => '_event_start', 'orderby' => array( @@ -290,12 +285,7 @@ public function get_current_events_for_user( int $user_id, int $page = -1, int $ 'compare' => '<=', 'type' => 'DATETIME', ), - array( - 'key' => '_event_end', - 'value' => $this->now->format( 'Y-m-d H:i:s' ), - 'compare' => '>=', - 'type' => 'DATETIME', - ), + $this->meta_query_end_after_or_unbounded( $this->now, '>=' ), ), 'meta_key' => '_event_start', 'orderby' => array( @@ -318,12 +308,7 @@ public function get_current_and_upcoming_events_for_user( int $user_id, int $pag $page_size, array( 'meta_query' => array( - array( - 'key' => '_event_end', - 'value' => $this->now->format( 'Y-m-d H:i:s' ), - 'compare' => '>', - 'type' => 'DATETIME', - ), + $this->meta_query_end_after_or_unbounded( $this->now ), ), 'meta_key' => '_event_start', 'orderby' => array( @@ -454,12 +439,7 @@ protected function get_events_active_between( 'compare' => '<=', 'type' => 'DATETIME', ), - array( - 'key' => '_event_end', - 'value' => $boundary_start->format( 'Y-m-d H:i:s' ), - 'compare' => '>', - 'type' => 'DATETIME', - ), + $this->meta_query_end_after_or_unbounded( $boundary_start ), ), 'meta_key' => '_event_start', 'meta_type' => 'DATETIME', @@ -604,18 +584,43 @@ private function get_event_meta( int $event_id ): ?array { $meta = get_post_meta( $event_id ); $utc = new DateTimeZone( 'UTC' ); - if ( ! isset( $meta['_event_start'][0], $meta['_event_end'][0], $meta['_event_timezone'][0] ) ) { + if ( ! isset( $meta['_event_start'][0], $meta['_event_timezone'][0] ) ) { return null; } + $end = null; + if ( isset( $meta['_event_end'][0] ) && '' !== $meta['_event_end'][0] ) { + $end = new Event_End_Date( $meta['_event_end'][0], $utc ); + } + return array( 'start' => new Event_Start_Date( $meta['_event_start'][0], $utc ), - 'end' => new Event_End_Date( $meta['_event_end'][0], $utc ), + 'end' => $end, 'timezone' => new DateTimeZone( $meta['_event_timezone'][0] ), 'attendance_mode' => ! isset( $meta['_event_attendance_mode'][0] ) ? 'onsite' : $meta['_event_attendance_mode'][0], ); } + /** + * Returns a meta_query fragment that matches events whose _event_end is after + * the given boundary, OR which have no _event_end meta (open-ended events). + */ + private function meta_query_end_after_or_unbounded( DateTimeImmutable $boundary, string $compare = '>' ): array { + return array( + 'relation' => 'OR', + array( + 'key' => '_event_end', + 'value' => $boundary->format( 'Y-m-d H:i:s' ), + 'compare' => $compare, + 'type' => 'DATETIME', + ), + array( + 'key' => '_event_end', + 'compare' => 'NOT EXISTS', + ), + ); + } + private function update_event_meta( Event $event ) { $hosts = $this->attendee_repository->get_hosts( $event->id() ); $hosts_ids = array_map( @@ -626,7 +631,11 @@ function ( $host ) { ); $hosts_ids = implode( ', ', $hosts_ids ); update_post_meta( $event->id(), '_event_start', $event->start()->utc()->format( 'Y-m-d H:i:s' ) ); - update_post_meta( $event->id(), '_event_end', $event->end()->utc()->format( 'Y-m-d H:i:s' ) ); + if ( null === $event->end() ) { + delete_post_meta( $event->id(), '_event_end' ); + } else { + update_post_meta( $event->id(), '_event_end', $event->end()->utc()->format( 'Y-m-d H:i:s' ) ); + } update_post_meta( $event->id(), '_event_timezone', $event->timezone()->getName() ); update_post_meta( $event->id(), '_hosts', $hosts_ids ); update_post_meta( $event->id(), '_event_attendance_mode', $event->attendance_mode() ); diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event.php index c013ccf18b..1759dcfda3 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/event/event.php @@ -36,7 +36,7 @@ class Event { private int $id = 0; private int $author_id; private Event_Start_Date $start; - private Event_End_Date $end; + private ?Event_End_Date $end; private DateTimeZone $timezone; private string $slug = ''; private string $status; @@ -53,7 +53,7 @@ class Event { public function __construct( int $author_id, Event_Start_Date $start, - Event_End_Date $end, + ?Event_End_Date $end, DateTimeZone $timezone, string $status, string $title, @@ -85,10 +85,14 @@ public function start(): Event_Start_Date { return $this->start; } - public function end(): Event_End_Date { + public function end(): ?Event_End_Date { return $this->end; } + public function is_open_ended(): bool { + return null === $this->end; + } + public function is_published(): bool { return 'publish' === $this->status; } @@ -103,11 +107,14 @@ public function is_trashed(): bool { public function is_active(): bool { $now = Translation_Events::now(); - return $now >= $this->start->utc() && $now < $this->end->utc(); + if ( $now < $this->start->utc() ) { + return false; + } + return null === $this->end || $now < $this->end->utc(); } public function is_past(): bool { - return $this->end->is_in_the_past(); + return null !== $this->end && $this->end->is_in_the_past(); } public function is_remote(): bool { @@ -154,7 +161,7 @@ public function set_start( Event_Start_Date $start ): void { $this->start = $start; } - public function set_end( Event_End_Date $end ): void { + public function set_end( ?Event_End_Date $end ): void { $this->end = $end; } @@ -196,13 +203,16 @@ public function set_attendance_mode( string $attendance_mode ): void { * @throws InvalidStart * @throws InvalidEnd */ - public function validate_times( Event_Start_Date $start, Event_End_Date $end ) { - if ( $end <= $start ) { - throw new InvalidEnd(); - } + public function validate_times( Event_Start_Date $start, ?Event_End_Date $end ) { if ( ! $start->getTimezone() || 'UTC' !== $start->getTimezone()->getName() ) { throw new InvalidStart(); } + if ( null === $end ) { + return; + } + if ( $end <= $start ) { + throw new InvalidEnd(); + } if ( ! $end->getTimezone() || 'UTC' !== $end->getTimezone()->getName() ) { throw new InvalidEnd(); } diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/rss.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/rss.php index cdd78fb914..cdc6989f3d 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/rss.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/rss.php @@ -82,7 +82,9 @@ private function get_item( Event $event ) { $item .= ' '; $item .= ' ' . esc_html( $event->updated_at()->format( DATE_RSS ) ) . ''; $item .= ' ' . esc_html( $event->start()->format( DateTimeInterface::ATOM ) ) . ''; - $item .= ' ' . esc_html( $event->end()->format( DateTimeInterface::ATOM ) ) . ''; + if ( null !== $event->end() ) { + $item .= ' ' . esc_html( $event->end()->format( DateTimeInterface::ATOM ) ) . ''; + } $item .= ' ' . esc_url( home_url( gp_url( gp_url_join( 'events', $event->slug() ) ) ) ) . ''; $item .= ' '; return $item; diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event-details.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event-details.php index 58cf12f73a..11659ccf22 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event-details.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event-details.php @@ -266,17 +266,22 @@ function ( $contributor ) { start()->print_relative_time_html(); ?> start()->print_time_html(); ?> - - end()->is_in_the_past() ? __( 'Ended', 'gp-translation-events' ) : __( 'Ends', 'gp-translation-events' ) ); ?>: - end()->print_relative_time_html(); ?> - - - end()->print_time_html(); ?> + is_open_ended() ) : ?> + + + + + + end()->is_in_the_past() ? __( 'Ended', 'gp-translation-events' ) : __( 'Ends', 'gp-translation-events' ) ); ?>: + end()->print_relative_time_html(); ?> + + end()->print_time_html(); ?> +

- end()->is_in_the_past() ) : ?> + is_past() ) : ?> @@ -306,7 +311,7 @@ function ( $contributor ) {

- end()->is_in_the_past() ) : ?> + is_past() ) : ?> diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-form.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-form.php index 8032eb650b..7dfc2a567d 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-form.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-form.php @@ -52,7 +52,22 @@

- id() ) ?: 'readonly' ); ?>> + is_open_ended(); + $end_value = $is_open_ended ? '' : $event->end()->format( 'Y-m-d H:i' ); + $can_edit_end = $is_create_form || current_user_can( 'edit_translation_event_end', $event->id() ); + $end_input_attrs = ! $can_edit_end ? 'readonly' : ''; + if ( $is_open_ended ) { + $end_input_attrs .= ' disabled'; + } + ?> + + > + +
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-list.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-list.php index 786738ff62..702abd9995 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-list.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/parts/event-list.php @@ -102,12 +102,14 @@ class="button is-small is-destructive" start() ); ?> - + is_open_ended() ) : ?> end()->is_in_the_past() ) : ?> end() ); ?> end() ); ?> + is_open_ended() ) : ?> + diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/themes/wporg-translate-events-2024/blocks/event-date/index.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/themes/wporg-translate-events-2024/blocks/event-date/index.php index c403ac74b4..cef569e055 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/themes/wporg-translate-events-2024/blocks/event-date/index.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/themes/wporg-translate-events-2024/blocks/event-date/index.php @@ -34,6 +34,9 @@ if ( ! $event ) { return ''; } + if ( $event->is_open_ended() ) { + return '

' . esc_html__( 'Ongoing', 'gp-translation-events' ) . '

'; + } $end = $event->end()->format( 'F j, Y' ); return '

' . esc_html( $end ) . '

'; }, diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php index 36077bca0f..5f99329d32 100644 --- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php +++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php @@ -211,8 +211,8 @@ public function event_dates_meta_box( WP_Post $post ) { ?>
- -
+ +