/**
 * 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;
 }
/**
 * Saves the event data posted from the event metabox.
 * Hooked to the 'save_post' action
 * 
 * @since 1.0.0
 *
 * @param int $post_id the event post ID
 * @return int $post_id the event post ID
 */
function eventorganiser_details_save($post_id)
{
    global $wpdb, $eventorganiser_events_table;
    //make sure data came from our meta box
    if (!isset($_POST['_eononce']) || !wp_verify_nonce($_POST['_eononce'], 'eventorganiser_event_update_' . $post_id)) {
        return;
    }
    // verify this is not an auto save routine.
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return $post_id;
    }
    //authentication checks
    if (!current_user_can('edit_event', $post_id)) {
        return $post_id;
    }
    $raw_data = isset($_POST['eo_input']) ? $_POST['eo_input'] : array();
    //Update venue
    $raw_data['Venue'] = !empty($raw_data['event-venue']) ? intval($raw_data['event-venue']) : null;
    $r = wp_set_post_terms($post_id, array($raw_data['Venue']), 'event-venue', false);
    //TODO Reoccurrence details wil be sotred as post meta - leaving just dates/occurrence/IDs
    //Check if there is existing event data.
    $event = new EO_Event($post_id);
    /*
     * If event data exists, we may have to delete the occurrances and replace them with new ones.
     * First we check if this is necessary. If not, we just update the data and exit.
     */
    $delete_existing = false;
    if ($event->exists) {
        if (isset($raw_data['schedule']) && $raw_data['schedule'] == 'once' && $event->is_schedule('once')) {
            //We are updating a single event (and it is still a one time event), can just update all data easily
            $event->create($raw_data);
            $event_input = array('post_id' => $post_id, 'StartDate' => $event->start->format('Y-m-d'), 'StartTime' => $event->start->format('H:i:s'), 'EndDate' => $event->end->format('Y-m-d'), 'FinishTime' => $event->end->format('H:i:s'), 'Venue' => $event->venue, 'event_schedule' => $event->schedule, 'event_schedule_meta' => $event->meta, 'event_frequency' => $event->frequency, 'event_occurrence' => 0, 'event_allday' => $event->allday, 'reoccurrence_start' => $event->schedule_start->format('Y-m-d'), 'reoccurrence_end' => $event->schedule_end->format('Y-m-d'));
            $upd = $wpdb->update($eventorganiser_events_table, $event_input, array('post_id' => $post_id));
            return;
        } elseif (!$event->is_schedule('once')) {
            //Event was reoccurring
            //If 'edit reocurrences' is checked we need to replace reoccurrences
            if (isset($raw_data['AlterRe']) && $raw_data['AlterRe'] == 'yes') {
                $delete_existing = true;
            }
        } else {
            //Was a one-time event, is now a reoccurring event - delete event.
            $delete_existing = true;
        }
    }
    //Populate event data from raw input and inserts (after deleting existing occurrences, if necessary)
    $event->insertEvent($raw_data, $post_id, $delete_existing);
    do_action('eventorganiser_save_event', $post_id);
    return $post_id;
}
 protected function setupSchedule()
 {
     $errors = get_option('eo_notice');
     $workaround = false;
     $occurrence = array("first", "second", "third", "fourth", "last");
     $start_days = array();
     switch ($this->schedule) {
         case 'daily':
             $interval = "+" . $this->frequency . "day";
             $start_days[] = clone $this->start;
             break;
         case 'weekly':
             $this->meta = array_filter($this->meta);
             if (!empty($this->meta)) {
                 array_map('esc_attr', $this->meta);
                 foreach ($this->meta as $day) {
                     $start_day = clone $this->start;
                     $start_day->modify(self::$ical2day[$day]);
                     $start_days[] = $start_day;
                 }
             } else {
                 $start_days[] = clone $this->start;
             }
             $this->meta = serialize($this->meta);
             $interval = "+" . $this->frequency . "week";
             break;
         case 'monthly':
             $start_days[] = clone $this->start;
             $rule_value = explode('=', $this->meta, 2);
             $rule = $rule_value[0];
             $values = explode(',', $rule_value[1]);
             //Should only be one value, but may support more in future
             $values = array_filter($values);
             if ($rule == 'BYMONTHDAY') {
                 $day = $start_days[0]->format('d');
                 $interval = "+" . $this->frequency . "month";
                 if ($day >= '29') {
                     $workaround = 'short months';
                 }
                 //This case deals with 29/30/31 of month
                 $this->meta = 'BYMONTHDAY=' . $day;
             } else {
                 $day = $start_days[0]->format('l');
                 $day_num = intval($start_days[0]->format('w'));
                 $date = intval($start_days[0]->format('d'));
                 $n = floor(($date - 1) / 7);
                 if ($n == 4) {
                     $n = -2;
                 }
                 if (empty($values)) {
                     $values = array($n + 1 . self::$daysofweek[$day_num]['ical']);
                 }
                 $this->meta = 'BYDAY=' . $values[0];
                 preg_match('/^(-?\\d{1,2})([a-zA-Z]{2})/', $values[0], $matches);
                 $n = intval($matches[1]) - 1;
                 if ($n == -2) {
                     $n = 4;
                 }
                 $day = self::$ical2day[$matches[2]];
                 if (!isset($occurrence[$n]) || !isset(self::$ical2day[$matches[2]])) {
                     $errors[$this->post_id][] = "Event dates were not saved.";
                     $errors[$this->post_id][] = "Invalid reoccurrence schedule";
                     update_option('eo_notice', $errors);
                     return false;
                 }
                 $interval = $occurrence[$n] . ' ' . $day . ' of +' . $this->frequency . ' month';
                 //Work around for PHP <5.3
                 if (!function_exists('date_diff')) {
                     $workaround = 'php5.2';
                 }
             }
             break;
         case 'yearly':
             $start_days[] = clone $this->start;
             if ($start_days[0]->format('d-m') == '29-02') {
                 $workaround = 'leap year';
             }
             $interval = "+" . $this->frequency . "year";
             break;
     }
     //Remove duplicates
     $start_days = EO_Event::removeDuplicate($start_days);
     $schedule_data = array('days' => $start_days, 'interval' => $interval, 'workaround' => $workaround);
     return $schedule_data;
 }
    function display()
    {
        //Get the time 'now' according to blog's timezone
        $now = new DateTIme(null, EO_Event::get_timezone());
        $venues = get_terms('event-venue', array('hide_empty' => false));
        ?>

	<div class="wrap">  
		<div id='icon-edit' class='icon32'><br/>
		</div>
		<h2><?php 
        _e('Events Calendar', 'eventorganiser');
        ?>
</h2>

		<div id="calendar-view">
			<span id='loading' style='display:none'><?php 
        _e('Loading&#8230;');
        ?>
</span>
			<a href="" class="view-button" id="agendaDay"><?php 
        _e('Day', 'eventorganiser');
        ?>
 </a>
			<a href="" class="view-button" id="agendaWeek"><?php 
        _e('Week', 'eventorganiser');
        ?>
</a>
			<a href="" class="view-button active" id="month"><?php 
        _e('Month', 'eventorganiser');
        ?>
 </a>
		</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>
		<div id='events-meta' class="thickbox"></div>

		<?php 
        if (current_user_can('publish_events') || current_user_can('edit_events')) {
            ?>
			<div id='eo_event_create_cal' style="display:none;" class="thickbox">
			<form name="eventorganiser_calendar" method="post" class="eo_cal">
				<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>
				<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>
				<tr>
					<th></th>
					<td><textarea rows="4" name="eo_event[event_content]"></textarea></td>
				</tr>
				</table>
				<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')) {
                ?>
					<p class="submit">	
						<input type="reset" class="button" id="reset" value="Cancel">
						<input type="submit" class="button button-highlighted" tabindex="4" value="<?php 
                _e('Save Draft', 'eventorganiser');
                ?>
"" id="event-draft" name="save">
					<span class="eo_alignright">
						<input type="submit" accesskey="p" tabindex="5" value="<?php 
                _e('Publish Event', 'eventorganiser');
                ?>
" class="button-primary" id="publish" name="publish">
					</span>
					<br class="clear">
					</p>
			<?php 
            } elseif (current_user_can('edit_events')) {
                ?>
				<p class="submit">	
					<input type="reset" class="button" id="reset" value="<?php 
                _e('Cancel', 'eventorganiser');
                ?>
">
					<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">
				<br class="clear">
				</p>
			<?php 
            }
            ?>
			</form>
		</div>
		<?php 
        }
        ?>
	</div><!-- .wrap -->
<?php 
    }