* @author Nils K. Windisch
* @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
* @category Stud.IP
* @package messaging
*/
require_once 'lib/user_visible.inc.php';
class messaging
{
var $send_as_email = false;
var $sig_string; //String, der Signaturen vom eigentlichen Text abgrenzt
public static function sendSystemMessage($recipient, $message_title, $message_body)
{
$m = new messaging();
$user = User::toObject($recipient);
return $m->insert_message($message_body, $user['username'], '____%system%____', FALSE, FALSE, '1', FALSE, $message_title);
}
/**
* Konstruktor
*/
function __construct()
{
$this->sig_string="\n \n -- \n";
}
/**
* Nachricht loeschen
*
* @param $message_id
* @param $user_id
*/
function delete_message($message_id, $user_id = FALSE)
{
if (!$user_id) {
$user_id = $GLOBALS['user']->id;
}
$query = "UPDATE message_user
SET deleted = '1'
WHERE message_id = ? AND user_id = ? AND deleted = '0'";
$statement = DBManager::get()->prepare($query);
$statement->execute([$message_id, $user_id]);
if ($statement->rowCount() == 0) {
return false;
}
$query = "SELECT 1 FROM message_user WHERE message_id = ? AND deleted = '0'";
$statement = DBManager::get()->prepare($query);
$statement->execute([$message_id]);
if (!$statement->fetchColumn()) {
$this->remove_message($message_id);
$folder = Folder::findOneBySQL(
"range_id = ? AND parent_id='' AND folder_type='MessageFolder'",
[$message_id]
);
if ($folder) {
$folder->delete();
}
}
return true;
}
/**
* Removes a message or a list of messages from the database
*
* @param mixed $id Id(s) of the message(s) in question
* @return bool Returns false if not a single message was removed
*/
private function remove_message($id)
{
if (empty($id)) {
return true;
}
$query = "DELETE message, message_user
FROM message
LEFT JOIN message_user USING(message_id)
WHERE message.message_id IN (?)";
$statement = DBManager::get()->prepare($query);
$statement->execute([$id]);
return $statement->rowCount() > 0;
}
/**
* delete all messages from user
*
* @param $user_id
*/
function delete_all_messages($user_id = FALSE)
{
if (!$user_id) {
$user_id = $GLOBALS['user']->id;
}
$query = "SELECT message_id FROM message_user WHERE user_id = ? AND deleted = '0'";
$statement = DBManager::get()->prepare($query);
$statement->execute([$user_id]);
$message_ids = $statement->fetchAll(PDO::FETCH_COLUMN);
foreach ($message_ids as $message_id) {
$this->delete_message($message_id, $user_id);
}
}
/**
*
* @param $userid
*/
function user_wants_email($userid)
{
$query = "SELECT email_forward FROM user_info WHERE user_id = ?";
$statement = DBManager::get()->prepare($query);
$statement->execute([$userid]);
$setting = $statement->fetchColumn();
if ($setting == 1) {
return false;
}
if (in_array($setting, [2, 3])) {
return $setting;
}
return $GLOBALS['MESSAGING_FORWARD_DEFAULT'];
}
/**
*
* @param $rec_user_id
* @param $snd_user_id
* @param $message
* @param $subject
* @param $message_id
*/
function sendingEmail($rec_user_id, $snd_user_id, $message, $subject, $message_id)
{
$msg = Message::find($message_id);
$receiver = User::find($rec_user_id);
$to = $receiver->Email;
$reply_to = '';
$snd_fullname = '';
// do not try to send mails to users without a mail address
if (!$to) {
return;
}
// do not send mails when account is locked or expired
if ($receiver->isBlocked()) {
return;
}
$rec_fullname = $receiver->getFullName();
setTempLanguage($rec_user_id);
$title_prefix = Config::get()->MAIL_USE_SUBJECT_PREFIX ? '[Stud.IP - ' . Config::get()->UNI_NAME_CLEAN . '] ' : '';
$title = $title_prefix . kill_format(str_replace(["\r", "\n"], '', $subject));
if ($snd_user_id != "____%system%____") {
$sender = User::find($snd_user_id);
$snd_fullname = $sender->getFullName() . ' (' . $sender->username . ')';
$reply_to = $sender->Email;
}
$attachments = [];
$attachments_as_links = false;
if ($GLOBALS['ENABLE_EMAIL_ATTACHMENTS'] && $msg->attachment_folder) {
$attachments = $msg->attachment_folder->file_refs;
$size_of_attachments = array_sum($attachments->pluck('size')) ?: 0;
//assume base64 takes 33% more space
$attachments_as_links = $size_of_attachments * 1.33 > $GLOBALS['MAIL_ATTACHMENTS_MAX_SIZE'] * 1048576; //1MiB = 1024 KiB = 1048576 Bytes
}
$template = $GLOBALS['template_factory']->open('mail/text');
$template->set_attribute('message', kill_format($message));
$template->set_attribute('rec_fullname', $rec_fullname);
$template->set_attribute('rec_email', $to);
$template->set_attribute('snd_email', $reply_to);
if (isset($snd_fullname)) {
$template->set_attribute('snd_fullname', $snd_fullname);
}
if ($attachments_as_links) {
$template->set_attribute('attachments', $attachments);
}
$mailmessage = $template->render();
$template = $GLOBALS['template_factory']->open('mail/html');
$template->set_attribute('lang', getUserLanguagePath($rec_user_id));
$template->set_attribute('message', $message);
$template->set_attribute('rec_fullname', $rec_fullname);
$template->set_attribute('rec_username', $receiver->username);
$template->set_attribute('rec_email', $to);
$template->set_attribute('snd_email', $reply_to);
if (isset($snd_fullname)) {
$template->set_attribute('snd_fullname', $snd_fullname);
}
if ($attachments_as_links) {
$template->set_attribute('attachments', $attachments);
}
$mailhtml = $template->render();
restoreLanguage();
// Now, let us send the message
$mail = new StudipMail();
$mail->setSubject($title)
->addRecipient($to, $rec_fullname)
->setBodyText($mailmessage);
// Add Stud.IP logo as "pseudo" attachment - this will be embedded in the mail via Content-ID.
$mail->addRelatedAttachment(
$GLOBALS['STUDIP_BASE_PATH'] . '/public/assets/images/logos/studip4-logo@2x.png',
'studip-logo.png',
'image/png',
'studiplogo'
);
if (mb_strlen($reply_to)) {
if ($GLOBALS['MESSAGING_FORWARD_USE_REPLYTO']) {
$mail->setReplyToEmail($reply_to)
->setReplyToName($snd_fullname)
->setSenderName(sprintf(_('Stud.IP für %s'), $snd_fullname));
} else {
$mail->setSenderEmail($reply_to)
->setSenderName($snd_fullname);
}
}
$user_cfg = UserConfig::get($rec_user_id);
if ($user_cfg->getValue('MAIL_AS_HTML')) {
$mail->setBodyHtml($mailhtml);
}
if (count($attachments) && !$attachments_as_links) {
foreach ($attachments as $attachment) {
$mail->addStudipAttachment($attachment);
}
}
if (!Config::get()->MAILQUEUE_ENABLE) {
$mail->send();
} else {
MailQueueEntry::add($mail, $message_id, $rec_user_id);
}
}
/**
*
* @param $message
* @param $rec_uname
* @param $user_id
* @param $time
* @param $tmp_message_id
* @param $set_deleted
* @param $signature
* @param $subject
* @param $force_email
* @param $priority
*/
function insert_message($message, $rec_uname, $user_id='', $time='', $tmp_message_id='', $set_deleted='', $signature='', $subject='', $force_email='', $priority='normal', $tags = null, $show_adressees = false)
{
// wenn keine user_id uebergeben
$user_id = $user_id ?: $GLOBALS['user']->id;
$my_messaging_settings = UserConfig::get($user_id)->MESSAGING_SETTINGS;
// wenn kein subject uebergeben
$subject = $subject ?: _('Ohne Betreff');
$email_request = $this->send_as_email ?: $my_messaging_settings['send_as_email'];
// wenn keine zeit uebergeben
$time = $time ?: time();
// wenn keine id uebergeben
$tmp_message_id = $tmp_message_id ?: md5(uniqid('321losgehtes', true));
# send message now
if ($user_id != '____%system%____') { // real-user message
$snd_user_id = $user_id;
$set_deleted = $set_deleted ?: ($my_messaging_settings['save_snd'] != '1'); // don't save sms in outbox
} else { // system-message
$set_deleted = '1';
// system-signatur
$snd_user_id = '____%system%____';
setTempLanguage();
restoreLanguage();
}
// insert message
$query = "INSERT INTO message (message_id, autor_id, subject, message, show_adressees, priority, mkdate)
VALUES (?, ?, ?, ?, ?, ?, UNIX_TIMESTAMP())";
$statement = DBManager::get()->prepare($query);
$internal_message = $message;
if ($snd_user_id === '____%system%____') {
$internal_message .= $this->sig_string . ' ' .
_('Diese Nachricht wurde automatisch vom Stud.IP-System generiert. Sie können darauf nicht antworten.');
}
$statement->execute([
$tmp_message_id,
$snd_user_id,
$subject,
$internal_message,
(int) $show_adressees,
$priority,
]);
// insert snd
$insert_tags = DBManager::get()->prepare("
INSERT IGNORE INTO message_tags
SET message_id = :message_id,
user_id = :user_id,
tag = :tag,
chdate = UNIX_TIMESTAMP(),
mkdate = UNIX_TIMESTAMP()
");
$query = "INSERT INTO message_user (message_id, user_id, snd_rec, deleted, mkdate)
VALUES (?, ?, 'snd', ?, UNIX_TIMESTAMP())";
$statement = DBManager::get()->prepare($query);
$statement->execute([
$tmp_message_id,
$snd_user_id,
$set_deleted ? 1 : 0, // save message?
]);
if ($tags) {
is_array($tags) || $tags = explode(" ", (string) $tags);
foreach ($tags as $tag) {
$insert_tags->execute([
'message_id' => $tmp_message_id,
'user_id' => $snd_user_id,
'tag' => mb_strtolower($tag)
]);
}
}
// heben wir kein array bekommen, machen wir einfach eins ...
if (!is_array($rec_uname)) {
$rec_uname = [$rec_uname];
}
// wir bastelen ein neues array, das die user_id statt des user_name enthaelt
$rec_id = [];
foreach ($rec_uname as $one) {
$rec_id[] = User::findByUsername($one)->user_id;
}
$rec_id = array_filter($rec_id);
// wir gehen das eben erstellt array durch und schauen, ob irgendwer was weiterleiten moechte.
// diese user_id schreiben wir in ein tempraeres array
foreach ($rec_id as $one) {
$smsforward_rec = User::find($one)->smsforward_rec;
if (!$smsforward_rec) {
continue;
}
$tmp_forward = User::find($smsforward_rec);
if (!$tmp_forward) {
continue;
}
$rec_id[] = $tmp_forward->id;
}
// wir mergen die eben erstellten arrays und entfernen doppelte eintraege
$rec_id = array_unique($rec_id);
// hier gehen wir alle empfaenger durch, schreiben das in die db und schicken eine mail
$query = "INSERT INTO message_user (message_id, user_id, readed, snd_rec, mkdate)
VALUES (?, ?, ?, 'rec', UNIX_TIMESTAMP())";
$insert = DBManager::get()->prepare($query);
$snd_name = ($user_id != '____%system%____')
? User::find($user_id)->getFullName() . ' (' . User::find($user_id)->username . ')'
: 'Stud.IP-System';
foreach ($rec_id as $one) {
$insert->execute([$tmp_message_id, $one, $one == $snd_user_id ? 1 : 0]);
if (!empty($GLOBALS['MESSAGING_FORWARD_AS_EMAIL'])) {
// mail to original receiver
$mailstatus_original = $this->user_wants_email($one);
if ($mailstatus_original == 2 || ($mailstatus_original == 3 && $email_request == 1) || $force_email) {
$this->sendingEmail($one, $snd_user_id, $message, $subject, $tmp_message_id);
}
}
if ($tags) {
foreach ($tags as $tag) {
$insert_tags->execute([
'message_id' => $tmp_message_id,
'user_id' => $one,
'tag' => mb_strtolower($tag)
]);
}
}
}
// Obtain all users that should receive a notification
$user_ids = array_diff($rec_id, [$user_id]);
// Create notifications
foreach ($user_ids as $uid) {
setTempLanguage($uid);
PersonalNotifications::add(
$uid,
URLHelper::getUrl("dispatch.php/messages/read/{$tmp_message_id}", [], true),
sprintf(_('Sie haben eine Nachricht von %s erhalten!'), $snd_name),
"message_{$tmp_message_id}",
Icon::create('mail'),
true
);
}
restoreLanguage();
NotificationCenter::postNotification('MessageDidSend', $tmp_message_id, compact('user_id', 'rec_id'));
return count($rec_id);
}
}