function get_tasks_gantt(&$tasks, $project_id, $project_start, $project_end, $parent_id = 0, $depth = 0, $show_actual = 0) { global $config; $id_user = $config["id_user"]; $result = mysql_query('SELECT * FROM ttask WHERE id_parent_task = ' . $parent_id . ' AND id_project = ' . $project_id); if ($result === false) { return; } while ($row = mysql_fetch_array($result)) { // ACL Check for this task // This user can see this task? $task_access = get_project_access($config["id_user"], $project_id, $row['id'], false, true); if ($task_access["read"]) { $task['id'] = $row['id']; $task['name'] = $row['name']; if ($show_actual) { $task["name"] .= " (" . __("Planned") . ")"; } $task['parent'] = $parent_id; $task['link'] = 'index.php?sec=projects&sec2=operation/projects/task_detail&id_project=' . $project_id . '&id_task=' . $row['id'] . '&operation=view'; // start > end $task['start'] = fix_date($row['start'], $project_start); $task['end'] = fix_date($row['end'], $project_end); if (date_to_epoch($task['start']) > date_to_epoch($task['end'])) { $temp = $task['start']; $task['start'] = $task['end']; $task['end'] = $temp; } $task['real_start'] = fix_date(get_db_sql('SELECT MIN(timestamp) FROM tworkunit, tworkunit_task WHERE tworkunit_task.id_workunit = tworkunit.id AND timestamp <> \'0000-00-00 00:00:00\' AND id_task = ' . $row['id']), $task['start']); $task['real_end'] = fix_date(get_db_sql('SELECT MAX(timestamp) FROM tworkunit, tworkunit_task WHERE tworkunit_task.id_workunit = tworkunit.id AND timestamp <> \'0000-00-00 00:00:00\' AND id_task = ' . $row['id']), $task['start']); $task['completion'] = $row['completion']; $task["actual_data"] = 0; $task["worked_hours"] = get_task_workunit_hours($row["id"]); $task["hours"] = $row["hours"]; array_push($tasks, $task); //Add another task to represent real effort for the task if ($show_actual) { $task_aux = array(); $task_aux["id"] = $task["id"] . "act"; $task_aux["actual_data"] = 1; $task_aux["parent"] = $task["parent"]; if ($task['real_start']) { $task_aux["start"] = $task['real_start']; } else { $task_aux["start"] = $task['start']; } if ($task['real_end']) { $task_aux["end"] = $task['real_end']; } else { $task_aux["end"] = $task['start']; } $task_aux["completion"] = 0; $task_aux["name"] = $row["name"] . " (" . __("Actual") . ")"; array_push($tasks, $task_aux); } get_tasks_gantt(&$tasks, $project_id, $project_start, $project_end, $task['id'], $depth + 1, $show_actual); } } }
function export_pilot_csv($id) { /* to be imported to a Palm with: * pilot-datebook -r csv -f webcalendar-export.txt -w hotsync */ $res = export_get_event_entry($id); echo "uid,attributes,category,untimed,beginDate,beginTime,endDate,endTime,description,note,alarm,advance,advanceUnit,repeatType,repeatForever,repeatEnd,repeatFrequency,repeatDay,repeatWeekdays,repeatWeekstart\n"; while ($row = dbi_fetch_row($res)) { // uid (long) echo $row[0], ','; // attributes (int) // 128 = 0x80 : Deleted // 64 = 0x40 : Dirty // 32 = 0x20 : Busy // 16 = 0x10 : Secret/Private echo $row[7] == 'R' ? '16,' : '0,'; // category (int: 0=Unfiled) echo '0,'; // untimed (int: 0=Appointment, 1=Untimed) // note: Palm "Untimed" is WebCalendar "AllDay" if ($row[4] < 0) { echo '1,', substr($row[3], 0, 4), '-', substr($row[3], 4, 2), '-', substr($row[3], 6, 2), ',00:00:00,', substr($row[3], 0, 4), '-', substr($row[3], 4, 2), '-', substr($row[3], 6, 2), ',00:00:00,'; } else { echo '0,', pilot_date_time($row[3], $row[4], 0, ','), ',', pilot_date_time($row[3], $row[4], $row[8], ','), ','; //endDate,endTime } //end if ( $row[4] < 0 ) // description (str) echo '"', preg_replace("/\r?\n/", "\\n", $row[1]), '",'; // note (str) echo '"', preg_replace("/\r?\n/", "\\n", $row[9]), '",'; // alarm, advance, advanceUnit // alarm (int: 0=no alarm, 1=alarm) // FIXME: verify if WebCal. DB interpreted correctly // advance (int), advanceUnit (int: 0=minutes, 1=hours, 2=days) // FIXME: better adjust unit $ext = get_cal_ent_extras($row[0], 'webcal_site_extras', "cal_name = 'Reminder' AND cal_remind = 1"); if ($ext) { echo '1,', $ext[5], ',0,'; } else { echo '0,0,0,'; } // repeat: // repeatType (int: 0=none, 1=daily, 2=weekly, 3=monthly, 4=monthly/weekday, // repeatForever (int: 0=not forever, 1=forever) 5=yearly) // repeatEnd (time) // repeatFrequency (int) // repeatDay (int: day# or 0..6=Sun..Sat 1st, 7..13 2nd, 14..20 3rd, // 21..27 4th, 28-34 last week) // repeatWeekdays (int: add - 1=Sun,2=Mon,4=Tue,8=Wed,16=Thu,32=Fri,64=Sat) // repeatWeekstart (int) $ext = get_cal_ent_extras($row[0], 'webcal_entry_repeats'); if ($ext) { switch ($ext[1]) { case 'daily': $repType = 1; break; case 'weekly': $repType = 2; break; case 'monthlyByDate': $repType = 3; break; case 'monthlyByDay': $repType = 4; break; case 'yearly': $repType = 5; break; default: $repType = 0; } } else { $repType = 0; } if ($repType) { echo $repType, ','; // repeatType if ($ext[2]) { echo '0,', substr($ext[2], 0, 4), '-', substr($ext[2], 4, 2), '-', substr($ext[2], 6, 2), ' 00:00:00,'; } else { echo '1,,'; } // repeatForever,repeatEnd echo $ext[3], ','; // repeatFrequency switch ($repType) { case 2: // weekly echo '0,', bindec(strtr(strrev($ext[4]), 'yn', '10')), ",1\n"; break; case 3: // monthly/weekday // repeatDay (0..6=Sun..Sat 1st, 7..13 2nd, 14..20 3rd, // 21..27 4th, 28-34 last week) echo floor(substr($row[3], 6, 2) / 7) * 7 + date('w', date_to_epoch($row[3])), ",0,0\n"; break; case 1: // daily // daily case 4: // monthly // monthly case 5: // yearly echo "0,0,0\n"; } //end switch } else { echo "0,0,,0,0,0,0\n"; } } //end if ( $repType ) }
function repeated_event_matches_date($event, $dateYmd) { // only repeat after the beginning, and if there is an end // before the end $date = date_to_epoch($dateYmd); $thisyear = substr($dateYmd, 0, 4); $start = date_to_epoch($event['cal_date']); $end = date_to_epoch($event['cal_end']); $freq = $event['cal_frequency']; $thismonth = substr($dateYmd, 4, 2); if ($event['cal_end'] && $dateYmd > date("Ymd", $end)) { return false; } if ($dateYmd <= date("Ymd", $start)) { return false; } $id = $event['cal_id']; if ($event['cal_type'] == 'daily') { if (floor(($date - $start) / 86400) % $freq) { return false; } return true; } else { if ($event['cal_type'] == 'weekly') { $dow = date("w", $date); $dow1 = date("w", $start); $isDay = substr($event['cal_days'], $dow, 1); $wstart = $start - $dow1 * 86400; if (floor(($date - $wstart) / 604800) % $freq) { return false; } if (strcmp($isDay, "y") == 0) { return true; } } else { if ($event['cal_type'] == 'monthlyByDay') { $dowS = date("w", $start); $dayS = ceil(date("d", $start) / 7); $mthS = date("m", $start); $yrS = date("Y", $start); $dow = date("w", $date); $day = ceil(date("d", $date) / 7); $mth = date("m", $date); $yr = date("Y", $date); if ((($yr - $yrS) * 12 + $mth - $mthS) % $freq) { return false; } if ($dowS == $dow && $day == $dayS) { return true; } } else { if ($event['cal_type'] == 'monthlyByDate') { $mthS = date("m", $start); $yrS = date("Y", $start); $mth = date("m", $date); $yr = date("Y", $date); if ((($yr - $yrS) * 12 + $mth - $mthS) % $freq) { return false; } if (date("d", $date) == date("d", $start)) { return true; } } else { if ($event['cal_type'] == 'yearly') { $yrS = date("Y", $start); $yr = date("Y", $date); if (($yr - $yrS) % $freq) { return false; } if (date("dm", $date) == date("dm", $start)) { return true; } } else { // unknown repeat type return false; } } } } } }
function list_unapproved($user) { global $login, $SERVER_URL; $count = 0; $ret = ''; $sql = 'SELECT we.cal_id, we.cal_name, we.cal_description, weu.cal_login, we.cal_priority, we.cal_date, we.cal_time, we.cal_duration, weu.cal_status, we.cal_type FROM webcal_entry we, webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND weu.cal_login = ? AND weu.cal_status = \'W\' ORDER BY weu.cal_login, we.cal_date'; $rows = dbi_get_cached_rows($sql, array($user)); if ($rows) { $allDayStr = translate('All day event'); $appConStr = translate('Approve/Confirm'); $appSelStr = translate('Approve Selected'); $checkAllStr = translate('Check All'); $deleteStr = translate('Delete'); $emailStr = translate('Emails Will Not Be Sent'); $rejectSelStr = translate('Reject Selected'); $rejectStr = translate('Reject'); $uncheckAllStr = translate('Uncheck All'); $viewStr = translate('View this entry'); for ($i = 0, $cnt = count($rows); $i < $cnt; $i++) { $row = $rows[$i]; $id = $row[0]; $name = $row[1]; $description = $row[2]; $cal_user = $row[3]; $pri = $row[4]; $date = $row[5]; $time = sprintf("%06d", $row[6]); $duration = $row[7]; $status = $row[8]; $type = $row[9]; $view_link = 'view_entry'; $entryID = 'entry' . $type . $id; $unixtime = date_to_epoch($date . $time); $timestr = ''; if ($time > 0 || $time == 0 && $duration != 1440) { $eventstart = date_to_epoch($date . $time); $eventstop = $eventstart + $duration; $eventdate = date_to_str(date('Ymd', $eventstart)); $timestr = display_time('', 0, $eventstart) . ($duration > 0 ? ' - ' . display_time('', 0, $eventstop) : ''); } else { // Don't shift date if All Day or Untimed. $eventdate = date_to_str($date); // If All Day display in popup. if ($time == 0 && $duration == 1440) { $timestr = $allDayStr; } } $ret .= "<item>\n" . ' <title><![CDATA[' . htmlspecialchars($name) . ']]></title>' . "\n <link>" . $SERVER_URL . $view_link . '.php?id=' . $id . '&user='******' <description><![CDATA[' . $description . ']]></description>' . "\n"; $ret .= ' <category><![CDATA[' . $category . ']]></category>' . "\n"; /* RSS 2.0 date format Wed, 02 Oct 2002 13:00:00 GMT */ $ret .= '<pubDate>' . gmdate('D, d M Y H:i:s', $unixtime) . ' GMT</pubDate>' . "\n" . ' <guid>' . $SERVER_URL . 'view_entry.php?id=' . $id . '&friendly=1&rssuser='******'&date=' . $d . "</guid>\n"; $ret .= "</item>\n\n"; } } return $ret; }
// but not if we are overriding a single entry of an already repeating // event... confusing, eh? if (!empty($override)) { $rpt_type = "none"; $rpt_end = 0; $rpt_end_date = $cal_date; $rpt_freq = 1; $rpt_days = "nnnnnnn"; $rpt_sun = $rpt_mon = $rpt_tue = $rpt_wed = $rpt_thu = $rpt_fri = $rpt_sat = false; } else { $res = dbi_query("SELECT cal_id, cal_type, cal_end, " . "cal_frequency, cal_days FROM webcal_entry_repeats " . "WHERE cal_id = {$id}"); if ($res) { if ($row = dbi_fetch_row($res)) { $rpt_type = $row[1]; if ($row[2] > 0) { $rpt_end = date_to_epoch($row[2]); } else { $rpt_end = 0; } $rpt_end_date = $row[2]; $rpt_freq = $row[3]; $rpt_days = $row[4]; $rpt_sun = substr($rpt_days, 0, 1) == 'y'; $rpt_mon = substr($rpt_days, 1, 1) == 'y'; $rpt_tue = substr($rpt_days, 2, 1) == 'y'; $rpt_wed = substr($rpt_days, 3, 1) == 'y'; $rpt_thu = substr($rpt_days, 4, 1) == 'y'; $rpt_fri = substr($rpt_days, 5, 1) == 'y'; $rpt_sat = substr($rpt_days, 6, 1) == 'y'; } }
function rss_activity_log($sys, $entries) { global $SERVER_URL, $login; $sql_params = array(); $limit = $where = ''; switch ($GLOBALS['db_type']) { case 'mysqli': case 'mysql': case 'postgresql': $limit .= ' LIMIT ' . $entries; break; case 'oracle': $where .= ' AND ROWNUM <= ' . $entries; break; } $sql = 'SELECT wel.cal_login, wel.cal_user_cal, wel.cal_type, wel.cal_date, wel.cal_time, wel.cal_text, ' . ($sys ? 'wel.cal_log_id FROM webcal_entry_log wel WHERE wel.cal_entry_id = 0' : 'we.cal_id, we.cal_name, wel.cal_log_id, we.cal_type, we.cal_description FROM webcal_entry_log wel, webcal_entry we WHERE wel.cal_entry_id = we.cal_id' . $where) . ' ORDER BY wel.cal_log_id DESC' . $limit; $rows = dbi_get_cached_rows($sql, $sql_params); $ret = ''; for ($i = 0; $i < count($rows) && $i < $entries; $i++) { $row = $rows[$i]; $num = 0; $l_login = $row[0]; $l_user = $row[1]; $l_type = $row[2]; $l_date = $row[3]; $l_time = $row[4]; $l_text = $row[5]; if ($sys) { $l_id = $row[6]; $l_description = ''; } else { $l_eid = $row[6]; $l_ename = $row[7]; $l_id = $row[8]; $l_etype = $row[9]; $l_description = $row[10]; // convert lines to <br> if no HTML formatting found if (strpos($l_description, "</") == false) { $l_description = nl2br($l_description); } } $num++; $unixtime = date_to_epoch($l_date . $l_time); $subject = display_activity_log($l_type, $l_text, "\n"); $ret .= "<item>\n" . ' <title><![CDATA[' . $subject . ': ' . htmlspecialchars($l_ename) . ']]></title>' . "\n <link>" . $SERVER_URL . 'view_entry.php?id=' . $l_eid . "</link>\n" . ' <description><![CDATA[' . $l_description . ']]></description>' . "\n"; //$ret .= // ' <category><![CDATA[' . $category . ']]></category>' . "\n"; /* RSS 2.0 date format Wed, 02 Oct 2002 13:00:00 GMT */ $ret .= '<pubDate>' . gmdate('D, d M Y H:i:s', $unixtime) . ' GMT</pubDate>' . "\n" . ' <guid>' . $SERVER_URL . 'view_entry.php?id=' . $l_eid . '&friendly=1&rssuser='******'&date=' . $l_date . "</guid>\n"; $ret .= "</item>\n\n"; } return $ret; }
$enddate = getValue('enddate'); if (empty($startdate)) { $startdate = date('Ymd'); } if (empty($enddate)) { $enddate = $startdate; } // Now read all the repeating events (for all users). $repeated_events = query_events($user, true, 'AND ( wer.cal_end > ' . $startdate . ' OR wer.cal_end IS NULL ) '); // Read non-repeating events (for all users). if ($WS_DEBUG) { $out .= ' <!-- ' . str_replace('XXX', array($user, $startdate, $enddate), translate('Checking for events for XXX from date XXX to date XXX.')) . ' --> '; } $events = read_events($user, date_to_epoch($startdate), date_to_epoch($enddate)); if ($WS_DEBUG) { $out .= ' <!-- ' . str_replace('XXX', count($events), translate('Found XXX events in time range.')) . ' --> '; } /* Process an event for a single day. Check to see if it has a reminder, * when it needs to be sent and when the last time it was sent. */ function process_event($id, $name, $event_date, $event_time) { global $out, $WS_DEBUG; if ($WS_DEBUG) { ws_log_message(str_replace('XXX', array($id, $name, $event_time, $event_date), translate('Event id=XXX XXX at XXX on XXX.'))); } return ws_print_event_xml($id, $event_date);
function repeated_event_matches_date($event, $dateYmd) { global $days_per_month, $ldays_per_month, $ONE_DAY; // only repeat after the beginning, and if there is an end // before the end $date = date_to_epoch($dateYmd); $thisyear = substr($dateYmd, 0, 4); $start = date_to_epoch($event['cal_date']); $end = date_to_epoch($event['cal_end']); $freq = $event['cal_frequency']; $thismonth = substr($dateYmd, 4, 2); if ($event['cal_end'] && $dateYmd > date("Ymd", $end)) { return false; } if ($dateYmd <= date("Ymd", $start)) { return false; } $id = $event['cal_id']; if ($event['cal_type'] == 'daily') { if (floor(($date - $start) / $ONE_DAY) % $freq) { return false; } return true; } else { if ($event['cal_type'] == 'weekly') { $dow = date("w", $date); $dow1 = date("w", $start); $isDay = substr($event['cal_days'], $dow, 1); $wstart = $start - $dow1 * $ONE_DAY; if (floor(($date - $wstart) / 604800) % $freq) { return false; } return strcmp($isDay, "y") == 0; } else { if ($event['cal_type'] == 'monthlyByDay') { $dowS = date("w", $start); $dow = date("w", $date); // do this comparison first in hopes of best performance if ($dowS != $dow) { return false; } $mthS = date("m", $start); $yrS = date("Y", $start); $dayS = floor(date("d", $start)); $dowS1 = (date("w", $start - $ONE_DAY * ($dayS - 1)) + 35) % 7; $days_in_first_weekS = (7 - $dowS1) % 7; $whichWeekS = floor(($dayS - $days_in_first_weekS) / 7); if ($dowS >= $dowS1 && $days_in_first_weekS) { $whichWeekS++; } //echo "dayS=$dayS;dowS=$dowS;dowS1=$dowS1;wWS=$whichWeekS<br />\n"; $mth = date("m", $date); $yr = date("Y", $date); $day = date("d", $date); $dow1 = (date("w", $date - $ONE_DAY * ($day - 1)) + 35) % 7; $days_in_first_week = (7 - $dow1) % 7; $whichWeek = floor(($day - $days_in_first_week) / 7); if ($dow >= $dow1 && $days_in_first_week) { $whichWeek++; } //echo "day=$day;dow=$dow;dow1=$dow1;wW=$whichWeek<br />\n"; if ((($yr - $yrS) * 12 + $mth - $mthS) % $freq) { return false; } return $whichWeek == $whichWeekS; } else { if ($event['cal_type'] == 'monthlyByDayR') { $dowS = date("w", $start); $dow = date("w", $date); // do this comparison first in hopes of best performance if ($dowS != $dow) { return false; } $dayS = ceil(date("d", $start)); $mthS = ceil(date("m", $start)); $yrS = date("Y", $start); $daysthismonthS = $mthS % 4 == 0 ? $ldays_per_month[$mthS] : $days_per_month[$mthS]; $whichWeekS = floor(($daysthismonthS - $dayS) / 7); $day = ceil(date("d", $date)); $mth = ceil(date("m", $date)); $yr = date("Y", $date); $daysthismonth = $mth % 4 == 0 ? $ldays_per_month[$mth] : $days_per_month[$mth]; $whichWeek = floor(($daysthismonth - $day) / 7); if ((($yr - $yrS) * 12 + $mth - $mthS) % $freq) { return false; } return $whichWeekS == $whichWeek; } else { if ($event['cal_type'] == 'monthlyByDate') { $mthS = date("m", $start); $yrS = date("Y", $start); $mth = date("m", $date); $yr = date("Y", $date); if ((($yr - $yrS) * 12 + $mth - $mthS) % $freq) { return false; } return date("d", $date) == date("d", $start); } else { if ($event['cal_type'] == 'yearly') { $yrS = date("Y", $start); $yr = date("Y", $date); if (($yr - $yrS) % $freq) { return false; } return date("dm", $date) == date("dm", $start); } else { // unknown repeat type return false; } } } } } } return false; }
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; }
echo '[' . translate('Confidential') . ']</td> </tr>'; } else { if (access_is_enabled()) { $can_email = access_user_calendar('email', $create_by); } $pubAccStr = $row[0] == '__public__' ? translate('Public Access') : $createby_fullname; echo (strlen($email_addr) && $can_email != 'N' ? '<a href="mailto:' . $email_addr . '?subject=' . $subject . '">' . $pubAccStr . '</a>' : $pubAccStr) . $proxy_fullname . '</td> </tr>'; } } } echo ' <tr> <td class="aligntop bold">' . translate('Updated') . ':</td> <td>' . (!empty($GENERAL_USE_GMT) && $GENERAL_USE_GMT == 'Y' ? date_to_str($mod_date) . ' ' . display_time($mod_date . $mod_time, 3) : date_to_str(date('Ymd', date_to_epoch($mod_date . $mod_time))) . ' ' . display_time($mod_date . $mod_time, 2)) . '</td> </tr>' . (!empty($reminder) ? ' <tr> <td class="aligntop bold">' . translate('Send Reminder') . ':</td> <td>' . $reminder . '</td> </tr>' : ''); // load any site-specific fields and display them $extras = get_site_extra_fields($id); $site_extracnt = count($site_extras); for ($i = 0; $i < $site_extracnt; $i++) { if ($site_extras[$i] == 'FIELDSET') { continue; } $extra_name = $site_extras[$i][0]; $extra_type = $site_extras[$i][2]; $extra_arg1 = $site_extras[$i][3];
function fs_gantt_chart($title, $from, $to, $tasks, $milestones, $width, $height) { // Generate the XML $chart = new FusionCharts("Gantt", $width, $height, "1", "0"); $chart->setSWFPath("include/graphs/FusionCharts/"); $chart->setChartParams('dateFormat=dd/mm/yyyy;hoverCapBorderColor=2222ff;hoverCapBgColor=e1f5ff;ganttLineAlpha=80;canvasBorderColor=024455;canvasBorderThickness=0;gridBorderColor=2179b1;gridBorderAlpha=20;ganttWidthPercent=80'); $chart->setGanttProcessesParams('headerText=' . __('Task') . ';fontColor=ffffff;fontSize=9;isBold=1;isAnimated=1;bgColor=2179b1;headerbgColor=2179b1;headerFontColor=ffffff;headerFontSize=12;align=left'); $chart->setGanttTasksParams(''); $start_date = explode('/', $from); $start_day = $start_date[0]; $start_month = $start_date[1]; $start_year = $start_date[2]; $end_date = explode('/', $to); $end_day = $end_date[0]; $end_month = $end_date[1]; $end_year = $end_date[2]; $time_span = date_to_epoch($to) - date_to_epoch($from); // Years $chart->addGanttCategorySet('bgColor=2179b1;fontColor=ff0000'); for ($i = $start_year; $i <= $end_year; $i++) { if ($i == $start_year) { $start = sprintf('%02d/%02d/%04d', $start_day, $start_month, $start_year); } else { $start = sprintf('%02d/%02d/%04d', 1, 1, $i); } if ($i == $end_year) { $end = sprintf('%02d/%02d/%04d', $end_day, $end_month, $end_year); } else { $end = sprintf('%02d/%02d/%04d', cal_days_in_month(CAL_GREGORIAN, 12, $i), 12, $i); } $chart->addGanttCategory($i, ';start=' . $start . ';end=' . $end . ';align=center;fontColor=ffffff;isBold=1;fontSize=16'); } // Months $chart->addGanttCategorySet('bgColor=ffffff;fontColor=1288dd;fontSize=10'); for ($i = $start_year; $i <= $end_year; $i++) { for ($j = 1; $j <= 12; $j++) { if ($i == $start_year && $j < $start_month) { continue; } else { if ($i == $end_year && $j > $end_month) { break; } } if ($i == $start_year && $j == $start_month) { $start = sprintf('%02d/%02d/%04d', $start_day, $start_month, $start_year); } else { $start = sprintf('%02d/%02d/%04d', 1, $j, $i); } if ($i == $end_year && $j == $end_month) { $end = sprintf('%02d/%02d/%04d', $end_day, $end_month, $end_year); } else { $end = sprintf('%02d/%02d/%04d', cal_days_in_month(CAL_GREGORIAN, $j, $i), $j, $i); } $chart->addGanttCategory(date('F', mktime(0, 0, 0, $j, 1)), ';start=' . $start . ';end=' . $end . ';align=center;isBold=1'); } } // Days if ($time_span < 2592000) { $chart->addGanttCategorySet(); for ($i = $start_year; $i <= $end_year; $i++) { for ($j = 1; $j <= 12; $j++) { if ($i == $start_year && $j < $start_month) { continue; } else { if ($i == $end_year && $j > $end_month) { break; } } $num_days = cal_days_in_month(CAL_GREGORIAN, $j, $i); for ($k = 1; $k <= $num_days; $k++) { if ($i == $start_year && $j == $start_month && $k < $start_day) { continue; } else { if ($i == $end_year && $j == $end_month && $k > $end_day) { break; } } $start = sprintf('%02d/%02d/%04d', $k, $j, $i); $end = sprintf('%02d/%02d/%04d', $k, $j, $i); $chart->addGanttCategory($k, ';start=' . $start . ';end=' . $end . ';fontSize=8;isBold=0'); } } } } else { if ($time_span < 10368000) { $chart->addGanttCategorySet(); for ($i = $start_year; $i <= $end_year; $i++) { for ($j = 1; $j <= 12; $j++) { if ($i == $start_year && $j < $start_month) { continue; } else { if ($i == $end_year && $j > $end_month) { break; } } $num_days = cal_days_in_month(CAL_GREGORIAN, $j, $i); for ($k = 1, $l = 1; $k <= $num_days; $k += 8, $l++) { if ($i == $start_year && $j == $start_month && $k + 7 < $start_day) { continue; } if ($i == $end_year && $j == $end_month && $k > $end_day) { break; } if ($i == $start_year && $j == $start_month && $k < $start_day) { $start = sprintf('%02d/%02d/%04d', $start_day, $j, $i); } else { $start = sprintf('%02d/%02d/%04d', $k, $j, $i); } if ($i == $end_year && $j == $end_month && $k + 7 > $end_day) { $end = sprintf('%02d/%02d/%04d', $end_day, $j, $i); } else { if ($k + 7 > $num_days) { $end = sprintf('%02d/%02d/%04d', $num_days, $j, $i); } else { $end = sprintf('%02d/%02d/%04d', $k + 7, $j, $i); } } $chart->addGanttCategory(__('Week') . " {$l}", ';start=' . $start . ';end=' . $end . ';fontSize=8;isBold=0'); } } } } } // Tasks foreach ($tasks as $task) { $chart->addGanttProcess(clean_flash_string($task['name']), 'id=' . $task['id'] . ';link=' . urlencode($task['link'])); $chart->addGanttTask(__('Planned'), 'start=' . $task['start'] . ';end=' . $task['end'] . ';id=' . $task['id'] . ';processId=' . $task['id'] . ';color=4b3cff;height=5;topPadding=10;animation=0'); if ($task['real_start'] !== false && $task['real_end']) { $chart->addGanttTask(__('Actual'), 'start=' . $task['real_start'] . ';end=' . $task['real_end'] . ';processId=' . $task['id'] . ';color=ff3c4b;alpha=100;topPadding=15;height=5'); } if ($task['completion'] != 0) { $task_span = date_to_epoch($task['end']) - date_to_epoch($task['start']); $end = date('d/m/Y', date_to_epoch($task['start']) + $task_span * $task['completion'] / 100.0); $chart->addGanttTask(__('Completion') . " (" . $task['completion'] . ")", 'start=' . $task['start'] . ';end=' . $end . ';processId=' . $task['id'] . ';color=32cd32;alpha=100;topPadding=20;height=5'); } if ($task['parent'] != 0) { $chart->addGanttConnector($task['parent'], $task['id'], 'color=2179b1;thickness=2;fromTaskConnectStart=1'); } } // Milestones if ($milestones !== '') { $chart->addGanttProcess(__('Milestones'), 'id=0'); foreach ($milestones as $milestone) { $chart->addGanttTask(clean_flash_string($milestone['name']), 'start=' . $milestone['date'] . ';end=' . $milestone['date'] . ';id=ms-' . $milestone['id'] . ';processId=0;color=ffffff;alpha=0;height=60;topPadding=0;animation=0'); $chart->addGanttMilestone('ms-' . $milestone['id'], 'date=' . $milestone['date'] . ';radius=8;color=efbb07;shape=star;numSides=3;borderThickness=1'); } } // Today $chart->addTrendLine('start=' . date('d/m/Y') . ';displayValue=' . __('Today') . ';color=666666;isTrendZone=1;alpha=20'); // Return the code return get_chart_code($chart, $width, $height, 'include/graphs/FusionCharts/FCF_Gantt.swf'); }
while ($row = dbi_fetch_row($res)) { $partlogin[] = $row[0]; } dbi_free_result($res); } // Get event name. $res = dbi_execute('SELECT cal_name, cal_date, cal_time FROM webcal_entry WHERE cal_id = ?', array($id)); if ($res) { $row = dbi_fetch_row($res); $name = $row[0]; $fmtdate = $row[1]; $time = sprintf("%06d", $row[2]); dbi_free_result($res); } $eventstart = date_to_epoch($fmtdate . $time); $TIME_FORMAT = 24; for ($i = 0, $cnt = count($partlogin); $i < $cnt; $i++) { // Log the deletion. activity_log($id, $login, $partlogin[$i], $log_delete, ''); // Check UAC. $can_email = access_is_enabled() ? access_user_calendar('email', $partlogin[$i], $login) : false; // Don't email the logged in user. if ($can_email && $partlogin[$i] != $login) { set_env('TZ', get_pref_setting($partlogin[$i], 'TIMEZONE')); $user_language = get_pref_setting($partlogin[$i], 'LANGUAGE'); user_load_variables($partlogin[$i], 'temp'); if (!$is_nonuser_admin && $partlogin[$i] != $login && get_pref_setting($partlogin[$i], 'EMAIL_EVENT_DELETED') == 'Y' && boss_must_be_notified($login, $partlogin[$i]) && !empty($tempemail) && $SEND_EMAIL != 'N') { reset_language(empty($user_language) || $user_language == 'none' ? $LANGUAGE : $user_language); // Use WebCalMailer class. $mail->WC_Send($login_fullname, $tempemail, $tempfullname, $name, str_replace('XXX', $tempfullname, translate('Hello, XXX.')) . ".\n\n" . str_replace('XXX', $login_fullname, translate('XXX has canceled an appointment.')) . "\n" . str_replace('XXX', $name, translate('Subject XXX')) . "\"\n" . str_replace('XXX', date_to_str($thisdate), translate('Date XXX')) . "\n" . (!empty($eventtime) && $eventtime != '-1' ? str_replace('XXX', display_time('', 2, $eventstart, get_pref_setting($partlogin[$i], 'TIME_FORMAT')), translate('Time XXX')) : '') . "\n\n", get_pref_setting($partlogin[$i], 'EMAIL_HTML'), $login_email);
function list_unapproved($user) { global $eventinfo, $key, $login, $NONUSER_ENABLED, $noret, $temp_fullname; user_load_variables($user, 'temp_'); $rssLink = '<a href="rss_unapproved.php?user='******'"><img src="images/rss.png" width="14" height="14" alt="RSS 2.0 - ' . htmlspecialchars($temp_fullname) . '" border="0"/></a>'; $count = 0; $ret = ''; $sql = 'SELECT we.cal_id, we.cal_name, we.cal_description, weu.cal_login, we.cal_priority, we.cal_date, we.cal_time, we.cal_duration, weu.cal_status, we.cal_type FROM webcal_entry we, webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND weu.cal_login = ? AND weu.cal_status = \'W\' ORDER BY weu.cal_login, we.cal_date'; $rows = dbi_get_cached_rows($sql, array($user)); if ($rows) { $allDayStr = translate('All day event'); $appConStr = translate('Approve/Confirm'); $appSelStr = translate('Approve Selected'); $checkAllStr = translate('Check All'); $deleteStr = translate('Delete'); $emailStr = translate('Emails Will Not Be Sent'); $rejectSelStr = translate('Reject Selected'); $rejectStr = translate('Reject'); $uncheckAllStr = translate('Uncheck All'); $viewStr = translate('View this entry'); for ($i = 0, $cnt = count($rows); $i < $cnt; $i++) { $row = $rows[$i]; $key++; $id = $row[0]; $name = $row[1]; $description = $row[2]; $cal_user = $row[3]; $pri = $row[4]; $date = $row[5]; $time = sprintf("%06d", $row[6]); $duration = $row[7]; $status = $row[8]; $type = $row[9]; $view_link = 'view_entry'; $entryID = 'entry' . $type . $id; $linkid = "pop{$id}-{$key}"; $timestr = ''; if ($time > 0 || $time == 0 && $duration != 1440) { $eventstart = date_to_epoch($date . $time); $eventstop = $eventstart + $duration; $eventdate = date_to_str(date('Ymd', $eventstart)); $timestr = display_time('', 0, $eventstart) . ($duration > 0 ? ' - ' . display_time('', 0, $eventstop) : ''); } else { // Don't shift date if All Day or Untimed. $eventdate = date_to_str($date); // If All Day display in popup. if ($time == 0 && $duration == 1440) { $timestr = $allDayStr; } } $ret .= ($count == 0 ? ' <tr> <td colspan="5"><h3>' . $temp_fullname . ' ' . $rssLink . '</h3></td> </tr>' : '') . ' <tr ' . ($count % 2 == 0 ? '' : 'class="odd"') . '> <td width="5%" align="right"><input type="checkbox" name="' . $entryID . '" value="' . $user . '"/></td> <td><a title="' . $viewStr . '" class="entry" id="' . $linkid . '" href="' . $view_link . '.php?id=' . $id . '&user='******'">' . htmlspecialchars($name) . '</a> (' . $eventdate . '):</td>' . ' <td align="center"><input type="image" src="images/check.gif" title="' . $appConStr . '" onclick="return do_confirm( \'approve\', \'' . $cal_user . '\', \'' . $entryID . '\' );" /></td>' . ' <td align="center"><input type="image" src="images/rejected.gif" title="' . $rejectStr . '" onclick="return do_confirm( \'reject\', \'' . $cal_user . '\', \'' . $entryID . '\' );" /></td>' . (!access_is_enabled() || access_user_calendar('edit', $user) ? ' <td align="center"><input type="image" src="images/delete.png" title="' . $deleteStr . '" onclick="return do_confirm( \'delete\', \'' . $cal_user . '\', \'' . $entryID . '\' );\\" /></td>' : '') . ' </tr>'; $eventinfo .= build_entry_popup('eventinfo-' . $linkid, $cal_user, $description, $timestr, site_extras_for_popup($id)); $count++; } if ($count > 1) { $ret .= ' <tr> <td colspan="5" nowrap="nowrap"> <img src="images/select.gif" border="0" alt="" /> <label><a title="' . $checkAllStr . '" onclick="check_all( \'' . $user . '\' );">' . $checkAllStr . '</a> / <a title="' . $uncheckAllStr . '" onclick="uncheck_all( \'' . $user . '\' );">' . $uncheckAllStr . '</a></label> <input type="image" src="images/check.gif" title="' . $appSelStr . '" onclick="return do_confirm( \'approveSelected\', \'' . $cal_user . '\' );" /> <input type="image" src="images/rejected.gif" title="' . $rejectSelStr . '" onclick="return do_confirm( \'rejectSelected\', \'' . $cal_user . '\' );" /> ( ' . $emailStr . ' ) </td> </tr>'; } } if ($count == 0) { $noret .= ' <tr> <td colspan="5" class="nounapproved">' . str_replace('XXX', $temp_fullname, translate('No unapproved entries for XXX.')) . ' ' . $rssLink . '</td> </tr>'; } return $ret; }
$thisdate = sprintf("%04d%02d%02d", $thisyear, empty($thismonth) ? date('m') : $thismonth, empty($thisday) ? date('d') : $thisday); } if (empty($cal_date) || !$cal_date) { $cal_date = $thisdate; } if (empty($due_date) || !$due_date) { $due_date = $thisdate; } // Setup to display user's timezone difference if Admin or Assistant. // Even though event is stored in GMT, // an Assistant may need to know that the boss is in a different Timezone. if ($is_assistant || $is_admin && !empty($user)) { $tz_offset = date('Z', date_to_epoch($cal_date . $cal_time)); $user_TIMEZONE = get_pref_setting($user, 'TIMEZONE'); set_env('TZ', $user_TIMEZONE); $user_tz_offset = date('Z', date_to_epoch($cal_date . $cal_time)); if ($tz_offset != $user_tz_offset) { // Different TZ_Offset. user_load_variables($user, 'temp'); $tz_diff = ($user_tz_offset - $tz_offset) / 3600; $abs_diff = abs($tz_diff); // translate ( 'is in a different timezone than you are. Currently' ) // translate ( 'hour ahead of you' ) translate ( 'hour behind you' ) // translate ( 'hours ahead of you' ) translate ( 'hours behind you' ) // translate ( 'XXX is in a different timezone (ahead)' ) // translate ( 'XXX is in a different timezone (behind)' ) // Line breaks in translates below are to bypass update_translation.pl. $TZ_notice = str_replace('XXX', array($tempfullname, $abs_diff . ' ' . translate('hour' . ($abs_diff == 1 ? '' : 's')), translate('Time entered here is based on your Timezone.')), translate('XXX is in a different timezone (' . ($tz_diff > 0 ? 'ahead)' : 'behind)'))); } // Return to $login TIMEZONE. set_env('TZ', $TIMEZONE);
function process_event($id, $name, $start, $end, $new_date = '') { global $debug, $is_task, $only_testing; // Get reminders array. $reminder = getReminders($id); if (!empty($reminder)) { if ($debug) { echo " Reminder set for event.<br />\n"; } $times_sent = $reminder['times_sent']; $repeats = $reminder['repeats']; $lastsent = $reminder['last_sent']; $related = $reminder['related']; // If we are working with a repeat or overdue task, and we have sent all the // reminders for the basic event, then reset the counter to 0. if (!empty($new_date)) { if ($times_sent == $repeats + 1) { if (!$is_task || $related == 'E' && date('Ymd', $new_date) != date('Ymd', $end)) { // Tasks only. $times_sent = 0; } } $new_offset = date_to_epoch($new_date) - ($start - $start % 86400); $start += $new_offset; $end += $new_offset; } if ($debug) { printf("Event %d: \"%s\" on %s at %s GMT<br />\n", $id, $name, gmdate('Ymd', $start), gmdate('H:i:s', $start)); } // It is pointless to send reminders after this time! $pointless = $end; $remB4 = $reminder['before'] == 'Y'; if (!empty($reminder['date'])) { // We're using a date. $remind_time = $reminder['timestamp']; } else { // We're using offsets. $offset = $reminder['offset'] * 60; // Convert to seconds. if ($related == 'S') { // Relative to start. $offset_msg = ($remB4 ? ' Mins Before Start: ' : ' Mins After Start: ') . $reminder['offset']; $remind_time = $remB4 ? $start - $offset : $start + $offset; } else { // Relative to end/due. $offset_msg = ($remB4 ? ' Mins Before End: ' : ' Mins After End: ') . $reminder['offset']; $remind_time = $remB4 ? $end - $offset : $end + $offset; $pointless = $remB4 ? $end : $end + $offset; } } // Factor in repeats if set. if ($repeats > 0 && $times_sent <= $repeats) { $remind_time += $reminder['duration'] * 60 * $times_sent; } if ($debug) { echo (empty($offset_msg) ? '' : $offset_msg . '<br />') . ' Event ' . ($related == 'S' ? 'start time is: ' . gmdate('m/d/Y H:i', $start) : 'end time is: ' . gmdate('m/d/Y H:i', $end)) . ' GMT<br /> Remind time is: ' . gmdate('m/d/Y H:i', $remind_time) . ' GMT<br /> Effective delivery time is: ' . date('m/d/Y H:i T', $remind_time) . '<br /> Last sent on: ' . ($lastsent == 0 ? 'NEVER' : date('m/d/Y H:i T', $lastsent)) . '<br /><br /> times_sent = ' . $times_sent . ' repeats = ' . $repeats . ' time = ' . date('His', time()) . ' remind_time = ' . date('His', $remind_time) . ' lastsent = ' . ($lastsent > 0 ? date('Ymd His', $lastsent) : " NEVER ") . ' pointless = ' . date('Ymd His', $pointless) . ' is_task = ' . ($is_task ? 'true' : 'false') . '<br />'; } if ($times_sent < $repeats + 1 && time() >= $remind_time && $lastsent <= $remind_time && (time() <= $pointless || $is_task)) { // Send a reminder. if ($debug) { echo ' SENDING REMINDER!<br />' . "\n"; } send_reminder($id, $start); // Now update the db... if ($debug) { echo '<br /> LOGGING REMINDER!<br /><br />' . "\n"; } log_reminder($id, $times_sent + 1); } } }
function export_time($date, $duration, $time, $texport, $vtype = 'E') { global $TIMEZONE, $vtimezone_data, $use_vtimezone; $ret = $vtimezone_exists = ''; $eventstart = date_to_epoch($date . ($time > 0 ? $time : 0), $time > 0); $eventend = $eventstart + $duration * 60; if ($time == 0 && $duration == 1440 && strcmp($texport, 'ical') == 0) { // all day. if ($use_vtimezone && ($vtimezone_data = get_vtimezone($TIMEZONE, $dtstart))) { $vtimezone_exists = true; $dtstart = $date . 'T000000'; $ret .= 'DTSTART;TZID=' . $TIMEZONE . ':' . $dtstart . "\r\n"; } else { $ret .= "DTSTART;VALUE=DATE:{$date}\r\n"; } } else { if ($time == -1) { // untimed event: this is the same regardless of timezone. For example, // New Year's Day starts at 12am localtime regardless of timezone. $ret .= "DTSTART;VALUE=DATE:{$date}\r\n"; } else { // timed event $utc_start = export_ts_utc_date($eventstart); $dtstart = $date . 'T000000'; if ($use_vtimezone && ($vtimezone_data = get_vtimezone($TIMEZONE, $dtstart))) { $vtimezone_exists = true; $ret .= 'DTSTART;TZID=' . $TIMEZONE . ':' . $utc_start . "\r\n"; } else { $ret .= "DTSTART:{$utc_start}\r\n"; } } } if (strcmp($texport, 'ical') == 0) { $utc_dtstamp = export_ts_utc_date(time()); $ret .= "DTSTAMP:{$utc_dtstamp}\r\n"; // We don' want DTEND for VTODOs if ($vtype == 'T' || $vtype == 'N') { return $ret; } if ($time == 0 && $duration == 1440) { // all day event: better to use end date than duration since // duration will be 23hr and 25hrs on DST switch-over days. if ($vtimezone_exists) { $ret .= 'DTEND;TZID=' . $TIMEZONE . ':' . date('Ymd', $eventend) . "T000000\r\n"; } else { $ret .= 'DTEND;VALUE=DATE:' . gmdate('Ymd', $eventend) . "\r\n"; } } else { if ($time == -1) { // untimed event $ret .= "DTEND;VALUE=DATE:{$date}\r\n"; } else { if ($time > 0) { // timed event if ($vtimezone_exists) { $ret .= 'DTEND;TZID=' . $TIMEZONE . ':' . date('Ymd', $eventend) . "T000000\r\n"; } else { $utc_end = export_ts_utc_date($eventend); $ret .= "DTEND:{$utc_end}\r\n"; } } } } } elseif (strcmp($texport, 'vcal') == 0) { $utc_end = export_ts_utc_date($eventend); $ret .= "DTEND:{$utc_end}\r\n"; } else { $ret .= "DURATION:P{$str_duration}\r\n"; } return $ret; }