function src_source_create($range = NULL)
 {
     if (!CheckPermissions($this->mPermission)) {
         return;
     }
     if (!isset($this->mPermissions['create'])) {
         return show_404();
     }
     // Validate the source
     if (!$this->_GetSource()) {
         return;
     }
     $this->load->library('calendar_view_edit_simple');
     $this->pages_model->SetPageCode('calendar_new_event');
     $this->main_frame->SetTitleParameters(array('source' => $this->mSource->GetSourceName()));
     // Get the redirect url tail
     $args = func_get_args();
     array_shift($args);
     $tail = implode('/', $args);
     // Whether to redirect to tail on success
     $success_redirect_to_tail = false;
     if (isset($_POST['eved_success_redirect'])) {
         $success_redirect_to_tail = true;
     }
     if (!$this->mSource->IsSupported('create')) {
         // Create isn't supported with this source
         $this->ErrorNotCreateable($tail);
         $this->main_frame->Load();
         return;
     }
     $prefix = 'eved';
     // Default start and end
     $start = strtotime('tomorrow+12hours');
     $end = strtotime('tomorrow+13hours');
     // check for post data from mini creater
     // this simply sets the _POST data so it can be analysed as if clicked save
     $input = array();
     if (isset($_POST['evad_create'])) {
         $input_valid = true;
         // Transfer post data
         @($_POST[$prefix . '_summary'] = $_POST['evad_summary']);
         @($_POST[$prefix . '_category'] = $_POST['evad_category']);
         @($_POST[$prefix . '_location'] = $_POST['evad_location']);
         @($_POST[$prefix . '_description'] = $_POST['evad_description']);
         $input_date = $this->input->post('evad_date');
         $input_start = $this->input->post('evad_start');
         $input_end = $this->input->post('evad_end');
         if (false === $input_date || false === $input_start || false === $input_end) {
             $this->messages->AddMessage('error', 'Missing event time information.');
             $input_valid = false;
         } else {
             if (!is_numeric($input_date)) {
                 $this->messages->AddMessage('error', 'Invalid date');
                 $input_valid = false;
             }
             if (!is_numeric($input_start) || $input_start < 0 || $input_start > 48 * 60) {
                 $this->messages->AddMessage('error', 'Invalid start time');
                 $input_valid = false;
             }
             if (!is_numeric($input_end) || $input_end < 0 || $input_end > 48 * 60) {
                 $this->messages->AddMessage('error', 'Invalid end time');
                 $input_valid = false;
             }
             if ($input_valid) {
                 $starthour = (int) ($input_start / 60);
                 $startminute = (int) ($input_start % 60);
                 $start = strtotime("{$input_date} 000000");
                 if ($starthour >= 24) {
                     $start = strtotime('+1day', $start);
                     $starthour -= 24;
                 }
                 $start = strtotime(date('Ymd', $start) . ' ' . sprintf("%02d%02d", $starthour, $startminute) . '00');
                 $endhour = (int) ($input_end / 60);
                 $endminute = (int) ($input_end % 60);
                 $end = strtotime("{$input_date} 000000");
                 if ($endhour >= 24) {
                     $end = strtotime('+1day', $end);
                     $endhour -= 24;
                 }
                 $end = strtotime(date('Ymd', $end) . ' ' . sprintf("%02d%02d", $endhour, $endminute) . '00');
                 if ($start >= $end) {
                     $this->messages->AddMessage('error', 'Event must not end before it starts');
                     $input_valid = false;
                 }
                 if ($start < strtotime('today-1year')) {
                     $this->messages->AddMessage('error', 'Event out of range');
                     $input_valid = false;
                 }
                 if ($end > strtotime('today+2year')) {
                     $this->messages->AddMessage('error', 'Event out of range');
                     $input_valid = false;
                 }
             }
         }
         if ($input_valid) {
             $_POST[$prefix . '_save'] = 'save';
             $start_end_predefined = true;
             $success_redirect_to_tail = true;
         }
     }
     // Get the buttons from post data
     if (isset($_POST[$prefix . '_return'])) {
         // REDIRECT
         return redirect($tail);
     }
     $errors = array();
     // Read the recurrence data
     if (isset($_POST[$prefix . '_recur_simple']) and isset($_POST[$prefix . '_start']) and isset($_POST[$prefix . '_duration']) and isset($_POST[$prefix . '_inex'])) {
         $rset_arr = $_POST[$prefix . '_recur_simple'];
         $rset = Calendar_view_edit_simple::validate_recurrence_set_data(!(isset($_POST[$prefix . '_allday']) && $_POST[$prefix . '_allday']), $_POST[$prefix . '_start'], $_POST[$prefix . '_duration'], $_POST[$prefix . '_recur_simple'], $_POST[$prefix . '_inex'], $errors);
     }
     // Fill it in if none supplied
     if (!isset($rset_arr)) {
         $rset = new RecurrenceSet();
         $rset->SetStartEnd($start, $end);
         $rset_arr = Calendar_view_edit_simple::transform_recur_for_view($rset, $errors);
     }
     // Always fill in the inex info again, ignoring input from form.
     $inex_arr = Calendar_view_edit_simple::transform_inex_for_view($rset, $errors);
     list($start, $end) = $rset->GetStartEnd();
     $categories = $this->mSource->GetAllCategories();
     $input = array('name' => '', 'description' => '', 'location_name' => '', 'category' => 0, 'time_associated' => true);
     $input_summary = $this->input->post($prefix . '_summary');
     $confirm_list = NULL;
     if (false !== $input_summary) {
         $input_valid = true;
         // Get more post data
         $input['name'] = $input_summary;
         if (strlen($input['name']) <= 3 or strlen($input['name']) >= 256) {
             $input_valid = false;
             $this->messages->AddMessage('error', 'Event summary is too long or too short.');
         }
         $input_description = $this->input->post($prefix . '_description');
         if (false !== $input_description) {
             $input['description'] = $input_description;
             if (strlen($input['name']) > 65535) {
                 $input_valid = false;
                 $this->messages->AddMessage('error', 'Event description is too long.');
             }
         }
         $input_category = $this->input->post($prefix . '_category');
         if (false !== $input_category) {
             $input['category'] = $input_category;
         }
         $input_location = $this->input->post($prefix . '_location');
         if (false !== $input_location) {
             $input['location_name'] = $input_location;
             if (strlen($input['location_name']) > 50) {
                 $input_valid = false;
                 $this->messages->AddMessage('error', 'Event location is too long.');
             }
         }
         $input['time_associated'] = $this->input->post($prefix . '_allday') === false;
         // at this point $start and $end are still plain timestamps
         $input['recur'] = $rset;
         if ($input_valid && empty($errors)) {
             $event = new CalendarEvent(-1, $this->mSource);
             if (isset($_POST[$prefix . '_save'])) {
                 $confirm_list = $this->mMainSource->GetEventRecurChanges($event, $rset);
                 if (isset($confirm_list['draft']) && !$this->mMainSource->IsSupported('publish')) {
                     unset($confirm_list['draft']);
                 }
                 if (empty($confirm_list)) {
                     $_POST[$prefix . '_confirm']['confirm_btn'] = 'Confirm';
                 }
             }
             if (isset($_POST[$prefix . '_confirm']['confirm_btn'])) {
                 $event_id = -1;
                 $messages = array();
                 $messages = $this->mSource->CreateEvent($input, $event_id);
                 $this->messages->AddMessages($messages);
                 if (!array_key_exists('error', $messages) || empty($messages['error'])) {
                     $this->messages->AddMessage('success', 'Event created successfully.');
                     // Publish the specified occurrences.
                     $publish_occurrences = array();
                     foreach (array('create') as $namespace) {
                         if (isset($_POST[$prefix . '_confirm'][$namespace . '_publish'])) {
                             if (NULL === $confirm_list) {
                                 $confirm_list = $this->mMainSource->GetEventRecurChanges($event, $rset);
                             }
                             foreach ($_POST[$prefix . '_confirm'][$namespace . '_publish'] as $day => $dummy) {
                                 if (isset($confirm_list[$namespace][$day])) {
                                     $publish_occurrences[] = $confirm_list[$namespace][$day]['start_time'];
                                 }
                             }
                         }
                     }
                     if (!empty($publish_occurrences)) {
                         $event = new CalendarEvent(-1, $this->mSource);
                         $event->SourceEventId = $event_id;
                         $published = $this->mSource->PublishOccurrences($event, $publish_occurrences);
                         $desired = count($publish_occurrences);
                         if ($published < $desired) {
                             $message_type = 'warning';
                         } else {
                             $message_type = 'success';
                         }
                         $this->messages->Addmessage($message_type, "{$published} out of {$desired} occurrences were published.");
                     }
                     if ($success_redirect_to_tail) {
                         return redirect($tail);
                     } else {
                         return redirect($this->mPaths->Range(date('Y-M-j', $start)));
                     }
                 }
             }
         }
     }
     // Ready output data
     $start = new Academic_time($start);
     $end = new Academic_time($end);
     $eventinfo = array('summary' => $input['name'], 'description' => $input['description'], 'location' => $input['location_name'], 'category' => $input['category'], 'allday' => !$input['time_associated'], 'start' => array('monthday' => $start->DayOfMonth(), 'month' => $start->Month(), 'year' => $start->Year(), 'time' => $start->Hour() . ':' . $start->Minute(), 'yearday' => $start->DayOfYear(), 'day' => $start->DayOfWeek(), 'monthweek' => (int) (($start->DayOfMonth() + 6) / 7)), 'duration' => Calendar_view_edit_simple::calculate_duration($start, $end));
     if ($this->events_model->IsVip()) {
         $help_xhtml = $this->pages_model->GetPropertyWikitext('help_vip');
     } else {
         $help_xhtml = $this->pages_model->GetPropertyWikitext('help_personal');
     }
     $data = array('SimpleRecur' => $rset_arr, 'InExDates' => $inex_arr, 'FailRedirect' => site_url($tail), 'Path' => $this->mPaths, 'EventCategories' => $categories, 'FormPrefix' => $prefix, 'EventInfo' => $eventinfo, 'Help' => $help_xhtml, 'CanPublish' => $this->mMainSource->IsSupported('publish'), 'Create' => true, 'SuccessRedirect' => $success_redirect_to_tail);
     if (is_array($confirm_list)) {
         $data['Confirms'] = $confirm_list;
         if (isset($_POST[$prefix . '_confirm'])) {
             $data['Confirm'] = $_POST[$prefix . '_confirm'];
         } else {
             $data['Confirm'] = NULL;
         }
     }
     foreach ($errors as $error) {
         $this->messages->AddMessage('error', $error['text']);
     }
     $this->SetupTabs('', $start);
     $this->main_frame->IncludeCss('stylesheets/calendar.css');
     $this->main_frame->IncludeJs('javascript/simple_ajax.js');
     $this->main_frame->IncludeJs('javascript/css_classes.js');
     $this->main_frame->IncludeJs('javascript/calendar_edit.js');
     $this->main_frame->SetContent(new FramesView('calendar/event_edit', $data));
     $this->main_frame->Load();
 }
 /**
  * @param $Event Event identifier.
  * @return RecurrenceSet,NULL.
  */
 function GetEventRecur(&$Event)
 {
     if (is_numeric($Event)) {
         $CI =& get_instance();
         $RecurrenceInfo = $CI->recurrence_model->SelectRecurByEvent($Event);
         $RecurrenceSet = new RecurrenceSet();
         $RecurrenceSet->SetRecurData($RecurrenceInfo);
         return $RecurrenceSet;
     } else {
         return parent::GetEventRecur($Event);
     }
 }
 static function validate_recurrence_set_data($time_associated, &$start, &$duration, &$simple, &$inex, &$errors)
 {
     $rset = new RecurrenceSet();
     // Start
     if (isset($start['year']) && is_numeric($start['year'])) {
         $start['year'] = (int) $start['year'];
         if ($start['year'] < 1970 or $start['year'] > 2030) {
             $errors[] = array('field' => 'start', 'text' => "Start year out of range.");
         }
     } else {
         $errors[] = array('field' => 'start', 'text' => "Start year missing or invalid.");
     }
     if (isset($start['month']) && is_numeric($start['month'])) {
         $start['month'] = (int) $start['month'];
         if ($start['month'] < 1 or $start['month'] > 12) {
             $errors[] = array('field' => 'start', 'text' => "Start month out of range.");
         }
     } else {
         $errors[] = array('field' => 'start', 'text' => "Start month missing or invalid.");
     }
     if (isset($start['monthday']) && is_numeric($start['monthday'])) {
         $start['monthday'] = (int) $start['monthday'];
         if ($start['monthday'] < 1 or $start['month'] > 31) {
             $errors[] = array('field' => 'start', 'text' => "Start month day out of range.");
         }
     } else {
         $errors[] = array('field' => 'start', 'text' => "Start month day missing or invalid.");
     }
     if ($time_associated) {
         if (isset($start['time'])) {
             $time = split(':', $start['time']);
             if (count($time) != 2) {
                 $errors[] = array('field' => 'start', 'text' => "Start time invalid.");
             } elseif (!is_numeric($time[0]) or !is_numeric($time[1])) {
                 $errors[] = array('field' => 'start', 'text' => 'Start time not correctly numeric.');
             } else {
                 $time[0] = (int) $time[0];
                 $time[1] = (int) $time[1];
                 if ($time[0] < 0 or $time[0] > 24 or $time[1] < 0 or $time[1] > 60) {
                     $errors[] = array('field' => 'start', 'text' => 'Start time out of range.');
                 }
             }
         } else {
             $errors[] = array('field' => 'start', 'text' => "Start month day missing or invalid.");
         }
     } else {
         $time = array(0, 0);
     }
     // Duration
     if (isset($duration['days']) && is_numeric($duration['days'])) {
         $duration['days'] = (int) $duration['days'];
         if ($duration['days'] < 0 or $duration['days'] > 7) {
             $errors[] = array('field' => 'duration', 'text' => "Duration days out of range.");
         }
     } else {
         $errors[] = array('field' => 'duration', 'text' => "Duration days missing or invalid.");
     }
     if ($time_associated) {
         if (isset($duration['time'])) {
             $duration_time = split(':', $duration['time']);
             if (count($duration_time) != 2) {
                 $errors[] = array('field' => 'duration', 'text' => "Duration time invalid.");
             } elseif (!is_numeric($duration_time[0]) or !is_numeric($duration_time[1])) {
                 $errors[] = array('field' => 'duration', 'text' => 'Duration time not correctly numeric.');
             } else {
                 // check time itself is valid
                 $duration_time[0] = (int) $duration_time[0];
                 $duration_time[1] = (int) $duration_time[1];
                 if ($duration_time[0] < 0 or $duration_time[0] > 24 or $duration_time[1] < 0 or $duration_time[1] > 60) {
                     $errors[] = array('field' => 'duration', 'text' => 'Duration time out of range.');
                 }
             }
         } else {
             $errors[] = array('field' => 'duration', 'text' => "Duration time missing or invalid.");
         }
     } else {
         $duration_time = array(0, 0);
     }
     // Set if all seems ok
     if (empty($errors)) {
         $start_ts = mktime($time[0], $time[1], 0, $start['month'], $start['monthday'], $start['year']);
         $end_ts = mktime($duration_time[0], $duration_time[1], 0, $start['month'], $start['monthday'], $start['year']);
         $days_later = $duration['days'];
         if ($duration_time[0] < $time[0] || $duration_time[0] == $time[0] && $duration_time[1] < $time[1]) {
             ++$days_later;
         }
         if ($days_later) {
             $end_ts = strtotime($days_later . 'days', $end_ts);
         }
         if ($start_ts == $end_ts) {
             $errors[] = array('field' => 'duration', 'text' => "Duration of zero not allowed.");
         }
         $rset->SetStartEnd($start_ts, $end_ts);
     } else {
         $rset->SetStartEnd(time(), strtotime('1hour'));
     }
     if ($simple !== NULL) {
         $recur = self::validate_recurrence_rule_data($simple, $errors);
         if ($recur !== NULL) {
             $rset->AddRRules($recur);
         }
     }
     if ($inex !== NULL) {
         $dates = self::validate_inex_dates_data($inex, $errors);
         if ($dates !== NULL) {
             $rset->AddExDates($dates['excludes']);
             $rset->AddRDates($dates['includes']);
         }
     }
     return $rset;
 }