From 767f0b5559472828c09be7de50c80f017cc0540a Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sun, 4 Jun 2017 00:51:21 -0400 Subject: mesg: Add mesg class --- app/class/mesg.class.php | 249 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 app/class/mesg.class.php (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php new file mode 100644 index 0000000..f9766ca --- /dev/null +++ b/app/class/mesg.class.php @@ -0,0 +1,249 @@ +fields['mesgs'] = array( + "guid", + "author", + "mesg", + "attachment", + ); + + parent::__construct($guid); + + try + { + $this->expectType("log"); + } + catch (Exception $e) + { + $this->expectType("mesg"); + } + } + + /* + * Initialize a new regular message. + */ + public static function initNew(string $message, user $author, object $parent) : mesg + { + $mesg = new mesg(); + $mesg->setOwner($author); + $mesg->setParent($parent); + $mesg->name = "message " . $mesg->guid; + $mesg->objtype = "mesg"; + $mesg->setAuthor($author); + $mesg->mesg = $message; + $mesg->saveObj(); + return $mesg; + } + + /* + * Initialize a new pad discussion thread. + */ + public static function initNewDiscussion(string $name, string $message, user $author, + pad $parent) : mesg + { + $mesg = new mesg(); + $mesg->setOwner($author); + $mesg->setParent($parent); + $mesg->name = $name; + $mesg->objtype = "mesg"; + $mesg->setAuthor($author); + $mesg->mesg = $message; + $mesg->saveObj(); + return $mesg; + } + + /* + * Initialize a new private message (user-to-user). + */ + public static function initNewPM(string $name, string $message, user $author, + user $rcpt) : mesg + { + $mesg = new mesg(); + $mesg->setOwner($rcpt); + $mesg->setParent($rcpt); + $mesg->name = $name; + $mesg->objtype = "mesg"; + $mesg->setAuthor($author); + $mesg->mesg = $message; + $mesg->saveObj(); + return $mesg; + } + + /* + * Initialize a new log message. + */ + public static function initNewLog(string $message, user $author, object $parent) : mesg + { + $owner = $parent->getOwner(); + + if (!$owner) + $owner = $parent; + + $mesg = new mesg(); + $mesg->setOwner($owner); + $mesg->setParent($parent); + $mesg->name = "log " . $mesg->guid; + $mesg->objtype = "log"; + $mesg->setAuthor($author); + $mesg->mesg = $message; + $mesg->saveObj(); + return $mesg; + } + + /* + * Initialize a new admin log message. + */ + public static function initNewAdminLog(string $message, user $author) : mesg + { + $mesg = new mesg(); + $mesg->saveObj(); // need to get a guid + $mesg->name = "admin log " . $mesg->guid; + $mesg->objtype = "log"; + $mesg->setAuthor($author); + $mesg->mesg = $message; + $mesg->saveObj(); + return $mesg; + } + + /* + * Get an array of messages in the admin log, between two timestamps. + * With no arguments, the entire log is returned. Results are sorted + * in reverse chronological order. + */ + public static function getAdminLog_ordByDatetime(?string $after = NULL, + ?string $before = NULL) : array + { + $query = "SELECT guid FROM objects WHERE objtype = 'log' AND " . + "parent = '' "; + + if ($after) + $query += "AND created >= '" . database::esc($after) . "' "; + + if ($before) + $query += "AND created < '" . database::esc($before) . "' "; + + $query += "ORDER BY created DESC"; + $res = database::query($query); + + $log = array(); + + foreach ($res as $l) + $log[] = new mesg($l['guid']); + + return $log; + } + + /* + * Get the author of this message. This user either actually wrote + * this message, or caused it to be generated. + */ + public function getAuthor() : user + { + if (!isset($this->author) || $this->author == "") + return NULL; + + return new user($this->author); + } + + /* + * Set the author of this message. This should usually only be done + * while constructing a new message or to clear out references to + * a user that got removed. + */ + public function setAuthor(user $author) : void + { + $this->author = $author->guid; + $this->saveObj(); + } + + /* + * Check whether this message has been seen by the given user + */ + public function seenBy(user $viewer) : bool + { + $query = "SELECT * FROM views WHERE guid = '" . database::esc($this->guid) . "' " . + "AND viewer = '" . database::esc($viewer->guid) . "'"; + $res = database::query($query); + + return count($res) > 0; + } + + /* + * Mark this message as seen by the given user + */ + public function markSeen(user $viewer) : void + { + if (!$this->seenBy($viewer)) + { + $query = "INSERT INTO views (guid, viewer) VALUES ('" . + database::esc($this->guid) . "', '" . database::esc($viewer->guid) . "')"; + database::query($query); + } + } + + /* + * Format message (if auto generated), and insert HTML linebreaks (
) + * at message newlines. + */ + public function renderMesg() : string + { + if ($this->objtype == "log") + $mesg = sprintf($this->mesg, $this->getAuthor()->getDisplayName()); + else + $mesg = $this->mesg; + + return nl2br($mesg); + } + + /* + * Get the URL to this message's attachment. If no file is attached, + * NULL is returned. + */ + public function getAttachment() : ?string + { + if (!is_file("dynmic/attach/" . $this->guid)) + return NULL; + + return ar() . "/df.php?d=attach&f=" . $this->guid; + } + + /* + * Set the attached file for this message. Should typically be done + * during new message creation and not changed afterward. Returns + * false if there is a problem saving the attachment. + */ + public function setAttachment(array $file) : bool + { + $path = "dynmic/attach/" . $this->guid; + return saveFile($file, $path, self::ATTACH_MAXSIZE); + } +} + +?> -- cgit v1.2.3 From 4ba37714838e1f863c264d6bea7c7de75cd62514 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sun, 4 Jun 2017 15:38:22 -0400 Subject: Define maxsize of attachment uploads Value set to 512 megabytes. --- app/class/mesg.class.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php index f9766ca..fd541cd 100644 --- a/app/class/mesg.class.php +++ b/app/class/mesg.class.php @@ -22,6 +22,11 @@ require_once "class/pad.class.php"; */ class mesg extends object { + /* + * Constants used for uploading attachments + */ + public const ATTACH_MAXSIZE = 536870912; // 512Mb + /* * Constructor */ -- cgit v1.2.3 From d677fe73839b22fe2065be5a7f6c49a1b11e8c18 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sun, 4 Jun 2017 15:44:13 -0400 Subject: Update mesg function setAttachment() Now saving the original name of the attachment file in the message object. --- app/class/mesg.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php index fd541cd..5d6ba4d 100644 --- a/app/class/mesg.class.php +++ b/app/class/mesg.class.php @@ -247,7 +247,13 @@ class mesg extends object public function setAttachment(array $file) : bool { $path = "dynmic/attach/" . $this->guid; - return saveFile($file, $path, self::ATTACH_MAXSIZE); + $origName = ""; + + $ret = saveFile($file, $path, self::ATTACH_MAXSIZE, NULL, $origName); + $this->attachment = $origName; + $this->saveObj(); + + return $ret; } } -- cgit v1.2.3 From 8e9beac9888e894c8db46401b0d5b4c4cb18407d Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Sun, 4 Jun 2017 20:25:35 -0400 Subject: Add mesg function makeIssue() This feature allows a pad-level discussion to be promoted to an issue. A new object is created, but all content is preserved. However, if the thread OP message had an attachment, that attachment cannot be retained. --- app/class/mesg.class.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php index 5d6ba4d..6c84d4f 100644 --- a/app/class/mesg.class.php +++ b/app/class/mesg.class.php @@ -15,6 +15,8 @@ require_once "class/object.class.php"; require_once "class/user.class.php"; require_once "class/pad.class.php"; +require_once "class/stage.class.php"; +require_once "class/issue.class.php"; /* * This class models issue activity, private messaging, pad discussions, @@ -255,6 +257,31 @@ class mesg extends object return $ret; } + + /* + * Promote a pad discussion thread to an issue. This message object + * must be the top-level message (op) of the discussion thread (ie: + * its parent must be a pad). All reply messages to this one are + * retained and will be messages left on the new issue. A new issue + * object is created and this message object will be destroyed. If + * this is not an eligible message for promotion, NULL is returned. + */ + public function makeIssue(stage $parent) : ?issue + { + if ($this->getParent()->objtype != "pad") + return NULL; + + $issue = issue::initNew($this->name, $this->getOwner(), $parent); + $issue->created = $this->created; + $issue->description = $this->mesg; + $issue->saveObj(); + + foreach ($this->getMesgs_ordByDatetime() as $mesg) + $mesg->setParent($issue); + + $this->delObj(); + return $issue; + } } ?> -- cgit v1.2.3 From 1162f87e4326868160cfddaa524efd1386b34133 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Tue, 13 Jun 2017 22:35:17 -0400 Subject: Add mesg function emailMesg() --- app/class/mesg.class.php | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php index 6c84d4f..da52fa6 100644 --- a/app/class/mesg.class.php +++ b/app/class/mesg.class.php @@ -282,6 +282,56 @@ class mesg extends object $this->delObj(); return $issue; } + + /* + * Email this message to parents, owners, members. In the case that + * this is an issue message or a reply message, the assignee or original + * author is also included. Attachments are included in mailing. Any + * duplicates in the rcpt list are removed before sending. Success + * or failure is returned. + */ + public function emailMesg() : bool + { + $parent = $this->getParent(); + + if (!$parent) + return true; + + $rcpt = $this->getMembers(); + $rcpt[] = $this->getOwner(); + + switch ($parent->objtype) + { + case "user": + $rcpt[] = $parent; + $subj = $this->author . " PM from " . $this->getAuthor()->getDisplayName(); + break; + + case "issue": + $rcpt[] = $parent->getAssignee(); + $pad = $parent->getPad(); + $subj = $parent->guid . " " . $pad->name . " [#" . $parent->numb . "] " . $parent->name; + break; + + case "mesg": + case "log": + $rcpt[] = $parent->getAuthor(); + $pad = $parent->getParent(); + $subj = $parent->guid . " " . $pad->name . " // " . $parent->name; + break; + } + + $rcpt = object::arrayUnique($rcpt); + $attachPath = ($this->getAttachment() ? "dynmic/attach/" . $this->guid : NULL); + + foreach ($rcpt as $r) + { + if (!$r->sendEmail($subj, $this->mesg, $attachPath, $this->attachment)) + return false; + } + + return true; + } } ?> -- cgit v1.2.3 From 9fd988bf44089634bd3efa8acc95368cf45c2498 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Wed, 14 Jun 2017 00:53:13 -0400 Subject: Update mesg function emailMesg() Fixed a bug and fine-tuned some of the behavior of this function. --- app/class/mesg.class.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php index da52fa6..2512d03 100644 --- a/app/class/mesg.class.php +++ b/app/class/mesg.class.php @@ -297,14 +297,14 @@ class mesg extends object if (!$parent) return true; - $rcpt = $this->getMembers(); - $rcpt[] = $this->getOwner(); + $rcpt = $parent->getMembers(); + $rcpt[] = $parent->getOwner(); switch ($parent->objtype) { case "user": $rcpt[] = $parent; - $subj = $this->author . " PM from " . $this->getAuthor()->getDisplayName(); + $subj = $this->author . " " . $this->getAuthor()->getDisplayName() . " // " . $this->name; break; case "issue": @@ -322,11 +322,15 @@ class mesg extends object } $rcpt = object::arrayUnique($rcpt); + $author = $this->author; + $rcpt = array_filter($rcpt, function ($val) use($author) { return $val->guid != $author; }); $attachPath = ($this->getAttachment() ? "dynmic/attach/" . $this->guid : NULL); + $mesg = $this->getAuthor()->getDisplayName() . " wrote on " . $this->created . "\n\n"; + $mesg .= $this->renderMesg(); foreach ($rcpt as $r) { - if (!$r->sendEmail($subj, $this->mesg, $attachPath, $this->attachment)) + if (!$r->sendEmail($subj, $mesg, $attachPath, $this->attachment)) return false; } -- cgit v1.2.3 From e54418762e279a1d7ca0efb7ed89b95464753ee8 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Wed, 7 Feb 2018 22:33:19 -0500 Subject: Update class files to use renamed obj class --- app/class/mesg.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php index 2512d03..1a864c0 100644 --- a/app/class/mesg.class.php +++ b/app/class/mesg.class.php @@ -12,7 +12,7 @@ * For more information, please refer to UNLICENSE */ -require_once "class/object.class.php"; +require_once "class/obj.class.php"; require_once "class/user.class.php"; require_once "class/pad.class.php"; require_once "class/stage.class.php"; @@ -22,7 +22,7 @@ require_once "class/issue.class.php"; * This class models issue activity, private messaging, pad discussions, * and system and object log messages. */ -class mesg extends object +class mesg extends obj { /* * Constants used for uploading attachments @@ -56,7 +56,7 @@ class mesg extends object /* * Initialize a new regular message. */ - public static function initNew(string $message, user $author, object $parent) : mesg + public static function initNew(string $message, user $author, obj $parent) : mesg { $mesg = new mesg(); $mesg->setOwner($author); @@ -106,7 +106,7 @@ class mesg extends object /* * Initialize a new log message. */ - public static function initNewLog(string $message, user $author, object $parent) : mesg + public static function initNewLog(string $message, user $author, obj $parent) : mesg { $owner = $parent->getOwner(); @@ -321,7 +321,7 @@ class mesg extends object break; } - $rcpt = object::arrayUnique($rcpt); + $rcpt = obj::arrayUnique($rcpt); $author = $this->author; $rcpt = array_filter($rcpt, function ($val) use($author) { return $val->guid != $author; }); $attachPath = ($this->getAttachment() ? "dynmic/attach/" . $this->guid : NULL); -- cgit v1.2.3 From 866c16abdce264362edb7f5a3c35e7bab9ddf2a5 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Wed, 19 Sep 2018 15:46:26 -0400 Subject: Update all usage of saveFile() Update all usage of saveFile() to use added saveIfFile() function, forwarding on the convenience to model code. Model code can pass in file field names, rather than $_FILES arrays directly. --- app/class/mesg.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/class/mesg.class.php') diff --git a/app/class/mesg.class.php b/app/class/mesg.class.php index 1a864c0..2e5c9d6 100644 --- a/app/class/mesg.class.php +++ b/app/class/mesg.class.php @@ -246,12 +246,12 @@ class mesg extends obj * during new message creation and not changed afterward. Returns * false if there is a problem saving the attachment. */ - public function setAttachment(array $file) : bool + public function setAttachment(string $file) : bool { $path = "dynmic/attach/" . $this->guid; $origName = ""; - $ret = saveFile($file, $path, self::ATTACH_MAXSIZE, NULL, $origName); + $ret = saveIfFile($file, $path, self::ATTACH_MAXSIZE, NULL, $origName); $this->attachment = $origName; $this->saveObj(); -- cgit v1.2.3