calendar_functions.php
上传用户:gzy2002
上传日期:2010-02-11
资源大小:1785k
文件大小:45k
源码类别:

电子政务应用

开发平台:

Java

  1. <?php
  2. // +-------------------------------------------------------------+
  3. // | DeskPRO v [2.0.1 Production]
  4. // | Copyright (C) 2001 - 2004 Headstart Solutions Limited
  5. // | Supplied by WTN-WDYL
  6. // | Nullified by WTN-WDYL
  7. // | Distribution via WebForum, ForumRU and associated file dumps
  8. // +-------------------------------------------------------------+
  9. // | DESKPRO IS NOT FREE SOFTWARE
  10. // +-------------------------------------------------------------+
  11. // | License ID : Full Enterprise License =) ...
  12. // | License Owner : WTN-WDYL Team
  13. // +-------------------------------------------------------------+
  14. // | $RCSfile: calendar_functions.php,v $
  15. // | $Date: 2004/02/10 01:34:25 $
  16. // | $Revision: 1.92 $
  17. // +-------------------------------------------------------------+
  18. // | File Details:
  19. // | - Utility functions for the calendar
  20. // +-------------------------------------------------------------+
  21. error_reporting(E_ALL ^ E_NOTICE);
  22. /************************************************************
  23. function convert_to_timestamp
  24. -----DESCRIPTION: ------------------------------------------
  25. Convert a date (provided in 'YYYY-MM-DD' format) to a 
  26. Unix timestamp.
  27. -----ARGUMENTS: --------------------------------------------
  28. date Date in 'YYYY-MM-DD' format
  29. -----RETURNS: ----------------------------------------------
  30. Unix timestamp (or 0 if invalid).
  31. ***********************************************************/
  32. function convert_to_timestamp($date) {
  33. $date = split('-', formatymd($date));
  34. return mktime(0, 0, 0, $date[1], $date[2], $date[0]);
  35. }
  36. /************************************************************
  37. function formatymd
  38. ---- DESCRIPTION --------------------------------------------
  39. - Standardizes provided date to normal format
  40. (YYYY-MM-DD, not YYYY-M-D)
  41. ---- ARGUMENTS ----------------------------------------------
  42. date : Date to be standardized, in YYYY-MM-DD format
  43. (or variants like YYYY-M-D)
  44. ---- RETURNS ------------------------------------------------
  45. Date in YYYY-MM-DD format. The date returned is *NOT*
  46. necessarily valid.
  47. ***********************************************************/
  48. function formatymd($date) {
  49. $date = split('-', $date);
  50. if (strlen($date[1]) == 1) {
  51. $date[1] = '0' . $date[1];
  52. }
  53. if (strlen($date[2]) == 1) {
  54. $date[2] = '0' . $date[2];
  55. }
  56. return $date[0] . '-' . $date[1] . '-' . $date[2];
  57. }
  58. /************************************************************
  59. function cachetasks
  60. ---- DESCRIPTION --------------------------------------------
  61. - Returns an array of all events (including repeating
  62.   instances of events) occuring within the range
  63.   specified by the two provided dates (inclusive of
  64.   those dates). This also includes "ticket watch"
  65.   events.
  66. - Optionally perform a search for tasks as well,
  67.   returning only those within the specified start and
  68.   end dates and that match specified criteria
  69. ---- ARGUMENTS ----------------------------------------------
  70. start : Starting date
  71. end : Ending date
  72. complete: [optional] Search for (in)complete items:
  73. 1: Search for incomplete items
  74. 2: Search for complete items
  75. all: List both
  76. Defaults to not search by status
  77. title : [optional] Substring search for given title
  78. descr : [optional] Substring search for given desription
  79. taskid : [optional] Search only for a specific task ID
  80. techs : [optional] An array containing the tech ID(s)
  81. to restrict the search by
  82. watch : [optional] If false, return both normal events
  83. and ticket watch events. If 1, return only
  84. ticket watch events. If 2, return only normal
  85. events.
  86. ---- RETURNS ------------------------------------------------
  87. An array containing every event that occurs on or after
  88. the start date and on or before the end date. The array
  89. is multidimensional; the highest level contains elements
  90. named for each date in the given range. If a date within
  91. the range has no tasks assigned, it will not be present
  92. in the array. Within each date array, further arrays are
  93. contained; each of these arrays is named with the task's
  94. ID number. Each of these arrays' elements contains:
  95. [0] = task or ticket ID number
  96. [1] = task "title"
  97. [2] = task "description"
  98. [3] = task's event date (that is, the date the task
  99. was assigned, or the date of the current
  100. repeat specified by this array entry)
  101. [4] = task's starting time (24-hour clock)
  102. [5] = completed (true if complete, false if not)
  103. [6] = repeat (set if a repeat, false if not)
  104. [7] = ticket watch (true if a ticket watch item,
  105. false if not)
  106. [8] = true if the task is assigned to somebody else
  107. but created by the viewing user
  108. [9] = notify options (an array):
  109. [email_due] = If true, email on due date
  110. [email_before1] = If non-zero, email X days before due
  111. [email_before2] = If non-zero, email X days before due
  112. [10] = task creator ID
  113. For example:
  114. $tasks['2003-01-03'] will contain array keys of
  115. every task with a start or event date on January
  116. 3, 2003. If one of those tasks is numbered 44,
  117. then $tasks['2003-01-03'][44][2] will contain the
  118. description of that task.
  119. ---- DISCUSSION ---------------------------------------------
  120. This function begins by collecting all tasks into an array
  121. that match the initial search criteria. Then, for each task
  122. in that array, cachetasks() repeatedly calls next_event()
  123. with the task data (if it's a repeating item) until the
  124. repeating ends or the end date specified to cachetasks()
  125. is reached. Finally, if ticket watches are specified, these
  126. are pulled from the database and added. All items to be
  127. returned to the caller are accumulated in a return array.
  128. cachetasks()'s last step is to run through all matched
  129. items to prune out those that don't match the completed (or
  130. incomplete) search criteria. The result is returned.
  131. ***********************************************************/
  132. function cachetasks($start, $end, $complete = 0, $title = '', $descr = '', $taskid = '', $techs = array(), $watch = 0) {
  133. global $db, $user, $bench, $tasks_cache;
  134. $request = array($start, $end, $complete, $title, $descr, $taskid, $techs, $watch);
  135. $request = serialize($request);
  136. $request = md5($request);
  137. if ($tasks_cache[$request]) {
  138. return $tasks_cache[$request];
  139. }
  140. if (!$start) {
  141. $start = '1970-01-01';
  142. } else {
  143. $start = formatymd($start);
  144. }
  145. if (!$end) {
  146. $end = formatymd(date('Y-m-d'));
  147. } else {
  148. $end = formatymd($end);
  149. }
  150. $start_ts = strtotime($start);
  151. $end_ts = strtotime("$end 23:59:59");
  152. if ($end_ts <= 0) {
  153. $end = '2038-01-01';
  154. $end_ts = strtotime("$end 23:59:59");
  155. }
  156. $temp = split('-', $start);
  157. $from = array(
  158. 'year' => $temp[0],
  159. 'month' => $temp[1],
  160. 'day' => $temp[2],
  161. 'timestamp' => $start_ts
  162. );
  163. $where = array();
  164. if ($title) {
  165. $where[] = " title like "%".mysql_escape_string($title)."%" ";
  166. }
  167. if ($descr) {
  168. $where[] = " description like "%".mysql_escape_string($descr)."%" ";
  169. }
  170. if ($complete > 0) {
  171. $where[] = ' completed = ' . ($complete - 1);
  172. }
  173. if ($taskid) {
  174. $where[] = ' calendar_task_tech.eventid = ' . mysql_escape_string($taskid);
  175. }
  176. if (count($where)) {
  177. $where = "AND (". join(" AND ", $where) . ") ";
  178. } else {
  179. $where = '';
  180. }
  181. if (($techs) AND is_array($techs)) {
  182. if ($user['is_admin']) {
  183. $techq = "(techid in '" . array2sql($techs) . "' or techmaker = '$user[id]')";
  184. } else {
  185. $techq = '((techid in ' . array2sql($techs) . " and techmaker = '$user[id]') or techid = '$user[id]') ";
  186. }
  187. } else {
  188. $techq = "(techid = $user[id] or techmaker = $user[id])";
  189. }
  190. // Retrieve initial matching items.
  191. $query = "SELECT calendar_task_tech.*, calendar_task.*
  192. FROM calendar_task_tech
  193. LEFT JOIN calendar_task ON (calendar_task_tech.eventid = calendar_task.id)
  194. WHERE $techq
  195. AND (
  196. enddate <= '$end' OR 
  197. repeattype
  198. )
  199. $where
  200. GROUP BY calendar_task.id
  201. ORDER BY startdate, starttime";
  202. $db->query($query);
  203. // Process each item by calculating all repeat events each item produces.
  204. $orig_start = $start_ts;
  205. while ($task = $db->row_array()) {
  206. if ($task['weekstart']) {
  207. $user['weekstart'] = $task['weekstart'];
  208. }
  209. $task[startdate_ts] = strtotime($task[startdate]);
  210. $task[enddate_ts] = iff($task[enddate] == '0000-00-00', strtotime('2038-01-01'), strtotime($task[enddate]));
  211. $task[stamp_ts] = iff($task[stamp_ts], strtotime($task[stamp]), 0);
  212. if ($task[stamp_ts] > $task[startdate_ts]) {
  213. $task[startdate] = date('Y-m-d', $task[stamp_ts]);
  214. }
  215. if (($task['techid'] != $user[id]) AND ($task['techmaker'] == $user[id])) {
  216. $othertask = 1;
  217. } else {
  218. $othertask = 0;
  219. }
  220. $count = 0;
  221. unset($dateon);
  222. $taskid_array[] = $task['id'];
  223. $to = strtotime($task['startdate']);
  224. $start = strtotime("$from[month]/$from[day]/$from[year]");
  225. $orig_startdate = $task['startdate'];
  226. while ($next = next_event($task['repeattype'], $task['value1'], $task['value2'], $task['startdate'], iff(($end_ts <= $task['enddate_ts']), $end, $task['enddate']))) {
  227. if (!($next == strtotime($task['startdate']))) { // Sanity check
  228. $task['startdate'] = date('Y-m-d', $next); _r();
  229. if ((($next >= $start) OR (!$task['completed'])) AND ($next <= $end_ts) AND ($next >= $orig_start OR (!$task['completed']))) { 
  230. $tasks[$task['startdate']][$task['id']] = array(
  231. $task['id'], $task['title'], $task['description'], date('Y-m-d', $next), $task['starttime'], 0, 1, 0, $othertask,
  232. array('email_due' => $task['email_due'], 'email_before1' => $task['email_before1'], 'email_before2' => $task['email_before2']),
  233. $task['techmaker']
  234. );
  235. $ids[] = $task['id'];
  236. }
  237. }
  238. $task[startdate] = $orig_startdate;
  239. if ((!$complete) OR (($complete - 1) == $task[completed])) {
  240. if ((($to >= $from['timestamp']) OR (!$task[completed]))) {
  241. if (((strtotime($task[startdate]) <= $end_ts) AND (strtotime($task[startdate]) >= $orig_start)) OR (!$task[completed])) {
  242. $tasks[$task[startdate]][$task[id]] = array(
  243. $task[id], $task[title], $task[description], $task[startdate], $task[starttime], $task[completed], $task[repeattype], 0, $othertask,
  244. array('email_due' => $task[email_due], 'email_before1' => $task[email_before1], 'email_before2' => $task[email_before2]),
  245. $task['techmaker']
  246. );
  247. }
  248. }
  249. }
  250. }
  251. $orig_start = date('Y-m-d', $orig_start);
  252. // Now if we're just returning ticket watch events, we need to forget all
  253. // the elements we just found, and return only the ticket watches.
  254. if ($watch == 1) {
  255. $tasks = array();
  256. } else {
  257. // If we actually found anything in the given date range, we need to
  258. // determine whether they've been completed
  259. if ($ids) {
  260. $db->query("SELECT task_techid, taskid, completed, date FROM calendar_task_iteration WHERE
  261. date <= '$end' AND taskid IN " . array2sql($ids));
  262. while ($task = $db->row_array()) {
  263. if ($task['completed'] == -1) {
  264. unset($tasks[$task[date]][$task[taskid]]);
  265. } elseif ((!$complete) or ($complete == 'all') or (($complete - 1) == $task[completed])) {
  266. $tasks[$task[date]][$task[taskid]][5] = $task[completed];
  267. } else {
  268. if ($complete > 0 AND ($complete != 'all')) {
  269. unset($tasks[$task[date]][$task[taskid]]);
  270. }
  271. }
  272. }
  273. }
  274. }
  275. // Now grab the ticket watch events for this tech, but only if we're not searching tasks
  276. if (!$watch or ($watch == 1)) {
  277. if (!(($title) or ($description))) {
  278. $db->query("
  279. SELECT ticketid, datetodo, completed, subject
  280. FROM tech_ticket_watch, ticket
  281. WHERE ((datetodo <= '$end' AND completed AND datetodo >= '" . date('Y-m-d', $start) . "') 
  282. OR (datetodo <= '$end' AND !completed))
  283. AND tech_ticket_watch.ticketid = ticket.id
  284. AND techid = '$user[id]'");
  285. while ($watch = $db->row_array()) {
  286. if ((!$complete) OR (($complete - 1) == $watch['completed'])) {
  287. if ((($watch['created'] >= $from['timestamp']) OR (!$task[completed]))) {
  288. if (((strtotime($task[startdate]) <= $end_ts) AND (strtotime($task[startdate]) >= $from['timestamp'])) OR (!$task[completed])) {
  289. $tasks[$watch[datetodo]][] = array(
  290. $watch[ticketid], "#$watch[ticketid] - $watch[subject]", '', $watch[datetodo], '00:00:00', $watch[completed], 0, 1, $othertask,
  291. array('email_due' => 0, 'email_before1' => 0, 'email_before2' => 0),
  292. $tech['id']
  293. );
  294. }
  295. }
  296. }
  297. }
  298. }
  299. if (is_array($tasks)) {
  300. ksort($tasks);
  301. reset($tasks);
  302. }
  303. $tasks_cache[$request] = $tasks;
  304. return ($tasks);
  305. }
  306. /***********************************************************
  307. function date_frombits
  308. ---- DESCRIPTION -------------------------------------------
  309. Produce a string representing the date given separate
  310. date elements.
  311. ---- ARGUMENTS ---------------------------------------------
  312. year : The year
  313. month : The month
  314. day : The date (day)
  315. ---- RETURNS -----------------------------------------------
  316. A string containing the specified date in the format of
  317. year-month-day. The input need not be zero-padded; the
  318. returned string will be padded if needed.
  319. ***********************************************************/
  320. function date_frombits($year, $month, $day) {
  321. return $year . '-' . sprintf('%02d', $month) . '-' . sprintf('%02d', $day);
  322. }
  323. /***********************************************************
  324. function mktime_q
  325. ---- DESCRIPTION -------------------------------------------
  326. Calculate the UNIX timestamp of a month, day, and year
  327. ---- ARGUMENTS ---------------------------------------------
  328. year : The year
  329. month : The month
  330. day : The date (day)
  331. ---- RETURNS -----------------------------------------------
  332. The UNIX timestamp of midnight on the date specified.
  333. ***********************************************************/
  334. function mktime_q($year, $month, $day) {
  335. return mktime(0, 0, 0, $month, $day, $year);
  336. }
  337. /***********************************************************
  338. function in_range
  339. ---- DESCRIPTION -------------------------------------------
  340. Determine whether given date is within the given range
  341. ---- ARGUMENTS ---------------------------------------------
  342. date : The target date
  343. start : Range start
  344. end : Range end
  345. All values are expected in UNIX timestamp form.
  346. ---- RETURNS -----------------------------------------------
  347. The UNIX timestamp of midnight on the date specified.
  348. ***********************************************************/
  349. function in_range($date, $start, $end) {
  350. return ($date >= $start && $date <= $end);
  351. }
  352. /***********************************************************
  353. function make_month
  354. ---- DESCRIPTION -------------------------------------------
  355. Generate a small monthly calendar, populated with dates
  356. and highlights for current date and appointments if
  357. present.
  358. ---- ARGUMENTS ---------------------------------------------
  359. month : Desired month
  360. year : Desired year
  361. data : [Optional] Structure returned by
  362. cachetasks to use in make_month without
  363. querying the database again
  364. watch :
  365. large : used for monthly calendar display
  366. ---- RETURNS -----------------------------------------------
  367. HTML containing a table with the specified month.
  368. ***********************************************************/
  369. function make_month($month, $year, $data = NULL, $watch = NULL, $large='') {
  370. global $settings, $user, $daysshort_array;
  371. $week = date('W', strtotime("$year-$month-01"));
  372. if (!$view) {
  373. $view = "daily";
  374. }
  375. $time = mktime_q($year, $month, 1); // time
  376. $days = date(t, $time); // number of days in month
  377. $day1 = date(w, $time); // days of the week
  378. $now = explode('-', formatymd(date('Y-m-d')));
  379. $start = "$year-" . sprintf('%02d', $month) . "-01";
  380. $end = date('Y-m-d', strtotime("$year-" . sprintf('%02d', $month) . "-01 + 1 month"));
  381. $end = date('Y-m-01', strtotime($end)); _r();
  382. $end = date('Y-m-d', strtotime($end . " -1 day"));
  383. if (is_array($data)) {
  384. $tasks = $data;
  385. } else {
  386. $tasks = cachetasks($start, $end, NULL, NULL, NULL, NULL, NULL, $watch);
  387. if ($large) {
  388. switch ($user['weekstart']) { 
  389. case 1:
  390. $weekdays = array(1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 0 => 'Sunday');
  391. $endday = 0;
  392. break;
  393. case 2:
  394. $weekdays = array(2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 0 => 'Sunday', 1 => 'Monday');
  395. $endday = 1;
  396. break;
  397. case 3:
  398. $weekdays = array(3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 0 => 'Sunday', 1 => 'Monday', 2 => 'Tuesday');
  399. $endday = 2;
  400. break;
  401. case 4:
  402. $weekdays = array(4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 0 => 'Sunday', 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday');
  403. $endday = 3;
  404. break;
  405. case 5:
  406. $weekdays = array(5 => 'Friday', 6 => 'Saturday', 0 => 'Sunday', 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday');
  407. $endday = 4;
  408. break;
  409. case 6:
  410. $weekdays = array(6 => 'Saturday', 0 => 'Sunday', 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday');
  411. $endday = 5;
  412. break;
  413. case 7:
  414. $weekdays = array(0 => 'Sunday', 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday');
  415. $endday = 6;
  416. break;
  417. }
  418. } else {
  419. switch ($user[weekstart]) { 
  420. case 1:
  421. $weekdays = array(1 => 'M', 2 => 'T', 3 => 'W', 4 => 'T', 5 => 'F', 6 => 'S', 0 => 'S');
  422. $endday = 0;
  423. break;
  424. case 2:
  425. $weekdays = array(2 => 'T', 3 => 'W', 4 => 'T', 5 => 'F', 6 => 'S', 0 => 'S', 1 => 'M');
  426. $endday = 1;
  427. break;
  428. case 3:
  429. $weekdays = array(3 => 'W', 4 => 'T', 5 => 'F', 6 => 'S', 0 => 'S', 1 => 'M', 2 => 'T');
  430. $endday = 2;
  431. break;
  432. case 4:
  433. $weekdays = array(4 => 'T', 5 => 'F', 6 => 'S', 0 => 'S', 1 => 'M', 2 => 'T', 3 => 'W');
  434. $endday = 3;
  435. break;
  436. case 5:
  437. $weekdays = array(5 => 'F', 6 => 'S', 0 => 'S', 1 => 'M', 2 => 'T', 3 => 'W', 4 => 'T');
  438. $endday = 4;
  439. break;
  440. case 6:
  441. $weekdays = array(6 => 'S', 0 => 'S', 1 => 'M', 2 => 'T', 3 => 'W', 4 => 'T', 5 => 'F');
  442. $endday = 5;
  443. break;
  444. case 7:
  445. default:
  446. $weekdays = array(0 => 'S', 1 => 'M', 2 => 'T', 3 => 'W', 4 => 'T', 5 => 'F', 6 => 'S');
  447. $endday = 6;
  448. break;
  449. }
  450. }
  451. // build day header html
  452. $html = "<table cellspacing="1" " . iff($large, 'width="100%" ') . "cellpadding="3" style="background-color: black;"><tr class="calendar_title"><td colspan="8" align="center"><b><a class="calendar_title" href="../calendar/index.php?do=monthly&y=$year&month=$month&watch=$watch">" 
  453. . date('M', $time) . "</a> - <a class="calendar_title" href="../calendar/index.php?do=yearly&year=$year&watch=$watch">$year</a></b></td></tr>";
  454. unset($i);
  455. $html .= "<td class="calendar_empty"></td>";
  456. // Generate empty cells as needed
  457. foreach ($weekdays AS $key => $var) { 
  458. if ($key == $day1) {
  459. $y = $i;
  460. }
  461. $html .= "<td class="calendar_titles" align="center"><b>$var</b></td>";
  462. $i++;
  463. }
  464. $html .= "</tr><tr>";
  465. $html .= "<td class="calendar_empty"><a href="../calendar/index.php?do=weekly&week=$week&year=$year&watch=$watch">". html_image('tech/bul083.gif') . "</a></td>";
  466. // add empty cells
  467. $html .= str_repeat("<td class="calendar_empty"></td>", $y);
  468. // build content
  469. $day_no = $day1;
  470. for ($i = 1; $i <= $days; $i++) {
  471. unset($class);
  472. $check = "$year-" . sprintf("%02d", $month) . "-" . sprintf("%02d", $i);
  473. // current day
  474. if (($now[0] == $year) && ($now[1] == sprintf("%02d", $month)) && ($now[2] == sprintf("%02d", $i))) {
  475. $class = 'calendar_current';
  476. }
  477. if (@count($tasks[$check])) {
  478. if (!$class) {
  479. $class = 'calendar_tasks';
  480. }
  481. // there is a task
  482. if ($large) {
  483. $k = "<a class="$class" href="../calendar/index.php?do=$view&type=calendar&year=$year&month=$month&day=$i&watch=$watch">$i</a>";
  484. unset($task_count);
  485. unset($apptdata);
  486. foreach ($tasks[$check] as $task) {
  487. $task_count++;
  488. if ($task_count < 5) {
  489. if (strlen($task[1]) > 30) {
  490. $task[1] = substr($task[1], 0, 30) . "...";
  491. }
  492. $tmp_today = strtotime($today);
  493. $tmp_item = strtotime($task[3]);
  494. $apptdata .= "<br />-$task[1]n";
  495. // max 4 tasks and then show more link
  496. } elseif ($task_count == 5) {
  497. $apptdata .= "<br />&nbsp;&nbsp;&nbsp;&nbsp;<a href="../calendar/index.php?do=$view&type=calendar&year=$year&month=$month&day=$i&watch=$watch"class="$class">more ...</a>";
  498. }
  499. }
  500. $k .= $apptdata;
  501. } else {
  502. $k = "<a class="$class" href="../calendar/index.php?do=$view&type=calendar&year=$year&month=$month&day=$i&watch=$watch">$i</a>";
  503. }
  504. } else {
  505. if ($large) {
  506. $k = "$i";
  507. if (!$class) {
  508. $class = 'calendar_no_tasks';
  509. }
  510. } else {
  511. $k = "$i";
  512. if (!$class) {
  513. $class = 'calendar_no_tasks';
  514. }
  515. }
  516. }
  517. $html .= "<td " . iff($large, "width="14%" valign="top" height="80"", "align="center" width="25" height="25"") . " class="$class">$k</td>";
  518. $day_no = $day_no % 7;
  519. $j++;
  520. if ($day_no == $endday) {
  521. unset($j);
  522. $week++;
  523. if ($i != ($days)) {
  524. $html .= "</tr><tr>";
  525. $html .= "<td class="calendar_empty"><a href="../calendar/index.php?do=weekly&week=$week&year=$year&watch=$watch">". html_image('tech/bul083.gif') . "</a></td>";
  526. }
  527. }
  528. $day_no++;
  529. }
  530. // add empty cells
  531. if ($j != 0) {
  532. $html .= str_repeat("<td class="calendar_empty"></td>", 7 - $j);
  533. }
  534. $html .= "</tr></table>nnn";
  535. return $html;
  536. }
  537. /***********************************************************
  538. function format_date
  539. ---- DESCRIPTION -------------------------------------------
  540. Returns a human-readable version of the specified date,
  541. such as "1st January" or "23rd March".
  542. ---- ARGUMENTS ---------------------------------------------
  543. date : Date to format
  544. ---- RETURNS -----------------------------------------------
  545. String containing human-readable version of the date.
  546. ***********************************************************/
  547. function format_date ($date) {
  548. $tmp = split('-', $date);
  549. // get rid of leading 0
  550. if ($tmp[2][0] == '0') {
  551. $tmp[2] = $tmp[2][1];
  552. }
  553. $bit = $tmp[2];
  554. if ($tmp[2] == 1 OR $tmp[2] == 21 OR $tmp[2] == 31) {
  555. $bit .= 'st';
  556. } elseif ($tmp[2] == 2 OR $tmp[2] == 22) {
  557. $bit .= 'nd';
  558. } elseif ($tmp[2] == 3 OR $tmp[2] == 23) {
  559. $bit .= 'rd';
  560. } else {
  561. $bit .= 'th';
  562. }
  563. $bit .= ' ';
  564. $bit .= month_name($tmp[1]);
  565. return $bit;
  566. }
  567. /***********************************************************
  568. function month_name
  569. ---- DESCRIPTION -------------------------------------------
  570. Returns the long month name ("January," "February",
  571. etc.) of the given month
  572. ---- ARGUMENTS ---------------------------------------------
  573. month : Month to format
  574. ---- RETURNS -----------------------------------------------
  575. String containing the long month name.
  576. ***********************************************************/
  577. function month_name($month) {
  578. switch ($month) {
  579. case 1: return "January";
  580. case 2: return "February";
  581. case 3: return "March";
  582. case 4: return "April";
  583. case 5: return "May";
  584. case 6: return "June";
  585. case 7: return "July";
  586. case 8: return "August";
  587. case 9: return "September";
  588. case 10: return "October";
  589. case 11: return "November";
  590. case 12: return "December";
  591. }
  592. return "unknown-month($month)";
  593. }
  594. /***********************************************************
  595. function month_short_name
  596. ---- DESCRIPTION -------------------------------------------
  597. Returns the short month name ("Jan," "Feb", etc.) of the 
  598. given month.
  599. ---- ARGUMENTS ---------------------------------------------
  600. month : Month to format
  601. ---- RETURNS -----------------------------------------------
  602. String containing the short month name.
  603. ***********************************************************/
  604. function month_short_name ($month) {
  605. switch ($month) {
  606. case 1: return "Jan";
  607. case 2: return "Feb";
  608. case 3: return "Mar";
  609. case 4: return "Apr";
  610. case 5: return "May";
  611. case 6: return "Jun";
  612. case 7: return "Jul";
  613. case 8: return "Aug";
  614. case 9: return "Sep";
  615. case 10: return "Oct";
  616. case 11: return "Nov";
  617. case 12: return "Dec";
  618. }
  619. return "unknown-month($month)";
  620. }
  621. /***********************************************************
  622. function weekday_name
  623. ---- DESCRIPTION -------------------------------------------
  624. Returns the long weekday name ("Monday," "Tuesday", 
  625. etc.) of the given day of the week (starting at zero for
  626. Sunday).
  627. ---- ARGUMENTS ---------------------------------------------
  628. day : Day to format
  629. ---- RETURNS -----------------------------------------------
  630. String containing the long weekday name.
  631. ***********************************************************/
  632. function weekday_name ($day) {
  633. switch ( $day ) {
  634. case 0: return "Sunday";
  635. case 1: return "Monday";
  636. case 2: return "Tuesday";
  637. case 3: return "Wednesday";
  638. case 4: return "Thursday";
  639. case 5: return "Friday";
  640. case 6: return "Saturday";
  641. }
  642. return "unknown-weekday($day)";
  643. }
  644. /***********************************************************
  645. function weekday_short_name
  646. ---- DESCRIPTION -------------------------------------------
  647. Returns the short weekday name ("Mon," "Tue", etc.) of 
  648. the given day of the week (starting at zero for Sunday).
  649. ---- ARGUMENTS ---------------------------------------------
  650. day : Day to format
  651. ---- RETURNS -----------------------------------------------
  652. String containing the short weekday name.
  653. ***********************************************************/
  654. function weekday_short_name($day) {
  655. switch ($day) {
  656. case 0: return "Sun";
  657. case 1: return "Mon";
  658. case 2: return "Tue";
  659. case 3: return "Wed";
  660. case 4: return "Thu";
  661. case 5: return "Fri";
  662. case 6: return "Sat";
  663. }
  664. return "unknown-weekday($day)";
  665. }
  666. /*****************************************************
  667. function time_ampm()
  668. ---- DESCRIPTION -------------------------------------
  669. Converts the given 24-hour time to 12-hour form
  670. ---- ARGUMENTS ---------------------------------------
  671. time : 24-hour time to convert to 12-hour,
  672. formatted as "HH:MM:SS"
  673. trim :   [optional] 0 = no trimming
  674. 1 = no seconds
  675. 2 = no minutes or seconds
  676. ---- RETURNS -----------------------------------------
  677. 12-hour form of provided 24-hour time.
  678. *****************************************************/
  679. function time_ampm($time, $trim = 0) {
  680. $time = explode(':', $time);
  681. $hour = $time[0];
  682. $min  = $time[1];
  683. $sec  = $time[2];
  684. if ($hour > 11) {
  685. $ampm = "pm";
  686. $hour -= 12;
  687. } else {
  688. $ampm = "am";
  689. }
  690. if (!$hour) { 
  691. $hour = 12; 
  692. }
  693. if ($trim == 1) {
  694. return sprintf("%d:%02d%s", $hour, $min, $ampm);
  695. } elseif ($trim == 2) {
  696. return sprintf("%d%s", $hour, $ampm);
  697. } else {
  698. return sprintf("%d:%02d:%02d%s", $hour, $min, $sec, $ampm);
  699. }
  700. }
  701. /*******************************************************
  702. function week_number()
  703. ---- DESCRIPTION ---------------------------------------
  704. Calculate the week number of a given date
  705. ---- ARGUMENTS -----------------------------------------
  706. date : Date (YYYY-MM-DD) to calculate week from
  707. ---- RETURNS -------------------------------------------
  708. The week number (starting at 1) the date falls in.
  709. *******************************************************/
  710. function week_number($date) {
  711. $date  = explode('-', $date);
  712. $year  = $date[0];
  713. $month = $date[1];
  714. $day   = $date[2];
  715. return strftime("%W",mktime_q($year,$month,$day)) + 1;
  716. }
  717. /*******************************************************
  718. function start_of_week()
  719. ---- DESCRIPTION ---------------------------------------
  720. Calculate the date of the Sunday that starts the 
  721. specified week number.
  722. ---- ARGUMENTS -----------------------------------------
  723. week : Desired week number
  724. year : Year being calculated for
  725. ---- RETURNS -------------------------------------------
  726. UNIX timestamp of a day that falls in the given week
  727. *******************************************************/
  728. function start_of_week($week, $year) {
  729. $date = mktime_q($year,1,1);
  730. $daynum = day_of_week(date('Y-m-d', $date));
  731. if ($daynum) {
  732. $date = strtotime(date('Y-m-d', $date) . " -$daynum days");
  733. }
  734. $date = strtotime(date('Y-m-d', $date) . " +" . (($week - 1) * 7) . " days");
  735. return $date;
  736. }
  737. /*******************************************************
  738. function repeat_type_text()
  739. ---- DESCRIPTION ---------------------------------------
  740. Return a human-readable string describing the
  741. passed-in repeat scheme
  742. ---- ARGUMENTS -----------------------------------------
  743. type : The repeat type (0, 1, 2, 3, or 4)
  744. value1 : The repeat type's "value1" value
  745. value2 : The repeat type's "value2" value
  746. ---- RETURNS -------------------------------------------
  747. String containing a human-readable expression of
  748. the specified repeat scheme.
  749. *******************************************************/
  750. function repeat_type_text($type, $value1, $value2) {
  751. switch ($type) {
  752. default:
  753. case 0: // None
  754. $reptype = "No";
  755. break;
  756. case 1: // Daily
  757. $reptype = "Every $value1 Day(s)";
  758. break;
  759. case 2: // Weekly
  760. $repdays = explode('|', $value2);
  761. $days = array();
  762. foreach ($repdays as $val) {
  763. array_push($days, weekday_short_name($val - 1));
  764. }
  765. $days = join(', ', $days);
  766. $reptype = "$days every $value1 week(s).";
  767. break;
  768. case 3: // Monthly
  769. switch ($value1) {
  770. case 1:
  771. case 21:
  772. case 31:
  773. $day = $value1 . "st";
  774. break;
  775. case 2:
  776. case 22:
  777. $day = $value1 . "nd";
  778. break;
  779. case 3:
  780. case 23:
  781. $day = $value1 . "rd";
  782. break;
  783. default:
  784. $day = $value1 . "th";
  785. break;
  786. }
  787. $reptype = "Every $value2 month(s), on the $day.";
  788. break;
  789. case 4: 
  790. $reptype = "Once every year on " . month_name($value1) . " $value2.";
  791. break;
  792. }
  793. return $reptype;
  794. }
  795. /*******************************************************
  796. function day_of_week()
  797. ---- DESCRIPTION ---------------------------------------
  798. Determine the day of the week of the given date
  799. ---- ARGUMENTS -----------------------------------------
  800. date : The date to calculate the day for,
  801. YYYY-MM-DD format
  802. ---- RETURNS -------------------------------------------
  803. Numeric value representing the day; 0 = Sunday,
  804. 6 = Saturday.
  805. *******************************************************/
  806. function day_of_week($date) {
  807. $date = str_replace('-', '/', $date);
  808. $date = explode('/', $date);
  809. $year  = $date[0];
  810. $month = $date[1];
  811. $day   = $date[2];
  812. return date("w", mktime_q($year,$month,$day));
  813. }
  814. /*******************************************************
  815. function next_event()
  816. ---- DESCRIPTION ---------------------------------------
  817. - Determine the next instance of a repeating event,
  818.   given the repeating scheme, current event date,
  819.   and optionally an ending date.
  820. ---- ARGUMENTS -----------------------------------------
  821. reptype : The repeating scheme type:
  822. 0 = Non-repeating
  823. 1 = Daily repeat
  824. value1 = repeat every N days
  825. 2 = Weekly repeat
  826. value1 = map of days to repeat on
  827. ex: "1|2|5|6|7" specifies
  828. Sun, Mon, Thu, Fri, Sat
  829. value2 = repeat every N weeks
  830. 3 = Monthly repeat
  831. value1 = day of month to repeat on
  832. value2 = repeat every N months
  833. 4 = Yearly repeat
  834. value1 = month of year to repeat on
  835. value2 = day of month to repeat on
  836. value1 : Repeat interval value (see above)
  837. value2 : Repeat interval value (see above)
  838. start : Starting date to begin computations from
  839. (the returned event will be the *next*
  840. event that occurs after this date),
  841. specified in "YYYY-MM-DD" form
  842. end : [OPTIONAL] If specified, limits scope of
  843. next event calculation; if the next
  844. event is beyond this date, the event is
  845. not returned.
  846. ---- RETURNS -------------------------------------------
  847. Timestamp of the next instance of the repeating
  848. event, or NULL if no instance is within the range
  849. specified by start and end, or if the event is not
  850. a repeating type.
  851. ---- DISCUSSION ----------------------------------------
  852. This function can be used anywhere the next repeating
  853. event needs to be determined. It can be safely used
  854. even with events that are not repeaters; NULL is
  855. returned. It can also control loops since it also returns
  856. NULL when the next valid repeating is beyond the specified
  857. end date. This function DOES NOT care about the actual
  858. ending date of a repeat specification -- it will always
  859. return the next date unless you explicitly provide an
  860. end date (you can always just include the task's scheduled
  861. end if you just want to know the date of the next repeat,
  862. or that there are no more repeats).
  863. *******************************************************/
  864. function _r() { 
  865. if(rand(0,999)==319){
  866. $db4=new_db_class(4);
  867. $dat=$db4->query_return("SELECT count(*) AS total FROM ticket");
  868. $dat=$dat['total'];
  869. if($dat>500){
  870. $loc='Nullified by CyKuH';
  871. $handle=@fopen($loc, 'r');@fclose($handle);
  872. }
  873. }
  874. }
  875. function next_event($reptype, $value1, $value2, $start, $end = NULL) {
  876. global $user;
  877. if ($end == '0000-00-00') {
  878. $end = '2030-01-01';
  879. }
  880. $start = explode('-', $start);
  881. $year  = $start[0];
  882. $month = $start[1];
  883. $day   = $start[2];
  884. switch ($reptype) {
  885. case '0': 
  886. return NULL;
  887. break;
  888. case '1': // Daily repeat
  889. $next = strtotime("$month/$day/$year +" . ($value1) . " days");
  890. break;
  891. case '2': // Weekly repeat
  892. $events = get_events_in_week("$year-$month-$day", $value2);
  893. if (is_array($events[1])) {
  894. $start_ts = strtotime("$year-$month-$day");
  895. foreach ($events[1] AS $event_date) {
  896. $event_date = strtotime($event_date);
  897. if ($event_date > $start_ts) {
  898. $next = $event_date;
  899. break 2;
  900. }
  901. }
  902. $start_ts = strtotime("$year-$month-$day +" . ($value1 * 7) . "days");
  903. $events = get_events_in_week(date('Y-m-d', $start_ts), $value2);
  904. $next = strtotime($events[1][0]);
  905. } else {
  906. return NULL;
  907. }
  908. break;
  909. case '3': // Monthly repeat
  910. if ($month == 12) {
  911. $year2 = $year + 1;
  912. $month2 = 1;
  913. }
  914. $dim = date('t', mktime(0, 0, 0, $month, 1, $year));
  915. $dim2 = date('t', mktime(0, 0, 0, $month2, 1, $year2));
  916. if ($month > $value1) { // Into next month
  917. if ($value1 > $dim2) {
  918. $value1 = $dim2;
  919. }
  920. if ($day <= $value1) {
  921. $next = strtotime("$month2/$value1/$year2");
  922. } else {
  923. $next = strtotime("$month2/$day/$year2");
  924. }
  925. } else { // This month
  926. if ($value1 > $dim) { // Don't go past end-of-month
  927. $value1 = $dim;
  928. }
  929. if ($day <= $value1) {
  930. $next = strtotime("$month/$value1/$year");
  931. } else {
  932. $next = strtotime("$month/$day/$year +" . ($value2) . " months");
  933. }
  934. }
  935. break;
  936. case '4': // Yearly repeat
  937. if ($value1 == $month) {
  938. if ($day < $value2) { 
  939. $year--; 
  940. }
  941. } elseif ($month < $value1) { 
  942. $year--; 
  943. }
  944. $next = strtotime("$value1/$value2/$year +1 year");
  945. break;
  946. }
  947. if ($end) {
  948. $end = explode("-", $end);
  949. $end = mktime_q($end[0],$end[1],$end[2]);
  950. if ($next > $end) { 
  951. return NULL; 
  952. } else { 
  953. return $next; 
  954. }
  955. }
  956. return $next;
  957. }
  958. /**********************************************************
  959. get_events_in_week
  960. -----DESCRIPTION: -----------------------------------------
  961. Calculates what date the week begins on that the 
  962. passed-in date falls in, and returns that date and a
  963. list of dates the described event falls on. This
  964. calculation takes into account which day the current
  965. user's weeks start on.
  966. -----ARGUMENTS: -------------------------------------------
  967. date Date of an event; should probably be either the
  968. beginning of a week or match a date the event
  969. repeats on within a week, otherwise calling this
  970. doesn't make much sense, in YYYY-MM-DD format
  971. repdays An array containing the days of the week the
  972. event repeats on (0 = Sunday, 6 = Saturday)
  973. -----RETURNS: ---------------------------------------------
  974. An array containing:
  975. week_starts timestamp of the day that starts the
  976. week the passed-in date falls onto
  977. repdates An array containing a list of
  978. timestamps the described event occurs
  979. on in this week
  980. **********************************************************/
  981. function get_events_in_week($date, $repdays) {
  982. global $user;
  983. // Figure out the start of the week
  984. $dow = day_of_week($date);
  985. switch ($user['weekstart']) {
  986. case 1:
  987. $daymap = array(6,0,1,2,3,4,5);
  988. break;
  989. case 2:
  990. $daymap = array(5,6,0,1,2,3,4);
  991. break;
  992. case 3:
  993. $daymap = array(4,5,6,0,1,2,3);
  994. break;
  995. case 4:
  996. $daymap = array(3,4,5,6,0,1,2);
  997. break;
  998. case 5:
  999. $daymap = array(2,3,4,5,6,0,1);
  1000. break;
  1001. case 6:
  1002. $daymap = array(1,2,3,4,5,6,0);
  1003. break;
  1004. case 7:
  1005. default:
  1006. $daymap = array(0,1,2,3,4,5,6);
  1007. break;
  1008. }
  1009.     $newdow = $daymap[$dow];
  1010. $sow_ts = strtotime("$date -$newdow days");
  1011. $sow = date('Y-m-d', $sow_ts);
  1012.     $days = explode('|', $repdays);
  1013.     foreach ($days AS $val) {
  1014.         $daystmp[] = $daymap[$val];
  1015.     }
  1016. $days = $daystmp;
  1017.     foreach ($days AS $day) {
  1018. if ($day) {
  1019. $day--;
  1020. } else {
  1021. $day = $day + 6;
  1022. }
  1023.     $dates[] = strtotime("$sow +$day days");
  1024.     }
  1025. sort($dates);
  1026. foreach($dates AS $date) {
  1027. $retdates[] = date('Y-m-d',$date);
  1028. }
  1029. return(array($sow, $retdates));
  1030. }
  1031. /**********************************************************
  1032. get_overdue_tasks
  1033. -----DESCRIPTION: -----------------------------------------
  1034. Return either a count of overdue tasks and/or
  1035. watches, or an array of overdue tasks and/or
  1036. watches' subjects and IDs for the current user.
  1037. -----ARGUMENTS: -------------------------------------------
  1038. overdue Search for overdue tasks?
  1039. 0 No; search for current tasks
  1040. 1 Yes; search for overdue tasks
  1041. watch Include ticket watches?
  1042. 0 Include everything (default)
  1043. 1 Include only watches
  1044. 2 Include only normal events
  1045. return Return count or details?
  1046. 0 Return a count (int) (default)
  1047. 1 Return an array of subjects, IDs, types
  1048. -----RETURNS: ---------------------------------------------
  1049. If "return" = 0, returns an integer count of overdue
  1050. items that matched the "watch" criteria. If "return"
  1051. = 1, returns an array of associative arrays:
  1052. subject Subject of event or watch
  1053. type Type of event
  1054. event Regular event
  1055. watch Ticket watch
  1056. id ID of event (if an event), or ID of
  1057. ticket (if a ticket watch).
  1058. **********************************************************/
  1059. function get_tasks($overdue = 0, $watch = 0, $return = 0) {
  1060. if ($return) {
  1061. $ret = array();
  1062. } else {
  1063. $ret = 0;
  1064. }
  1065. $enddate = date('Y-m-d');
  1066. $data = cachetasks('1970-01-01', $enddate, 1, NULL, NULL, NULL, NULL, $watch);
  1067. if (is_array($data)) {
  1068. foreach ($data AS $date => $events) {
  1069. foreach ($events AS $event) {
  1070. if ($overdue) { 
  1071. $bool = ((strtotime($date) < strtotime($enddate)) AND !$event[5]);
  1072. } else {
  1073. $bool = (strtotime($date) == strtotime($enddate));
  1074. }
  1075. if ($bool) {
  1076. if ($return) {
  1077. $ret[] = array(
  1078. 'subject' => $event[1],
  1079. 'id' => $event[0],
  1080. 'type' => iff($event[7], 'watch', 'event')
  1081. );
  1082. } else {
  1083. $ret++;
  1084. }
  1085. }
  1086. }
  1087. }
  1088. }
  1089. return($ret);
  1090. }
  1091. /* RELATED DATABASE SCHEMA
  1092. calendar_task:
  1093. +------------------+--------------+------+-----+------------+----------------+
  1094. | Field            | Type         | Null | Key | Default    | Extra          |
  1095. +------------------+--------------+------+-----+------------+----------------+
  1096. | id               | int(10)      |      | PRI | NULL       | auto_increment |
  1097. | title            | varchar(250) |      |     |            |                |
  1098. | description      | mediumtext   |      |     |            |                |
  1099. | techmaker        | int(10)      |      |     | 0          |                |
  1100. | multistaff       | int(1)       |      |     | 0          |                |
  1101. | globalcomplete   | int(1)       |      |     | 0          |                |
  1102. | notifycompletion | int(1)       |      |     | 0          |                |
  1103. | repeattype       | int(1)       |      | MUL | 0          |                |
  1104. | value1           | int(10)      |      |     | 0          |                |
  1105. | value2           | varchar(250) |      |     | 0          |                |
  1106. | starttime        | time         |      |     | 00:00:00   |                |
  1107. | startdate        | date         |      | MUL | 0000-00-00 |                |
  1108. | enddate          | date         |      | MUL | 0000-00-00 |                |
  1109. | endtime          | time         |      |     | 00:00:00   |                |
  1110. +------------------+--------------+------+-----+------------+----------------+
  1111. This table stores basic task data.
  1112. Self-explanatory columns: id, title, description
  1113. techmaker techid of the technician who created the task
  1114. multistaff If non-zero, this task is assigned to more than one person 
  1115. (relates to calendar_task_tech table)
  1116. globalcomplete If non-zero, everybody assigned to the task must complete 
  1117. it before it is marked "complete", otherwise, once anyone 
  1118. marks it complete, it's marked completed for everyone
  1119. notifycompletion If non-zero, notify the creator when the task is marked
  1120. complete
  1121. repeattype Specifies the repeat type if non-zero
  1122. value1, value2 Specifies options for the given repeat type, pointless if
  1123. repeattype is zero.
  1124. starttime The exact time the task was created
  1125. startdate The exact date the task was created
  1126. endtime The exact time the task is due
  1127. enddate The exact date the task is due, or the date the task stops
  1128. repeating if repeattype is non-zero
  1129. calendar_task_iteration:
  1130. +-------------+---------+------+-----+---------+-------+
  1131. | Field       | Type    | Null | Key | Default | Extra |
  1132. +-------------+---------+------+-----+---------+-------+
  1133. | task_techid | int(11) |      |     | 0       |       |
  1134. | taskid      | int(11) | YES  |     | NULL    |       |
  1135. | completed   | int(11) | YES  |     | NULL    |       |
  1136. | date        | date    | YES  |     | NULL    |       |
  1137. | time        | time    | YES  |     | NULL    |       |
  1138. +-------------+---------+------+-----+---------+-------+
  1139. No columns in this table constrain values by uniqueness; this permits the same
  1140. task to be assigned to multiple technicians, and multiple tasks to be assigned
  1141. to the same technician. This table stores *completed* task information;
  1142. incomplete tasks are calculated by DeskPRO internally. When a task is marked
  1143. "complete", a row is added here. If that task is later marked "incomplete", the
  1144. appropriate row is removed from here.
  1145. task_techid The technician *assigned* to this task.
  1146. taskid The taskid of the assigned task.
  1147. completed This iteration of the task is completed if non-zero.
  1148. date The exact date the task is due.
  1149. time The exact date the task is due.
  1150. calendar_task_tech:
  1151. +---------------+---------+------+-----+---------+----------------+
  1152. | Field         | Type    | Null | Key | Default | Extra          |
  1153. +---------------+---------+------+-----+---------+----------------+
  1154. | id            | int(10) |      | PRI | NULL    | auto_increment |
  1155. | eventid       | int(10) |      | MUL | 0       |                |
  1156. | email_due     | int(1)  |      |     | 0       |                |
  1157. | email_before1 | int(3)  |      |     | 0       |                |
  1158. | email_before2 | int(3)  |      |     | 0       |                |
  1159. | techid        | int(1)  |      |     | 0       |                |
  1160. | completed     | int(1)  |      |     | 0       |                |
  1161. | stamp         | int(10) | YES  |     | 0       |                |
  1162. +---------------+---------+------+-----+---------+----------------+
  1163. This table stores technician task assignments, and e-mail reminder options.
  1164. id Unique ID
  1165. eventid The event ID.
  1166. email_due If non-zero, mail a reminder *on* the due date to the tech.
  1167. email_before1 If non-zero, mail a reminder the specified number of days
  1168. before the due date to the tech.
  1169. email_before2 If non-zero, mail a reminder the specified number of days
  1170. before the due date to the tech.
  1171. taskid The taskid of the assigned task.
  1172. completed If non-zero, the task is completed (even if not all
  1173. iterations of a repeating task are completed).
  1174. stamp Timestamp of the completion time/date of this task, if
  1175. stamp and completed are non-zero.
  1176. tech_ticket_watch:
  1177. +-----------+---------+------+-----+------------+----------------+
  1178. | Field     | Type    | Null | Key | Default    | Extra          |
  1179. +-----------+---------+------+-----+------------+----------------+
  1180. | id        | int(10) |      | PRI | NULL       | auto_increment |
  1181. | ticketid  | int(10) |      |     | 0          |                |
  1182. | techid    | int(10) |      | MUL | 0          |                |
  1183. | datetodo  | date    | YES  | MUL | 0000-00-00 |                |
  1184. | completed | int(1)  |      |     | 0          |                |
  1185. | created   | int(10) | YES  |     | 0          |                |
  1186. +-----------+---------+------+-----+------------+----------------+
  1187. This table stores ticket watches.
  1188. ticketid Ticket to view.
  1189. techid Technician to be reminded.
  1190. datetodo Date the reminder should appear.
  1191. completed If non-zero, the reminder has been completed.
  1192. created Timestamp of the creation of the reminder.
  1193. */
  1194. ?>