static function handle_calendar_shortcode($atts = array()) { /* Shortcodes don't accept hyphens, so convert taxonomy names */ $taxs = array('category', 'tag', 'venue'); foreach ($taxs as $tax) { if (isset($atts['event_' . $tax])) { $atts['event-' . $tax] = $atts['event_' . $tax]; unset($atts['event_' . $tax]); } } if (isset($atts['show_long'])) { $atts['show-long'] = $atts['show_long']; unset($atts['show_long']); } if (isset($atts['link_to_single'])) { $atts['link-to-single'] = $atts['link_to_single']; unset($atts['link_to_single']); } /* Parse defaults */ $atts = wp_parse_args($atts, array('showpastevents' => 1, 'show-long' => 0, 'link-to-single' => 0)); self::$add_script = true; $id = count(self::$widget_calendars); $cal_id = 'eo_shortcode_calendar_' . $id; self::$widget_calendars[$cal_id] = $atts; $tz = eo_get_blog_timezone(); $date = isset($_GET['eo_month']) ? $_GET['eo_month'] . '-01' : 'now'; $month = new DateTime($date, $tz); $month = date_create($month->format('Y-m-1'), $tz); $html = '<div class="widget_calendar eo-calendar eo-calendar-shortcode eo_widget_calendar" id="' . $cal_id . '">'; $html .= '<div id="' . $cal_id . '_content" class="eo-widget-cal-wrap" data-eo-widget-cal-id="' . $cal_id . '">'; $html .= EO_Calendar_Widget::generate_output($month, $atts); $html .= '</div>'; $html .= '</div>'; return $html; }
public function testEventMetaList() { $event_id = $this->factory->event->create(array('start' => new DateTime('2014-07-09 13:02:00', eo_get_blog_timezone()), 'end' => new DateTime('2014-07-09 14:02:00', eo_get_blog_timezone()), 'all_day' => 0, 'schedule' => 'once')); $tag = wp_insert_term('foobar', 'event-tag'); wp_set_object_terms($event_id, (int) $tag['term_id'], 'event-tag'); $cat = wp_insert_term('hellworld', 'event-category'); wp_set_object_terms($event_id, (int) $cat['term_id'], 'event-category'); $html = eo_get_event_meta_list($event_id); $expected = file_get_contents(EO_DIR_TESTDATA . '/event-functions/event-meta-list.html'); $this->assertXmlStringEqualsXmlString($expected, $html); }
/** * When grouping events by series, the plug-in should use the first date * (chronologicaly) of the series, matching the query */ public function testSeriesQuery() { $events = eo_get_events(array('event_start_after' => '2015-03-01 00:00:00', 'showpastevents' => true, 'group_events_by' => 'series')); $actual = array(); foreach ($events as $event) { $actual[] = eo_get_the_start(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); } $expected = array(new DateTime('2015-03-02 14:00:00', eo_get_blog_timezone()), new DateTime('2015-03-20 19:30:00', eo_get_blog_timezone()), new DateTime('2015-03-23 09:45:00', eo_get_blog_timezone())); $this->assertEquals($expected, $actual); foreach ($this->event_ids as $event_id) { //var_dump( eo_get_the_occurrences( $event_id ) ); } $events = eo_get_events(array('event_start_after' => '2015-03-22 00:00:00', 'showpastevents' => true, 'group_events_by' => 'series')); $actual = array(); foreach ($events as $event) { $actual[] = eo_get_the_start(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); } $expected = array(new DateTime('2015-03-22 19:30:00', eo_get_blog_timezone()), new DateTime('2015-03-23 09:45:00', eo_get_blog_timezone()), new DateTime('2015-03-23 14:00:00', eo_get_blog_timezone())); $this->assertEquals($expected, $actual); }
/** * Callback for the delete expired events cron job. Deletes events that finished at least 24 hours ago. * For recurring events it is only deleted once the last occurrence has expired. * * @since 1.4.0 * @ignore * @access private */ function eventorganiser_delete_expired_events() { //Get expired events $events = eo_get_events(array('showrepeats' => 0, 'showpastevents' => 1, 'eo_interval' => 'expired')); $time_until_expired = (int) apply_filters('eventorganiser_events_expire_time', 24 * 60 * 60); $time_until_expired = max($time_until_expired, 0); if ($events) { $now = new DateTime('now', eo_get_blog_timezone()); foreach ($events as $event) { $start = eo_get_the_start(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); $end = eo_get_the_end(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); $expired = round(abs($end->format('U') - $start->format('U'))) + $time_until_expired; //Duration + expire time $finished = eo_get_schedule_last(DATETIMEOBJ, $event->ID); $finished->modify("+{$expired} seconds"); //[Expired time] after the last occurrence finishes //Delete if [expired time] has passed if ($finished <= $now) { wp_trash_post((int) $event->ID); } } } }
/** * Deals with ordinal month manipulation (e.g. second day of +2 month) for PHP <5.3 * @since 1.2 * @param datetime - 'current' date-time * @string the modify string: second day of +2 month * @return datetime - the date-time calculated. */ function php52_modify($date = '', $modify = '') { $pattern = '/([a-zA-Z]+)\\s([a-zA-Z]+) of \\+(\\d+) month/'; preg_match($pattern, $modify, $matches); $ordinal_arr = array('last' => 0, 'first' => 1, 'second' => 2, 'third' => 3, 'fourth' => 4); $week = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); $ordinal = $ordinal_arr[$matches[1]]; $day = array_search(strtolower($matches[2]), $week); $freq = intval($matches[3]); //set to first day of month $date = date_create($date->format('Y-m-1')); //add months $date->modify('+' . $freq . ' month'); //Calculate offset to day of week //Date of desired day if ($ordinal > 0) { $offset = ($day - intval($date->format('w')) + 7) % 7; $d = $offset + 7 * ($ordinal - 1) + 1; } else { $date = date_create($date->format('Y-m-t')); $offset = intval(($date->format('w') - $day + 7) % 7); $d = intval($date->format('t')) - $offset; } $blog_tz = eo_get_blog_timezone(); $date = date_create($date->format('Y-m-' . $d), $blog_tz); return $date; }
public function testTimezoneChangeRRULE() { //When day changes when start date is converted to UTC timezone (for iCal feed) //Remember to correct [day] the 'reccurs weekly by [day]', so thats true for UTC timezone. wp_cache_set('eventorganiser_timezone', 'America/New_York'); //Event recurrs every Monday evening in New York (event recurs very Tuesday in UTC) $event_id = $this->factory->event->create(array('start' => new DateTime('2013-12-02 21:00', eo_get_blog_timezone()), 'end' => new DateTime('2013-12-02 23:00', eo_get_blog_timezone()), 'schedule_last' => new DateTime('2013-12-30 21:00', eo_get_blog_timezone()), 'frequency' => 1, 'all_day' => 0, 'schedule' => 'weekly', 'schedule_meta' => array('MO'), 'post_title' => 'The Event Title', 'post_content' => 'My event content')); $this->assertEquals("FREQ=WEEKLY;INTERVAL=1;BYDAY=TU;UNTIL=20131231T020000Z", eventorganiser_generate_ics_rrule($event_id)); wp_cache_delete('eventorganiser_timezone'); //Now try it the other direction.... wp_cache_set('eventorganiser_timezone', 'Europe/Moscow'); //Event recurrs every Monday morning in Moscow (event recurs very Sunday in UTC) $event_id = $this->factory->event->create(array('start' => new DateTime('2013-12-02 01:00', eo_get_blog_timezone()), 'end' => new DateTime('2013-12-02 02:00', eo_get_blog_timezone()), 'schedule_last' => new DateTime('2013-12-30 01:00', eo_get_blog_timezone()), 'frequency' => 1, 'all_day' => 0, 'schedule' => 'weekly', 'schedule_meta' => array('MO'), 'post_title' => 'The Event Title', 'post_content' => 'My event content')); $this->assertEquals("FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20131229T210000Z", eventorganiser_generate_ics_rrule($event_id)); wp_cache_delete('eventorganiser_timezone'); }
/** * Parses event queries and alters the WP_Query object appropriately * * Parse's the query, and sets date range and other event specific query variables. * If query is for 'event' post type - the posts_* filters are added. * * Hooked onto pre_get_posts * @since 1.0.0 * @access private * @ignore * * @param WP_Query $query The query */ function eventorganiser_pre_get_posts($query) { //Deprecated, use event-venue instead. if (!empty($query->query_vars['venue'])) { $venue = $query->get('venue'); $query->set('event-venue', $venue); $query->set('post_type', 'event'); } //If the query is for eo-events feed, set post type if ($query->is_feed('eo-events')) { $query->set('post_type', 'event'); } //If querying for all events starting on given date, set the date parameters if (!empty($query->query_vars['ondate'])) { $ondate_start = str_replace('/', '-', $query->query_vars['ondate']); $ondate_end = str_replace('/', '-', $query->query_vars['ondate']); $parts = count(explode('-', $ondate_start)); if ($parts == 1 && is_numeric($ondate_start)) { //Numeric - interpret as year $ondate_start .= '-01-01'; $ondate_end .= '-12-31'; } elseif ($parts == 2) { // 2012-01 format: interpret as month $ondate_start .= '-01'; try { $end = new DateTime($ondate_start); $ondate_end = $end->format('Y-m-t'); } catch (Exception $e) { $query->set('ondate', false); break; } } $query->set('post_type', 'event'); $query->set('event_start_before', $ondate_end); $query->set('event_end_after', $ondate_start); } //If not on event, stop here. if (!eventorganiser_is_event_query($query, true)) { return $query; } $blog_now = new DateTime(null, eo_get_blog_timezone()); //Determine whether or not to show past events and each occurrence. //If not set, use options if (!is_admin() && !is_single() && !$query->is_feed('eo-events') && !isset($query->query_vars['showpastevents'])) { //If showpastevents is not set - use options (except for admin / single pages. $query->set('showpastevents', eventorganiser_get_option('showpast')); } //Deprecated: showrepeats - use group_events_by instead if (isset($query->query_vars['showrepeats']) && !isset($query->query_vars['group_events_by'])) { if (!$query->query_vars['showrepeats']) { $query->set('group_events_by', 'series'); } } //Determine how to group events: by series or show each occurrence if (!isset($query->query_vars['group_events_by'])) { //Group by isn't set - default depends on context: if ($query->is_main_query() && (is_admin() || is_single() || $query->is_feed('eo-events'))) { //If in admin or single page - we probably don't want to see duplicates of (recurrent) events - unless specified otherwise. $query->set('group_events_by', 'series'); } elseif (eventorganiser_get_option('group_events') == 'series') { //In other instances (archives, shortcode listing) if showrepeats option is false display only the next event. $query->set('group_events_by', 'series'); } else { $query->set('group_events_by', 'occurrence'); } } //Parse user input as date-time objects $date_objs = array('event_start_after' => '', 'event_start_before' => '', 'event_end_after' => '', 'event_end_before' => ''); foreach ($date_objs as $prop => $value) { $date = $query->get($prop); try { $date = empty($date) ? false : new DateTime($date, eo_get_blog_timezone()); } catch (Exception $e) { $date = false; } $date_objs[$prop] = $date; $query->set($prop, $date); } //If eo_interval is set, determine date ranges if (!empty($query->query_vars['eo_interval'])) { switch ($query->get('eo_interval')) { case 'expired': $meta_query = (array) $query->get('meta_query'); $meta_query[] = array('key' => '_eventorganiser_schedule_last_finish', 'value' => $blog_now->format('Y-m-d H:i:s'), 'compare' => '<='); $query->set('meta_query', $meta_query); break; case 'future': $meta_query = $query->get('meta_query'); $meta_query = empty($meta_query) ? array() : $meta_query; $meta_query[] = array('key' => '_eventorganiser_schedule_last_start', 'value' => $blog_now->format('Y-m-d H:i:s'), 'compare' => '>='); $query->set('meta_query', $meta_query); break; case 'P1D': case 'P1W': case 'P1M': case 'P6M': case 'P1Y': //I hate you php5.2 $intervals = array('P1D' => '+1 day', 'P1W' => '+1 week', 'P1M' => '+1 month', 'P6M' => '+6 month', 'P1Y' => '+1 Year'); $cutoff = clone $blog_now; $cutoff->modify($intervals[$query->query_vars['eo_interval']]); if (is_admin() && 'series' == $query->get('group_events_by')) { //On admin we want to show the **first** occurrence of a recurring event which has an occurrence in the interval global $wpdb; $post_ids = $wpdb->get_results($wpdb->prepare("SELECT DISTINCT post_id FROM {$wpdb->eo_events}\n\t\t\t\t\t\tWHERE {$wpdb->eo_events}.StartDate <= %s\n\t\t\t\t\t\tAND {$wpdb->eo_events}.EndDate >= %s", $cutoff->format('Y-m-d'), $blog_now->format('Y-m-d'))); if ($post_ids) { $query->set('post__in', wp_list_pluck($post_ids, 'post_id')); } } else { if (empty($date_objs['event_start_before']) || $cutoff < $date_objs['event_start_before']) { $date_objs['event_start_before'] = $cutoff; } if (empty($date_objs['event_end_after']) || $blog_now > $date_objs['event_end_after']) { $date_objs['event_end_after'] = $blog_now; } } } } //Endif interval set $running_event_is_past = eventorganiser_get_option('runningisnotpast') ? true : false; //Set date range according to whether we show past events if (isset($query->query_vars['showpastevents']) && !$query->query_vars['showpastevents']) { //Showing only future events //Running event is past - Get events which start in the future //A current event is not past - Get events which finish in the future $key = $running_event_is_past ? 'event_start_after' : 'event_end_after'; //If current queried date is not set or before now, set the queried date to now $date_objs[$key] = empty($date_objs[$key]) || $blog_now > $date_objs[$key] ? $blog_now : $date_objs[$key]; } //Set event dates to 'Y-m-d H:i:s' format. foreach ($date_objs as $prop => $datetime) { if (!empty($datetime)) { $query->set($prop, $datetime->format('Y-m-d H:i:s')); } } if ($query->is_feed('eo-events')) { //Posts per page for feeds bug http://core.trac.wordpress.org/ticket/17853 add_filter('post_limits', 'wp17853_eventorganiser_workaround'); $query->set('posts_per_page', -1); } //Add the posts_* filters to modify the query add_filter('posts_fields', 'eventorganiser_event_fields', 10, 2); add_filter('posts_join', 'eventorganiser_join_tables', 10, 2); add_filter('posts_where', 'eventorganiser_events_where', 10, 2); add_filter('posts_orderby', 'eventorganiser_sort_events', 10, 2); add_filter('posts_groupby', 'eventorganiser_event_groupby', 10, 2); }
/** * Upgrade routine for 1.5 * *@since 1.5 *@access private *@ignore */ function eventorganiser_150_update() { global $wpdb; $et = $wpdb->eo_events; $events = $wpdb->get_results("SELECT*, min({$et}.StartDate) as StartDate, min({$et}.EndDate) as EndDate FROM {$wpdb->eo_events} GROUP BY {$et}.post_id ORDER BY {$et}.StartDate"); if ($events) { foreach ($events as $event) { $post_id = (int) $event->post_id; $event_data = array('schedule' => $event->event_schedule, 'all_day' => $event->event_allday, 'schedule_meta' => 'weekly' == $event->event_schedule ? maybe_unserialize($event->event_schedule_meta) : $event->event_schedule_meta, 'frequency' => $event->event_frequency, 'exclude' => array(), 'include' => array()); $start = new DateTime($event->StartDate . ' ' . $event->StartTime, eo_get_blog_timezone()); $end = new DateTime($event->EndDate . ' ' . $event->FinishTime, eo_get_blog_timezone()); $schedule_last = new DateTime($event->reoccurrence_end . ' ' . $event->StartTime, eo_get_blog_timezone()); $seconds = round(abs($start->format('U') - $end->format('U'))); $days = floor($seconds / 86400); // 86400 = 60*60*24 seconds in a normal day $sec_diff = $seconds - $days * 86400; $duration_str = '+' . $days . 'days ' . $sec_diff . ' seconds'; $event_data['duration_str'] = $duration_str; $schedule_last_end = clone $schedule_last; $schedule_last_end->modify($duration_str); update_post_meta($post_id, '_eventorganiser_event_schedule', $event_data); update_post_meta($post_id, '_eventorganiser_schedule_start_start', $start->format('Y-m-d H:i:s')); //Schedule start update_post_meta($post_id, '_eventorganiser_schedule_start_finish', $end->format('Y-m-d H:i:s')); //Schedule start update_post_meta($post_id, '_eventorganiser_schedule_last_start', $schedule_last->format('Y-m-d H:i:s')); //Schedule last update_post_meta($post_id, '_eventorganiser_schedule_last_finish', $schedule_last_end->format('Y-m-d H:i:s')); //Schedule last } } }
function display() { //Get the time 'now' according to blog's timezone $now = new DateTime(null, eo_get_blog_timezone()); $venues = eo_get_venues(); ?> <div class="wrap"> <?php screen_icon('edit'); ?> <h2><?php _e('Events Calendar', 'eventorganiser'); ?> </h2> <?php $current = !empty($_COOKIE['eo_admin_cal_last_view']) ? $_COOKIE['eo_admin_cal_last_view'] : 'month'; $views = array('agendaDay' => __('Day', 'eventorganiser'), 'agendaWeek' => __('Week', 'eventorganiser'), 'month' => __('Month', 'eventorganiser')); ?> <div id="calendar-view"> <span id='loading' style='display:none'><?php _e('Loading…', 'eventorganiser'); ?> </span> <?php foreach ($views as $id => $label) { printf('<a href="#" class="nav-tab view-button %s" id="%s">%s</a>', $id == $current ? 'nav-tab-active' : '', $id, $label); } ?> </div> <div id='eo_admin_calendar'></div> <span><?php _e('Current date/time', 'eventorganiser'); ?> : <?php echo $now->format('Y-m-d G:i:s \\G\\M\\TP'); ?> </span> <?php eventorganiser_event_detail_dialog(); ?> <?php if (current_user_can('publish_events') || current_user_can('edit_events')) { ?> <div id='eo_event_create_cal' style="display:none;" class="eo-dialog" title="<?php esc_attr_e('Create an event', 'eventorganiser'); ?> "> <form name="eventorganiser_calendar" method="post" class="eo_cal"> <table class="form-table"> <tr> <th><?php _e('When', 'eventorganiser'); ?> : </th> <td id="date"></td> </tr> <tr> <th><?php _e('Event Title', 'eventorganiser'); ?> : </th> <td><input name="eo_event[event_title]" class="eo-event-title ui-autocomplete-input ui-widget-content ui-corner-all" ></td> </tr> <?php if (taxonomy_exists('event-venue')) { ?> <tr> <th><?php _e('Where', 'eventorganiser'); ?> : </th> <td><!-- If javascript is disabed, a simple drop down menu box is displayed to choose venue. Otherwise, the user is able to search the venues by typing in the input box.--> <select size="30" id="venue_select" name="eo_event[venue_id]"> <option>Select a venue </option> <?php foreach ($venues as $venue) { ?> <option value="<?php echo intval($venue->term_id); ?> "><?php echo esc_html($venue->name); ?> </option> <?php } ?> </select> </td> </tr> <?php } ?> <tr> <th></th> <td><textarea rows="4" name="eo_event[event_content]" style="width: 220px;"></textarea></td> </tr> </table> <p class="submit"> <input type="hidden" name="eo_event[StartDate]"> <input type="hidden" name="eo_event[EndDate]"> <input type="hidden" name="eo_event[StartTime]"> <input type="hidden" name="eo_event[FinishTime]"> <input type="hidden" name="eo_event[allday]"> <?php wp_nonce_field('eventorganiser_calendar_save'); ?> <?php if (current_user_can('publish_events')) { ?> <input type="submit" class="button" tabindex="4" value="<?php _e('Save Draft', 'eventorganiser'); ?> " id="event-draft" name="save"> <input type="reset" class="button" id="reset" value="<?php _e('Cancel', 'eventorganiser'); ?> "> <span id="publishing-action"> <input type="submit" accesskey="p" tabindex="5" value="<?php _e('Publish Event', 'eventorganiser'); ?> " class="button-primary" id="publish" name="publish"> </span> <?php } elseif (current_user_can('edit_events')) { ?> <input type="reset" class="button" id="reset" value="<?php _e('Cancel', 'eventorganiser'); ?> "> <span id="publishing-action"> <input type="submit" accesskey="p" tabindex="5" value="<?php _e('Submit for Review', 'eventorganiser'); ?> " class="eo_alignright button-primary" id="submit-for-review" name="publish"> </span> <?php } ?> <br class="clear"> </form> </div> <?php } ?> </div><!-- .wrap --> <?php }
/** * Currently the following case is not allowed: * - Changing the start date to a date where an occurrence already exists */ public function testMoveOccurrenceNotAllowed() { $event = array('start' => new DateTime('2014-08-11 18:48:00', eo_get_blog_timezone()), 'end' => new DateTime('2014-08-11 19:48:00', eo_get_blog_timezone()), 'schedule' => 'weekly', 'until' => new DateTime('2014-09-01 18:48:00', eo_get_blog_timezone())); $event_id = $this->factory->event->create($event); $occurrences = eo_get_the_occurrences_of($event_id); $occurrence_ids = array_keys($occurrences); $occurrence_id = $occurrence_ids[2]; //Check the start/end datetimes are as expected $this->assertEquals(array('start' => new DateTime('2014-08-25 18:48:00', eo_get_blog_timezone()), 'end' => new DateTime('2014-08-25 19:48:00', eo_get_blog_timezone())), $occurrences[$occurrence_id]); //Try to move to an 'occupied date' (even with different time) $new_start = new DateTime('2014-08-18 15:48:00', eo_get_blog_timezone()); $new_end = new DateTime('2014-08-18 16:48:00', eo_get_blog_timezone()); $response = eventorganiser_move_occurrence($event_id, $occurrence_id, $new_start, $new_end); $this->assertInstanceOf('WP_Error', $response); $this->assertEquals('events-cannot-share-date', $response->get_error_code()); }
/** * @ignore */ function eo_has_event_finished($id = '', $occurrence = 0) { $tz = eo_get_blog_timezone(); $end = new DateTime(eo_get_the_end('d-m-Y H:i', $id, $occurrence), $tz); $now = new DateTime('now', $tz); return $end <= $now; }
/** * This is a private function - handles the generation of occurrence dates from the schedule data * @access private * @ignore * * @param array $event_data - Array containing the event's schedule data * @return array $event_data - Array containing the event's schedule data including 'occurrences', an array of DateTimes */ function _eventorganiser_generate_occurrences($event_data = array()) { $event_defaults = array('start' => '', 'end' => '', 'all_day' => 0, 'schedule' => 'once', 'schedule_meta' => '', 'frequency' => 1, 'schedule_last' => '', 'number_occurrences' => 0, 'exclude' => array(), 'include' => array()); extract(wp_parse_args($event_data, $event_defaults)); $occurrences = array(); //occurrences array $exclude = array_filter((array) $exclude); $include = array_filter((array) $include); $exclude = array_udiff($exclude, $include, '_eventorganiser_compare_datetime'); $include = array_udiff($include, $exclude, '_eventorganiser_compare_datetime'); //White list schedule if (!in_array($schedule, array('once', 'daily', 'weekly', 'monthly', 'yearly', 'custom'))) { return new WP_Error('eo_error', __('Schedule not recognised.', 'eventorganiser')); } //Ensure event frequency is a positive integer. Else set to 1. $frequency = max(absint($frequency), 1); $all_day = (int) $all_day; $number_occurrences = absint($number_occurrences); //Check dates are supplied and are valid if (!$start instanceof DateTime) { return new WP_Error('eo_error', __('Start date not provided.', 'eventorganiser')); } if (!$end instanceof DateTime) { $end = clone $start; } //If use 'number_occurrences' to limit recurring event, set dummy 'schedule_last' date. if (!$schedule_last instanceof DateTime && $number_occurrences && in_array($schedule, array('daily', 'weekly', 'monthly', 'yearly'))) { //Set dummy "last occurrance" date. $schedule_last = clone $start; } else { $number_occurrences = 0; } if ('once' == $schedule || !$schedule_last instanceof DateTime) { $schedule_last = clone $start; } //Check dates are in chronological order if ($end < $start) { return new WP_Error('eo_error', __('Start date occurs after end date.', 'eventorganiser')); } if ($schedule_last < $start) { return new WP_Error('eo_error', __('Schedule end date is before is before the start date.', 'eventorganiser')); } //Now set timezones $timezone = eo_get_blog_timezone(); $start->setTimezone($timezone); $end->setTimezone($timezone); $schedule_last->setTimezone($timezone); $H = intval($start->format('H')); $i = intval($start->format('i')); $start_days = array(); $workaround = ''; $icaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'); $weekdays = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); $ical2day = array('SU' => 'Sunday', 'MO' => 'Monday', 'TU' => 'Tuesday', 'WE' => 'Wednesday', 'TH' => 'Thursday', 'FR' => 'Friday', 'SA' => 'Saturday'); //Set up schedule switch ($schedule) { case 'once': case 'custom': $frequency = 1; $schedule_meta = ''; $schedule_start = clone $start; $schedule_last = clone $start; $start_days[] = clone $start; $workaround = 'once'; //Not strictly a workaround. break; case 'daily': $interval = "+" . $frequency . "day"; $start_days[] = clone $start; break; case 'weekly': $schedule_meta = $schedule_meta ? array_filter($schedule_meta) : array(); if (!empty($schedule_meta) && is_array($schedule_meta)) { foreach ($schedule_meta as $day) { $start_day = clone $start; $start_day->modify($ical2day[$day]); $start_days[] = $start_day; } } else { $schedule_meta = array($icaldays[$start->format('w')]); $start_days[] = clone $start; } $interval = "+" . $frequency . "week"; break; case 'monthly': $start_days[] = clone $start; $rule_value = explode('=', $schedule_meta, 2); $rule = $rule_value[0]; $values = !empty($rule_value[1]) ? explode(',', $rule_value[1]) : array(); //Should only be one value, but may support more in future $values = array_filter($values); if ($rule == 'BYMONTHDAY') { $date = (int) $start_days[0]->format('d'); $interval = "+" . $frequency . "month"; if ($date >= 29) { $workaround = 'short months'; } //This case deals with 29/30/31 of month $schedule_meta = 'BYMONTHDAY=' . $date; } else { if (empty($values)) { $date = (int) $start_days[0]->format('d'); $n = ceil($date / 7); // nth weekday of month. $day_num = intval($start_days[0]->format('w')); //0 (Sun) - 6(Sat) } else { //expect e.g. array( 2MO ) preg_match('/^(-?\\d{1,2})([a-zA-Z]{2})/', $values[0], $matches); $n = (int) $matches[1]; $day_num = array_search($matches[2], $icaldays); //(Sun) - 6(Sat) } if ($n == 5) { $n = -1; } //If 5th, interpret it as last. $ordinal = array('1' => "first", '2' => "second", '3' => "third", '4' => "fourth", '-1' => "last"); if (!isset($ordinal[$n])) { return new WP_Error('eo_error', __('Invalid monthly schedule (invalid ordinal)', 'eventorganiser')); } $ical_day = $icaldays[$day_num]; //ical day from day_num (SU - SA) $day = $weekdays[$day_num]; //Full day name from day_num (Sunday -Monday) $schedule_meta = 'BYDAY=' . $n . $ical_day; //E.g. BYDAY=2MO $interval = $ordinal[$n] . ' ' . $day . ' of +' . $frequency . ' month'; //E.g. second monday of +1 month //Work around for PHP <5.3 if (!function_exists('date_diff')) { $workaround = 'php5.2'; } } break; case 'yearly': $start_days[] = clone $start; if ('29-02' == $start_days[0]->format('d-m')) { $workaround = 'leap year'; } $interval = "+" . $frequency . "year"; break; } //End $schedule switch //Now we have setup and validated the schedules - loop through and generate occurrences foreach ($start_days as $index => $start_day) { $current = clone $start_day; $occurrence_n = 0; switch ($workaround) { //Not really a workaround. Just add the occurrence and finish. case 'once': $current->setTime($H, $i); $occurrences[] = clone $current; break; //Loops for monthly events that require php5.3 functionality //Loops for monthly events that require php5.3 functionality case 'php5.2': while ($current <= $schedule_last || $occurrence_n < $number_occurrences) { $current->setTime($H, $i); $occurrences[] = clone $current; $current = _eventorganiser_php52_modify($current, $interval); $occurrence_n++; } break; //Loops for monthly events on the 29th/30th/31st //Loops for monthly events on the 29th/30th/31st case 'short months': $day_int = intval($start_day->format('d')); //Set the first month $current_month = clone $start_day; $current_month = date_create($current_month->format('Y-m-1')); while ($current_month <= $schedule_last || $occurrence_n < $number_occurrences) { $month_int = intval($current_month->format('m')); $year_int = intval($current_month->format('Y')); if (checkdate($month_int, $day_int, $year_int)) { $current = new DateTime($day_int . '-' . $month_int . '-' . $year_int, $timezone); $current->setTime($H, $i); $occurrences[] = clone $current; $occurrence_n++; } $current_month->modify($interval); } break; //To be used for yearly events occuring on Feb 29 //To be used for yearly events occuring on Feb 29 case 'leap year': $current_year = clone $current; $current_year->modify('-1 day'); while ($current_year <= $schedule_last || $occurrence_n < $number_occurrences) { $is_leap_year = (int) $current_year->format('L'); if ($is_leap_year) { $current = clone $current_year; $current->modify('+1 day'); $current->setTime($H, $i); $occurrences[] = clone $current; $occurrence_n++; } $current_year->modify($interval); } break; default: while ($current <= $schedule_last || $occurrence_n < $number_occurrences) { $current->setTime($H, $i); $occurrences[] = clone $current; $current->modify($interval); $occurrence_n++; } break; } //End 'workaround' switch; } //Now schedule meta is set up and occurrences are generated. if ($number_occurrences > 0) { //If recurrence is limited by #occurrences. Do that here. sort($occurrences); $occurrences = array_slice($occurrences, 0, $number_occurrences); } //Add inclusions, removes exceptions and duplicates if (defined('WP_DEBUG') && WP_DEBUG) { //Make sure 'included' dates doesn't appear in generate date $include = array_udiff($include, $occurrences, '_eventorganiser_compare_datetime'); } $occurrences = array_merge($occurrences, $include); $occurrences = array_udiff($occurrences, $exclude, '_eventorganiser_compare_datetime'); $occurrences = _eventorganiser_remove_duplicates($occurrences); //Sort occurrences sort($occurrences); if (empty($occurrences) || !$occurrences[0] || !$occurrences[0] instanceof DateTime) { return new WP_Error('eo_error', __('Event does not contain any dates.', 'eventorganiser')); } $schedule_start = clone $occurrences[0]; $schedule_last = clone end($occurrences); $_event_data = array('start' => $start, 'end' => $end, 'all_day' => $all_day, 'schedule' => $schedule, 'schedule_meta' => $schedule_meta, 'frequency' => $frequency, 'schedule_start' => $schedule_start, 'schedule_last' => $schedule_last, 'exclude' => $exclude, 'include' => $include, 'occurrences' => $occurrences); /** * Filters the event schedule after its dates has been generated by a given schedule. * * The filtered array is an array of occurrences generated from a * schedule which may include: * * * **start** (DateTime) - when the event starts * * **end** (DateTime) - when the event ends * * **all_day** (Bool) - If the event is all day or no * * **all_day** (Bool) - If the event is all day or not * * **schedule** (String) - One of once|weekl|daily|monthly|yearly|custom * * **schedule_meta** (Array|String) - See documentation for `eo_insert_event()` * * **frequency** (int) - The frequency of which the event repeats * * **schedule_last** (DateTime) - date of last occurrence of event * * **number_occurrences** (int) - number of times the event should repeat (if `schedule_last` is not specified). * * **exclude** (array) - Array of DateTime objects to exclude from the schedule * * **include** (array) - Array of DateTime objects to include in the schedule * * **occurrences** (array) - Array of DateTime objects generated from the above schedule. * * @param array The event schedule with generated occurrences. * @param array The original event schedule (without occurrences). */ $_event_data = apply_filters('eventorganiser_generate_occurrences', $_event_data, $event_data); return $_event_data; }
/** * Update and EO event, given a CiviEvent. If no EO event exists * then create one. This will NOT create sequences and is intended for the * initial migration of CiviEvents to WordPress * * @since 0.1 * * @param array $civi_event An array of data for the CiviEvent * @return int $event_id The numeric ID of the event */ public function update_event($civi_event) { /* error_log( print_r( array( 'method' => __METHOD__, 'civi_event' => $civi_event, ), true ) ); */ // define schedule $event_data = array('start' => new DateTime($civi_event['start_date'], eo_get_blog_timezone()), 'end' => new DateTime($civi_event['end_date'], eo_get_blog_timezone()), 'schedule_last' => new DateTime($civi_event['end_date'], eo_get_blog_timezone()), 'frequency' => 1, 'all_day' => 0, 'schedule' => 'once'); // define post $post_data = array('post_title' => $civi_event['title'], 'post_content' => isset($civi_event['description']) ? $civi_event['description'] : '', 'post_excerpt' => isset($civi_event['summary']) ? $civi_event['summary'] : '', 'to_ping' => '', 'pinged' => '', 'post_content_filtered' => ''); // test for created date, which may be absent if (isset($civi_event['created_date']) and !empty($civi_event['created_date'])) { // create DateTime object $datetime = new DateTime($civi_event['created_date'], eo_get_blog_timezone()); // add it, but format it first since Civi seems to send data in the form 20150916135435 $post_data['post_date'] = $datetime->format('Y-m-d H:i:s'); } // assume the CiviEvent is live $post_data['post_status'] = 'publish'; // is the event active? if ($civi_event['is_active'] == 0) { // make the CiviEvent unpublished $post_data['post_status'] = 'draft'; } // init venue as undefined $venue_id = 0; // get location ID if (isset($civi_event['loc_block_id'])) { // we have a location... // get location data $location = $this->plugin->civi->get_location_by_id($civi_event['loc_block_id']); // get corresponding EO venue ID $venue_id = $this->plugin->eo_venue->get_venue_id($location); // did we get one? if ($venue_id === false) { // no, let's create one $venue_id = $this->plugin->eo_venue->create_venue($location); } else { // yes, update it $venue_id = $this->plugin->eo_venue->update_venue($location); } } // init category as undefined $terms = array(); // get location ID if (isset($civi_event['event_type_id'])) { // we have a category... //print_r( $this->plugin->civi->get_event_types() ); die(); // get event type data for this pseudo-ID (actually "value") $type = $this->plugin->civi->get_event_type_by_value($civi_event['event_type_id']); // does this type have an existing term? $term_id = $this->get_term_id($type); // if not... if ($term_id === false) { // create one $term = $this->create_term($type); // assign term ID $term_id = $term['term_id']; } // define as array $terms = array(absint($term_id)); } // add to post data $post_data['tax_input'] = array('event-venue' => array(absint($venue_id)), 'event-category' => $terms); /* error_log( print_r( array( 'method' => __METHOD__, 'post_data' => $post_data, 'type' => isset( $type ) ? $type : 'NOT SET', ) ); die(); */ // do we have a post ID for this event? $eo_post_id = $this->plugin->db->get_eo_event_id_by_civi_event_id($civi_event['id']); // remove hooks remove_action('wp_insert_post', array($this, 'insert_post'), 10); remove_action('eventorganiser_save_event', array($this, 'intercept_save_event'), 10); // did we get a post ID? if ($eo_post_id === false) { // use EO's API to create event $event_id = eo_insert_event($post_data, $event_data); } else { // use EO's API to update event $event_id = eo_update_event($eo_post_id, $post_data, $event_data); } // re-add hooks add_action('wp_insert_post', array($this, 'insert_post'), 10, 2); add_action('eventorganiser_save_event', array($this, 'intercept_save_event'), 10, 1); // --< return $event_id; }
function eventorganiser_delete_expired_events() { //Get expired events $events = eo_get_events(array('showrepeats' => 0, 'showpastevents' => 1, 'eo_interval' => 'expired')); if ($events) { foreach ($events as $event) { $now = new DateTime('now', eo_get_blog_timezone()); $start = new DateTime($event->StartDate . ' ' . $event->StartTime, eo_get_blog_timezone()); $end = new DateTime($event->EndDate . ' ' . $event->FinishTime, eo_get_blog_timezone()); $duration = date_diff($start, $end); $finished = new DateTime($event->reoccurrence_end . ' ' . $event->StartTime, eo_get_blog_timezone()); $finished->add($duration); $finished->modify('+1 day'); //Delete if 24 hours has passed if ($finished <= $now) { wp_trash_post((int) $event->ID); } } } }
public function testPrePropertyParseAction() { add_filter('eventorganiser_pre_ical_property_dtstart', array($this, '_modifyDtstart'), 10, 5); $ical = new EO_ICAL_Parser(); $ical->parse(EO_DIR_TESTDATA . '/ical/eventWithInvalidDateTime.ics'); remove_filter('eventorganiser_pre_ical_property_dtstart', array($this, '_modifyDtstart')); $exp_start = new DateTime('2015-02-01', eo_get_blog_timezone()); $event = $ical->events[0]; $this->assertEquals($exp_start, $event['start']); }
function handle_eventlist_shortcode($atts = array(), $content = null) { global $post; $tmp_post = $post; $taxs = array('category', 'tag', 'venue'); foreach ($taxs as $tax) { if (isset($atts['event_' . $tax])) { $atts['event-' . $tax] = $atts['event_' . $tax]; unset($atts['event_' . $tax]); } } if (isset($atts['venue']) && $atts['venue'] == '%this%' || isset($atts['event-venue']) && $atts['event-venue'] == '%this%') { if (!empty($post->Venue)) { $atts['event-venue'] = eo_get_venue_slug(); } else { unset($atts['venue']); unset($atts['event-venue']); } } $events = eo_get_events($atts); $tz = eo_get_blog_timezone(); if ($events) { $return = '<ul class="eo-events eo-events-shortcode">'; foreach ($events as $post) { setup_postdata($post); //Check if all day, set format accordingly if (eo_is_all_day()) { $format = get_option('date_format'); } else { $format = get_option('date_format') . ' ' . get_option('time_format'); } $dateTime = new DateTime($post->StartDate . ' ' . $post->StartTime, $tz); if (empty($content)) { $return .= '<li><a title="' . the_title_attribute(array('echo' => false)) . '" href="' . get_permalink() . '">' . get_the_title() . '</a> ' . __('on', 'eventorganiser') . ' ' . eo_format_date($post->StartDate . ' ' . $post->StartTime, $format) . '</li>'; } else { $return .= '<li>' . self::read_template($content) . '</li>'; } } $return .= '</ul>'; $post = $tmp_post; wp_reset_postdata(); return $return; } }
function eventorganiser_widget_agenda() { global $wpdb, $wp_locale; $meridiem = $wp_locale->meridiem; $direction = intval($_GET['direction']); $today = new DateTIme('now', eo_get_blog_timezone()); $before_or_after = $direction < 1 ? 'before' : 'after'; $date = $direction < 1 ? $_GET['start'] : $_GET['end']; $order = $direction < 1 ? 'DESC' : 'ASC'; $selectDates = "SELECT DISTINCT StartDate FROM {$wpdb->eo_events}"; if ($order == 'ASC') { $whereDates = " WHERE {$wpdb->eo_events}.StartDate >= %s "; } else { $whereDates = " WHERE {$wpdb->eo_events}.StartDate <= %s "; } $whereDates .= " AND {$wpdb->eo_events}.StartDate >= %s "; $orderlimit = "ORDER BY {$wpdb->eo_events}.StartDate {$order} LIMIT 4"; $dates = $wpdb->get_col($wpdb->prepare($selectDates . $whereDates . $orderlimit, $date, $today->format('Y-m-d'))); if (!$dates) { return false; } $date1 = min($dates[0], $dates[count($dates) - 1]); $date2 = max($dates[0], $dates[count($dates) - 1]); $events = eo_get_events(array('event_start_after' => $date1, 'event_start_before' => $date2)); $return_array = array(); global $post; foreach ($events as $post) { $startDT = new DateTime($post->StartDate . ' ' . $post->StartTime); if (!eo_is_all_day()) { $ampm = trim($meridiem[$startDT->format('a')]); $ampm = empty($ampm) ? $startDT->format('a') : $ampm; //Tranlsate am/pm $time = $startDT->format('g:i') . $ampm; } else { $time = __('All Day', 'eventorganiser'); } $color = ''; $terms = get_the_terms($post->ID, 'event-category'); if ($terms) { $term = array_shift(array_values($terms)); $color = isset($term->color) ? $term->color : ''; } //'StartDate'=>eo_format_date($post->StartDate,'l jS F'), $return_array[] = array('StartDate' => $post->StartDate, 'time' => $time, 'post_title' => substr($post->post_title, 0, 25), 'event_allday' => $post->event_allday, 'color' => $color, 'link' => get_permalink(), 'Glink' => eo_get_the_GoogleLink()); } echo json_encode($return_array); exit; }
/** * Parses through an array of lines (of an ICAL file), creates events and inserts them as they are found. * @since 1.1.0 * * @param array - $lines, array of lines of an ICAL file */ function import_events($lines) { global $EO_Errors; $state = "NONE"; $error = false; $error_count = 0; $event_count = 0; $event_array = array(); $event_array['event'] = array(); $event_array['event_post'] = array(); $event_array['event_meta'] = array(); //Get Blog timezone, set Calendar timezone to this by default $blog_tz = eo_get_blog_timezone(); $cal_tz = $blog_tz; $output = ""; //Record number of venues / categories created global $eventorganiser_venues_created, $eventorganiser_cats_created; $eventorganiser_venues_created = 0; $eventorganiser_cats_created = 0; //Read through each line for ($n = 0; $n < count($lines) && !$error; $n++) { $buff = trim($lines[$n]); if (!empty($buff)) { $line = explode(':', $buff, 2); //On the right side of the line we may have DTSTART;TZID= or DTSTART;VALUE= $modifiers = explode(';', $line[0]); $property = array_shift($modifiers); $value = isset($line[1]) ? trim($line[1]) : ''; //If we are in EVENT state if ($state == "VEVENT") { //If END:VEVENT, insert event into database if ($property == 'END' && $value == 'VEVENT') { $state = "VCALENDAR"; $event_array['event']['YmdFormated'] = true; $event_array['event']['dateObjects'] = true; //Insert new post from objects $post_id = EO_Event::insertNewEvent($event_array['event_post'], $event_array['event']); if (!$post_id) { $error_count++; } } else { //Otherwise, parse event property try { $event_array = $this->parse_Event_Property($event_array, $property, $value, $modifiers, $blog_tz, $cal_tz); } catch (Exception $e) { $error_count++; $preamble = sprintf(__('Line: %1$d', 'eventorganiser'), $n + 1); $EO_Errors->add('eo_error', $preamble . ' ' . $e->getMessage()); //Abort parsing event $state = "VCALENDAR"; } } // If we are in CALENDAR state } elseif ($state == "VCALENDAR") { //Begin event if ($property == 'BEGIN' && $value == 'VEVENT') { $state = "VEVENT"; $event_count++; $event_array['event'] = array(); $event_array['event_post'] = array(); $event_array['event_meta'] = array(); } elseif ($property == 'END' && $value == 'VCALENDAR') { $state = "NONE"; } elseif ($property == 'X-WR-TIMEZONE') { try { $cal_tz = self::parse_TZID($value); } catch (Exception $e) { $preamble = sprintf(__('Line: %1$d', 'eventorganiser'), $n + 1); $EO_Errors->add('eo_error', $preamble . ' ' . $e->getMessage()); break; } } } elseif ($state == "NONE" && $property == 'BEGIN' && $value == 'VCALENDAR') { $state = "VCALENDAR"; } } //If line is not empty } //For each line //Display message if ($event_count == 0) { $EO_Errors->add('eo_error', __("No events were imported.", 'eventorganiser')); } elseif ($error_count > 0) { $EO_Errors->add('eo_error', sprintf(__('There was an error with %1$d of %2$d events in the ical file'), $error_count, $event_count)); } else { if ($event_count == 1) { $message = __("1 event was successfully imported", 'eventorganiser') . "."; } else { $message = sprintf(__("%d events were successfully imported", 'eventorganiser'), $event_count) . "."; } if ($eventorganiser_venues_created == 1) { $message .= " " . __("1 venue was created", 'eventorganiser') . "."; } elseif ($eventorganiser_venues_created > 1) { $message .= " " . sprintf(__("%d venues were created", 'eventorganiser'), $eventorganiser_venues_created) . "."; } if ($eventorganiser_cats_created == 1) { $message .= " " . __("1 category was created", 'eventorganiser') . "."; } elseif ($eventorganiser_cats_created > 1) { $message .= " " . sprintf(__("%d categories were created", 'eventorganiser'), $eventorganiser_cats_created) . "."; } $EO_Errors->add('eo_notice', $message); } return true; }
/** * Ajax response for the agenda widget * * This gets the month being viewed and generates the * *@since 1.0 *@access private *@ignore */ function eventorganiser_widget_agenda() { global $wpdb; $number = (int) $_GET['instance_number']; $wid = new EO_Events_Agenda_Widget(); $settings = $wid->get_settings(); $instance = $settings[$number]; $today = new DateTime('now', eo_get_blog_timezone()); $query = array(); $return_array = array(); $query['mode'] = !empty($instance['mode']) ? $instance['mode'] : 'day'; $query['direction'] = intval($_GET['direction']); $query['date'] = $query['direction'] < 1 ? $_GET['start'] : $_GET['end']; $query['order'] = $query['direction'] < 1 ? 'DESC' : 'ASC'; $key = 'eo_ag_' . md5(serialize($query)) . get_locale(); $agenda = get_transient('eo_widget_agenda'); if ($agenda && is_array($agenda) && isset($agenda[$key])) { echo json_encode($agenda[$key]); exit; } if ('day' == $query['mode']) { //Day mode $selectDates = "SELECT DISTINCT StartDate FROM {$wpdb->eo_events}"; $whereDates = " WHERE {$wpdb->eo_events}.StartDate" . ($query['order'] == 'ASC' ? " >= " : " <= ") . "%s "; $whereDates .= " AND {$wpdb->eo_events}.StartDate >= %s "; $orderlimit = "ORDER BY {$wpdb->eo_events}.StartDate {$query['order']} LIMIT 4"; $dates = $wpdb->get_col($wpdb->prepare($selectDates . $whereDates . $orderlimit, $query['date'], $today->format('Y-m-d'))); if (!$dates) { return false; } $query['date1'] = min($dates[0], $dates[count($dates) - 1]); $query['date2'] = max($dates[0], $dates[count($dates) - 1]); } elseif ('week' == $query['mode']) { //Week mode - find the week of the next/previous event $selectDates = "SELECT DISTINCT StartDate FROM {$wpdb->eo_events}"; $whereDates = " WHERE {$wpdb->eo_events}.StartDate" . ($query['order'] == 'ASC' ? " > " : " < ") . "%s "; $whereDates .= " AND {$wpdb->eo_events}.StartDate >= %s "; $orderlimit = "ORDER BY {$wpdb->eo_events}.StartDate {$query['order']} LIMIT 1"; $date = $wpdb->get_row($wpdb->prepare($selectDates . $whereDates . $orderlimit, $query['date'], $today->format('Y-m-d'))); if (!$date) { return false; } $datetime = new DateTime($date->StartDate, eo_get_blog_timezone()); //Get the week day, and the start of the week $week_start_day = (int) get_option('start_of_week'); $event_day = (int) $datetime->format('w'); $offset_from_week_start = ($event_day - $week_start_day + 7) % 7; $week_start_date = clone $datetime; $week_start_date->modify('- ' . $offset_from_week_start . ' days'); $week_end_date = clone $week_start_date; $week_end_date->modify('+6 days'); //Query is inclusive. $query['date1'] = $week_start_date->format('Y-m-d'); $query['date2'] = $week_end_date->format('Y-m-d'); } else { //Month mode - find the month of the next date $selectDates = "SELECT DISTINCT StartDate FROM {$wpdb->eo_events}"; $whereDates = " WHERE {$wpdb->eo_events}.StartDate" . ($query['order'] == 'ASC' ? " > " : " < ") . "%s "; $whereDates .= " AND {$wpdb->eo_events}.StartDate >= %s "; $orderlimit = "ORDER BY {$wpdb->eo_events}.StartDate {$query['order']} LIMIT 1"; $date = $wpdb->get_row($wpdb->prepare($selectDates . $whereDates . $orderlimit, $query['date'], $today->format('Y-m-d'))); if (!$date) { return false; } $datetime = new DateTime($date->StartDate, eo_get_blog_timezone()); $query['date1'] = $datetime->format('Y-m-01'); $query['date2'] = $datetime->format('Y-m-t'); } $events = eo_get_events(array('event_start_after' => $query['date1'], 'event_start_before' => $query['date2'])); global $post; foreach ($events as $post) { $return_array[] = array('StartDate' => $post->StartDate, 'display' => eo_get_the_start($instance['group_format']), 'time' => $instance['mode'] == 'day' && eo_is_all_day() ? __('All Day', 'eventorganiser') : eo_get_the_start($instance['item_format']), 'post_title' => get_the_title(), 'color' => eo_get_event_color(), 'event_url' => get_permalink(), 'link' => '<a href="' . get_permalink() . '">' . __('View', 'eventorganiser') . '</a>', 'Glink' => '<a href="' . eo_get_add_to_google_link() . '" target="_blank">' . __('Add To Google Calendar', 'eventorganiser') . '</a>'); } if (!$agenda || !is_array($agenda)) { $agenda = array(); } $agenda[$key] = $return_array; set_transient('eo_widget_agenda', $agenda, 60 * 60 * 24); echo json_encode($return_array); exit; }
/** * Takes a date in ICAL and returns a datetime object * * Expects date in yyyymmdd format * @ignore * @param string $ical_date - date in ICAL format * @return DateTime - the $ical_date as DateTime object */ public function parse_ical_date($ical_date) { preg_match('/^(\\d{8})$/', $ical_date, $matches); if (count($matches) != 2) { throw new Exception(sprintf(__('Invalid date "%s". Date expected in YYYYMMDD format.', 'eventorganiser'), $ical_date)); } //No time is given, so ignore timezone. (So use blog timezone). $datetime = new DateTime($matches[1], eo_get_blog_timezone()); return $datetime; }
public function testTimezoneChangeRRULE() { //When day changes when start date is converted to UTC timezone (for iCal feed) //Remember to correct [day] the 'reccurs weekly by [day]', so thats true for UTC timezone. wp_cache_set('eventorganiser_timezone', 'America/New_York'); //Event recurrs every Monday evening in New York (event recurs every Tuesday in UTC) $event_id = $this->factory->event->create(array('start' => new DateTime('2013-12-02 21:00', eo_get_blog_timezone()), 'end' => new DateTime('2013-12-02 23:00', eo_get_blog_timezone()), 'schedule_last' => new DateTime('2013-12-30 21:00', eo_get_blog_timezone()), 'frequency' => 1, 'all_day' => 0, 'schedule' => 'weekly', 'schedule_meta' => array('MO'), 'post_title' => 'The Event Title', 'post_content' => 'My event content')); $this->assertEquals("FREQ=WEEKLY;INTERVAL=1;BYDAY=TU;UNTIL=20131231T020000Z", eventorganiser_generate_ics_rrule($event_id)); wp_cache_delete('eventorganiser_timezone'); //Now try it the other direction.... wp_cache_set('eventorganiser_timezone', 'Europe/Moscow'); //Event recurrs every Monday morning in Moscow (event recurs very Sunday in UTC) $event_id = $this->factory->event->create(array('start' => new DateTime('2013-12-02 01:00', eo_get_blog_timezone()), 'end' => new DateTime('2013-12-02 02:00', eo_get_blog_timezone()), 'schedule_last' => new DateTime('2013-12-30 01:00', eo_get_blog_timezone()), 'frequency' => 1, 'all_day' => 0, 'schedule' => 'weekly', 'schedule_meta' => array('MO'), 'post_title' => 'The Event Title', 'post_content' => 'My event content')); //This is a bit of a hack, some php5.2 instances will have an out of date Europe/Moscow timezone details //but cannot install the pecl.php.net/timezonedb package. We therefore can't hardcode the until date string //as it may be 21:00 or 22:00 $utc = new DateTimeZone('UTC'); $until = new DateTime('2013-12-30 01:00', eo_get_blog_timezone()); $until->setTimezone($utc); $until_string = $until->format('Ymd\\THis\\Z'); //Probably 20131229T210000Z or 20131229T220000Z $this->assertEquals("FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL={$until_string}", eventorganiser_generate_ics_rrule($event_id)); wp_cache_delete('eventorganiser_timezone'); }
/** * @see https://github.com/stephenharris/Event-Organiser/issues/242 */ function testDuplicatePostCompatability() { $tz = eo_get_blog_timezone(); $start = new DateTime('2015-02-12 14:45:00', $tz); $end = new DateTime('2015-02-12 15:45:00', $tz); $event = array('start' => $start, 'end' => $end, 'frequency' => 1, 'schedule' => 'weekly', 'schedule_meta' => array('TH'), 'schedule_last' => new DateTime('2015-02-26 14:45:00', $tz)); $event_id = $this->factory->event->create($event); $event_post = get_post($event_id); $duplicated_event_id = $this->duplicate($event_post); $this->duplicate_metadata($duplicated_event_id, $event_post); eo_update_event($duplicated_event_id); //Check occurrences of duplicate event exist $expected = array(new DateTime('2015-02-12 14:45:00', $tz), new DateTime('2015-02-19 14:45:00', $tz), new DateTime('2015-02-26 14:45:00', $tz)); $actual = eo_get_the_occurrences($duplicated_event_id); $actual = array_values($actual); $this->assertEquals($expected, $actual); }
function eventorganiser_events_where($where, $query) { global $wpdb; //Only alter event queries if (isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'event') { //Ensure all date queries are yyyy-mm-dd format. Process relative strings ('today','tomorrow','+1 week') $dates = array('ondate', 'event_start_after', 'event_start_before', 'event_end_after', 'event_end_before'); foreach ($dates as $prop) { if (!empty($query->query_vars[$prop])) { $date = $query->query_vars[$prop]; $dateString = eo_format_date($date, 'Y-m-d'); $query->set($prop, $dateString); } } //If we only want events (or occurrences of events) that belong to a particular 'event' if (isset($query->query_vars['event_series'])) { $series_id = $query->query_vars['event_series']; $where .= $wpdb->prepare(" AND {$wpdb->eo_events}.post_id =%d ", $series_id); } if (isset($query->query_vars['event_occurrence_id'])) { $occurrence_id = $query->query_vars['event_occurrence_id']; $where .= $wpdb->prepare(" AND {$wpdb->eo_events}.event_id=%d ", $occurrence_id); } //Retrieve blog's time and date $blog_now = new DateTIme(null, eo_get_blog_timezone()); $now_date = $blog_now->format('Y-m-d'); $now_time = $blog_now->format('H:i:s'); $eo_settings_array = get_option('eventorganiser_options'); $running_event_is_past = empty($eo_settings_array['runningisnotpast']) ? true : false; //Query by interval if (isset($query->query_vars['eo_interval'])) { switch ($query->query_vars['eo_interval']) { case 'future': $query->set('showpastevents', 0); $running_event_is_past = true; break; case 'expired': $now_date = $blog_now->format('Y-m-d'); $now_time = $blog_now->format('H:i:s'); $where .= $wpdb->prepare(" \n\t\t\t\t\t\tAND {$wpdb->eo_events}.post_id NOT IN (\n\t\t\t\t\t\t\tSELECT post_id FROM {$wpdb->eo_events} \n\t\t\t\t\t\t\tWHERE ({$wpdb->eo_events}.EndDate > %s)\n\t\t\t\t\t\t\tOR ({$wpdb->eo_events}.EndDate=%s AND {$wpdb->eo_events}.FinishTime >= %s)\n\t\t\t\t\t\t)", $now_date, $now_date, $now_time); break; case 'P1D': case 'P1W': case 'P1M': case 'P6M': case 'P1Y': if (!isset($cutoff)) { $interval = new DateInterval($query->query_vars['eo_interval']); $cutoff = clone $blog_now; $cutoff->add($interval); } if (empty($query->query_vars['showrepeats'])) { $where .= $wpdb->prepare(" \n\t\t\t\t\t\t\tAND {$wpdb->eo_events}.post_id IN (\n\t\t\t\t\t\t\t\tSELECT post_id FROM {$wpdb->eo_events} \n\t\t\t\t\t\t\t\tWHERE {$wpdb->eo_events}.StartDate <= %s\n\t\t\t\t\t\t\t\tAND {$wpdb->eo_events}.EndDate >= %s)", $cutoff->format('Y-m-d'), $blog_now->format('Y-m-d')); } else { $where .= $wpdb->prepare(" \n\t\t\t\t\t\t\tAND {$wpdb->eo_events}.StartDate <=%s'\n\t\t\t\t\t\t\tAND {$wpdb->eo_events}.EndDate >= %s", $cutoff->format('Y-m-d'), $blog_now->format('Y-m-d')); } break; } } /* * If requested, retrieve only future events. * Single pages behave differently - WordPress sees them as displaying the first event * There could be options in the future to change this behaviour. * Currently we show single pages, even if they don't appear in archive listings. * There could be options in the future to change this behaviour too. * * 'Future events' only works if we are showing all reoccurrences, and not wanting just the first occurrence of an event. */ if (isset($query->query_vars['showpastevents']) && !$query->query_vars['showpastevents']) { //If quering for all occurrences, look at start/end date if (!$query->get('group_events_by') || $query->get('group_events_by') == 'occurrence') { $query_date = $wpdb->eo_events . '.' . ($running_event_is_past ? 'StartDate' : 'EndDate'); $query_time = $wpdb->eo_events . '.' . ($running_event_is_past ? 'StartTime' : 'FinishTime'); $where .= $wpdb->prepare(" AND ( \n\t\t\t\t\t({$query_date} > %s) OR\n\t\t\t\t\t({$query_date} = %s AND {$query_time}>= %s))", $now_date, $now_date, $now_time); //If querying for an 'event schedule': event is past if it all of its occurrences are 'past'. } else { if ($running_event_is_past) { //Check if each occurrence has started, i.e. just check reoccurrence_end $query_date = $wpdb->eo_events . '.reoccurrence_end'; $query_time = $wpdb->eo_events . '.StartTime'; $where .= $wpdb->prepare(" AND ( \n\t\t\t\t\t\t({$query_date} > %s) OR\n\t\t\t\t\t\t({$query_date} = %s AND {$query_time}>= %s))", $now_date, $now_date, $now_time); } else { //Check each occurrence has finished, need to do a sub-query. $where .= $wpdb->prepare(" \n\t\t\t\t\t\tAND {$wpdb->eo_events}.post_id IN (\n\t\t\t\t\t\t\tSELECT post_id FROM {$wpdb->eo_events} \n\t\t\t\t\t\t\tWHERE ({$wpdb->eo_events}.EndDate > %s)\n\t\t\t\t\t\t\tOR ({$wpdb->eo_events}.EndDate=%s AND {$wpdb->eo_events}.FinishTime >= %s)\n\t\t\t\t\t\t\t)", $now_date, $now_date, $now_time); } } } //Check date ranges were are interested in if (isset($query->query_vars['event_start_before']) && $query->query_vars['event_start_before'] != '') { $s_before = $query->query_vars['event_start_before']; $where .= $wpdb->prepare(" AND {$wpdb->eo_events}.StartDate <= %s ", $s_before); } if (isset($query->query_vars['event_start_after']) && $query->query_vars['event_start_after'] != '') { $s_after = $query->query_vars['event_start_after']; $where .= $wpdb->prepare(" AND {$wpdb->eo_events}.StartDate >= %s ", $s_after); } if (isset($query->query_vars['event_end_before']) && $query->query_vars['event_end_before'] != '') { $e_before = $query->query_vars['event_end_before']; $where .= $wpdb->prepare(" AND {$wpdb->eo_events}.EndDate <= %s ", $e_before); } if (isset($query->query_vars['event_end_after']) && $query->query_vars['event_end_after'] != '') { $e_after = $query->query_vars['event_end_after']; $where .= $wpdb->prepare(" AND {$wpdb->eo_events}.EndDate >= %s ", $e_after); } } return $where; }
/** * (Private) Utility function checks a date-time string is formatted correctly (according to the options) * @access private * @ignore * @since 1.0.0 * @param datetime_string - a datetime string * @param string $format - Format of the datetime string. One of 'd-m-Y H:i', 'm-d-Y H:i' and 'Y-m-d H:i'. * @return int DateTime| false - the parsed datetime string as a DateTime object or false on error (incorrectly formatted for example) */ function _eventorganiser_check_datetime($datetime_string = '', $format = null) { if (is_null($format)) { $format = eventorganiser_get_option('dateformat'); } //Backwards compatible - can probably remove 2.1+ if (is_bool($format)) { _deprecated_argument('_eventorganiser_check_datetime', '1.8', 'This function no longer accepts a boolean, pass the format of the passed date-time string.'); if (true === $format) { $format = 'Y-m-d'; } else { $format = eventorganiser_get_option('dateformat'); } } //Get regular expression. if ($format == 'Y-m-d') { $reg_exp = "/(?P<year>\\d{4})[-.\\/](?P<month>\\d{1,})[-.\\/](?P<day>\\d{1,}) (?P<hour>\\d{2}):(?P<minute>\\d{2})/"; } elseif ($format == 'd-m-Y') { $reg_exp = "/(?P<day>\\d{1,})[-.\\/](?P<month>\\d{1,})[-.\\/](?P<year>\\d{4}) (?P<hour>\\d{2}):(?P<minute>\\d{2})/"; } else { $reg_exp = "/(?P<month>\\d{1,})[-.\\/](?P<day>\\d{1,})[-.\\/](?P<year>\\d{4}) (?P<hour>\\d{2}):(?P<minute>\\d{2})/"; } if (!preg_match($reg_exp, $datetime_string, $matches)) { return false; } extract(array_map('intval', $matches)); if (!checkdate($month, $day, $year) || $hour < 0 || $hour > 23 || $minute < 0 || $minute > 59) { return false; } $datetime = new DateTime(null, eo_get_blog_timezone()); $datetime->setDate($year, $month, $day); $datetime->setTime($hour, $minute); return $datetime; }
/** * Generates widget / shortcode calendar html * * param $month - DateTime object for first day of the month (in blog timezone) */ function generate_output($month, $args = array()) { //Translations global $wp_locale; $months = $wp_locale->month; $monthsAbbrev = $wp_locale->month_abbrev; $weekdays = $wp_locale->weekday; $weekdays_initial = $wp_locale->weekday_initial; //Month should be a DateTime object of the first day in that month $today = new DateTime('now', eo_get_blog_timezone()); if (empty($args)) { $args = array(); } //Month details $firstdayofmonth = intval($month->format('N')); $lastmonth = clone $month; $lastmonth->modify('last month'); $nextmonth = clone $month; $nextmonth->modify('next month'); $daysinmonth = intval($month->format('t')); //Retrieve the start day of the week from the options. $startDay = intval(get_option('start_of_week')); //How many blank cells before inserting dates $offset = ($firstdayofmonth - $startDay + 7) % 7; //Number of weeks to show in Calendar $totalweeks = ceil(($offset + $daysinmonth) / 7); //Get events for this month $start = $month->format('Y-m-d'); $end = $month->format('Y-m') . '-' . $daysinmonth; $required = array('numberposts' => -1, 'showrepeats' => 1, 'start_before' => $end, 'start_after' => $start); $query_array = array_merge($args, $required); $events = eo_get_events($query_array); //Populate events array $tableArray = array(); foreach ($events as $event) { $date = esc_html($event->StartDate); $tableArray[$date][] = esc_attr($event->post_title); } $before = "<table id='wp-calendar'>"; $title = "<caption>" . esc_html($months[$month->format('m')] . ' ' . $month->format('Y')) . "</caption>"; $head = "<thead><tr>"; for ($d = 0; $d <= 6; $d++) { $day = $weekdays_initial[$weekdays[($d + $startDay) % 7]]; $head .= "<th title='" . esc_attr($day) . "' scope='col'>" . esc_html($day) . "</th>"; } $head .= "</tr></thead>"; $prev = esc_html($monthsAbbrev[$months[$lastmonth->format('m')]]); $next = esc_html($monthsAbbrev[$months[$nextmonth->format('m')]]); $prev_link = add_query_arg('eo_month', $lastmonth->format('Y-m')); $next_link = add_query_arg('eo_month', $nextmonth->format('Y-m')); $foot = "<tfoot><tr>"; $foot .= "<td id='eo-widget-prev-month' colspan='3'><a title='" . esc_html__('Previous month', 'eventorganiser') . "' href='{$prev_link}'>« " . $prev . "</a></td>"; $foot .= "<td class='pad'> </td>"; $foot .= "<td id='eo-widget-next-month' colspan='3'><a title='" . esc_html__('Next month', 'eventorganiser') . "' href='{$next_link}'>" . $next . "» </a></td>"; $foot .= "</tr></tfoot>"; $body = "<tbody>"; $currentDate = clone $month; $event_archive_link = get_post_type_archive_link('event'); for ($w = 0; $w <= $totalweeks - 1; $w++) { $body .= "<tr>"; $cell = $w * 7; //For each week day foreach ($weekdays_initial as $i => $day) { $cell = $cell + 1; if ($cell <= $offset || $cell - $offset > $daysinmonth) { $body .= "<td class='pad' colspan='1'> </td>"; } else { $class = array(); $formated_date = $currentDate->format('Y-m-d'); //Is the date 'today'? if ($formated_date == $today->format('Y-m-d')) { $class[] = 'today'; } //Does the date have any events if (isset($tableArray[$formated_date])) { $class[] = 'event'; $classes = implode(' ', $class); $classes = esc_attr($classes); $titles = implode(', ', $tableArray[$formated_date]); $titles = esc_attr($titles); $link = add_query_arg('ondate', $currentDate->format('Y-m-d'), $event_archive_link); $link = esc_url($link); $body .= "<td class='" . $classes . "'> <a title='" . $titles . "' href='" . $link . "'>" . ($cell - $offset) . "</a></td>"; } else { $classes = implode(' ', $class); $body .= "<td class='" . $classes . "'>" . ($cell - $offset) . "</td>"; } $currentDate->modify('+1 day'); } } //Endforeach Week day $body .= "</tr>"; } //End for each week $body .= "</tbody>"; $after = "</table>"; return $before . $title . $head . $foot . $body . $after; }
public function download_debug_info() { global $wpdb; $installed = get_plugins(); $active_plugins = array(); foreach ($installed as $plugin_slug => $plugin_data) { if (!is_plugin_active($plugin_slug)) { continue; } $active_plugins[] = $plugin_slug; } $theme = wp_get_theme(); $db_tables = array(); if ($this->db_tables) { foreach ($this->db_tables as $db_table) { if ($this->table_exists($db_table)) { $db_table = "**" . $db_table . "**"; } $db_tables[] = $db_table; } } $options = array(); $options['event-organiser'] = eventorganiser_get_option(false); /** * Settings to include in an export. * * These options are included in both the settings export on the settings * page and the also printed in the system information file. By default * they inlude Event Organiser's options, but others can be added. * * The filtered value should be a (2+ dimensional) array, indexed by plugin/ * extension name. * * @param array $options Array of user settings, indexed by plug-in/extension. */ $options = apply_filters('eventorganiser_export_settings', $options); $filename = 'event-organiser-system-info-' . get_bloginfo('name') . '.md'; $filename = sanitize_file_name($filename); header("Content-type: text/plain"); header('Content-disposition: attachment; filename=' . $filename); echo '## Event Organiser Sytem Informaton ##' . "\n"; echo "\n"; echo "\n"; echo '### Site Information ###' . "\n"; echo "\n"; echo 'Site url' . "\t\t\t" . site_url() . "\n"; echo 'Home url' . "\t\t\t" . home_url() . "\n"; echo 'Multisite' . "\t\t\t" . (is_multisite() ? 'Yes' : 'No') . "\n"; echo 'Permalink' . "\t\t\t" . get_option('permalink_structure') . "\n"; echo "\n"; echo "\n"; echo '### Versions ###' . "\n"; echo "\n"; echo 'Event Organiser' . "\t\t" . EVENT_ORGANISER_VER . "\n"; if ($this->jquery_version) { echo 'jQuery Version' . "\t\t" . $this->jquery_version . "\n"; } echo 'WordPress' . "\t\t\t" . get_bloginfo('version') . "\n"; echo 'PHP Version' . "\t\t\t" . PHP_VERSION . "\n"; global $wpdb; $ver = empty($wpdb->use_mysqli) ? mysql_get_server_info() : mysqli_get_server_info($wpdb->dbh); echo 'MySQL Version' . "\t\t" . $ver . "\n"; echo "\n"; echo "\n"; echo '### Server Information ###' . "\n"; echo "\n"; echo 'Web Server' . "\t\t\t" . $_SERVER['SERVER_SOFTWARE'] . "\n"; echo 'PHP Memory Usage' . "\t" . $this->get_memory_usage('percent') . '%' . "\n"; echo 'PHP Memory Limit' . "\t" . ini_get('memory_limit') . "\n"; echo 'PHP Upload Max Size' . "\t" . ini_get('post_max_size') . "\n"; echo 'PHP FSOCKOPEN support' . "\t" . (function_exists('fsockopen') ? 'Yes' : 'No') . "\n"; echo 'PHP cURL support' . "\t" . (function_exists('curl_init') ? 'Yes' : 'No') . "\n"; echo 'PHP openSSL support' . "\t" . (function_exists('openssl_verify') ? 'Yes' : 'No') . "\n"; echo "\n"; echo "\n"; echo '### Plug-ins & Themes ###' . "\n"; echo "\n"; echo 'Active Plug-ins' . "\n\t-\t" . implode("\n\t-\t", $active_plugins) . "\n"; echo 'Theme' . "\n\t-\t" . $theme->get('Name') . ' (' . $theme->get('Version') . ')' . "\n"; echo "\n"; echo "\n"; echo '### Database ###' . "\n"; echo "\n"; echo "Database Prefix" . "\t\t\t" . $wpdb->prefix . "\n"; echo "Database tables" . "\t\t\t" . implode(', ', $db_tables) . "\n"; echo "Database character set" . "\t" . ($this->database_charset_check() ? DB_CHARSET : "**" . DB_CHARSET . "**") . "\n"; echo "\n"; echo "\n"; echo '### Site Settings ###' . "\n"; echo 'Timezone' . "\t\t\t" . eo_get_blog_timezone()->getName() . sprintf(' ( %s / %s ) ', get_option('gmt_offset'), get_option('timezone_string')) . "\n"; echo 'WP Cron' . "\t\t\t" . ($this->get_cron_status() == 0 ? 'Disabled' : ($this->get_cron_status() == 1 ? 'Enabled' : 'Alternative ')) . "\n"; echo 'WP Lang' . "\t\t\t" . (defined('WP_LANG') && WP_LANG ? WP_LANG : 'en_us') . "\n"; echo 'Date format' . "\t\t" . get_option('date_format') . "\n"; echo 'Time format' . "\t\t" . get_option('time_format'); echo "\n"; echo "\n"; echo '### Event Organiser Settings ###' . "\n"; foreach ($options['event-organiser'] as $option => $value) { if (is_array($value)) { $value = implode(', ', $value); } echo "\n\t-\t**" . esc_html($option) . ":**\t " . $value; } echo "\n"; echo "\n"; echo '### Debug Mode ###' . "\n"; echo "\n"; echo 'Debug mode' . "\t\t\t" . (defined('WP_DEBUG') && WP_DEBUG ? 'Enabled' : 'Disabled') . "\n"; echo 'Script mode' . "\t\t\t" . (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? 'Enabled' : 'Disabled') . "\n"; exit; }
/** * Generates widget / shortcode calendar html * * @param $month - DateTime object for first day of the month (in blog timezone) */ static function generate_output($month, $args = array()) { //Translations global $wp_locale; $today = new DateTime('now', eo_get_blog_timezone()); $key = $month->format('YM') . serialize($args) . get_locale() . $today->format('Y-m-d'); $calendar = get_transient('eo_widget_calendar'); if ((!defined('WP_DEBUG') || !WP_DEBUG) && $calendar && is_array($calendar) && isset($calendar[$key])) { return $calendar[$key]; } //Parse defaults $args['show-long'] = isset($args['show-long']) ? $args['show-long'] : false; $args['link-to-single'] = isset($args['link-to-single']) ? $args['link-to-single'] : false; //Month details $first_day_of_month = intval($month->format('N')); //0=sun,...,6=sat $days_in_month = intval($month->format('t')); // 28-31 $last_month = clone $month; $last_month->modify('last month'); $next_month = clone $month; $next_month->modify('next month'); //Retrieve the start day of the week from the options. $start_day = intval(get_option('start_of_week')); //0=sun,...,6=sat //How many blank cells before inserting dates $offset = ($first_day_of_month - $start_day + 7) % 7; //Number of weeks to show in Calendar $totalweeks = ceil(($offset + $days_in_month) / 7); //Get events for this month $start = $month->format('Y-m-d'); $end = $month->format('Y-m-t'); //Query events $required = array('numberposts' => -1, 'showrepeats' => 1); if ($args['show-long']) { $args['event_start_before'] = $end; $args['event_end_after'] = $start; } else { $args['event_start_before'] = $end; $args['event_start_after'] = $start; } $events = eo_get_events(array_merge($args, $required)); //Populate events array $calendar_events = array(); foreach ($events as $event) { if ($args['show-long']) { $start = eo_get_the_start(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); $end = eo_get_the_end(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); $pointer = clone $start; while ($pointer <= $end) { $date = eo_format_datetime($pointer, 'Y-m-d'); $calendar_events[$date][] = $event; $pointer->modify('+1 day'); } } else { $date = eo_get_the_start('Y-m-d', $event->ID, null, $event->occurrence_id); $calendar_events[$date][] = $event; } } $before = "<table id='wp-calendar'>"; $title = sprintf("<caption> %s </caption>", esc_html(eo_format_datetime($month, 'F Y'))); $head = "<thead><tr>"; for ($d = 0; $d <= 6; $d++) { $day = $wp_locale->get_weekday(($d + $start_day) % 7); $day_abbrev = $wp_locale->get_weekday_initial($day); $head .= sprintf("<th title='%s' scope='col'>%s</th>", esc_attr($day), esc_html($day_abbrev)); } $head .= "</tr></thead>"; $foot = sprintf("<tfoot><tr>\n\t\t\t\t\t<td id='eo-widget-prev-month' colspan='3'><a title='%s' href='%s'>« %s</a></td>\n\t\t\t\t\t<td class='pad'> </td>\n\t\t\t\t\t<td id='eo-widget-next-month' colspan='3'><a title='%s' href='%s'> %s » </a></td>\n\t\t\t\t</tr></tfoot>", esc_html__('Previous month', 'eventorganiser'), add_query_arg('eo_month', $last_month->format('Y-m')), esc_html(eo_format_datetime($last_month, 'M')), esc_html__('Next month', 'eventorganiser'), add_query_arg('eo_month', $next_month->format('Y-m')), esc_html(eo_format_datetime($next_month, 'M'))); $body = "<tbody>"; $current_date = clone $month; //Foreach week in calendar for ($w = 0; $w <= $totalweeks - 1; $w++) { $body .= "<tr>"; //For each cell in this week for ($cell = $w * 7 + 1; $cell <= ($w + 1) * 7; $cell++) { $formated_date = $current_date->format('Y-m-d'); $data = "data-eo-wc-date='{$formated_date}'"; if ($cell <= $offset) { $body .= "<td class='pad eo-before-month' colspan='1'> </td>"; } elseif ($cell - $offset > $days_in_month) { $body .= "<td class='pad eo-after-month' colspan='1'> </td>"; } else { $class = array(); if ($formated_date < $today->format('Y-m-d')) { $class[] = 'eo-past-date'; } elseif ($formated_date == $today->format('Y-m-d')) { $class[] = 'today'; } else { $class[] = 'eo-future-date'; } //Does the date have any events if (isset($calendar_events[$formated_date])) { $class[] = 'event'; $events = $calendar_events[$formated_date]; if ($events && count($events) == 1 && $args['link-to-single']) { $only_event = $events[0]; $link = get_permalink($only_event->ID); } else { $link = eo_get_event_archive_link($current_date->format('Y'), $current_date->format('m'), $current_date->format('d')); } $link = esc_url($link); /** * Filters the the link of a date on the events widget calendar * @param string $link The link * @param datetime $current_date The date being filtered * @param array $events Array of events starting on this day */ $link = apply_filters('eventorganiser_widget_calendar_date_link', $link, $current_date, $events); foreach ($events as $event) { $class = array_merge($class, eo_get_event_classes($event->ID, $event->occurrence_id)); } $class = array_unique(array_filter($class)); $classes = implode(' ', $class); $titles = implode(', ', wp_list_pluck($events, 'post_title')); $body .= sprintf("<td {$data} class='%s'> <a title='%s' href='%s'> %s </a></td>", esc_attr($classes), esc_attr($titles), $link, $cell - $offset); } else { $classes = implode(' ', $class); $body .= sprintf("<td {$data} class='%s'> %s </td>", esc_attr($classes), $cell - $offset); } //Proceed to next day $current_date->modify('+1 day'); } } //Endfor each day in week $body .= "</tr>"; } //End for each week $body .= "</tbody>"; $after = "</table>"; if (!$calendar || !is_array($calendar)) { $calendar = array(); } $calendar[$key] = $before . $title . $head . $foot . $body . $after; set_transient('eo_widget_calendar', $calendar, 60 * 60 * 24); return $calendar[$key]; }
/** * Ajax response to event occurrence being moved. * * TODO Prevent two occurrences from the same event * occuring on the same *date*. * * @ignore */ function eventorganiser_admin_calendar_edit_date() { $event_id = (int) $_POST['event_id']; $occurrence_id = (int) $_POST['occurrence_id']; $all_day = eo_is_all_day($event_id); if ('event' != get_post_type($event_id)) { echo json_encode(array('success' => false, 'data' => array('message' => __('Event not found', 'eventorganiser')))); exit; } $edittime = defined('EVENT_ORGANISER_BETA_FEATURES') && EVENT_ORGANISER_BETA_FEATURES; if (!$edittime) { echo json_encode(array('success' => false, 'data' => array('message' => __('Events are not editable via the admin calendar', 'eventorganiser')))); exit; } if (!check_ajax_referer('edit_events', false, false)) { echo json_encode(array('success' => false, 'data' => array('message' => __('Are you sure you want to do this?', 'eventorganiser')))); exit; } if (!current_user_can('edit_event', $event_id)) { echo json_encode(array('success' => false, 'data' => array('message' => __('You do not have permission to edit this event', 'eventorganiser')))); exit; } $tz = eo_get_blog_timezone(); $new_start = new DateTime($_POST['start'], $tz); $new_end = new DateTime($_POST['end'], $tz); $re = eventorganiser_move_occurrence($event_id, $occurrence_id, $new_start, $new_end); if (!is_wp_error($re)) { echo json_encode(array('success' => true)); exit; } else { echo json_encode(array('success' => false, 'data' => array('message' => sprintf(__('Event not created: %s', 'eventorganiser'), $re->get_error_message())))); exit; } }
/** * Callback for the delete expired events cron job. Deletes events that finished at least 24 hours ago. * For recurring events it is only deleted once the last occurrence has expired. * * @since 1.4.0 * @ignore * @access private */ function eventorganiser_delete_expired_events() { //Get expired events $events = eo_get_events(array('showrepeats' => 0, 'showpastevents' => 1, 'eo_interval' => 'expired')); /** * Filters how long (in seconds) after an event as finished it should be considered expired. * * If enabled in *Settings > Event Organiser > General*, expired events are trashed. * * @param int $time_until_expired Time (in seconds) to wait after an event has finished. Defaults to 24 hours. */ $time_until_expired = (int) apply_filters('eventorganiser_events_expire_time', 24 * 60 * 60); $time_until_expired = max($time_until_expired, 0); if ($events) { $now = new DateTime('now', eo_get_blog_timezone()); foreach ($events as $event) { $start = eo_get_the_start(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); $end = eo_get_the_end(DATETIMEOBJ, $event->ID, null, $event->occurrence_id); $expired = round(abs($end->format('U') - $start->format('U'))) + $time_until_expired; //Duration + expire time $finished = eo_get_schedule_last(DATETIMEOBJ, $event->ID); $finished->modify("+{$expired} seconds"); //[Expired time] after the last occurrence finishes //Delete if [expired time] has passed if ($finished <= $now) { wp_trash_post((int) $event->ID); } } } }