summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2010-07-06 13:21:30 +0000
committerdeva <deva>2010-07-06 13:21:30 +0000
commit093e36530916e21c09cbe55efd03d2825fe820b4 (patch)
treef377d747422df3cc4df26ea14e2aadcfb0ee9730
parenta7b6200402e341e97472ec401eabe4cf49f1161c (diff)
New tasks system.
-rw-r--r--forum/htdocs/index.php10
-rw-r--r--forum/utils/tasks.php295
2 files changed, 303 insertions, 2 deletions
diff --git a/forum/htdocs/index.php b/forum/htdocs/index.php
index 7e372c7..c4e0570 100644
--- a/forum/htdocs/index.php
+++ b/forum/htdocs/index.php
@@ -40,12 +40,13 @@ include_once($UTIL_DIR . "/clientinfo.php");
<?php if($mode == "editor") {?> <script language="javascript" src="lib.js" type="text/javascript"></script><?php } ?>
</head>
<body>
- <div class="menu">
+ <div id="menu_top" class="menu">
<a href="?mode=forum">Forum</a>
<a href="?mode=filehandler">Filehandler</a>
<a href="?mode=calendar">Calendar</a>
<a href="?mode=addressbook">Addressbook</a>
<a href="?mode=profile">Profile</a>
+ <a href="?mode=tasks">Tasks</a>
<?php if($current_user->uid == 0) {?> <a href="?mode=diagnostics">Diagnostics</a><?php } ?>
</div>
<?php
@@ -64,6 +65,10 @@ if($current_user) {
include_once($UTIL_DIR. "/profile.php");
break;
+ case "tasks":
+ include_once($UTIL_DIR. "/tasks.php");
+ break;
+
case "calendar":
include_once($UTIL_DIR. "/calendar.php");
break;
@@ -92,12 +97,13 @@ if($current_user) {
default:
include_once($UTIL_DIR. "/view.php");
?>
- <div class="menu">
+ <div id="menu_bottom" class="menu">
<a href="?mode=forum">Forum</a>
<a href="?mode=filehandler">Filehandler</a>
<a href="?mode=calendar">Calendar</a>
<a href="?mode=addressbook">Addressbook</a>
<a href="?mode=profile">Profile</a>
+ <a href="?mode=tasks">Tasks</a>
<?php if($current_user->uid == 0) {?> <a href="?mode=diagnostics">Diagnostics</a><?php } ?>
</div>
<?php
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&amp;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&amp;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>