Created
December 15, 2016 00:33
-
-
Save barryhughes/5f864b9b3dc4340300a3899e5f08a72d to your computer and use it in GitHub Desktop.
Auto update countdown widget: move it to the next available event if it's target has already started
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Updates instances of the Countdown Widget so that they always | |
* point to an event which has not yet started. | |
* | |
* This works by intercepting events before the widget is rendered: | |
* if it looks like the event the widget is targeting has already | |
* started, the object will select the next upcoming event (if one | |
* is available) and set the widget to use that instead. | |
* | |
* Tested with Events Calendar PRO 4.4 (in development) | |
*/ | |
class Perpetual_Countdown_Widget { | |
protected $instance; | |
protected $widget; | |
protected $next_event; | |
public function __construct() { | |
add_filter( 'widget_display_callback', array( $this, 'listen' ), 10, 2 ); | |
} | |
public function listen( $instance, $widget ) { | |
$this->instance = $instance; | |
$this->widget = $widget; | |
if ( | |
$widget->id_base !== 'tribe-events-countdown-widget' | |
|| ! $this->current_event_has_started() | |
|| ! $this->get_next_event() | |
) { | |
return $instance; | |
} | |
$this->update_instance(); | |
return $this->instance; | |
} | |
/** | |
* Checks if the current target event has started or not. | |
* | |
* @return bool | |
*/ | |
protected function current_event_has_started() { | |
// Load the widget's current target event | |
$target_event = current( tribe_get_events( array( 'p' => $this->instance['event'] ) ) ); | |
// Check if it's a valid event that has already started | |
if ( | |
$target_event | |
&& date( 'Y-m-d H:i:s' ) >= $target_event->_EventStartDateUTC | |
) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Fetches the next suitable event for the countdown widget, | |
* if one is available and returns true (else returns false). | |
* | |
* Be nice to use WP_Query or tribe_get_events() here, but a | |
* straight select will be used instead to avoid unwanted side | |
* effects. | |
* | |
* @returns bool | |
*/ | |
protected function get_next_event() { | |
global $wpdb; | |
$query = " | |
SELECT DISTINCT( ID ) | |
FROM $wpdb->posts | |
JOIN $wpdb->postmeta ON post_id = ID | |
WHERE post_type = 'tribe_events' | |
AND meta_key = '_EventStartDateUTC' | |
AND meta_value > %s | |
ORDER BY meta_value ASC | |
LIMIT 1 | |
"; | |
$next_id = $wpdb->get_var( $wpdb->prepare( | |
$query, date( 'Y-m-d H:i:s', strtotime( '+1 second' ) ) | |
) ); | |
$next_event = get_post( $next_id ); | |
if ( ! $next_id || $next_event->ID != $next_id ) { | |
return false; | |
} | |
$this->next_event = $next_event; | |
return true; | |
} | |
protected function update_instance() { | |
$this->instance['event'] = $this->instance['event_id'] = $this->next_event->ID; | |
$this->widget->save_settings( array( $this->widget->number => $this->instance ) ); | |
} | |
} | |
new Perpetual_Countdown_Widget; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment