00001 <?
00011 abstract class BaseMessage extends MyObject
00012 {
00016 public $read = false;
00017
00021 public $inboxTable;
00022
00026 public $outboxTable;
00027
00034 public function __construct($data = null, $table = 'messages', $inboxTable = 'inbox', $outboxTable = 'outbox')
00035 {
00036 parent::__construct($data, $table);
00037
00038
00039 $this->inboxTable = $inboxTable;
00040 $this->outboxTable = $outboxTable;
00041
00042 $this->recipients = $this->getRecipients();
00043
00044 $this->needsJs('lib/js/message.js');
00045
00046 if (is_array($data))
00047 $this->read = $data['read'];
00048
00049 $this->fullTextFields[] = 'subject';
00050 $this->fullTextFields[] = 'body';
00051 }
00052
00056 public function delete()
00057 {
00058 dbExecute("
00059 DELETE FROM $this->inboxTable
00060 WHERE message_id = '$this->id'
00061 ");
00062
00063 dbExecute("
00064 DELETE FROM $this->outboxTable
00065 WHERE message_id = '$this->id'
00066 ");
00067
00068 $kids = $this->getChildren();
00069 if (count($kids))
00070 {
00071 foreach ($kids AS $kid)
00072 $kid->delete();
00073 }
00074
00075 parent::delete();
00076 }
00077
00083 protected function getRecipients()
00084 {
00085 if (!is_array($this->recipients))
00086 $ret = explode(",", $this->recipients);
00087 else
00088 $ret = $this->recipients;
00089
00090 return $ret;
00091 }
00092
00096 protected function getEditPageParamXml()
00097 {
00098 return <<<XML
00099 <param name="subject"/>
00100 <param name="body"/>
00101 <param name="user_id"/>
00102 <param name="parent_id"/>
00103 XML;
00104 }
00105
00109 public function initEditPage()
00110 {
00111 global $me;
00112
00113 parent::initEditPage();
00114
00115 $this->pageTitle = 'Send Private Message';
00116
00117 $parentId = $this->params('parent_id');
00118 if ($parentId)
00119 {
00120 $class = get_class($this);
00121 $parent = new $class($parentId);
00122 if (!$parent->canView())
00123 throw new PageError('You cannot reply to this message.');
00124 }
00125 }
00126
00130 public function canEdit()
00131 {
00132 global $me;
00133
00134 if ($this->id && $me->isAdmin())
00135 return true;
00136 if (!$this->id)
00137 return true;
00138
00139 return false;
00140 }
00141
00145 public function editFormAddFields($form)
00146 {
00147 global $me;
00148
00149
00150 $form->layout = new OneColumnTableLayout();
00151
00152 $recipients = array();
00153
00154
00155
00156 $userId = $this->params('user_id');
00157 $user = new User($userId);
00158 if ($userId)
00159 $recipients[$user->id] = $user->getName();
00160
00161
00162 $recipients = $this->createRecipientsList($recipients);
00163
00164
00165 $form->add('MultiSelectField', 'recipients', array(
00166 'multiple' => true,
00167 'required' => true,
00168 'size' => 10,
00169 'noneTitle' => false,
00170 'options' => $recipients,
00171 'explanation' => '
00172 <p>Tip: By holding the \'Ctrl\' key and clicking on names, you
00173 can select multiple people.</p>
00174
00175 <p>Additonally, you can select large chunks of the list by
00176 holding \'Shift\' and clicking names</p>
00177 '
00178 ));
00179
00180 $form->add('TextField', 'subject', array(
00181 "required" => true,
00182 "width" => '100%',
00183 ));
00184
00185 $form->add('TextAreaField', 'body', array(
00186 "required" => true,
00187 "title" => 'Message',
00188 "width" => '100%',
00189 "height" => '150px'
00190 ));
00191
00192 $form->add('HiddenField', 'parent_id', array());
00193
00194 $form->addSubmit('Send Message');
00195 }
00196
00203 protected function createRecipientsList($recipients)
00204 {
00205 return $recipients;
00206 }
00207
00214 public function createReplyForm($recipients)
00215 {
00216 $form = new Form();
00217 $form->action = $this->getUrl(".edit");
00218
00219
00220 if (count($recipients) > 1)
00221 $form->name = 'replyAllForm_' . $this->id;
00222 else
00223 $form->name = 'replyForm_' . $this->id;
00224
00225
00226 $form->add('HiddenField', 'parent_id', array(
00227 'value' => $this->id
00228 ));
00229
00230 $form->add('HiddenField', 'recipients', array(
00231 'value' => array_unique($recipients)
00232 ));
00233
00234 $form->add('HiddenField', 'subject', array(
00235 'value' => $this->subject
00236 ));
00237
00238 $form->add('TextAreaField', 'body', array(
00239 'height' => '75px',
00240 'width' => '100%',
00241 'title' => ''
00242 ));
00243
00244 if (count($recipients) == 1)
00245 {
00246 $user = new User($recipients[0]);
00247 $form->addSubmit('Send to ' . $user->getName());
00248 }
00249 else
00250 $form->addSubmit('Send to All');
00251
00252 return $form;
00253 }
00254
00260 function editFormLoad($form)
00261 {
00262 $userId = $this->params('user_id');
00263 $parentId = $this->params('parent_id');
00264
00265 if (!$this->id)
00266 {
00267 $data = array();
00268
00269
00270 if ($parentId)
00271 {
00272 $class = get_class($this);
00273 $parent = new $class($parentId);
00274
00275
00276 if (preg_match('/^Re:/', $parent->subject))
00277 $subject = $parent->subject;
00278 else
00279 $subject = 'Re: ' . $parent->subject;
00280
00281
00282 $data['parent_id'] = $parentId;
00283 $data['recipients'] = implode(',', $parent->recipients);
00284 $data['subject'] = $subject;
00285 }
00286
00287 else if ($userId)
00288 $data['recipients'] = array($userId);
00289
00290
00291 $form->setData($data);
00292 }
00293 else
00294 parent::editFormLoad($form);
00295 }
00296
00302 function editPagePostSaveSync($form)
00303 {
00304 global $me;
00305
00306 parent::editPagePostSaveSync($form);
00307
00308
00309 $recipients = explode(',', $form->getData('recipients'));
00310 foreach ($recipients AS $id)
00311 $this->addRecipient($id);
00312
00313
00314 $this->addSender($me->id);
00315 }
00316
00322 protected function addSender($id)
00323 {
00324 dbExecute("
00325 INSERT INTO $this->outboxTable
00326 (user_id, message_id)
00327 VALUES
00328 ('$id', '$this->id')
00329 ");
00330 }
00331
00337 protected function addRecipient($id)
00338 {
00339
00340 dbExecute("
00341 INSERT INTO $this->inboxTable
00342 (user_id, message_id)
00343 VALUES
00344 ('$id', '$this->id')
00345 ");
00346
00347
00348 $this->emailRecipient($id);
00349 }
00350
00356 protected function emailRecipient($id)
00357 {
00358 global $me;
00359
00360 $user = new User($id);
00361
00362 $subject = $me->getName() . ' sent you a message on ' . Config::get('site_name');
00363
00364
00365 $body = "You can either log in and view your inbox, or go straight to the message with the link below.\n\n";
00366 $body .= $user->getTicket(strtolower(get_class($this)) . ".view?id=$this->id") . "\n\n";
00367 $body .= "Thank you,\nThe Happy " . Config::get('site_name') . " Message Notification Robot";
00368 $body .= "\n\nPS. You can turn these emails off at:\n" . $user->getUrl(".emailprefs", null, true);
00369
00370
00371 $html = $user->getTicket(strtolower(get_class($this)) . ".view?id=$this->id", 'Click here to read the message.') . "<br/><br/>";
00372 $html .= "Thank you,<br/>The Happy " . Config::get('site_name') . " Message Notification Robot";
00373 $html .= "<br/><br/>PS. You can turn these emails off " . $user->getLink('.emailprefs', 'here.', null, true);
00374
00375 $user->mail($subject, $body, $html);
00376 }
00377
00381 public function initViewPage()
00382 {
00383 $this->assertLogin();
00384
00385
00386 $this->id = $this->params('id');
00387 $this->recipients = $this->getRecipients();
00388
00389
00390 parent::initViewPage();
00391
00392 $this->pageTitle = "View Message - $this->subject";
00393 }
00394
00398 public function canView()
00399 {
00400 global $me;
00401
00402 if ($this->user_id == $me->id)
00403 return true;
00404 if (in_array($me->id, $this->recipients))
00405 return true;
00406 return false;
00407 }
00408
00412 public function drawViewPage()
00413 {
00414 global $me;
00415
00416
00417 if ($this->parent_id)
00418 {
00419 $class = get_class($this);
00420 $parent = new $class($this->parent_id);
00421
00422 if ($parent->parent_id)
00423 {
00424 echo "<div class=\"titleBar\">\n";
00425 echo "<div class=\"titleText\">\n";
00426 $this->drawUrl(".view?id=$parent->parent_id", 'Previous Message');
00427 echo "</div></div>";
00428 }
00429
00430 echo "<ol class=\"threaded\">\n";
00431 $parent->drawMessage(true);
00432 echo "</ol>\n";
00433 }
00434
00435 else
00436 {
00437 echo "<ol class=\"threaded\">\n";
00438 $this->drawMessage(true);
00439 echo "</ol>\n";
00440 }
00441 }
00442
00446 public function drawRecipients()
00447 {
00448 $recips = array();
00449 foreach ($this->recipients AS $key)
00450 {
00451 $recipient = new User($key);
00452 $recips[] = $recipient->getName(true, 'tiny');
00453 }
00454 echo implode(", ", $recips);
00455 }
00456
00464 protected function getRecipientIds($ignoreMe = false)
00465 {
00466 global $me;
00467
00468 $recips = array();
00469 foreach ($this->recipients AS $key)
00470 {
00471 if (!$ignoreMe || ($ignoreMe && $me->id != $key))
00472 $recips[] = $key;
00473 }
00474
00475 return $recips;
00476 }
00477
00483 public function drawMessage($kids = false)
00484 {
00485 global $me;
00486
00487 if ($this->canView())
00488 {
00489
00490 $this->markRead();
00491
00492 echo "<li class=\"threaded\">\n";
00493
00494
00495 $this->drawTitleBar();
00496 $this->drawMessageDetails();
00497
00498
00499 echo "<div class=\"childContainer\">\n";
00500
00501
00502 $this->drawMessageBody();
00503
00504
00505 if (!$this->creator->isMe())
00506 $this->drawMessageReplyForm();
00507
00508
00509 $this->drawChildMessages($kids, $this->id);
00510
00511 echo "</div>";
00512
00513
00514 echo "</li>";
00515 }
00516 }
00517
00521 protected function drawTitleBar()
00522 {
00523
00524 echo "<div class=\"titlebar\">";
00525
00526
00527 echo '<table class="struct"><tr><td class="titleLeft">';
00528
00529 echo $this->creator->getIcon();
00530
00531
00532 if ($this->creator->isMe())
00533 echo "You";
00534 else
00535 echo $this->creator->getName(true);
00536 echo " said to ";
00537
00538
00539 if (count($this->recipients) > 1)
00540 echo "everyone";
00541 else if ($this->recipients[0] == $me->id)
00542 echo "me";
00543 else
00544 {
00545 $recip = new User($this->recipients[0]);
00546 echo $recip->getName(true);
00547 }
00548
00549 echo ": " . Time::formatRelative($this->add_date);
00550
00551
00552 echo '</td><td class="titleRight">';
00553
00554
00555 if (!$this->creator->isMe())
00556 {
00557 echo "\t<span class=\"titleLink\" id=\"messageReplyLink_$this->id\">";
00558 echo "<a href=\"" . $this->getUrl(array('page' => 'edit', 'parent_id' => $this->id));
00559 echo "\" onclick=\"return showReplyForm('$this->id');\">reply</a></span>\n";
00560 if (count($this->recipients) > 1)
00561 {
00562 echo "\t<span class=\"titleLink\" id=\"messageReplyAllLink_$this->id\">";
00563 echo "<a href=\"" . $this->getUrl(array('page' => 'edit', 'parent_id' => $this->id));
00564 echo "\" onclick=\"return showReplyAllForm('$this->id');\">reply all</a></span>\n";
00565 }
00566 }
00567
00568 echo "\t<span class=\"titleLink\" id=\"messageOptions_$this->id\">";
00569 echo "<a href=\"#\" onclick=\"return showMessageOptions('$this->id');\">options</a>";
00570 echo "</span>\n";
00571
00572
00573 echo "</td></tr></table>";
00574
00575
00576 echo "</div>\n";
00577 }
00578
00582 protected function drawMessageDetails()
00583 {
00584
00585 echo "<div class=\"messageDetail\" id=\"message_$this->id\" style=\"display: none;\">";
00586 echo "<table>";
00587 echo "<tr><td>Subject:</td><td> $this->subject</td></tr>";
00588 echo "<tr><td>Sent by:</td><td> " . $this->creator->getName(true) . "</td></tr>\n";
00589 echo "<tr><td>Sent: </td><td>" . Time::formatRelative($this->add_date, false) . "</td></tr>\n";
00590 echo "<tr><td>Recipients: </td><td>";
00591 $this->drawRecipients();
00592 echo "</td></tr></table>";
00593 echo "</div>\n";
00594 }
00595
00599 protected function drawMessageBody()
00600 {
00601 echo "<div class=\"messageBody\">";
00602 echo Linkify::bbcode($this->body);
00603 $this->drawMessageSignature();
00604 echo "</div>";
00605 }
00606
00612 protected function drawMessageSignature()
00613 {
00614 }
00615
00619 protected function drawMessageReplyForm()
00620 {
00621
00622 echo "<div class=\"messageReply\" id=\"messageReply_$this->id\" style=\"display: none;\">\n";
00623 $form = $this->createReplyForm(array($this->creator->id));
00624 $form->drawAll();
00625 echo "</div>\n";
00626
00627
00628 if (count($this->recipients) > 1)
00629 {
00630 echo "<div class=\"messageReply\" id=\"messageReplyAll_$this->id\" style=\"display: none;\">\n";
00631
00632 $recips = $this->getRecipientIds(true);
00633 $recips[] = $this->user_id;
00634
00635 $form = $this->createReplyForm($recips);
00636 $form->drawAll();
00637 echo "</div>\n";
00638 }
00639 }
00640
00646 function drawChildMessages()
00647 {
00648
00649 $kidRs = dbQuery("
00650 SELECT id
00651 FROM $this->tableName
00652 WHERE parent_id = '$this->id'
00653 ORDER BY add_date DESC
00654 ");
00655
00656 if (dbGetNumRows($kidRs))
00657 {
00658 echo "<div class=\"threaded\">";
00659 echo "<ol class=\"threaded\">\n";
00660 while ($kidAr = dbFetchAssoc($kidRs))
00661 {
00662 $class = get_class($this);
00663 $kid = new $class($kidAr['id']);
00664 $kid->drawMessage(true);
00665 }
00666 echo "</ol>\n";
00667 echo "</div>";
00668 }
00669 }
00670
00676 function drawHeaderRow($type)
00677 {
00678 echo "<tr class=\"headerRow\">\n";
00679 echo "\t<th id=\"messageCheck\">\n";
00680 echo "\t\t<input type=\"checkbox\" name=\"checkAll\" onclick=\"setAllMessages(this.checked);\"/>\n";
00681 echo "\t</th>\n";
00682
00683 if ($type == 'inbox')
00684 echo "\t<th id=\"messagePeople\">From</th>\n";
00685 else
00686 echo "\t<th id=\"messagePeople\">Recipients</th>\n";
00687
00688 echo "\t<th id=\"messageSubject\">Subject</th>\n";
00689
00690 echo "\t<th id=\"messageDate\">Sent</th>\n";
00691
00692 echo "</tr>\n";
00693 }
00694
00701 function drawRow($type, $on)
00702 {
00703 global $me;
00704
00705 $class = "messageRow";
00706 if (!$this->read && $me->id != $this->user_id)
00707 $class .= " unread";
00708 if ($on)
00709 $class .= " on";
00710
00711 echo "<tr class=\"$class\">\n";
00712
00713 echo "\t<td class=\"messageCheck\">\n";
00714 echo "\t\t<input type=\"checkbox\" name=\"message[]\" value=\"$this->id\"/>\n";
00715 echo "\t</td>\n";
00716
00717 if ($type == 'inbox')
00718 {
00719 echo "\t<td class=\"messagePeople\">\n";
00720 echo "\t\t" . $this->creator->getName(true, 'tiny') . "\n";
00721 echo "\t</td>\n";
00722 }
00723 else
00724 {
00725 echo "\t<td class=\"messagePeople\">\n";
00726 echo "\t\t";
00727 echo $this->drawRecipients();
00728 echo "\n\t</td>\n";
00729 }
00730
00731 echo "\t<td class=\"messageSubject\">\n\t\t";
00732 $this->drawUrl(array('page' => 'view', 'id' => $this->id), $this->subject);
00733 echo "\n\t</td>\n";
00734
00735
00736 echo "\t<td class=\"messageDate\">\n";
00737 echo "\t\t" . Time::formatRelative($this->add_date, false) . "\n";
00738 echo "\t</td>\n";
00739 echo "</tr>\n";
00740 }
00741
00747 function markRead($force = false)
00748 {
00749 global $me;
00750
00751 if (in_array($me->id, $this->recipients) || $force)
00752 {
00753 dbExecute("
00754 UPDATE $this->inboxTable
00755 SET `read` = '1'
00756 WHERE user_id = '$me->id'
00757 AND message_id = '$this->id'
00758 ");
00759 }
00760 }
00761
00769 function getChildren()
00770 {
00771 $kids = array();
00772
00773 if ($this->id)
00774 {
00775 $rs = dbQuery("
00776 SELECT *
00777 FROM $this->tableName
00778 WHERE parent_id = '$this->id'
00779 ");
00780 while ($ar = dbFetchAssoc($rs))
00781 $kids[] = new Message($ar);
00782 }
00783
00784 return $kids;
00785 }
00786
00790 function getRssItem()
00791 {
00792 $rss = parent::getRssItem();
00793
00794 $rss->title = $this->subject;
00795 $rss->description = $this->body;
00796
00797 return $rss;
00798 }
00799
00803 function getPublicData()
00804 {
00805 $data = parent::getPublicData();
00806
00807 $data['name'] = $this->subject;
00808 $data['message'] = $this->body;
00809 $data['read'] = $this->read;
00810
00811 return $data;
00812 }
00813
00817 public function getName($link = false)
00818 {
00819 return parent::getName($link, $this->subject);
00820 }
00821
00827 public function getCreateFieldsArray()
00828 {
00829 $fields = parent::getCreateFieldsArray();
00830
00831 $fields['parent_id'] = "parent_id int(11) default 0 not null";
00832 $fields['subject'] = "subject varchar(255) default '' not null";
00833 $fields['body'] = "body text default '' not null";
00834 $fields['recipients'] = "recipients text default '' not null";
00835
00836 return $fields;
00837 }
00838
00844 public function getCreateIndexesArray()
00845 {
00846 $fields = parent::getCreateIndexesArray();
00847
00848 $fields['parent_id'] = "key(parent_id)";
00849
00850 return $fields;
00851 }
00852 }
00853 ?>