/** * Format an event to comply with the fullcalendar format * @param Event $event */ public static function format_event_for_fullcalendar($event) { $bgColor = '#999'; //default $textColor = '#FFF'; //default $borderColor = '#555'; $arr = array('id' => $event->ID, 'title' => $event->Title, 'start' => self::format_datetime_for_fullcalendar($event->StartDateTime), 'end' => self::format_datetime_for_fullcalendar($event->EndDateTime), 'allDay' => $event->isAllDay(), 'className' => $event->ClassName, 'backgroundColor' => $bgColor, 'textColor' => '#FFFFFF', 'borderColor' => $borderColor); return $arr; }
function query_events($user, $want_repeated, $date_filter, $cat_id = '', $is_task = false) { global $db_connection_info, $jumpdate, $layers, $login, $max_until, $PUBLIC_ACCESS_DEFAULT_VISIBLE, $result, $thismonth, $thisyear; global $OVERRIDE_PUBLIC, $OVERRIDE_PUBLIC_TEXT; // New multiple categories requires some checking to see if this cat_id is // valid for this cal_id. It could be done with nested SQL, // but that may not work for all databases. This might be quicker also. $catlist = $cloneRepeats = $layers_byuser = $result = array(); $sql = 'SELECT DISTINCT( cal_id ) FROM webcal_entry_categories '; // None was selected...return only events without categories. if ($cat_id == -1) { $rows = dbi_get_cached_rows($sql, array()); } elseif (!empty($cat_id)) { $cat_array = explode(',', $cat_id); $placeholders = ''; for ($p_i = 0, $cnt = count($cat_array); $p_i < $cnt; $p_i++) { $placeholders .= $p_i == 0 ? '?' : ', ?'; } $rows = dbi_get_cached_rows($sql . 'WHERE cat_id IN ( ' . $placeholders . ' )', $cat_array); } if (!empty($cat_id)) { // $rows = dbi_get_cached_rows ( $sql, array ( $cat_id ) ); if ($rows) { for ($i = 0, $cnt = count($rows); $i < $cnt; $i++) { $row = $rows[$i]; $catlist[$i] = $row[0]; } } } $catlistcnt = count($catlist); $query_params = array(); $sql = 'SELECT we.cal_name, we.cal_description, we.cal_date, we.cal_time, we.cal_id, we.cal_ext_for_id, we.cal_priority, we.cal_access, we.cal_duration, weu.cal_status, we.cal_create_by, weu.cal_login, we.cal_type, we.cal_location, we.cal_url, we.cal_due_date, we.cal_due_time, weu.cal_percent, we.cal_mod_date, we.cal_mod_time ' . ($want_repeated ? ', wer.cal_type, wer.cal_end, wer.cal_frequency, wer.cal_days, wer.cal_bymonth, wer.cal_bymonthday, wer.cal_byday, wer.cal_bysetpos, wer.cal_byweekno, wer.cal_byyearday, wer.cal_wkst, wer.cal_count, wer.cal_endtime FROM webcal_entry we, webcal_entry_repeats wer, webcal_entry_user weu WHERE we.cal_id = wer.cal_id AND ' : 'FROM webcal_entry we, webcal_entry_user weu WHERE ') . 'we.cal_id = weu.cal_id AND weu.cal_status IN ( \'A\',\'W\' ) '; if ($catlistcnt > 0) { $placeholders = ''; for ($p_i = 0; $p_i < $catlistcnt; $p_i++) { $placeholders .= $p_i == 0 ? '?' : ', ?'; $query_params[] = $catlist[$p_i]; } if ($cat_id > 0) { $sql .= 'AND we.cal_id IN ( ' . $placeholders . ' ) '; } elseif ($cat_id == -1) { // Eliminate events with categories. $sql .= 'AND we.cal_id NOT IN ( ' . $placeholders . ' ) '; } } else { if (!empty($cat_id)) { // Force no rows to be returned. No matching entries in category. $sql .= 'AND 1 = 0 '; } } $sql .= 'AND we.cal_type IN ' . ($is_task == false ? '( \'E\',\'M\' ) ' : '( \'N\',\'T\' ) AND ( we.cal_completed IS NULL ) ') . (strlen($user) > 0 ? 'AND ( weu.cal_login = ? ' : ''); $query_params[] = $user; if ($user == $login && strlen($user) > 0 && $layers) { foreach ($layers as $layer) { $layeruser = $layer['cal_layeruser']; $sql .= 'OR weu.cal_login = ? '; $query_params[] = $layeruser; // While we are parsing the whole layers array, build ourselves // a new array that will help when we have to check for dups. $layers_byuser[$layeruser] = $layer['cal_dups']; } } $rows = dbi_get_cached_rows($sql . ($user == $login && strlen($user) && $PUBLIC_ACCESS_DEFAULT_VISIBLE == 'Y' ? 'OR weu.cal_login = \'__public__\' ' : '') . (strlen($user) > 0 ? ') ' : '') . $date_filter . (!$is_task ? ' ORDER BY we.cal_time, we.cal_name' : ''), $query_params); if ($rows) { $i = 0; $checkdup_id = $first_i_this_id = -1; for ($ii = 0, $cnt = count($rows); $ii < $cnt; $ii++) { $row = $rows[$ii]; if ($row[9] == 'D' || $row[9] == 'R') { continue; } // Don't show deleted/rejected ones. // Get primary category for this event, used for icon and color. $categories = get_categories_by_id($row[4], $user); $cat_keys = array_keys($categories); $primary_cat = empty($cat_keys[0]) ? '' : $cat_keys[0]; if ($login == '__public__' && !empty($OVERRIDE_PUBLIC) && $OVERRIDE_PUBLIC == 'Y') { $evt_name = $OVERRIDE_PUBLIC_TEXT; $evt_descr = $OVERRIDE_PUBLIC_TEXT; } else { $evt_name = $row[0]; $evt_descr = $row[1]; } if ($want_repeated && !empty($row[20])) { // row[20] = cal_type $item = new RepeatingEvent($evt_name, $evt_descr, $row[2], $row[3], $row[4], $row[5], $row[6], $row[7], $row[8], $row[9], $row[10], $primary_cat, $row[11], $row[12], $row[13], $row[14], $row[15], $row[16], $row[17], $row[18], $row[19], $row[20], $row[21], $row[22], $row[23], $row[24], $row[25], $row[26], $row[27], $row[28], $row[29], $row[30], $row[31], $row[32], array(), array(), array()); } else { $item = new Event($evt_name, $evt_descr, $row[2], $row[3], $row[4], $row[5], $row[6], $row[7], $row[8], $row[9], $row[10], $primary_cat, $row[11], $row[12], $row[13], $row[14], $row[15], $row[16], $row[17], $row[18], $row[19]); } if ($item->getID() != $checkdup_id) { $checkdup_id = $item->getID(); $first_i_this_id = $i; } if ($item->getLogin() == $user) { // Insert this one before all other ones with this ID. array_splice($result, $first_i_this_id, 0, array($item)); $i++; if ($first_i_this_id + 1 < $i) { // There's another one with the same ID as the one we inserted. // Check for dup and if so, delete it. $other_item = $result[$first_i_this_id + 1]; if (!empty($layers_byuser[$other_item->getLogin()]) && $layers_byuser[$other_item->getLogin()] == 'N') { // NOTE: array_splice requires PHP4 array_splice($result, $first_i_this_id + 1, 1); $i--; } } } else { if ($i == $first_i_this_id || !empty($layers_byuser[$item->getLogin()]) && $layers_byuser[$item->getLogin()] != 'N') { // This item either is the first one with its ID, or allows dups. // Add it to the end of the array. $result[$i++] = $item; } } // Does event go past midnight? if (date('Ymd', $item->getDateTimeTS()) != date('Ymd', $item->getEndDateTimeTS()) && !$item->isAllDay() && $item->getCalTypeName() == 'event') { getOverLap($item, $i, true); $i = count($result); } } } if ($want_repeated) { // Now load event exceptions/inclusions and store as array. // TODO: Allow passing this max_until as param in case we create // a custom report that shows N years of events. if (empty($max_until)) { $max_until = mktime(0, 0, 0, $thismonth + 2, 1, $thisyear); } for ($i = 0, $resultcnt = count($result); $i < $resultcnt; $i++) { if ($result[$i]->getID() != '') { $rows = dbi_get_cached_rows('SELECT cal_date, cal_exdate FROM webcal_entry_repeats_not WHERE cal_id = ?', array($result[$i]->getID())); for ($ii = 0, $rowcnt = count($rows); $ii < $rowcnt; $ii++) { $row = $rows[$ii]; // If this is not a clone, add exception date. if (!$result[$i]->getClone()) { $except_date = $row[0]; } if ($row[1] == 1) { $result[$i]->addRepeatException($except_date, $result[$i]->getID()); } else { $result[$i]->addRepeatInclusion($except_date); } } // Get all dates for this event. // If clone, we'll get the dates from parent later. if (!$result[$i]->getClone()) { $until = $result[$i]->getRepeatEndDateTimeTS() ? $result[$i]->getRepeatEndDateTimeTS() : $max_until; // Try to minimize the repeat search by shortening // until if BySetPos is not used. if (!$result[$i]->getRepeatBySetPos() && $until > $max_until) { $until = $max_until; } $rpt_count = 999; //Some BIG number. // End date... for year view and some reports we need whole year... // So, let's do up to 365 days after current month. // TODO: Add this end time as a parameter in case someone creates // a custom report that asks for N years of events. // $jump = mktime ( 0, 0, 0, $thismonth -1, 1, $thisyear); if ($result[$i]->getRepeatCount()) { $rpt_count = $result[$i]->getRepeatCount() - 1; } $date = $result[$i]->getDateTimeTS(); if ($result[$i]->isAllDay() || $result[$i]->isUntimed()) { $date += 43200; } //A simple hack to prevent DST problems. // TODO get this to work // C heck if this event id has been cached. // $file = ''; // if ( ! empty ( $db_connection_info['cachedir'] ) ){ // $hash = md5 ( $result[$i]->getId () . $until . $jump ); // $file = $db_connection_info['cachedir'] . '/' . $hash . '.dat'; // } // if ( file_exists ( $file ) ) { // $dates = unserialize ( file_get_contents ( $file ) ); // } else { $dates = get_all_dates($date, $result[$i]->getRepeatType(), $result[$i]->getRepeatFrequency(), array($result[$i]->getRepeatByMonth(), $result[$i]->getRepeatByWeekNo(), $result[$i]->getRepeatByYearDay(), $result[$i]->getRepeatByMonthDay(), $result[$i]->getRepeatByDay(), $result[$i]->getRepeatBySetPos()), $rpt_count, $until, $result[$i]->getRepeatWkst(), $result[$i]->getRepeatExceptions(), $result[$i]->getRepeatInclusions(), $jumpdate); $result[$i]->addRepeatAllDates($dates); // Serialize and save in cache for later use. // if ( ! empty ( $db_connection_info['cachedir'] ) ) { // $fd = @fopen ( $file, 'w+b', false ); // if ( empty ( $fd ) ) { // dbi_fatal_error ( "Cache error: could not write file $file" ); // } // fwrite ( $fd, serialize ( $dates ) ); // fclose ( $fd ); // chmod ( $file, 0666 ); // } // } } else { // Process clones if any. if (count($result[$i - 1]->getRepeatAllDates()) > 0) { $parentRepeats = $result[$i - 1]->getRepeatAllDates(); $cloneRepeats = array(); for ($j = 0, $parentRepeatscnt = count($parentRepeats); $j < $parentRepeatscnt; $j++) { $cloneRepeats[] = gmdate('Ymd', date_to_epoch($parentRepeats[$j]) + ONE_DAY); } $result[$i]->addRepeatAllDates($cloneRepeats); } } } } } return $result; }