protected function match_existing_post(array $record) { $start_date = $this->get_event_start_date($record); $end_date = $this->get_event_end_date($record); $all_day = $this->get_boolean_value_by_key($record, 'event_all_day'); // Base query - only the meta query will be different $query_args = array('post_type' => Tribe__Events__Main::POSTTYPE, 'post_title' => $this->get_value_by_key($record, 'event_name'), 'fields' => 'ids', 'posts_per_page' => 1); // When trying to find matches for all day events, the comparison should only be against the date // component only since a) the time is irrelevant and b) the time may have been adjusted to match // the eod cutoff setting if (Tribe__Date_Utils::is_all_day($all_day)) { $meta_query = array(array('key' => '_EventStartDate', 'value' => $this->get_event_start_date($record, true), 'compare' => 'LIKE'), array('key' => '_EventAllDay', 'value' => 'yes')); // For regular, non-all day events, use the full date *and* time in the start date comparison } else { $meta_query = array(array('key' => '_EventStartDate', 'value' => $start_date)); } // Optionally use the end date/time for matching, where available if (!empty($end_date) && !$all_day) { $meta_query[] = array('key' => '_EventEndDate', 'value' => $end_date); } $query_args['meta_query'] = $meta_query; add_filter('posts_search', array($this, 'filter_query_for_title_search'), 10, 2); $matches = get_posts($query_args); remove_filter('posts_search', array($this, 'filter_query_for_title_search'), 10, 2); if (empty($matches)) { return 0; } return reset($matches); }
protected function setup_where_clause() { /** @var wpdb $wpdb */ global $wpdb; $clauses = array(); $values = array_map('intval', $this->currentValue); $values = implode(',', $values); $eod_cutoff = tribe_get_option('multiDayCutoff', '00:00'); if ($eod_cutoff != '00:00') { $eod_time_difference = Tribe__Date_Utils::time_between('1/1/2014 00:00:00', "1/1/2014 {$eod_cutoff}:00"); $start_date = "DATE_SUB({$wpdb->postmeta}.meta_value, INTERVAL {$eod_time_difference} SECOND)"; $end_date = "DATE_SUB(tribe_event_end_date.meta_value, INTERVAL {$eod_time_difference} SECOND)"; } else { $start_date = "{$wpdb->postmeta}.meta_value"; $end_date = 'tribe_event_end_date.meta_value'; } $clauses[] = "(DAYOFWEEK({$start_date}) IN ({$values}))"; // is it on at least 7 days (first day is 0) $clauses[] = "(DATEDIFF({$end_date}, {$start_date}) >=6)"; // determine if the start of the nearest matching day is between the start and end dates $distance_to_day = array(); foreach ($this->currentValue as $day_of_week_index) { $day_of_week_index = (int) $day_of_week_index; $distance_to_day[] = "MOD( 7 + {$day_of_week_index} - DAYOFWEEK({$start_date}), 7 )"; } if (count($distance_to_day) > 1) { $distance_to_next_matching_day = 'LEAST(' . implode(',', $distance_to_day) . ')'; } else { $distance_to_next_matching_day = reset($distance_to_day); } $clauses[] = "(DATE(DATE_ADD({$start_date}, INTERVAL {$distance_to_next_matching_day} DAY)) < {$end_date})"; $this->whereClause = ' AND (' . implode(' OR ', $clauses) . ')'; }
public function render() { $aggregator = Tribe__Events__Aggregator::instance(); $event_id = get_the_ID(); $record = Tribe__Events__Aggregator__Records::instance()->get_by_event_id($event_id); $last_import = null; $source = null; $origin = null; if (is_wp_error($record)) { $last_import = get_post_meta($event_id, Tribe__Events__Aggregator__Event::$updated_key, true); $source = get_post_meta($event_id, Tribe__Events__Aggregator__Event::$source_key, true); $origin = get_post_meta($event_id, Tribe__Events__Aggregator__Event::$origin_key, true); } else { $last_import = $record->post->post_modified; $source_info = $record->get_source_info(); $source = $source_info['title']; $origin = $record->origin; } $origin = $aggregator->api('origins')->get_name($origin); $datepicker_format = Tribe__Date_Utils::datepicker_formats(tribe_get_option('datepickerFormat')); $last_import = $last_import ? tribe_format_date($last_import, true, $datepicker_format . ' h:i a') : null; $settings_link = Tribe__Settings::instance()->get_url(array('tab' => 'imports')); $import_setting = tribe_get_option('tribe_aggregator_default_update_authority', Tribe__Events__Aggregator__Settings::$default_update_authority); include Tribe__Events__Main::instance()->plugin_path . 'src/admin-views/aggregator/meta-box.php'; }
/** * Checks to fix all the required datepicker dates to the correct format * * @param array $recurrence The Recurrence meta rules * @return array Recurrence Meta after maybe fixing the data */ public static function maybe_fix_datepicker_output($recurrence, $post_id) { if (empty($recurrence['exclusions'])) { return $recurrence; } // Fetch the datepicker current format $datepicker_format = Tribe__Date_Utils::datepicker_formats(tribe_get_option('datepickerFormat')); foreach ($recurrence['exclusions'] as &$exclusion) { // Only do something if the exclusion is custom+date if (empty($exclusion['custom']) || 'Date' !== $exclusion['custom']['type']) { continue; } // Actually do the conversion of output $exclusion['custom']['date']['date'] = date($datepicker_format, strtotime($exclusion['custom']['date']['date'])); } return $recurrence; }
/** * Gets a given occurence on a given day-of-week. * * @param int $curdate The current timestamp of an occurence. * @param int $day_of_week The index of a given day-of-week. * @param int $week_of_month The index of a given week-of-month. * * @return int The timestamp of the requested occurrence. */ private function getNthDayOfWeek($curdate, $day_of_week, $week_of_month) { if ($week_of_month == -1) { // LAST WEEK $nextdate = Tribe__Date_Utils::get_last_day_of_week_in_month($curdate, $day_of_week); // If the date returned above is the same as the date we're starting from // move on to the next month by interval to consider. if ($curdate == $nextdate) { $curdate = mktime(0, 0, 0, date('n', $curdate) + $this->months_between, 1, date('Y', $curdate)); $nextdate = Tribe__Date_Utils::get_last_day_of_week_in_month($curdate, $day_of_week); } return $nextdate; } else { // get the first occurrence of the requested day of the week from the requested $curdate's month $first_occurring_day_of_week = Tribe__Date_Utils::get_first_day_of_week_in_month($curdate, $day_of_week); // get that day of the week in the requested nth week $maybe_date = strtotime(date(Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_FORMAT, $first_occurring_day_of_week) . ' + ' . ($week_of_month - 1) . ' weeks'); // if $maybe_date equals or is before the $curdate, then try next month // (this should only be true if $week_of_month is 1) if (date(Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_ONLY_FORMAT, $maybe_date) <= date(Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_ONLY_FORMAT, $curdate)) { // get the first day of the next month according to $this->months_between $next_month = mktime(0, 0, 0, date('n', $curdate) + $this->months_between, 1, date('Y', $curdate)); // Get the first occurrence of the requested day of the week from $next_month's month $first_occurring_day_of_week = Tribe__Date_Utils::get_first_day_of_week_in_month($next_month, $day_of_week); // Get that day of the week in the requested nth week $maybe_date = strtotime(date(Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_FORMAT, $first_occurring_day_of_week) . ' + ' . ($week_of_month - 1) . ' weeks'); } // if $maybe_date doesn't have the same month as $first_occurring_day_of_week, keep incrementing by $this->months_between // until they do, but don't infinitely loop past the 'recurrenceMaxMonthsAfter' setting $i = 0; while (date('n', $maybe_date) != date('n', $first_occurring_day_of_week) && $i <= tribe_get_option('recurrenceMaxMonthsAfter', 24)) { $next_month = mktime(0, 0, 0, date('n', $first_occurring_day_of_week) + $this->months_between, 1, date('Y', $first_occurring_day_of_week)); $first_occurring_day_of_week = Tribe__Date_Utils::get_first_day_of_week_in_month($next_month, $day_of_week); $maybe_date = strtotime(date(Tribe__Events__Pro__Date_Series_Rules__Rules_Interface::DATE_FORMAT, $first_occurring_day_of_week) . ' + ' . ($week_of_month - 1) . ' weeks'); $i += $this->months_between; } return $maybe_date; } }
/** * Returns the GCal export link for a given event id. * * @param int|WP_Post|null $post The Event Post Object or ID, if left empty will give get the current post. * * @return string The URL for the GCal export link. */ public function googleCalendarLink($post = null) { if (is_null($post)) { $post = self::postIdHelper($post); } if (is_numeric($post)) { $post = WP_Post::get_instance($post); } if (!$post instanceof WP_Post) { return false; } // After this point we know that we have a safe WP_Post object // Fetch if the Event is a Full Day Event $is_all_day = Tribe__Date_Utils::is_all_day(get_post_meta($post->ID, '_EventAllDay', true)); // Fetch the required Date TimeStamps $start_date = Tribe__Events__Timezones::event_start_timestamp($post->ID); // Google Requires that a Full Day event end day happens on the next Day $end_date = Tribe__Events__Timezones::event_end_timestamp($post->ID) + ($is_all_day ? DAY_IN_SECONDS : 0); if ($is_all_day) { $dates = date('Ymd', $start_date) . '/' . date('Ymd', $end_date); } else { $dates = date('Ymd', $start_date) . 'T' . date('Hi00', $start_date) . '/' . date('Ymd', $end_date) . 'T' . date('Hi00', $end_date); } // Fetch the $location = trim($this->fullAddressString($post->ID)); $event_details = apply_filters('the_content', get_the_content($post->ID)); // Hack: Add space after paragraph // Normally Google Cal understands the newline character %0a // And that character will automatically replace newlines on urlencode() $event_details = str_replace('</p>', '</p> ', $event_details); $event_details = strip_tags($event_details); //Truncate Event Description and add permalink if greater than 996 characters if (strlen($event_details) > 996) { $event_url = get_permalink($post->ID); $event_details = substr($event_details, 0, 996); //Only add the permalink if it's shorter than 900 characters, so we don't exceed the browser's URL limits if (strlen($event_url) < 900) { $event_details .= sprintf(esc_html__(' (View Full %1$s Description Here: %2$s)', 'the-events-calendar'), $this->singular_event_label, $event_url); } } $params = array('action' => 'TEMPLATE', 'text' => urlencode(strip_tags($post->post_title)), 'dates' => $dates, 'details' => urlencode($event_details), 'location' => urlencode($location), 'trp' => 'false', 'sprop' => 'website:' . home_url()); $timezone = Tribe__Events__Timezones::get_event_timezone_string($post->ID); $timezone = Tribe__Events__Timezones::maybe_get_tz_name($timezone); // If we have a good timezone string we setup it; UTC doesn't work on Google if (false !== $timezone) { $params['ctz'] = urlencode($timezone); } /** * Allow users to Filter our Google Calendar Link params * @var array Params used in the add_query_arg * @var int Event ID */ $params = apply_filters('tribe_google_calendar_parameters', $params, $post->ID); $base_url = 'http://www.google.com/calendar/event'; $url = add_query_arg($params, $base_url); return $url; }
</option> <option value="Yearly" data-plural="<?php esc_attr_e('Year(s) on:', 'tribe-events-calendar-pro'); ?> " data-rule-segment=".custom-recurrence-years"><?php esc_html_e('Yearly', 'tribe-events-calendar-pro'); ?> </option> {{/tribe_recurrence_select}} </select> <span class="recurrence-end"> <?php esc_html_e('will not occur on', 'tribe-events-calendar-pro'); ?> <input autocomplete="off" placeholder="<?php echo esc_attr(Tribe__Date_Utils::date_only(date(Tribe__Date_Utils::DBDATEFORMAT))); ?> " type="text" class="tribe-datepicker custom-date" name="recurrence[exclusions][][custom][date][date]" data-field="custom-date" value="{{custom.date.date}}"/> </span> <span class="recurrence-row custom-recurrence-frequency"> <?php esc_html_e('will not occur every', 'tribe-events-calendar-pro'); ?> <input type="text" name="recurrence[exclusions][][custom][interval]" data-field="custom-interval" value="{{#if custom.interval}}{{custom.interval}}{{else}}1{{/if}}" /> <span class="recurrence-interval-type"></span> <input type="hidden" name="recurrence[exclusions][][custom][type-text]" data-field="custom-type-text" value="{{custom.[type-text]}}" /> <input type="hidden" name="recurrence[exclusions][][occurrence-count-text]" data-field="occurrence-count-text" value="<?php esc_attr_e(_x('events', 'occurence count text', 'tribe-events-calendar-pro')); ?> " /> <span class="rec-error rec-days-error"><?php
/** * Gets the event counts for individual days. * * @param array $args * * @return array The counts array. */ public static function getEventCounts($args = array()) { _deprecated_function(__METHOD__, '3.10.1'); global $wpdb; $date = date('Y-m-d'); $defaults = array('post_type' => Tribe__Events__Main::POSTTYPE, 'start_date' => tribe_beginning_of_day($date), 'end_date' => tribe_end_of_day($date), 'display_type' => 'daily', 'hide_upcoming_ids' => null); $args = wp_parse_args($args, $defaults); $args['posts_per_page'] = -1; $args['fields'] = 'ids'; // 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 = 'daily_counts_and_ids_' . serialize($args); $found = $cache->get($cache_key, 'save_post'); if ($found) { return $found; } $cache_key = 'month_post_ids_' . serialize($args); $found = $cache->get($cache_key, 'save_post'); if ($found && is_array($found)) { $post_ids = $found; } else { $post_id_query = new WP_Query(); $post_ids = $post_id_query->query($args); $cache->set($cache_key, $post_ids, Tribe__Cache::NON_PERSISTENT, 'save_post'); } $counts = array(); $event_ids = array(); if (!empty($post_ids)) { switch ($args['display_type']) { case 'daily': default: global $wp_query; $output_date_format = '%Y-%m-%d %H:%i:%s'; $raw_counts = $wpdb->get_results($wpdb->prepare("\n\t\t\t\t\t\t\tSELECT \ttribe_event_start.post_id as ID,\n\t\t\t\t\t\t\t\t\ttribe_event_start.meta_value as EventStartDate,\n\t\t\t\t\t\t\t\t\tDATE_FORMAT( tribe_event_end_date.meta_value, '%1\$s') as EventEndDate,\n\t\t\t\t\t\t\t\t\t{$wpdb->posts}.menu_order as menu_order\n\t\t\t\t\t\t\tFROM {$wpdb->postmeta} AS tribe_event_start\n\t\t\t\t\t\t\t\t\tLEFT JOIN {$wpdb->posts} ON (tribe_event_start.post_id = {$wpdb->posts}.ID)\n\t\t\t\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\t\t\t\tWHERE tribe_event_start.meta_key = '_EventStartDate'\n\t\t\t\t\t\t\tAND tribe_event_start.post_id IN ( %5\$s )\n\t\t\t\t\t\t\tAND ( (tribe_event_start.meta_value >= '%3\$s' AND tribe_event_start.meta_value <= '%4\$s')\n\t\t\t\t\t\t\t\tOR (tribe_event_start.meta_value <= '%3\$s' AND tribe_event_end_date.meta_value >= '%3\$s')\n\t\t\t\t\t\t\t\tOR ( tribe_event_start.meta_value >= '%3\$s' AND tribe_event_start.meta_value <= '%4\$s')\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tORDER BY menu_order ASC, DATE(tribe_event_start.meta_value) ASC, TIME(tribe_event_start.meta_value) ASC;", $output_date_format, $output_date_format, $post_id_query->query_vars['start_date'], $post_id_query->query_vars['end_date'], implode(',', array_map('intval', $post_ids)))); $start_date = new DateTime($post_id_query->query_vars['start_date']); $end_date = new DateTime($post_id_query->query_vars['end_date']); $days = Tribe__Date_Utils::date_diff($start_date->format('Y-m-d'), $end_date->format('Y-m-d')); $term_id = isset($wp_query->query_vars[Tribe__Events__Main::TAXONOMY]) ? $wp_query->query_vars[Tribe__Events__Main::TAXONOMY] : null; $terms = array(); if (is_int($term_id)) { $terms[0] = $term_id; } elseif (is_string($term_id)) { $term = get_term_by('slug', $term_id, Tribe__Events__Main::TAXONOMY); if ($term) { $terms[0] = $term->term_id; } } if (!empty($terms) && is_tax(Tribe__Events__Main::TAXONOMY)) { $terms = array_merge($terms, get_term_children($terms[0], Tribe__Events__Main::TAXONOMY)); } for ($i = 0, $date = $start_date; $i <= $days; $i++, $date->modify('+1 day')) { $formatted_date = $date->format('Y-m-d'); $count = 0; $_day_event_ids = array(); foreach ($raw_counts as $record) { $event = new stdClass(); $event->EventStartDate = $record->EventStartDate; $event->EventEndDate = $record->EventEndDate; $per_day_limit = apply_filters('tribe_events_month_day_limit', tribe_get_option('monthEventAmount', '3')); if (tribe_event_is_on_date($formatted_date, $event)) { if (!empty($terms) && !has_term($terms, Tribe__Events__Main::TAXONOMY, $record->ID)) { continue; } if (count($_day_event_ids) < $per_day_limit) { $_day_event_ids[] = $record->ID; } $count++; } } $event_ids[$formatted_date] = $_day_event_ids; $counts[$formatted_date] = $count; } break; } // get a unique list of the event IDs that will be displayed, and update all their postmeta and term caches at once $final_event_ids = call_user_func_array('array_merge', $event_ids); $final_event_ids = array_unique($final_event_ids); update_object_term_cache($final_event_ids, Tribe__Events__Main::POSTTYPE); update_postmeta_cache($final_event_ids); } // return IDs per day and total counts per day $return = array('counts' => $counts, 'event_ids' => $event_ids); $cache = new Tribe__Cache(); $cache_key = 'daily_counts_and_ids_' . serialize($args); $cache->set($cache_key, $return, Tribe__Cache::NON_PERSISTENT, 'save_post'); return $return; }
/** * Bump the :30 min EOD cutoff option to the next full hour * */ public function remove_30_min_eod_cutoffs() { $eod_cutoff = tribe_end_of_day(); if (Tribe__Date_Utils::minutes_only($eod_cutoff) == '29') { $eod_cutoff = date_create('@' . (strtotime($eod_cutoff) + 1)); $eod_cutoff->modify('+30 minutes'); tribe_update_option('multiDayCutoff', $eod_cutoff->format('h:i')); } }
protected function set_end_date_time() { $this->vars['endMinuteOptions'] = Tribe__View_Helpers::getMinuteOptions($this->vars['_EventEndDate']); $this->vars['endHourOptions'] = Tribe__View_Helpers::getHourOptions($this->vars['_EventAllDay'] == 'yes' ? null : $this->vars['_EventEndDate']); $this->vars['endMeridianOptions'] = Tribe__View_Helpers::getMeridianOptions($this->vars['_EventEndDate']); $datepicker_format = Tribe__Date_Utils::datepicker_formats(tribe_get_option('datepickerFormat')); if ($this->vars['_EventEndDate']) { $end = Tribe__Date_Utils::date_only($this->vars['_EventEndDate'], false, $datepicker_format); } // If we don't have a valid end date, assume today's date $this->vars['EventEndDate'] = isset($end) && $end ? $end : date($datepicker_format); }
/** * Get the timestamp of the next upcoming Nth day of month. * * @param int $curdate The current occurrence's timestamp * @param int|array $days_of_week Index(-es) of the possible day(s)-of-week the next instance may land on * @param int|array $weeks_of_month Index(-es) of the possible week(s) of the month the next instance may land on * @param int|array $months_of_year Index(-es) of the possible month(s) of the year the next instance may land on * * @return int|false The timestamp of the next occurrence on the nth day of the month or false */ private function getNthDayOfMonth($curdate, $days_of_week, $weeks_of_month, $months_of_year) { // Cast to arrays for consistency $days_of_week = (array) $days_of_week; $weeks_of_month = (array) $weeks_of_month; $months_of_year = (array) $months_of_year; // Obtain the hour, minute and second of $curdate for later comparison $cur_hour = (int) date('G', $curdate); $cur_minute = (int) date('i', $curdate); $cur_second = (int) date('s', $curdate); // Sort and rotate the arrays to give us a sensible starting point $this->sort_and_rotate_int_array($days_of_week, (int) date('N', $curdate)); $this->sort_and_rotate_int_array($months_of_year, (int) date('n', $curdate)); sort($weeks_of_month); $weeks_of_month = array_map('intval', $weeks_of_month); // The next occurence must take place this year or the next applicable year $year = (int) date('Y', $curdate); $years = array($year, $year + $this->years_between); // Examine each possible year and month foreach ($years as $year) { foreach ($months_of_year as $month) { // If we are behind $curdate's month and year then keep advancing if ($year <= date('Y', $curdate) && $month < date('n', $curdate)) { continue; } foreach ($weeks_of_month as $nth_week) { foreach ($days_of_week as $day) { // Determine the date of the first of these days (ie, the date of the first Tuesday this month) $start_of_month = mktime(0, 0, 0, $month, 1, $year); $first_date = Tribe__Date_Utils::get_first_day_of_week_in_month($start_of_month, $day); $day_of_month = (int) date('j', $first_date); // Add the relevant number of weeks $week = $nth_week > 0 ? $nth_week : abs($nth_week); $direction = $nth_week > 0 ? 1 : -1; $day_of_month = date('j', Tribe__Date_Utils::get_weekday_timestamp($day, $week, $month, $year, $direction)); // Form a timestamp representing this day of the week in the appropriate week of the month $timestamp = mktime($cur_hour, $cur_minute, $cur_second, $month, $day_of_month, $year); // If we got a valid timestamp that is ahead of $curdate, we have a winner if ($timestamp && $timestamp > $curdate) { return $timestamp; } } } } } // No match? return false; }
public function setup_list($template_file) { if (basename(dirname($template_file)) . '/' . basename($template_file) == 'mini-calendar/list.php') { if ($this->args['count'] == 0) { return; } // make sure the widget taxonomy filter setting is respected add_action('pre_get_posts', array($this, 'set_count'), 1000); global $wp_query; $post_status = array('publish'); if (is_user_logged_in()) { $post_status[] = 'private'; } // hijack the main query to load the events via provided $args if (!is_null($this->args)) { $query_args = array('posts_per_page' => $this->args['count'], 'tax_query' => $this->args['tax_query'], 'eventDisplay' => 'custom', 'start_date' => $this->get_month(), 'post_status' => $post_status, 'is_tribe_widget' => true); // set end date if initial load, or ajax month switch if (!defined('DOING_AJAX') || defined('DOING_AJAX') && $_POST['action'] == 'tribe-mini-cal') { $query_args['end_date'] = substr_replace($this->get_month(Tribe__Date_Utils::DBDATEFORMAT), Tribe__Date_Utils::get_last_day_of_month(strtotime($this->get_month())), -2); // @todo use tribe_events_end_of_day() ? $query_args['end_date'] = tribe_end_of_day($query_args['end_date']); } $wp_query = Tribe__Events__Query::getEvents($query_args, true); } } }
public function datetime_from_format($format, $date) { return Tribe__Date_Utils::datetime_from_format($format, $date); }
/** * End Date * * Returns the event end date * * @category Events * @param int $event (optional) * @param bool $display_time If true shows date and time, if false only shows date * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php) * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set) * * @return string|null Date */ function tribe_get_end_date($event = null, $display_time = true, $date_format = '', $timezone = null) { if (is_null($event)) { global $post; $event = $post; } if (is_numeric($event)) { $event = get_post($event); } if (!is_object($event)) { return ''; } if (Tribe__Date_Utils::is_all_day(get_post_meta($event->ID, '_EventAllDay', true))) { $display_time = false; } // @todo move timezones to Common if (class_exists('Tribe__Events__Timezones')) { $end_date = Tribe__Events__Timezones::event_end_timestamp($event->ID, $timezone); } return tribe_format_date($end_date, $display_time, $date_format); }
/** * Get a date option. * * Retrieve an option value taking care to escape it to preserve date format slashes. * * @category Events * @param string $optionName Name of the option to retrieve. * @param string $default Value to return if no such option is found. * * @return mixed Value of the option if found */ function tribe_get_date_option($optionName, $default = '') { $value = tribe_get_option($optionName, $default); return Tribe__Date_Utils::unescape_date_format($value); }
/** * given a set of meta data, prepare date data if it exists * * @param $data array Associative array of event meta data * * @return array */ protected static function prepare_event_date_meta($event_id, $data) { $date_provided = false; if (isset($data['EventAllDay'])) { if (Tribe__Date_Utils::is_all_day($data['EventAllDay'])) { $data['EventAllDay'] = 'yes'; } else { $data['EventAllDay'] = 'no'; } } $datepicker_format = Tribe__Date_Utils::datepicker_formats(tribe_get_option('datepickerFormat')); if (isset($data['EventStartDate'])) { $data['EventStartDate'] = Tribe__Date_Utils::datetime_from_format($datepicker_format, $data['EventStartDate']); } if (isset($data['EventEndDate'])) { $data['EventEndDate'] = Tribe__Date_Utils::datetime_from_format($datepicker_format, $data['EventEndDate']); } if (isset($data['EventAllDay']) && 'yes' === $data['EventAllDay']) { $date_provided = true; $data['EventStartDate'] = tribe_beginning_of_day($data['EventStartDate']); $data['EventEndDate'] = tribe_end_of_day($data['EventEndDate']); } elseif (isset($data['EventStartDate']) && isset($data['EventEndDate'])) { $date_provided = true; delete_post_meta($event_id, '_EventAllDay'); $start_date_string = "{$data['EventStartDate']} {$data['EventStartHour']}:{$data['EventStartMinute']}:00"; $end_date_string = "{$data['EventEndDate']} {$data['EventEndHour']}:{$data['EventEndMinute']}:00"; if (isset($data['EventStartMeridian'])) { $start_date_string .= " {$data['EventStartMeridian']}"; } if (isset($data['EventEndMeridian'])) { $end_date_string .= " {$data['EventEndMeridian']}"; } $data['EventStartDate'] = date(Tribe__Date_Utils::DBDATETIMEFORMAT, strtotime($start_date_string)); $data['EventEndDate'] = date(Tribe__Date_Utils::DBDATETIMEFORMAT, strtotime($end_date_string)); } if (!$date_provided) { $data['EventStartDate'] = get_post_meta($event_id, '_EventStartDate', true); $data['EventEndDate'] = get_post_meta($event_id, '_EventEndDate', true); return $data; } // If a specific timezone was not specified, default to the sitewide timezone if (!isset($data['EventTimezone'])) { $data['EventTimezone'] = Tribe__Events__Timezones::wp_timezone_string(); } // Additionally store datetimes in UTC if (empty($data['EventStartDateUTC'])) { $data['EventStartDateUTC'] = Tribe__Events__Timezones::to_utc($data['EventStartDate'], $data['EventTimezone']); } if (empty($data['EventEndDateUTC'])) { $data['EventEndDateUTC'] = Tribe__Events__Timezones::to_utc($data['EventEndDate'], $data['EventTimezone']); } if (empty($data['EventTimezoneAbbr'])) { $data['EventTimezoneAbbr'] = Tribe__Events__Timezones::abbr($data['EventStartDate'], $data['EventTimezone']); } // sanity check that start date < end date $start_timestamp = strtotime($data['EventStartDate']); $end_timestamp = strtotime($data['EventEndDate']); if ($start_timestamp > $end_timestamp) { $data['EventEndDate'] = $data['EventStartDate']; } $data['EventDuration'] = strtotime($data['EventEndDate']) - $start_timestamp; return $data; }
/** * Returns the earliest known event start date, which can be expected to be a string * in MySQL datetime format (unless some other specific format is provided). * * If this is impossible to determine it will return boolean false. * * @category Events * * @param string $format * * @return mixed bool|string */ function tribe_events_earliest_date($format = Tribe__Date_Utils::DBDATETIMEFORMAT) { // Check if the earliest start date is already known $earliest = tribe_get_option('earliest_date', false); if (false !== $earliest) { return Tribe__Date_Utils::reformat($earliest, $format); } // If not, try to determine now Tribe__Events__Main::instance()->rebuild_known_range(); $earliest = tribe_get_option('earliest_date', false); if (false !== $earliest) { return Tribe__Date_Utils::reformat($earliest, $format); } return false; }
/** * Generates the iCal file * * @static * * @param int|null $post If you want the ical file for a single event */ public static function generate_ical_feed($post = null) { $tec = Tribe__Events__Main::instance(); $events = ''; $blogHome = get_bloginfo('url'); $blogName = get_bloginfo('name'); if ($post) { $events_posts = is_array($post) ? $post : array($post); } else { if (tribe_is_month()) { $events_posts = self::get_month_view_events(); } else { global $wp_query; $events_posts = $wp_query->posts; } } $event_ids = wp_list_pluck($events_posts, 'ID'); foreach ($events_posts as $event_post) { // add fields to iCal output $item = array(); $full_format = 'Ymd\\THis'; $time = (object) array('start' => tribe_get_start_date($event_post->ID, false, 'U'), 'end' => tribe_get_end_date($event_post->ID, false, 'U'), 'modified' => Tribe__Date_Utils::wp_strtotime($event_post->post_modified), 'created' => Tribe__Date_Utils::wp_strtotime($event_post->post_date)); if ('yes' == get_post_meta($event_post->ID, '_EventAllDay', true)) { $type = 'DATE'; $format = 'Ymd'; } else { $type = 'DATE-TIME'; $format = $full_format; } $tzoned = (object) array('start' => date($format, $time->start), 'end' => date($format, $time->end), 'modified' => date($format, $time->modified), 'created' => date($format, $time->created)); if ('DATE' === $type) { $item[] = "DTSTART;VALUE={$type}:" . $tzoned->start; $item[] = "DTEND;VALUE={$type}:" . $tzoned->end; } else { // Are we using the sitewide timezone or the local event timezone? $tz = Tribe__Events__Timezones::EVENT_TIMEZONE === Tribe__Events__Timezones::mode() ? Tribe__Events__Timezones::get_event_timezone_string($event_post->ID) : Tribe__Events__Timezones::wp_timezone_string(); $item[] = 'DTSTART;TZID=' . $tz . ':' . $tzoned->start; $item[] = 'DTEND;TZID=' . $tz . ':' . $tzoned->end; } $item[] = 'DTSTAMP:' . date($full_format, time()); $item[] = 'CREATED:' . $tzoned->created; $item[] = 'LAST-MODIFIED:' . $tzoned->modified; $item[] = 'UID:' . $event_post->ID . '-' . $time->start . '-' . $time->end . '@' . parse_url(home_url('/'), PHP_URL_HOST); $item[] = 'SUMMARY:' . str_replace(array(',', "\n", "\r", "\t"), array('\\,', '\\n', '', '\\t'), html_entity_decode(strip_tags($event_post->post_title), ENT_QUOTES)); $item[] = 'DESCRIPTION:' . str_replace(array(',', "\n", "\r", "\t"), array('\\,', '\\n', '', '\\t'), html_entity_decode(strip_tags($event_post->post_content), ENT_QUOTES)); $item[] = 'URL:' . get_permalink($event_post->ID); // add location if available $location = $tec->fullAddressString($event_post->ID); if (!empty($location)) { $str_location = str_replace(array(',', "\n"), array('\\,', '\\n'), html_entity_decode($location, ENT_QUOTES)); $item[] = 'LOCATION:' . $str_location; } // add geo coordinates if available if (class_exists('Tribe__Events__Pro__Geo_Loc')) { $long = Tribe__Events__Pro__Geo_Loc::instance()->get_lng_for_event($event_post->ID); $lat = Tribe__Events__Pro__Geo_Loc::instance()->get_lat_for_event($event_post->ID); if (!empty($long) && !empty($lat)) { $item[] = sprintf('GEO:%s;%s', $lat, $long); $str_title = str_replace(array(',', "\n"), array('\\,', '\\n'), html_entity_decode(tribe_get_address($event_post->ID), ENT_QUOTES)); if (!empty($str_title) && !empty($str_location)) { $item[] = 'X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-ADDRESS=' . str_replace('\\,', '', trim($str_location)) . ';' . 'X-APPLE-RADIUS=500;' . 'X-TITLE=' . trim($str_title) . ':geo:' . $long . ',' . $lat; } } } // add categories if available $event_cats = (array) wp_get_object_terms($event_post->ID, Tribe__Events__Main::TAXONOMY, array('fields' => 'names')); if (!empty($event_cats)) { $item[] = 'CATEGORIES:' . html_entity_decode(join(',', $event_cats), ENT_QUOTES); } // add featured image if available if (has_post_thumbnail($event_post->ID)) { $thumbnail_id = get_post_thumbnail_id($event_post->ID); $thumbnail_url = wp_get_attachment_url($thumbnail_id); $thumbnail_mime_type = get_post_mime_type($thumbnail_id); $item[] = apply_filters('tribe_ical_feed_item_thumbnail', sprintf('ATTACH;FMTTYPE=%s:%s', $thumbnail_mime_type, $thumbnail_url), $event_post->ID); } // add organizer if available $organizer_email = tribe_get_organizer_email($event_post->ID); if ($organizer_email) { $organizer_id = tribe_get_organizer_id($event_post->ID); $organizer = get_post($organizer_id); if ($organizer_id) { $item[] = sprintf('ORGANIZER;CN="%s":MAILTO:%s', rawurlencode($organizer->post_title), $organizer_email); } else { $item[] = sprintf('ORGANIZER:MAILTO:%s', $organizer_email); } } $item = apply_filters('tribe_ical_feed_item', $item, $event_post); $events .= "BEGIN:VEVENT\r\n" . implode("\r\n", $item) . "\r\nEND:VEVENT\r\n"; } $site = sanitize_title(get_bloginfo('name')); $hash = substr(md5(implode($event_ids)), 0, 11); /** * Modifies the filename provided in the Content-Disposition header for iCal feeds. * * @var string $ical_feed_filename * @var WP_Post|null $post */ $filename = apply_filters('tribe_events_ical_feed_filename', $site . '-' . $hash . '.ics', $post); header('Content-type: text/calendar; charset=UTF-8'); header('Content-Disposition: attachment; filename="' . $filename . '"'); $content = "BEGIN:VCALENDAR\r\n"; $content .= "VERSION:2.0\r\n"; $content .= 'PRODID:-//' . $blogName . ' - ECPv' . Tribe__Events__Main::VERSION . "//NONSGML v1.0//EN\r\n"; $content .= "CALSCALE:GREGORIAN\r\n"; $content .= "METHOD:PUBLISH\r\n"; $content .= 'X-WR-CALNAME:' . apply_filters('tribe_ical_feed_calname', $blogName) . "\r\n"; $content .= 'X-ORIGINAL-URL:' . $blogHome . "\r\n"; $content .= 'X-WR-CALDESC:Events for ' . $blogName . "\r\n"; $content = apply_filters('tribe_ical_properties', $content); $content .= $events; $content .= 'END:VCALENDAR'; echo $content; exit; }
/** * Given a date and an event, returns true or false if the event is happening on that date * This function properly adjusts for the EOD cutoff and multi-day events * * @param null $date * @param null $event * * @return mixed|void */ function tribe_event_is_on_date($date = null, $event = null) { if (null === $date) { $date = current_time('mysql'); } if (null === $event) { global $post; $event = $post; if (empty($event)) { _doing_it_wrong(__FUNCTION__, esc_html__('The function needs to be passed an $event or used in the loop.', 'the-events-calendar')); return false; } } $start_of_day = tribe_beginning_of_day($date, 'U'); $end_of_day = tribe_end_of_day($date, 'U'); $event_start = tribe_get_start_date($event, null, 'U'); $event_end = tribe_get_end_date($event, null, 'U'); // kludge if (!empty($event->_end_date_fixed)) { // @todo remove this once we can have all day events without a start / end time $event_end = date_create(date(Tribe__Date_Utils::DBDATETIMEFORMAT, $event_end)); $event_end->modify('+1 day'); $event_end = $event_end->format('U'); } /* note: * events that start exactly on the EOD cutoff will count on the following day * events that end exactly on the EOD cutoff will count on the previous day */ $event_is_on_date = Tribe__Date_Utils::range_coincides($start_of_day, $end_of_day, $event_start, $event_end); return apply_filters('tribe_event_is_on_date', $event_is_on_date, $date, $event); }
/** * Handler for the date column * * @param $item * * @return string */ public function column_date($item) { return Tribe__Date_Utils::reformat($item['completed_at'], Tribe__Date_Utils::DATEONLYFORMAT); }
/** * Generates and returns a set of classes for the current day. * * @return string */ public static function day_classes() { $current_day = self::get_current_day(); $calendar_day = Tribe__Date_Utils::date_only($current_day['date']); $today = date_i18n(Tribe__Date_Utils::DBDATEFORMAT); // Start by determining which month we're looking at if ($current_day['month'] == self::CURRENT_MONTH) { $classes = 'tribe-events-thismonth'; } else { $classes = 'tribe-events-othermonth'; } // Check if the calendar day is in the past, present, or future if ($calendar_day < $today) { $classes .= ' tribe-events-past'; } elseif ($calendar_day === $today) { $classes .= ' tribe-events-present'; } elseif ($calendar_day > $today) { $classes .= ' tribe-events-future'; } // The day has some events if ($current_day['total_events'] > 0) { $classes .= ' tribe-events-has-events'; } // Needed for mobile js $daynum = date('d', strtotime($calendar_day)); $classes .= ' mobile-trigger tribe-event-day-' . $daynum; // Determine which column of the grid the day is in $column = self::$current_day - self::$current_week * 7; if ($column > 0 && ($column % 4 == 0 || $column % 5 == 0 || $column % 6 == 0)) { $classes .= ' tribe-events-right'; } return $classes; }
/** * Accepts two dates and returns the number of days between them * * @category Events * * @param string $start_date * @param string $end_date * @param string|bool $day_cutoff * * @return int * @see Tribe__Date_Utils::date_diff() **/ function tribe_get_days_between($start_date, $end_date, $day_cutoff = '00:00') { if ($day_cutoff === false) { $day_cutoff = '00:00'; } elseif ($day_cutoff === true) { $day_cutoff = tribe_get_option('multiDayCutoff', '00:00'); } $start_date = new DateTime($start_date); if ($start_date < new DateTime($start_date->format('Y-m-d ' . $day_cutoff))) { $start_date->modify('-1 day'); } $end_date = new DateTime($end_date); if ($end_date <= new DateTime($end_date->format('Y-m-d ' . $day_cutoff))) { $end_date->modify('-1 day'); } return Tribe__Date_Utils::date_diff($start_date->format('Y-m-d ' . $day_cutoff), $end_date->format('Y-m-d ' . $day_cutoff)); }