diff options
Diffstat (limited to 'lib/models/Message.php')
| -rw-r--r-- | lib/models/Message.php | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/lib/models/Message.php b/lib/models/Message.php new file mode 100644 index 0000000..fb6b78e --- /dev/null +++ b/lib/models/Message.php @@ -0,0 +1,343 @@ +<?php +/** + * Message.php + * model class for table message + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * @author mlunzena + * @copyright (c) Authors + * + * @property string $id alias column for message_id + * @property string $message_id database column + * @property string $autor_id database column + * @property string $subject database column + * @property string $message database column + * @property int $show_adressees database column + * @property int $mkdate database column + * @property string $priority database column + * @property SimpleORMapCollection|MessageUser[] $receivers has_many MessageUser + * @property User $author belongs_to User + * @property MessageUser $originator has_one MessageUser + * @property Folder $attachment_folder has_one Folder + */ + +class Message extends SimpleORMap implements PrivacyObject +{ + protected static function configure($config = []) + { + $config['db_table'] = 'message'; + + $config['belongs_to']['author'] = [ + 'class_name' => User::class, + 'foreign_key' => 'autor_id' + ]; + $config['has_one']['originator'] = [ + 'class_name' => MessageUser::class, + 'assoc_func' => 'findSentByMessageId', + 'on_store' => 'store', + 'on_delete' => 'delete' + ]; + $config['has_many']['receivers'] = [ + 'class_name' => MessageUser::class, + 'assoc_func' => 'findReceivedByMessageId', + 'on_store' => 'store', + 'on_delete' => 'delete' + ]; + $config['has_one']['attachment_folder'] = [ + 'class_name' => Folder::class, + 'assoc_foreign_key' => 'range_id', + 'on_store' => 'store', + 'on_delete' => 'delete' + ]; + + parent::configure($config); + } + + public static function markAllAs($user_id = null, $state_of_flag = 1) + { + PersonalNotifications::markAsReadByHTML('message_%', $user_id ?: $GLOBALS['user']->id); + + $query = "UPDATE message_user + SET readed = :flag + WHERE user_id = :user_id + AND snd_rec = 'rec' AND deleted = 0 + AND readed = :other_flag"; + $statement = DBManager::get()->prepare($query); + return $statement->execute([ + 'user_id' => $user_id ?: $GLOBALS['user']->id, + 'flag' => $state_of_flag ? 1 : 0, + 'other_flag' => $state_of_flag ? 0 : 1 + ]); + } + + public static function getUserTags($user_id = null) + { + $query = "SELECT DISTINCT tag + FROM message_tags + WHERE user_id = :user_id + ORDER BY tag ASC"; + return DBManager::get()->fetchFirst($query, [ + ':user_id' => $user_id ?: $GLOBALS['user']->id, + ], function ($tag) { + return ucfirst($tag); + }); + } + + public static function findNew($user_id, $receiver = true, $since = 0, $tag = null) + { + if ($tag) { + $messages_data = DBManager::get()->prepare(" + SELECT message.* + FROM message_user + INNER JOIN message ON (message_user.message_id = message.message_id) + INNER JOIN message_tags ON (message_tags.message_id = message_user.message_id + AND message_user.user_id = message_tags.user_id) + WHERE message_user.user_id = :me + AND snd_rec = :sender_receiver + AND message_tags.tag = :tag + AND message_user.mkdate > :since + ORDER BY message_user.mkdate ASC + "); + $messages_data->execute([ + 'me' => $user_id, + 'tag' => $tag, + 'sender_receiver' => $receiver ? "rec" : "snd", + 'since' => $since + ]); + } else { + $messages_data = DBManager::get()->prepare(" + SELECT message.* + FROM message_user + INNER JOIN message ON (message_user.message_id = message.message_id) + WHERE message_user.user_id = :me + AND snd_rec = :sender_receiver + AND message_user.mkdate > :since + ORDER BY message_user.mkdate ASC + "); + $messages_data->execute([ + 'me' => $user_id, + 'sender_receiver' => $receiver ? "rec" : "snd", + 'since' => $since + ]); + } + $messages_data->setFetchMode(PDO::FETCH_ASSOC); + $messages = []; + foreach ($messages_data as $data) { + $messages[] = Message::buildExisting($data); + } + return $messages; + } + + public function getSender() + { + return $this->author; + } + + public function getRecipients() + { + if ($this->relations['receivers'] === null) { + $sql = "SELECT user_id,vorname,nachname,username,title_front,title_rear,perms,motto + FROM message_user + INNER JOIN auth_user_md5 aum USING (user_id) + LEFT JOIN user_info ui USING (user_id) + WHERE message_id = ? AND snd_rec = 'rec' + ORDER BY Nachname, Vorname"; + $params = [$this->id]; + } else { + $sql = "SELECT user_id,vorname,nachname,username,title_front,title_rear,perms,motto + FROM auth_user_md5 AS aum + LEFT JOIN user_info ui USING (user_id) + WHERE aum.user_id IN (?) + ORDER BY Nachname, Vorname"; + $params = [$this->receivers->pluck('user_id')]; + } + $db = DBManager::get(); + return new SimpleCollection( + $db->fetchAll($sql, + $params, + function ($data) { + $user_id = $data['user_id']; + unset($data['user_id']); + $user = User::build($data); + $ret = $user->toArray('username vorname nachname'); + $ret['fullname'] = $user->getFullName(); + $ret['user_id'] = $user_id; + return $ret; + }) + ); + } + + public function getNumRecipients() + { + return MessageUser::countBySQL("message_id=? AND snd_rec='rec'", [$this->id]); + } + + public function markAsRead($user_id) + { + PersonalNotifications::markAsReadByHTML('message_'.$this->getId(), $user_id); + return $this->markAs($user_id, 1); + } + + public function markAsUnread($user_id) + { + return $this->markAs($user_id, 0); + } + + private function markAs($user_id, $state_of_flag) + { + $changed = 0; + $mu = []; + if ($user_id == $this->autor_id) { + $mu[] = $this->originator; + } + $receiver = MessageUser::findOneBySQL("message_id = ? AND user_id = ? AND snd_rec ='rec'", [$this->id, $user_id]); + if ($receiver) { + $mu[] = $receiver; + } + foreach ($mu as $message_user) { + $message_user->readed = $state_of_flag; + $changed += $message_user->store(); + } + return $changed; + } + + public function markAsAnswered($user_id) + { + $mu = MessageUser::findOneBySQL("message_id = ? AND user_id = ? AND snd_rec IN('rec','snd')", [$this->id, $user_id]); + if ($mu) { + $mu->answered = 1; + return $mu->store(); + } + } + + public function isRead($user_id = null) + { + $user_id || $user_id = $GLOBALS['user']->id; + return (bool)MessageUser::countBySQL("message_id = ? AND user_id = ? AND snd_rec IN('rec','snd') AND readed = 1", [$this->message_id, $user_id]); + } + + public function isAnswered($user_id = null) + { + $user_id || $user_id = $GLOBALS['user']->id; + return (bool)MessageUser::countBySQL("message_id = ? AND user_id = ? AND snd_rec IN('rec','snd') AND answered = 1", [$this->message_id, $user_id]); + } + + public static function send($sender, $recipients, $subject, $message) + { + if ($sender === 'cli') { + $sender = '____%system%____'; + } + $messaging = new \messaging(); + $result = $messaging->insert_message($message, + $recipients, + $sender, + time(), + $message_id = md5(uniqid('message', true)), + false, // deleted + '', // force email + $subject); + return $result ? self::find($message_id) : null; + } + + public function permissionToRead($user_id = null) + { + $user_id || $user_id = $GLOBALS['user']->id; + return (bool) MessageUser::countBySQL("message_id = ? AND user_id = ? AND snd_rec IN('rec','snd') AND deleted = 0", [$this->message_id, $user_id]); + } + + /** + * Returns all tags for the message for the given user. + * @param null $user_id : user-id of the user that tags should be related. null if it's the current user. + * @return array of string : tags + */ + public function getTags($user_id = null) + { + $query = "SELECT tag + FROM message_tags + WHERE message_id = :message_id AND user_id = :user_id + ORDER BY tag ASC"; + return DBManager::get()->fetchFirst($query, [ + 'message_id' => $this->id, + 'user_id' => $user_id ?: $GLOBALS['user']->id, + ], function ($tag) { + return ucfirst($tag); + }); + } + + public function addTag($tag, $user_id = null) + { + $user_id || $user_id = $GLOBALS['user']->id; + $statement = DBManager::get()->prepare(" + INSERT INTO message_tags + SET message_id = :message_id, + user_id = :user_id, + tag = :tag, + mkdate = UNIX_TIMESTAMP() + ON DUPLICATE KEY + UPDATE chdate = UNIX_TIMESTAMP() + "); + return $statement->execute([ + 'message_id' => $this->getId(), + 'user_id' => $user_id, + 'tag' => mb_strtolower($tag) + ]); + } + + public function removeTag($tag, $user_id = null) + { + $user_id || $user_id = $GLOBALS['user']->id; + $statement = DBManager::get()->prepare(" + DELETE FROM message_tags + WHERE message_id = :message_id + AND user_id = :user_id + AND tag = :tag + "); + return $statement->execute([ + 'message_id' => $this->getId(), + 'user_id' => $user_id, + 'tag' => mb_strtolower($tag) + ]); + } + + public function getNumAttachments() + { + return FileRef::countBySql("INNER JOIN folders ON(folders.id = folder_id) WHERE folders.range_id = ?", [$this->id]); + } + + /** + * Deletes the message if all references in message_user indicate 'deleted' + * @return bool + */ + public function removeIfOrphaned() + { + if (!MessageUser::countBySQL("message_id = ? AND snd_rec IN('rec','snd') AND deleted = 0", [$this->message_id])) { + return (bool)$this->delete(); + } + return false; + } + + /** + * Export available data of a given user into a storage object + * (an instance of the StoredUserData class) for that user. + * + * @param StoredUserData $storage object to store data into + */ + public static function exportUserData(StoredUserData $storage) + { + $sorm = self::findBySQL("autor_id = ?", [$storage->user_id]); + if ($sorm) { + $field_data = []; + foreach ($sorm as $row) { + $field_data[] = $row->toRawArray(); + } + if ($field_data) { + $storage->addTabularData(_('Nachrichten'), 'message', $field_data); + } + } + } + +} |
