Make WordPress Core


Ignore:
Timestamp:
10/14/2020 06:17:55 PM (4 years ago)
Author:
iandunn
Message:

Community Events: Trim events by Unix timestamp for accuracy.

The date and end_date fields are WP timestamps representing the venue's local time. As of meta:changeset:10270 (#meta4480), new start_unix_timestamp and end_unix_timestamp values are available, providing a proper Unix timestamp in the UTC timezone. Using those is more precise, and removes the time window where the event has expired but still appears in the Events Widget.

To simplify the function, it now only accepts and returns the events themselves, rather than the entire response body.

See #51130
See #meta4480
Related: https://make.wordpress.org/core/2019/09/23/date-time-improvements-wp-5-3/

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-community-events.php

    r48991 r49145  
    159159            }
    160160
     161            /*
     162             * Store the raw response, because events will expire before the cache does.
     163             * The response will need to be processed every page load.
     164             */
    161165            $this->cache_events( $response_body, $expiration );
    162166
    163             $response_body = $this->trim_events( $response_body );
     167            $response_body['events'] = $this->trim_events( $response_body['events'] );
    164168            $response_body = $this->format_event_data_time( $response_body );
    165169
     
    347351    public function get_cached_events() {
    348352        $cached_response = get_site_transient( $this->get_events_transient_key( $this->user_location ) );
    349         $cached_response = $this->trim_events( $cached_response );
     353
     354        if ( isset( $cached_response['events'] ) ) {
     355            $cached_response['events'] = $this->trim_events( $cached_response['events'] );
     356        }
    350357
    351358        return $this->format_event_data_time( $cached_response );
     
    436443     * @since 4.8.0
    437444     * @since 4.9.7 Stick a WordCamp to the final list.
    438      *
    439      * @param array $response_body The response body which contains the events.
     445     * @since 5.6.0 Accepts and returns only the events, rather than an entire HTTP response.
     446     *
     447     * @param array $events The events that will be prepared.
    440448     * @return array The response body with events trimmed.
    441449     */
    442     protected function trim_events( $response_body ) {
    443         if ( isset( $response_body['events'] ) ) {
    444             $wordcamps = array();
    445             $today     = current_time( 'Y-m-d' );
    446 
    447             foreach ( $response_body['events'] as $key => $event ) {
    448                 /*
    449                  * Skip WordCamps, because they might be multi-day events.
    450                  * Save a copy so they can be pinned later.
    451                  */
    452                 if ( 'wordcamp' === $event['type'] ) {
    453                     $wordcamps[] = $event;
    454                     continue;
    455                 }
    456 
    457                 // We don't get accurate time with timezone from API, so we only take the date part (Y-m-d).
    458                 $event_date = substr( $event['date'], 0, 10 );
    459 
    460                 if ( $today > $event_date ) {
    461                     unset( $response_body['events'][ $key ] );
    462                 }
    463             }
    464 
    465             $response_body['events'] = array_slice( $response_body['events'], 0, 3 );
    466             $trimmed_event_types     = wp_list_pluck( $response_body['events'], 'type' );
    467 
    468             // Make sure the soonest upcoming WordCamp is pinned in the list.
    469             if ( ! in_array( 'wordcamp', $trimmed_event_types, true ) && $wordcamps ) {
    470                 array_pop( $response_body['events'] );
    471                 array_push( $response_body['events'], $wordcamps[0] );
    472             }
    473         }
    474 
    475         return $response_body;
     450    protected function trim_events( array $events ) {
     451        $future_events = array();
     452
     453        foreach ( $events as $event ) {
     454            /*
     455             * The API's `date` and `end_date` fields are in the _event's_ local timezone, but UTC is needed so
     456             * it can be converted to the _user's_ local time.
     457             */
     458            $end_time = (int) $event['end_unix_timestamp'];
     459
     460            if ( time() < $end_time ) {
     461                array_push( $future_events, $event );
     462            }
     463        }
     464
     465        $future_wordcamps = array_filter(
     466            $future_events,
     467            function( $wordcamp ) {
     468                return 'wordcamp' === $wordcamp['type'];
     469            }
     470        );
     471
     472        $future_wordcamps    = array_values( $future_wordcamps ); // Remove gaps in indices.
     473        $trimmed_events      = array_slice( $future_events, 0, 3 );
     474        $trimmed_event_types = wp_list_pluck( $trimmed_events, 'type' );
     475
     476        // Make sure the soonest upcoming WordCamp is pinned in the list.
     477        if ( $future_wordcamps && ! in_array( 'wordcamp', $trimmed_event_types, true ) ) {
     478            array_pop( $trimmed_events );
     479            array_push( $trimmed_events, $future_wordcamps[0] );
     480        }
     481
     482        return $trimmed_events;
    476483    }
    477484
Note: See TracChangeset for help on using the changeset viewer.