90 |
90 |
91 if ( ! $location_search && $cached_events ) { |
91 if ( ! $location_search && $cached_events ) { |
92 return $cached_events; |
92 return $cached_events; |
93 } |
93 } |
94 |
94 |
95 // include an unmodified $wp_version |
95 // Include an unmodified $wp_version. |
96 include( ABSPATH . WPINC . '/version.php' ); |
96 require ABSPATH . WPINC . '/version.php'; |
97 |
97 |
98 $api_url = 'http://api.wordpress.org/events/1.0/'; |
98 $api_url = 'http://api.wordpress.org/events/1.0/'; |
99 $request_args = $this->get_request_args( $location_search, $timezone ); |
99 $request_args = $this->get_request_args( $location_search, $timezone ); |
100 $request_args['user-agent'] = 'WordPress/' . $wp_version . '; ' . home_url( '/' ); |
100 $request_args['user-agent'] = 'WordPress/' . $wp_version . '; ' . home_url( '/' ); |
101 |
101 |
111 if ( is_wp_error( $response ) ) { |
111 if ( is_wp_error( $response ) ) { |
112 $response_error = $response; |
112 $response_error = $response; |
113 } elseif ( 200 !== $response_code ) { |
113 } elseif ( 200 !== $response_code ) { |
114 $response_error = new WP_Error( |
114 $response_error = new WP_Error( |
115 'api-error', |
115 'api-error', |
116 /* translators: %d: numeric HTTP status code, e.g. 400, 403, 500, 504, etc. */ |
116 /* translators: %d: Numeric HTTP status code, e.g. 400, 403, 500, 504, etc. */ |
117 sprintf( __( 'Invalid API response code (%d)' ), $response_code ) |
117 sprintf( __( 'Invalid API response code (%d).' ), $response_code ) |
118 ); |
118 ); |
119 } elseif ( ! isset( $response_body['location'], $response_body['events'] ) ) { |
119 } elseif ( ! isset( $response_body['location'], $response_body['events'] ) ) { |
120 $response_error = new WP_Error( |
120 $response_error = new WP_Error( |
121 'api-invalid-response', |
121 'api-invalid-response', |
122 isset( $response_body['error'] ) ? $response_body['error'] : __( 'Unknown API error.' ) |
122 isset( $response_body['error'] ) ? $response_body['error'] : __( 'Unknown API error.' ) |
359 * the cache, then all users would see the events in the localized data/time |
359 * the cache, then all users would see the events in the localized data/time |
360 * of the user who triggered the cache refresh, rather than their own. |
360 * of the user who triggered the cache refresh, rather than their own. |
361 * |
361 * |
362 * @since 4.8.0 |
362 * @since 4.8.0 |
363 * |
363 * |
364 * @param array $response_body The response which contains the events. |
364 * @param array $response_body The response which contains the events. |
365 * @return array The response with dates and times formatted. |
365 * @return array The response with dates and times formatted. |
366 */ |
366 */ |
367 protected function format_event_data_time( $response_body ) { |
367 protected function format_event_data_time( $response_body ) { |
368 if ( isset( $response_body['events'] ) ) { |
368 if ( isset( $response_body['events'] ) ) { |
369 foreach ( $response_body['events'] as $key => $event ) { |
369 foreach ( $response_body['events'] as $key => $event ) { |
373 * The `date_format` option is not used because it's important |
373 * The `date_format` option is not used because it's important |
374 * in this context to keep the day of the week in the formatted date, |
374 * in this context to keep the day of the week in the formatted date, |
375 * so that users can tell at a glance if the event is on a day they |
375 * so that users can tell at a glance if the event is on a day they |
376 * are available, without having to open the link. |
376 * are available, without having to open the link. |
377 */ |
377 */ |
378 /* translators: Date format for upcoming events on the dashboard. Include the day of the week. See https://secure.php.net/date. */ |
378 /* translators: Date format for upcoming events on the dashboard. Include the day of the week. See https://www.php.net/date */ |
379 $response_body['events'][ $key ]['formatted_date'] = date_i18n( __( 'l, M j, Y' ), $timestamp ); |
379 $formatted_date = date_i18n( __( 'l, M j, Y' ), $timestamp ); |
380 $response_body['events'][ $key ]['formatted_time'] = date_i18n( get_option( 'time_format' ), $timestamp ); |
380 $formatted_time = date_i18n( get_option( 'time_format' ), $timestamp ); |
|
381 |
|
382 if ( isset( $event['end_date'] ) ) { |
|
383 $end_timestamp = strtotime( $event['end_date'] ); |
|
384 $formatted_end_date = date_i18n( __( 'l, M j, Y' ), $end_timestamp ); |
|
385 |
|
386 if ( 'meetup' !== $event['type'] && $formatted_end_date !== $formatted_date ) { |
|
387 /* translators: Upcoming events month format. See https://www.php.net/date */ |
|
388 $start_month = date_i18n( _x( 'F', 'upcoming events month format' ), $timestamp ); |
|
389 $end_month = date_i18n( _x( 'F', 'upcoming events month format' ), $end_timestamp ); |
|
390 |
|
391 if ( $start_month === $end_month ) { |
|
392 $formatted_date = sprintf( |
|
393 /* translators: Date string for upcoming events. 1: Month, 2: Starting day, 3: Ending day, 4: Year. */ |
|
394 __( '%1$s %2$dā%3$d, %4$d' ), |
|
395 $start_month, |
|
396 /* translators: Upcoming events day format. See https://www.php.net/date */ |
|
397 date_i18n( _x( 'j', 'upcoming events day format' ), $timestamp ), |
|
398 date_i18n( _x( 'j', 'upcoming events day format' ), $end_timestamp ), |
|
399 /* translators: Upcoming events year format. See https://www.php.net/date */ |
|
400 date_i18n( _x( 'Y', 'upcoming events year format' ), $timestamp ) |
|
401 ); |
|
402 } else { |
|
403 $formatted_date = sprintf( |
|
404 /* translators: Date string for upcoming events. 1: Starting month, 2: Starting day, 3: Ending month, 4: Ending day, 5: Year. */ |
|
405 __( '%1$s %2$d ā %3$s %4$d, %5$d' ), |
|
406 $start_month, |
|
407 date_i18n( _x( 'j', 'upcoming events day format' ), $timestamp ), |
|
408 $end_month, |
|
409 date_i18n( _x( 'j', 'upcoming events day format' ), $end_timestamp ), |
|
410 date_i18n( _x( 'Y', 'upcoming events year format' ), $timestamp ) |
|
411 ); |
|
412 } |
|
413 |
|
414 $formatted_date = wp_maybe_decline_date( $formatted_date, 'F j, Y' ); |
|
415 } |
|
416 } |
|
417 |
|
418 $response_body['events'][ $key ]['formatted_date'] = $formatted_date; |
|
419 $response_body['events'][ $key ]['formatted_time'] = $formatted_time; |
381 } |
420 } |
382 } |
421 } |
383 |
422 |
384 return $response_body; |
423 return $response_body; |
385 } |
424 } |
395 * higher position, so that it doesn't get trimmed off. |
434 * higher position, so that it doesn't get trimmed off. |
396 * |
435 * |
397 * @since 4.8.0 |
436 * @since 4.8.0 |
398 * @since 4.9.7 Stick a WordCamp to the final list. |
437 * @since 4.9.7 Stick a WordCamp to the final list. |
399 * |
438 * |
400 * @param array $response_body The response body which contains the events. |
439 * @param array $response_body The response body which contains the events. |
401 * @return array The response body with events trimmed. |
440 * @return array The response body with events trimmed. |
402 */ |
441 */ |
403 protected function trim_events( $response_body ) { |
442 protected function trim_events( $response_body ) { |
404 if ( isset( $response_body['events'] ) ) { |
443 if ( isset( $response_body['events'] ) ) { |
405 $wordcamps = array(); |
444 $wordcamps = array(); |
406 $current_timestamp = current_time( 'timestamp' ); |
445 $today = current_time( 'Y-m-d' ); |
407 |
446 |
408 foreach ( $response_body['events'] as $key => $event ) { |
447 foreach ( $response_body['events'] as $key => $event ) { |
409 /* |
448 /* |
410 * Skip WordCamps, because they might be multi-day events. |
449 * Skip WordCamps, because they might be multi-day events. |
411 * Save a copy so they can be pinned later. |
450 * Save a copy so they can be pinned later. |
413 if ( 'wordcamp' === $event['type'] ) { |
452 if ( 'wordcamp' === $event['type'] ) { |
414 $wordcamps[] = $event; |
453 $wordcamps[] = $event; |
415 continue; |
454 continue; |
416 } |
455 } |
417 |
456 |
418 $event_timestamp = strtotime( $event['date'] ); |
457 // We don't get accurate time with timezone from API, so we only take the date part (Y-m-d). |
419 |
458 $event_date = substr( $event['date'], 0, 10 ); |
420 if ( $current_timestamp > $event_timestamp && ( $current_timestamp - $event_timestamp ) > DAY_IN_SECONDS ) { |
459 |
|
460 if ( $today > $event_date ) { |
421 unset( $response_body['events'][ $key ] ); |
461 unset( $response_body['events'][ $key ] ); |
422 } |
462 } |
423 } |
463 } |
424 |
464 |
425 $response_body['events'] = array_slice( $response_body['events'], 0, 3 ); |
465 $response_body['events'] = array_slice( $response_body['events'], 0, 3 ); |
426 $trimmed_event_types = wp_list_pluck( $response_body['events'], 'type' ); |
466 $trimmed_event_types = wp_list_pluck( $response_body['events'], 'type' ); |
427 |
467 |
428 // Make sure the soonest upcoming WordCamp is pinned in the list. |
468 // Make sure the soonest upcoming WordCamp is pinned in the list. |
429 if ( ! in_array( 'wordcamp', $trimmed_event_types ) && $wordcamps ) { |
469 if ( ! in_array( 'wordcamp', $trimmed_event_types, true ) && $wordcamps ) { |
430 array_pop( $response_body['events'] ); |
470 array_pop( $response_body['events'] ); |
431 array_push( $response_body['events'], $wordcamps[0] ); |
471 array_push( $response_body['events'], $wordcamps[0] ); |
432 } |
472 } |
433 } |
473 } |
434 |
474 |