diff options
Diffstat (limited to 'forum/utils/tasks.php')
-rw-r--r-- | forum/utils/tasks.php | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/forum/utils/tasks.php b/forum/utils/tasks.php new file mode 100644 index 0000000..3c5cbcd --- /dev/null +++ b/forum/utils/tasks.php @@ -0,0 +1,295 @@ +<?php +include_once($UTIL_DIR . "/error.php"); +include_once($UTIL_DIR . "/notify.php"); + +function xmlenc($message) +{ + return htmlspecialchars($message, ENT_QUOTES, "UTF-8"); +} + +function userList($uid) { + global $users; + $str = ""; + $str .= "<select name=\"userid\">\n"; + foreach($users->users as $user) { + if($user->enabled && $user->uid != 0) { + $str .= "<option value=\"".$user->uid."\""; + if($user->uid == $uid) $str .= " selected"; + $str .= ">".$user->name."</option>\n"; + } + } + $str .= "</select>"; + return $str; +} + +class Task { + public $id; + public $title; + public $deadline; + public $description; + public $lastreminder; + public $reassignable; + public $userid; + public $completed; + + public function write($fp) + { + fwrite($fp, " <task id=\"" .xmlenc($this->id) . "\"\n"); + fwrite($fp, " title=\"" .xmlenc($this->title) . "\"\n"); + fwrite($fp, " deadline=\"" . xmlenc($this->deadline) . "\"\n"); + fwrite($fp, " userid=\"" . xmlenc($this->userid) . "\"\n"); + if($this->reassignable) fwrite($fp, " reassignable=\"true\"\n"); + else fwrite($fp, " reassignable=\"false\"\n"); + if($this->completed) fwrite($fp, " completed=\"true\"\n"); + else fwrite($fp, " completed=\"false\"\n"); + fwrite($fp, " lastreminder=\"" . xmlenc($this->lastreminder) . "\">\n"); + fwrite($fp, " <description>".xmlenc($this->description)."</description>\n"); + if($this->refs) $this->refs->write($fp, " "); + fwrite($fp, " </task>\n"); + } + + public function show() + { + global $users, $current_user; + $str .= " <tr>\n"; + $str .= " <form method=\"post\" enctype=\"multipart/form-data\" ". + "action=\"?mode=tasks&action=update\">\n"; + $str .= " <input type=\"hidden\" name=\"id\" value=\"".$this->id."\"/>\n"; + if($this->userid == $current_user->uid) { + $str .= " <td>Done<input name=\"completed\" type=\"checkbox\""; + if($this->completed) $str .= " checked"; + $str .= "/></td>\n"; + } else { + if($this->completed) $str .= " <td>Done ☑</td>\n"; + else $str .= " <td>Done ☐</td>\n"; + } + $str .= " <td><strong>".$this->title."</strong></td>\n"; + $str .= " <td>".substr($this->description, 0, 64)."</td>\n"; + + if($this->reassignable && $this->userid == $current_user->uid) { + $str .= " <td>".userList($this->userid)."</td>\n"; + } else { + $str .= " <td><em>".$users->getUser($this->userid)->name."</em></td>\n"; + } + + $str .= " <td>Deadline ".date("j/n-Y", $this->deadline)."</td>\n"; + $str .= " <td height=\"24px;\">"; + if($this->userid == $current_user->uid) $str .= "<input type=\"submit\" value=\"set\"/>"; + $str .= "</td>\n"; + $str .= " </form>\n"; + $str .= " </tr>\n"; + return $str; + } + + public function mailTextSubject() + { + return $this->title . " - deadline: ".date("j/n-Y", $this->deadline); + } + + public function mailTextBody() + { + return $this->title . "\n\n" . $this->description . "\n\nDeadline: ".date("j/n-Y", $this->deadline); + } + + public function Task($id, $title, $deadline, $description, $lastreminder, + $reassignable, $userid, $completed) + { + $this->id = $id; + $this->title = $title; + $this->deadline = $deadline; + $this->description = $description; + $this->lastreminder = $lastreminder; + $this->reassignable = $reassignable; + $this->userid = $userid; + $this->completed = $completed; + } +} + +class Tasks { + + private $file; + public $tasks = array(); + + public function show() + { + $str = "<table>\n"; + + foreach($this->tasks as $task) { + if($task->completed == false) { + $str .= $task->show(); + } + } + + foreach($this->tasks as $task) { + if($task->completed == true) { + $str .= $task->show(); + } + } + + $str .= "</table>\n"; + return $str; + } + + public function add($task) { + $this->tasks[$task->id] = $task; + } + + public function getNextID() + { + $id = 0; + foreach($this->tasks as $task) { + if($task->id > $id) $id = $task->id; + } + return $id + 1; + } + + public function write() + { + $fp = fopen($this->file, "w"); + fwrite($fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + + fwrite($fp, "<tasks>\n"); + foreach($this->tasks as $task) { + $task->write($fp); + } + fwrite($fp, "</tasks>\n"); + + fclose($fp); + } + + private function read() + { + $dom = new DomDocument; + $dom->preserveWhiteSpace = FALSE; + $dom->load($this->file); + $params = $dom->getElementsByTagName('task'); + + foreach($params as $param) { + + $description = ""; + $dess = $param->getElementsByTagName('description'); + foreach($dess as $des) { + $description = $des->textContent; + } + + $task = new Task($param->getAttribute('id'), + $param->getAttribute('title'), + $param->getAttribute('deadline'), + $description, + $param->getAttribute('lastreminder'), + $param->getAttribute('reassignable') == "true", + $param->getAttribute('userid'), + $param->getAttribute('completed') == "true"); + + $this->add($task); + } + } + + public function Tasks($file) + { + $this->file = $file; + if(file_exists($file)) $this->read(); + } + +} + +function tasks_init() +{ + global $DATA_DIR; + return new Tasks($DATA_DIR . "/tasks.xml"); +} + +function sendMail($id, $new, $reassigned) +{ + global $tasks, $users; + + $task = $tasks->tasks[$id]; + $task->lastreminder = time(); + $tasks->write(); + + $user = $users->getUser($task->userid); + + $prefix = "Task Reminder - "; + if($new) $prefix = "New Task - "; + if($reassigned) $prefix = "Reassigned Task - "; + + $email = $user->email; + $subject = $prefix . $task->mailTextSubject(); + $body = $task->mailTextBody(); + + send($email, $subject, $body); +} + +$tasks = tasks_init(); + +if($action == "tick") { + $now = time(); + + $mininterval = 60 * 60 * 24; // 24 hours + $maxinterval = 60 * 60 * 24 * 7; // 1 week + + foreach($tasks->tasks as $task) { + + if($task->completed) continue; // no need for reminding + + if(($now > $task->deadline) && (($now - $task->lastreminder) > $mininterval)) { + // Deadline is overdue, and it has been more than $mininterval since last reminder. + sendMail($task->id, false, false); + } elseif((($task->deadline - $now) > $maxinterval) && (($now - $task->lastreminder) > $maxinterval)) { + // Deadline is a long way off, but it has been $maxinterval since last reminder. + sendMail($task->id, false, false); + } elseif((($task->deadline - $now) > $mininterval) && (($now - $task->lastreminder) > $mininterval)) { + // Deadline is near, and it has been $mininterval since last reminder. + sendMail($task->id, false, false); + } + } +} + +if($action == "update") { + $reassigned = false; + $id = $GLOBALS['id']; + $task = $tasks->tasks[$id]; + if(isset($GLOBALS['completed'])) $task->completed = $GLOBALS['completed'] == "on"; + if(isset($GLOBALS['userid'])) { + $reassigned = $task->userid != $GLOBALS['userid']; + $task->userid = $GLOBALS['userid']; + } + $tasks->write(); + + if($reassigned) sendMail($id, false, true); +} + +if($action == "add") { + + $deadline = strtotime($GLOBALS['deadline_year']."-". + $GLOBALS['deadline_month']."-". + $GLOBALS['deadline_day']); + + $task = new Task($tasks->getNextID(), + stripslashes($GLOBALS['title']), + $deadline, + stripslashes($GLOBALS['description']), + 0, + $GLOBALS['reassignable'] == "on", + $GLOBALS['userid'], + false); + $tasks->add($task); + $tasks->write(); + + sendMail($task->id, true, false); +} + +echo $tasks->show(); +?> +<hr/> +<form method="post" enctype="multipart/form-data" action="?mode=tasks&action=add"> + Title: <input name="title" value=""><br/> + User: <?php echo userList($current_user->uid); ?><br/> + Deadline: D<input name="deadline_day" style="width: 2em" value=""> + M<input name="deadline_month" style="width: 2em" value=""> + Y<input name="deadline_year" style="width: 4em" value=""><br/> + Reassignable: <input name="reassignable" type="checkbox" checked><br/> + <textarea name="description" cols="60" rows="2"></textarea><br/> + <br/> + <button type="submit">Add</button> +</form> |