diff --git a/inc/Abilities/MetaSyncAbilities.php b/inc/Abilities/MetaSyncAbilities.php index 476c6ea..23d3bff 100644 --- a/inc/Abilities/MetaSyncAbilities.php +++ b/inc/Abilities/MetaSyncAbilities.php @@ -368,14 +368,17 @@ private function calculateExpectedDatetime( array $attrs ): string { /** * Calculate expected end datetime value from block attributes. - * Used for dry-run preview. + * Used for dry-run preview. Mirrors meta-storage.php logic: + * - Has endDate + endTime: use them. + * - Has endDate, no endTime: use sentinel 23:59:59. + * - Has endTime, no endDate: same day as start. + * - Neither: no end meta (empty string). * * @param array $attrs Block attributes - * @return string Expected end datetime value + * @return string Expected end datetime value, or empty if none. */ private function calculateExpectedEndDatetime( array $attrs ): string { $start_date = $attrs['startDate'] ?? ''; - $start_time = $attrs['startTime'] ?? '00:00:00'; $end_date = $attrs['endDate'] ?? ''; $end_time = $attrs['endTime'] ?? ''; @@ -383,11 +386,6 @@ private function calculateExpectedEndDatetime( array $attrs ): string { return ''; } - $start_time_parts = explode( ':', $start_time ); - if ( count( $start_time_parts ) === 2 ) { - $start_time .= ':00'; - } - $end_time_parts = explode( ':', $end_time ); if ( $end_time && count( $end_time_parts ) === 2 ) { $end_time .= ':00'; @@ -398,12 +396,11 @@ private function calculateExpectedEndDatetime( array $attrs ): string { return $end_date . ' ' . $effective_end_time; } - try { - $start_dt = new \DateTime( $start_date . ' ' . $start_time ); - $start_dt->modify( '+3 hours' ); - return $start_dt->format( 'Y-m-d H:i:s' ); - } catch ( \Exception $e ) { - return $start_date . ' ' . $start_time; + if ( $end_time ) { + return $start_date . ' ' . $end_time; } + + // No end date or time — no end meta should exist. + return ''; } } diff --git a/inc/Blocks/Calendar/Data/EventHydrator.php b/inc/Blocks/Calendar/Data/EventHydrator.php index 463030c..c0381b6 100644 --- a/inc/Blocks/Calendar/Data/EventHydrator.php +++ b/inc/Blocks/Calendar/Data/EventHydrator.php @@ -70,10 +70,17 @@ private static function hydrate_datetime_from_meta( int $post_id, array &$event_ $end_datetime = get_post_meta( $post_id, EVENT_END_DATETIME_META_KEY, true ); if ( $end_datetime ) { - $date_obj = date_create( $end_datetime ); - if ( $date_obj ) { - $event_data['endDate'] = $date_obj->format( 'Y-m-d' ); - $end_time_from_meta = $date_obj->format( 'H:i:s' ); + $end_obj = date_create( $end_datetime ); + if ( $end_obj ) { + // Skip if end datetime is identical to start (legacy data with no real end time). + $start_check = $start_datetime ? date_create( $start_datetime ) : null; + if ( $start_check && $end_obj->format( 'Y-m-d H:i' ) === $start_check->format( 'Y-m-d H:i' ) ) { + // No real end time — don't populate endDate/endTime. + return; + } + + $event_data['endDate'] = $end_obj->format( 'Y-m-d' ); + $end_time_from_meta = $end_obj->format( 'H:i:s' ); // Only set if not the sentinel value (23:59:59 means "no end time provided") if ( '23:59:59' !== $end_time_from_meta ) { $event_data['endTime'] = $end_time_from_meta; diff --git a/inc/Blocks/Calendar/Display/DisplayVars.php b/inc/Blocks/Calendar/Display/DisplayVars.php index 44da7a4..d9312be 100644 --- a/inc/Blocks/Calendar/Display/DisplayVars.php +++ b/inc/Blocks/Calendar/Display/DisplayVars.php @@ -103,6 +103,11 @@ public static function format_time_range( DateTime $start_datetime_obj, string $ $end_datetime_obj = new DateTime( $end_date . ' ' . $end_time, $event_tz ); + // Don't show a range when start and end are identical (no real end time). + if ( $start_datetime_obj->format( 'Y-m-d H:i' ) === $end_datetime_obj->format( 'Y-m-d H:i' ) ) { + return $start_formatted_full; + } + $is_same_day = $start_datetime_obj->format( 'Y-m-d' ) === $end_datetime_obj->format( 'Y-m-d' ); if ( ! $is_same_day ) { return $start_formatted_full; diff --git a/inc/Cli/Check/CheckMetaSyncCommand.php b/inc/Cli/Check/CheckMetaSyncCommand.php index 90130c6..a05bca8 100644 --- a/inc/Cli/Check/CheckMetaSyncCommand.php +++ b/inc/Cli/Check/CheckMetaSyncCommand.php @@ -174,10 +174,16 @@ private function resync_meta( array $events ): void { if ( ! empty( $attrs['endDate'] ) ) { $end_datetime = $attrs['endDate']; - if ( ! empty( $attrs['endTime'] ) ) { - $end_datetime .= ' ' . $attrs['endTime']; - } + $end_time = ! empty( $attrs['endTime'] ) ? $attrs['endTime'] : '23:59:59'; + $end_datetime .= ' ' . $end_time; update_post_meta( (int) $post_id, '_datamachine_event_end_datetime', $end_datetime ); + } elseif ( ! empty( $attrs['endTime'] ) ) { + // End time but no end date: same day as start. + $end_datetime = $attrs['startDate'] . ' ' . $attrs['endTime']; + update_post_meta( (int) $post_id, '_datamachine_event_end_datetime', $end_datetime ); + } else { + // No end data: remove stale meta rather than fabricate. + delete_post_meta( (int) $post_id, '_datamachine_event_end_datetime' ); } ++$fixed; diff --git a/inc/Core/EventSchemaProvider.php b/inc/Core/EventSchemaProvider.php index aacb242..8eb80c9 100644 --- a/inc/Core/EventSchemaProvider.php +++ b/inc/Core/EventSchemaProvider.php @@ -355,8 +355,15 @@ public static function generateSchemaOrg( array $event_data, array $venue_data, [$resolved_end_date, $resolved_end_time] = self::resolveEndDate( $event_data, $post_id ); if ( ! empty( $resolved_end_date ) ) { - $end_time = ! empty( $resolved_end_time ) ? 'T' . $resolved_end_time : ''; - $schema['endDate'] = $resolved_end_date . $end_time; + $end_time = ! empty( $resolved_end_time ) ? 'T' . $resolved_end_time : ''; + $end_date_iso = $resolved_end_date . $end_time; + + // Only include endDate if it differs from startDate. + // Identical values mean no real end time was provided — omitting + // is better than telling Google the event is zero minutes long. + if ( ! isset( $schema['startDate'] ) || $end_date_iso !== $schema['startDate'] ) { + $schema['endDate'] = $end_date_iso; + } } if ( ! empty( $event_data['description'] ) ) { diff --git a/inc/Core/meta-storage.php b/inc/Core/meta-storage.php index 5d9ddd4..c6ee451 100644 --- a/inc/Core/meta-storage.php +++ b/inc/Core/meta-storage.php @@ -211,12 +211,18 @@ function data_machine_events_sync_datetime_meta( $post_id, $post, $update ) { update_post_meta( $post_id, EVENT_DATETIME_META_KEY, $datetime ); if ( $end_date ) { - $effective_end_time = $end_time ? $end_time : $effective_start_time; + // Has explicit end date: use sentinel 23:59:59 when no end time provided. + $effective_end_time = $end_time ? $end_time : '23:59:59'; $end_datetime_val = $end_date . ' ' . $effective_end_time; + update_post_meta( $post_id, EVENT_END_DATETIME_META_KEY, $end_datetime_val ); + } elseif ( $end_time ) { + // Has end time but no end date: same day, store with start date. + $end_datetime_val = $start_date . ' ' . $end_time; + update_post_meta( $post_id, EVENT_END_DATETIME_META_KEY, $end_datetime_val ); } else { - $end_datetime_val = $datetime; + // No end date or time: delete stale meta rather than fabricate one. + delete_post_meta( $post_id, EVENT_END_DATETIME_META_KEY ); } - update_post_meta( $post_id, EVENT_END_DATETIME_META_KEY, $end_datetime_val ); } else { // No date found, delete meta if it exists. delete_post_meta( $post_id, EVENT_DATETIME_META_KEY );