/** * Returns all the IDs of the event posts children to the specified one. * * @param int $post_id * @param array $args An array of arguments overriding the default ones. * * @type bool $use_cache Whether the query should try to hit and update the cache or not. * * @return array|mixed */ public function get_ids($post_id, $args = array()) { $use_cache = isset($args['use_cache']) && false == $args['use_cache'] ? false : true; if (isset($args['fields'])) { unset($args['fields']); } if ($use_cache) { $children = $this->cache->get('child_events_' . $post_id, 'save_post'); if (is_array($children)) { return $children; } } $args = wp_parse_args($args, self::defaults_for_post($post_id)); $children = get_posts($args); if ($use_cache) { $this->cache->set('child_events_' . $post_id, $children, Tribe__Cache::NO_EXPIRATION, 'save_post'); } return $children; }
/** * Get all the events in the month by directly querying the postmeta table * Also caches the postmeta and terms for the found events */ protected function set_events_in_month() { global $wpdb; $grid_start_datetime = tribe_beginning_of_day($this->first_grid_date); $grid_end_datetime = tribe_end_of_day($this->final_grid_date); $cache = new Tribe__Cache(); $cache_key = 'events_in_month' . $grid_start_datetime . '-' . $grid_end_datetime; // if we have a cached result, use that $cached_events = $cache->get($cache_key, 'save_post'); if ($cached_events !== false) { $this->events_in_month = $cached_events; return; } $post_stati = array('publish'); if (is_user_logged_in()) { $post_stati[] = 'private'; } $post_stati = implode("','", $post_stati); $ignore_hidden_events_AND = $this->hidden_events_fragment(); $events_request = $wpdb->prepare("SELECT tribe_event_start.post_id as ID,\n\t\t\t\t\t\ttribe_event_start.meta_value as EventStartDate,\n\t\t\t\t\t\ttribe_event_end_date.meta_value as EventEndDate\n\t\t\t\tFROM {$wpdb->postmeta} AS tribe_event_start\n\t\t\t\tLEFT JOIN {$wpdb->posts} ON tribe_event_start.post_id = {$wpdb->posts}.ID\n\t\t\t\tLEFT JOIN {$wpdb->postmeta} as tribe_event_end_date ON ( tribe_event_start.post_id = tribe_event_end_date.post_id AND tribe_event_end_date.meta_key = '_EventEndDate' )\n\t\t\t\tWHERE {$ignore_hidden_events_AND} tribe_event_start.meta_key = '_EventStartDate'\n\t\t\t\tAND ( (tribe_event_start.meta_value >= '%1\$s' AND tribe_event_start.meta_value <= '%2\$s')\n\t\t\t\t\tOR (tribe_event_start.meta_value <= '%1\$s' AND tribe_event_end_date.meta_value >= '%1\$s')\n\t\t\t\t\tOR ( tribe_event_start.meta_value >= '%1\$s' AND tribe_event_start.meta_value <= '%2\$s')\n\t\t\t\t)\n\t\t\t\tAND {$wpdb->posts}.post_status IN('{$post_stati}')\n\t\t\t\tORDER BY {$wpdb->posts}.menu_order ASC, DATE(tribe_event_start.meta_value) ASC, TIME(tribe_event_start.meta_value) ASC;\n\t\t\t\t", $grid_start_datetime, $grid_end_datetime); $this->events_in_month = $wpdb->get_results($events_request); // cache the postmeta and terms for all these posts in one go $event_ids_in_month = wp_list_pluck($this->events_in_month, 'ID'); update_object_term_cache($event_ids_in_month, Tribe__Events__Main::POSTTYPE); update_postmeta_cache($event_ids_in_month); // cache the found events in the object cache $cache->set($cache_key, $this->events_in_month, 0, 'save_post'); }
/** * Get the start dates of all instances of the event, * in ascending order * * @param int $post_id * * @return array Start times, as Y-m-d H:i:s */ public static function get_start_dates($post_id) { if (empty($post_id)) { return array(); } $cache = new Tribe__Cache(); $dates = $cache->get('event_dates_' . $post_id, 'save_post'); if (is_array($dates)) { return $dates; } /** @var wpdb $wpdb */ global $wpdb; $ancestors = get_post_ancestors($post_id); $post_id = empty($ancestors) ? $post_id : end($ancestors); $sql = "SELECT meta_value FROM {$wpdb->postmeta} m INNER JOIN {$wpdb->posts} p ON p.ID=m.post_id AND (p.post_parent=%d OR p.ID=%d) WHERE meta_key='_EventStartDate' ORDER BY meta_value ASC"; $sql = $wpdb->prepare($sql, $post_id, $post_id); $result = $wpdb->get_col($sql); $cache->set('recurrence_start_dates_' . $post_id, $result, Tribe__Cache::NO_EXPIRATION, 'save_post'); return $result; }
/** * Customized WP_Query wrapper to setup event queries with default arguments. * * @param array $args * @param bool $full * * @return array|WP_Query */ public static function getEvents($args = array(), $full = false) { $defaults = array('post_type' => Tribe__Events__Main::POSTTYPE, 'orderby' => 'event_date', 'order' => 'ASC', 'posts_per_page' => tribe_get_option('postsPerPage', 10), 'tribe_render_context' => 'default'); $args = wp_parse_args($args, $defaults); // remove empty args and sort by key, this increases chance of a cache hit $args = array_filter($args, array(__CLASS__, 'filter_args')); ksort($args); $cache = new Tribe__Cache(); $cache_key = 'get_events_' . serialize($args); $result = $cache->get($cache_key, 'save_post'); if ($result && $result instanceof WP_Query) { do_action('log', 'cache hit', 'tribe-events-cache', $args); } else { do_action('log', 'no cache hit', 'tribe-events-cache', $args); $result = new WP_Query($args); $cache->set($cache_key, $result, Tribe__Cache::NON_PERSISTENT, 'save_post'); } if (!empty($result->posts)) { if ($full) { return $result; } else { $posts = $result->posts; return $posts; } } else { if ($full) { return $result; } else { return array(); } } }
/** * A recurring event will have the base post's slug in the * 'name' query var. We need to remove that and replace it * with the correct post's ID * * @param WP_Query $query * * @return void */ private function set_post_id_for_recurring_event_query($query) { $date = $query->get('eventDate'); $slug = $query->get('name'); if (empty($date) || empty($slug)) { return; // we shouldn't be here } $cache = new Tribe__Cache(); $post_id = $cache->get('single_event_' . $slug . '_' . $date, 'save_post'); if (!empty($post_id)) { unset($query->query_vars['name']); unset($query->query_vars['tribe_events']); $query->set('p', $post_id); return; } global $wpdb; $parent_sql = "SELECT ID FROM {$wpdb->posts} WHERE post_name=%s AND post_type=%s"; $parent_sql = $wpdb->prepare($parent_sql, $slug, Tribe__Events__Main::POSTTYPE); $parent_id = $wpdb->get_var($parent_sql); $parent_start = get_post_meta($parent_id, '_EventStartDate', true); if (empty($parent_start)) { return; // how does this series not have a start date? } else { $parent_start_date = date('Y-m-d', strtotime($parent_start)); } if ($parent_start_date == $date) { $post_id = $parent_id; } else { /* Look for child posts taking place on the requested date (but not * necessarily at the same time as the parent event). This does not * cater to scenarios where multiple children take place on the same * date but at different times - which is a known limitation to be * addressed in a future release. */ $child_sql = "\n\t\t\t\t\t\tSELECT ID\n\t\t\t\t\t\tFROM {$wpdb->posts} p\n\t\t\t\t\t\tINNER JOIN {$wpdb->postmeta} m ON m.post_id=p.ID AND m.meta_key='_EventStartDate'\n\t\t\t\t\t\tWHERE p.post_parent=%d\n\t\t\t\t\t\t AND p.post_type=%s\n\t\t\t\t\t\t AND LEFT( m.meta_value, 10 ) = %s\n\t\t\t\t\t"; $child_sql = $wpdb->prepare($child_sql, $parent_id, Tribe__Events__Main::POSTTYPE, $date); $post_id = $wpdb->get_var($child_sql); } if ($post_id) { unset($query->query_vars['name']); unset($query->query_vars['tribe_events']); $query->set('p', $post_id); $cache->set('single_event_' . $slug . '_' . $date, $post_id, Tribe__Cache::NO_EXPIRATION, 'save_post'); } }
/** * A recurring event will have the base post's slug in the * 'name' query var. We need to remove that and replace it * with the correct post's ID * * @param WP_Query $query * * @return void */ private function set_post_id_for_recurring_event_query($query) { $date = $query->get('eventDate'); $slug = isset($query->query['name']) ? $query->query['name'] : ''; if (empty($date) || empty($slug)) { return; // we shouldn't be here } /** * Filters the recurring event parent post ID. * * @param bool|int $parent_id The parent event post ID. Defaults to `false`. * If anything but `false` is returned from this filter * that value will be used as the recurring event parent * post ID. * @param WP_Query $query The current query. */ $parent_id = apply_filters('tribe_events_pro_recurring_event_parent_id', false, $query); $cache = new Tribe__Cache(); if (false === $parent_id) { $post_id = $cache->get('single_event_' . $slug . '_' . $date, 'save_post'); } else { $post_id = $cache->get('single_event_' . $slug . '_' . $date . '_' . $parent_id, 'save_post'); } if (!empty($post_id)) { unset($query->query_vars['name']); unset($query->query_vars[Tribe__Events__Main::POSTTYPE]); $query->set('p', $post_id); return; } /** @var \wpdb $wpdb */ global $wpdb; if (false === $parent_id) { $parent_sql = "SELECT ID FROM {$wpdb->posts} WHERE post_name=%s AND post_type=%s"; $parent_sql = $wpdb->prepare($parent_sql, $slug, Tribe__Events__Main::POSTTYPE); $parent_id = $wpdb->get_var($parent_sql); } $parent_start = get_post_meta($parent_id, '_EventStartDate', true); if (empty($parent_start)) { return; // how does this series not have a start date? } else { $parent_start_date = date('Y-m-d', strtotime($parent_start)); } if ($parent_start_date == $date) { $post_id = $parent_id; } else { /* Look for child posts taking place on the requested date (but not * necessarily at the same time as the parent event); take sequence into * account to distinguish between recurring event instances happening on the same * day. */ $sequence_number = $query->get('eventSequence'); $should_use_sequence = !empty($sequence_number) && is_numeric($sequence_number) && intval($sequence_number) > 1; $sequence_number = intval($sequence_number); if (!$should_use_sequence) { $child_sql = "\n\t\t\t\t\t\tSELECT ID\n\t\t\t\t\t\tFROM {$wpdb->posts} p\n\t\t\t\t\t\tINNER JOIN {$wpdb->postmeta} m ON m.post_id=p.ID AND m.meta_key='_EventStartDate'\n\t\t\t\t\t\tWHERE p.post_parent=%d\n\t\t\t\t\t\t AND p.post_type=%s\n\t\t\t\t\t\t AND LEFT( m.meta_value, 10 ) = %s\n\t\t\t\t\t"; $child_sql = $wpdb->prepare($child_sql, $parent_id, Tribe__Events__Main::POSTTYPE, $date); } else { $child_sql = "\n\t\t\t\t\t\tSELECT ID\n\t\t\t\t\t\tFROM {$wpdb->posts} p\n\t\t\t\t\t\tINNER JOIN {$wpdb->postmeta} m ON m.post_id=p.ID AND m.meta_key='_EventStartDate'\n\t\t\t\t\t\tINNER JOIN {$wpdb->postmeta} seqm ON seqm.post_id=p.ID AND seqm.meta_key='_EventSequence'\n\t\t\t\t\t\tWHERE p.post_parent=%d\n\t\t\t\t\t\t AND p.post_type=%s\n\t\t\t\t\t\t AND LEFT( m.meta_value, 10 ) = %s\n\t\t\t\t\t\t AND LEFT( seqm.meta_value, 10 ) = %s\n\t\t\t\t\t"; $child_sql = $wpdb->prepare($child_sql, $parent_id, Tribe__Events__Main::POSTTYPE, $date, $sequence_number); } $post_id = $wpdb->get_var($child_sql); } if ($post_id) { unset($query->query_vars['name']); unset($query->query_vars['tribe_events']); $query->set('p', $post_id); $cache->set('single_event_' . $slug . '_' . $date, $post_id, Tribe__Cache::NO_EXPIRATION, 'save_post'); } }