Skip to content

Instantly share code, notes, and snippets.

@jarednova
Created June 29, 2017 23:58
Show Gist options
  • Save jarednova/894fe08dc01b1466a296423b7a9618d7 to your computer and use it in GitHub Desktop.
Save jarednova/894fe08dc01b1466a296423b7a9618d7 to your computer and use it in GitHub Desktop.
<?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">&middot;</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">&middot;</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