Created
June 29, 2017 23:58
-
-
Save jarednova/894fe08dc01b1466a296423b7a9618d7 to your computer and use it in GitHub Desktop.
This file contains 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 | |
class ClientEvent extends ClientPost { | |
protected $_venue; | |
protected $_hosts; | |
protected $_master_id; | |
protected $_is_alt_event; // whether or not this instance is an alt date/time of another event | |
protected $_is_alt_event_or_master; // whether or not this instance is an alt event or a master with alts | |
protected $_alt_events; // (if is_alt_event is false) | |
protected $_alt_parent; // (if is_alt_event is true) | |
protected $_sort_by_date; | |
public $PostClass = 'ClientEvent'; | |
/** | |
* | |
* | |
* @param int|bool $pid | |
*/ | |
function init( $pid = false ) { | |
if ( $pid === false ) { | |
$pid = get_the_ID(); | |
} | |
$post_info = $this->get_info( $pid ); | |
$this->import( $post_info ); | |
} | |
function breadcrumbs() { | |
return null; | |
} | |
// The latest end date for this event that includes all in an alt event series. | |
// | |
public function EventLastDate() { | |
$all_related = $this->other_occurrences(); | |
if (is_array($all_related) && count($all_related) > 0) { | |
$all_related[] = $this->_alt_parent; | |
if ($this->_alt_parent->ID != $this->ID) { | |
$all_related[] = $this; | |
} | |
TimberHelper::osort( $all_related, '_EventEndDate' ); | |
return array_pop($all_related)->EventEndDate(); | |
} | |
return $this->EventEndDate(); | |
} | |
// Opposite of EventLastDate! TODO Refactor to promote reuse; non-crit. | |
// | |
public function EventFirstDate() { | |
$all_related = $this->other_occurrences(); | |
if (is_array($all_related) && count($all_related) > 0) { | |
$all_related[] = $this->_alt_parent; | |
if ($this->_alt_parent->ID != $this->ID) { | |
$all_related[] = $this; | |
} | |
TimberHelper::osort( $all_related, '_EventStartDate' ); | |
$reversed = array_reverse( $all_related ); | |
return array_pop( $reversed )->EventStartDate(); | |
} | |
return $this->EventStartDate(); | |
} | |
// This event's end date. | |
// | |
public function EventEndDate() { | |
return $this->_EventEndDate; | |
} | |
// This event's start date. | |
// | |
public function EventStartDate() { | |
return $this->_EventStartDate; | |
} | |
// Display helpers: | |
public function GetEventSortByDate() { | |
if ( !$this->_sort_by_date ) { | |
$this->_sort_by_date = $this->EventStartDate(); | |
} | |
return $this->_sort_by_date; | |
} | |
public function MaybeSetEventSortByDate( $date ) { | |
if ( !$this->_sort_by_date || ( $this->_sort_by_date && (strtotime( $date ) < strtotime( $this->_sort_by_date )) )) { | |
$this->_sort_by_date = $date; | |
} | |
} | |
function get_adjacent_event( $mode = 'next' ) { | |
global $wpdb; | |
if ( $mode == 'previous' ) { | |
$order = 'DESC'; | |
$sign = '<'; | |
} else { | |
$order = 'ASC'; | |
$sign = '>'; | |
} | |
$date = $this->EventStartDate; | |
$id = $this->ID; | |
$eventsQuery = $wpdb->prepare( " | |
SELECT $wpdb->posts.*, d1.meta_value as EventStartDate | |
FROM $wpdb->posts | |
LEFT JOIN $wpdb->postmeta as d1 ON($wpdb->posts.ID = d1.post_id) | |
WHERE $wpdb->posts.post_type = '%s' | |
AND d1.meta_key = '_EventStartDate' | |
AND ((d1.meta_value = '%s' AND ID $sign %d) OR | |
d1.meta_value $sign '%s') | |
AND $wpdb->posts.post_status = 'publish' | |
AND ($wpdb->posts.ID != %d OR d1.meta_value != '%s') | |
ORDER BY TIMESTAMP(d1.meta_value) $order, ID $order | |
LIMIT 1", $this->post_type, $date, $id, $date, $id, $date ); | |
$args = array( | |
'post_type' => $this->post_type, | |
'post_status' => 'publish', | |
'post__not_in' => array( $this->ID ), | |
'order' => $order, | |
'orderby' => "TIMESTAMP($wpdb->postmeta.meta_value) ID", | |
'posts_per_page' => 1, | |
'meta_query' => array( | |
array( | |
'key' => '_EventStartDate', | |
'value' => $this->EventStartDate, | |
'type' => 'DATE' | |
) | |
) | |
); | |
$results = $wpdb->get_row( $eventsQuery, OBJECT ); | |
if ( is_object( $results ) ) { | |
return new ClientEvent( $results->ID ); | |
} | |
} | |
function get_next($taxonomy = false){ | |
if (!isset($this->next)) { | |
$this->next = $this->get_adjacent_event('next'); | |
} | |
return $this->next; | |
} | |
function get_prev($taxonomy = false){ | |
if (!isset($this->prev)) { | |
$this->prev = $this->get_adjacent_event('previous'); | |
} | |
return $this->prev; | |
} | |
public function hosts() { | |
if ( !isset( $this->_hosts ) ) { | |
$args = array('orderby' => 'slug', 'order' => 'ASC', 'fields' => 'all'); | |
$this->_hosts = $this->get_terms( 'host', 'ClientEventHost', $args ); | |
if ( is_array($this->_hosts) && isset($this->_hosts[0]) && isset($this->_hosts[0]->term_order) ){ | |
TimberHelper::osort($this->_hosts, 'term_order'); | |
} | |
} | |
return $this->_hosts; | |
} | |
function target() { | |
if ( $this->is_external() ) { | |
return '_blank'; | |
} | |
return '_self'; | |
} | |
// Similar to get_master_id, except returns the instance. | |
// | |
function get_master_event() { | |
$master_id = $this->get_master_id(); | |
return ($master_id == $this->ID) ? $this : (new ClientEvent($master_id)); | |
} | |
public function is_child() { | |
return tribe_is_recurring_event( $this->ID ); | |
} | |
// Custom events; different from normal Tribe recurring events; | |
public function is_alt_event() { | |
if ($this->_is_alt_event !== null) { | |
return $this->_is_alt_event; | |
} | |
global $wpdb; | |
$this->_is_alt_event = ((int)$wpdb->get_var( | |
"SELECT meta_value FROM $wpdb->postmeta WHERE post_id=$this->ID AND meta_key LIKE '_IsAltEvent'") == 1) ? true : false; | |
return $this->_is_alt_event; | |
} | |
// A helper to explicitly flag an alt event (or master/rollup) for event-time.twig | |
public function is_alt_event_or_master() { | |
if ( !isset( $this->_is_alt_event_or_master ) ) { | |
$this->_is_alt_event_or_master = $this->is_alt_event(); | |
if ( !$this->_is_alt_event_or_master ) { | |
$this->_is_alt_event_or_master = ( $this->get_master_id() == $this->ID ); | |
if ( $this->_is_alt_event_or_master == true ) { | |
$this->_is_alt_event_or_master = $this->is_recurring(); // true master? (has children) | |
} | |
} | |
} | |
return $this->_is_alt_event_or_master; | |
} | |
public function is_external() { | |
return ( isset( $this->external_url ) && strlen( trim( $this->external_url ) ) ); | |
} | |
public function is_past(){ | |
if (isset($this->_EventStartDate)){ | |
$now = new DateTime('now'); | |
$now->modify( '-1 day' ); | |
$event_start = new DateTime($this->_EventStartDate); | |
return $now > $event_start; | |
} | |
return false; | |
} | |
public function first_occurrence() { | |
$recurs = $this->recurrences(); | |
if (is_array($recurs) && count($recurs)) { | |
return $recurs[0]; | |
} | |
} | |
public function last_occurrence() { | |
$recurs = $this->recurrences(); | |
if (is_array($recurs) && count($recurs)) { | |
return end($recurs); | |
} | |
} | |
public function is_recurring() { | |
$oo = $this->other_occurrences( -1, false ); | |
if ( count($oo) ){ | |
return true; | |
} | |
return false; | |
} | |
public function link() { | |
if ( $this->is_external() ) { | |
return $this->external_url; | |
} | |
if ( $parent = $this->parent() ) { | |
return $parent->link(); | |
} | |
return parent::link(); | |
} | |
// Non-breaking proxy to get_alternate_times below that functions on this instance | |
// and identifies the alt event group parent (initial event post). | |
// | |
// @legacy_order_by Preserve legacy ordering as defined in get_alternate_times; | |
// This is provided for edge cases (@see get_master_id) when we | |
// need to use both the legacy and new system of alt management; | |
// ie, we need the alt_parent derived via postmeta, but don't mind | |
// the unreliable order_by behavior of get_alternate_times. | |
// This is for interim systems compatibility only. | |
// | |
public function get_alt_events($start = null, $end = null, $legacy_order_by = false) | |
{ | |
if ( !isset($this->_alt_events)) { | |
$this->_alt_events = $this->get_alternate_times($this->ID, $start, $end); | |
// Keep ordered in ascending post creation | |
if ( !$legacy_order_by ) { | |
usort($this->_alt_events, function($a, $b) { | |
return strcmp(strtotime($a->post_date_gmt), strtotime($b->post_date_gmt)); | |
}); | |
} | |
foreach ($this->_alt_events as $alt_event) { | |
if (! $alt_event->is_alt_event() ) { | |
$this->_alt_parent = $alt_event; | |
// Legacy | |
$this->_master_id = $this->_alt_parent->ID; | |
break; | |
} | |
} | |
} | |
return $this->_alt_events; | |
} | |
public function get_alt_parent() { | |
$this->get_alt_events(); | |
if (isset($this->_alt_parent)) { | |
return $this->_alt_parent; | |
} | |
return $this; | |
} | |
public function has_odd_recurrance() { | |
$events = $this->get_alt_events(); | |
if (count($events)) { | |
return true; | |
} | |
return false; | |
} | |
// Note on behavior here, this is not just the alternate times to the initial event, but a bi-directional | |
// aggregate. ie, an alternate event should return all siblings, including the initial event. For heirarchical | |
// use, see get_alt_events above. | |
// | |
public function get_alternate_times( $parent_id, $start = null, $end = null ) { | |
if ( $start == null ) { | |
$start = '1 Jan 1970'; | |
} | |
if ( $end == null ) { | |
$end = date( 'j M Y', strtotime( '10 years' ) ); | |
} | |
global $wpdb; | |
if (!$parent_id) { | |
return array(); | |
} | |
$query = 'SELECT p2p_from, p2p_to FROM '. $wpdb->prefix. 'p2p WHERE (p2p_from = '.$parent_id.' OR p2p_to = '.$parent_id.' ) AND p2p_type = "alternate_events"'; | |
$rows = $wpdb->get_results( $query ); | |
$connects = array(); | |
foreach ( $rows as $row ) { | |
if ( $row->p2p_from != $parent_id ) { | |
$connects[] = $row->p2p_from; | |
} | |
if ( $row->p2p_to != $parent_id ) { | |
$connects[] = $row->p2p_to; | |
} | |
} | |
if ( count( $connects ) ) { | |
$connects[] = $this->ID; | |
$connects = array_unique($connects); | |
$query = array( 'post__in' => $connects ); | |
$query['start_date'] = $start; | |
$query['orderby'] = 'start_date'; | |
$query['order'] = 'asc'; | |
$query['end_date'] = $end; | |
$events = tribe_get_events( $query ); | |
foreach ( $events as &$event ) { | |
$event = new ClientEvent( $event->ID ); | |
} | |
return $events; | |
} | |
return array(); | |
} | |
function get_master_id() { | |
if ( isset($this->_master_id) ) { | |
return $this->_master_id; | |
} | |
// TEC recurring events support, return parent | |
if ( tribe_is_recurring_event( $this->ID ) ) { | |
if ( $this->post_parent > 0) { | |
$this->_master_id = $this->post_parent; | |
} else { | |
$this->_master_id = $this->ID; | |
} | |
$this->_alt_parent = new ClientEvent($this->_master_id); | |
} else { | |
// Cache events and _alt_parent | |
$this->get_alt_events(null, null, true); | |
// Support for new alt_event alt event management; | |
// Alt events should have a _IsAltEvent postmeta bool: | |
if (isset($this->_alt_parent)) { | |
$this->_master_id = $this->_alt_parent->ID; | |
} else { | |
// Legacy alternate time derivation for compatibility with | |
// some areas of the site not yet refactored to use new system; | |
// This is unreliable since it uses date ordering and an early | |
// event start date does not guarantee it is the parent since it | |
// is reasonable (yet unlikely) that alt times can have an earlier | |
// start time than the initial event parent: | |
if ( count( $this->_alt_events ) && isset( $this->_alt_events[0] ) ) { | |
$this->_master_id = $this->_alt_events[0]->ID; | |
} else { | |
$this->_master_id = $this->ID; | |
} | |
$this->_alt_parent = new ClientEvent($this->_master_id); | |
} | |
} | |
return $this->_master_id; | |
} | |
public function occurance_title() { | |
if ( $this->is_alt_event_or_master() ) { | |
$start_date = date( 'D, M j, Y', strtotime( $this->_EventStartDate ) ); | |
$end_date = date( 'D, M j, Y', strtotime( $this->_EventEndDate ) ); | |
$start_time = date( 'g:i a', strtotime( $this->_EventStartDate ) ); | |
$end_time = date( 'g:i a', strtotime( $this->_EventEndDate ) ); | |
$str = $start_date; | |
if ( $start_date != $end_date ) { | |
$str .= ' - <br/>'. $end_date; | |
} | |
$str .= ' <span class="bullet">·</span> '. $start_time; | |
if ( $start_time != $end_time ) { | |
$str .= ' - ' . $end_time; | |
} | |
} else { | |
$str = date( 'D, M j, Y', strtotime( $this->_EventStartDate ) ); | |
//not all day event if (){ | |
$str .= ' <span class="bullet">·</span> '.date( 'g:i a', strtotime( $this->_EventStartDate ) ); | |
//} | |
} | |
return $str; | |
} | |
// Note: Return does not always include event master post! | |
// | |
public function other_occurrences( $ct = -1, $include_master = false ) { | |
$master_id = $this->get_master_id(); | |
$master_event = ($master_id == $this->ID) ? $this : (new ClientEvent($master_id)); | |
// Get heirarchical siblings | |
$siblings = get_children( 'post_parent=' . $master_id . '&post_type=' . $this->post_type . '&numberposts=-1' ); | |
foreach ( $siblings as &$sibling ) { | |
$sibling = new ClientEvent( $sibling->ID ); | |
} | |
// Get all custom alt event posts | |
$others = $master_event->get_alt_events(); | |
if ( $include_master ) { | |
$others[] = $master_event; | |
} | |
// Merge custom alt events with heirarchical siblings | |
$siblings = array_merge( $siblings, $others ); | |
$siblings = array_values( $siblings ); | |
// Remove self(ves) for display | |
foreach ( $siblings as &$sib ) { | |
if ( $sib->ID == $this->ID ) { | |
$sib = false; | |
} | |
} | |
$siblings = array_filter($siblings); | |
TimberHelper::osort( $siblings, '_EventStartDate' ); | |
return $siblings; | |
} | |
public function recurrences( $include_master = true ) { | |
$all = $this->other_occurrences(-1, $include_master); | |
$all[] = $this; | |
TimberHelper::osort( $all, '_EventStartDate' ); | |
return $all; | |
} | |
public function recurrence($i = null, $master = false) { | |
if ($i === null) { | |
$master_id = $this->get_master_id(); | |
return new ClientEvent($master_id); | |
} | |
$occurs = $this->other_occurrences(); | |
if ($i < 0){ | |
$i = count($occurs) + $i; | |
} | |
return $occurs[$i]; | |
} | |
public function related($id = null) { | |
$master_id = $this->get_master_id(); | |
$master_post = get_post($master_id); | |
return parent::related($master_post); | |
} | |
public function tags() { | |
return $this->get_terms( 'tribe_events_cat', 'ClientEventTag' ); | |
} | |
public function venue() { | |
if ( !isset( $this->_venue ) ) { | |
if ( isset( $this->_EventVenueID ) ) { | |
$vid = $this->_EventVenueID; | |
$this->_venue = null; | |
if ( $vid ) { | |
$this->_venue = new ClientPost( $vid ); | |
} | |
} | |
} | |
return $this->_venue; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment