');
// Prevent duplicates
$hash = md5($subject . $body);
if (
$this->getOne(
'select count(*) from `messu_sent` where `user`=? and `user_from`=? and `hash`=?',
[$user, $from, $hash]
)
) {
return false;
}
$query = 'insert into `messu_sent`' .
' (`user`, `user_from`, `user_to`, `user_cc`, `subject`, `body`, `date`,' .
' `isRead`, `isReplied`, `isFlagged`, `priority`, `hash`, `replyto_hash`)' .
' values(?,?,?,?,?,?,?,?,?,?,?,?,?)';
$this->query(
$query,
[
$user,
$from,
$to,
$cc,
$subject,
$body,
(int) $this->now,
'n',
'n',
'n',
(int) $priority,
$hash,
$replyto_hash
]
);
return true;
}
/**
* Send a message to a user
*
* @param string $user username
* @param string $from from username
* @param string $to to username (again?)
* @param string $cc cc username
* @param string $subject
* @param string $body
* @param int $priority
* @param string $replyto_hash
* @param string $replyto_email y/n
* @param string $bcc_sender y/n send blind copy email to from user's
* @return bool success
*/
public function post_message($user, $from, $to, $cc, $subject, $body, $priority, $replyto_hash = '', $replyto_email = '', $bcc_sender = '')
{
global $prefs;
$userlib = TikiLib::lib('user');
$smarty = TikiLib::lib('smarty');
$subject = strip_tags($subject);
$body = strip_tags($body, '
');
// Prevent duplicates
$hash = md5($subject . $body);
if (
$this->getOne(
'select count(*) from `messu_messages` where `user`=? and `user_from`=? and `hash`=?',
[$user, $from, $hash]
)
) {
return false;
}
$query = 'insert into `messu_messages`' .
' (`user`, `user_from`, `user_to`, `user_cc`, `subject`, `body`, `date`' .
', `isRead`, `isReplied`, `isFlagged`, `priority`, `hash`, `replyto_hash`)' .
' values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
$this->query(
$query,
[
$user,
$from,
$to,
$cc,
$subject,
$body,
(int) $this->now,
'n',
'n',
'n',
(int) $priority,
$hash,
$replyto_hash
]
);
// Now check if the user should be notified by email
$magId = $this->getOne('select LAST_INSERT_ID() from `messu_messages`', []);
$foo = parse_url($_SERVER['REQUEST_URI']);
$machine = $this->httpPrefix(true) . $foo['path'];
$machine = str_replace('messu-compose', 'messu-mailbox', $machine);
$machine = str_replace('messu-broadcast', 'messu-mailbox', $machine);
// For non-sefurl calls, replace tiki-ajax_services with messu-mailbox if
// service called is user > send_message
if ($foo['query'] == "controller=user&action=send_message") {
$machine = str_replace('tiki-ajax_services', 'messu-mailbox', $machine);
}
//For sefurl service call user > send_message, redirect to messu-mailbox.php
$machine = str_replace('tiki-user-send_message', 'messu-mailbox.php', $machine);
if ($this->get_user_preference($user, 'minPrio', 6) <= $priority) {
if (! isset($_SERVER['SERVER_NAME'])) {
$_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST'];
}
$email = $userlib->get_user_email($user);
if ($userlib->user_exists($from)) {
$from_email = $userlib->get_user_email($from); // $from_email required for TikiMail constructor
} elseif ($from == 'tiki-contact.php' && ! empty($prefs['sender_email'])) {
$from_email = $prefs['sender_email'];
} else {
return false; // non-existent users can't send messages (etc)
}
if ($email) {
include_once('lib/webmail/tikimaillib.php');
$smarty->assign('mail_site', $_SERVER['SERVER_NAME']);
$smarty->assign('mail_machine', $machine);
$smarty->assign('mail_date', $this->now);
$smarty->assign('mail_user', stripslashes($user));
$smarty->assign('mail_from', stripslashes($from));
$smarty->assign('mail_subject', stripslashes($subject));
$smarty->assign('mail_body', stripslashes($body));
$smarty->assign('mail_truncate', $prefs['messu_truncate_internal_message']);
$smarty->assign('messageid', $magId);
try {
$mail = new TikiMail($user, $from_email);
$lg = $this->get_user_preference($user, 'language', $prefs['site_language']);
if (empty($subject)) {
$s = $smarty->fetchLang($lg, 'mail/messu_message_notification_subject.tpl');
$mail->setSubject(sprintf($s, $_SERVER['SERVER_NAME']));
} else {
$mail->setSubject($subject);
}
$mail_data = $smarty->fetchLang($lg, 'mail/messu_message_notification.tpl');
$mail->setText($mail_data);
if ($from_email) {
if ($bcc_sender === 'y' && ! empty($from_email)) {
$mail->setBcc($from_email);
}
if ($replyto_email !== 'y' && $userlib->get_user_preference($from, 'email is public', 'n') == 'n') {
$from_email = ''; // empty $from_email if not to be used - saves getting it twice
}
if (! empty($from_email)) {
$mail->setReplyTo($from_email);
}
}
if (! $mail->send([$email], 'mail')) {
return false; //TODO echo $mail->errors;
}
} catch (ZendMailException | SlmMailException $e) {
Feedback::error($e->getMessage());
return false;
}
}
}
return true;
}
/**
* Get a list of messages from users mailbox or users mail archive (from
* which depends on $dbsource)
*/
public function list_user_messages(
$user,
$offset,
$maxRecords,
$sort_mode,
$find,
$flag,
$flagval,
$prio,
$dbsource,
$replyto_hash = '',
$orig_or_reply = 'r'
) {
if ($dbsource == '') {
$dbsource = 'messages';
}
$bindvars = [$user];
$mid = '';
if ($prio) {
$mid = ' and priority=? ';
$bindvars[] = $prio;
}
if ($replyto_hash) {
// find replies
if ($orig_or_reply == 'r') {
$mid .= ' and replyto_hash=? ';
// find original for the reply
} else {
$mid .= ' and hash=? ';
}
$bindvars[] = $replyto_hash;
}
if ($flag) {
// Process the flags
$mid .= " and `$flag`=? ";
$bindvars[] = $flagval;
}
if ($find) {
$findesc = '%' . $find . '%';
$mid .= ' and (`subject` like ? or `body` like ?)';
$bindvars[] = $findesc;
$bindvars[] = $findesc;
}
$query = 'select * from `messu_' . $dbsource . "` where `user`=? $mid order by " .
$this->convertSortMode($sort_mode) . ',' . $this->convertSortMode('msgId_desc');
$query_cant = 'select count(*) from `messu_' . $dbsource . "` where `user`=? $mid";
$result = $this->query($query, $bindvars, $maxRecords, $offset);
$cant = $this->getOne($query_cant, $bindvars);
$ret = [];
while ($res = $result->fetchRow()) {
$res['len'] = strlen($res['body']);
if (empty($res['subject'])) {
$res['subject'] = tra('NONE');
}
$ret[] = $res;
}
$retval = [];
$retval['data'] = $ret;
$retval['cant'] = $cant;
return $retval;
}
/**
* Get the number of messages in the users mailbox or mail archive (from
* which depends on $dbsource)
*/
public function count_messages($user, $dbsource = 'messages', $unreadOnly = false, $newSince = 0)
{
if ($dbsource == '') {
$dbsource = 'messages';
}
$bindvars = [$user];
$query_cant = 'select count(*) from `messu_' . $dbsource . '` where `user`=?';
if ($unreadOnly == true) {
$query_cant .= ' and `isRead`="n"';
}
if (! empty($newSince)) {
$query_cant .= ' and `date` >= ?';
$bindvars[] = $newSince;
}
$cant = $this->getOne($query_cant, $bindvars);
return $cant;
}
/**
* Update message flagging
*/
public function flag_message($user, $msgId, $flag, $val, $dbsource = 'messages')
{
if (! $msgId || ! (in_array($flag, ['isRead', 'isFlagged']))) {
return false;
}
if ($dbsource == '') {
$dbsource = 'messages';
}
$query = 'update `messu_' . $dbsource . "` set `$flag`=? where `user`=? and `msgId`=?";
return $this->query($query, [$val, $user, (int)$msgId]);
}
/**
* Mark a message as replied
*/
public function mark_replied($user, $replyto_hash, $dbsource = 'sent')
{
if ((! $replyto_hash) || ($replyto_hash == '')) {
return false;
}
if ($dbsource == '') {
$dbsource = 'sent';
}
$query = 'update `messu_' . $dbsource . '` set `isReplied`=? where `user`=? and `hash`=?';
$this->query($query, ['y', $user, $replyto_hash]);
}
/**
* Delete message from mailbox or users mail archive (from which depends on
* $dbsource)
*/
public function delete_message($user, $msgId, $dbsource = 'messages')
{
if (! $msgId) {
return false;
}
if ($dbsource == '') {
$dbsource = 'messages';
}
$query = 'delete from `messu_' . $dbsource . '` where `user`=? and `msgId`=?';
return $this->query($query, [$user, (int)$msgId]);
}
/**
* Move message from mailbox to users mail archive
*/
public function archive_message($user, $msgId, $dbsource = 'messages')
{
if (! $msgId) {
return false;
}
if ($dbsource == '') {
$dbsource = 'messages';
}
$columns = '`user`, `user_from`, `user_to`, `user_cc`, `subject`, `body`, `date`, `isRead`, `isReplied`, `isFlagged`, `priority`, `hash`, `replyto_hash`';
$query = 'insert into `messu_archive` (' . $columns . ') select ' . $columns . ' from `messu_' . $dbsource . '` where `user`=? and `msgId`=?';
$this->query($query, [$user, (int)$msgId]);
$query = 'delete from `messu_' . $dbsource . '` where `user`=? and `msgId`=?';
return $this->query($query, [$user, (int)$msgId]);
}
/**
* Move message from archive to users mailbox
*/
public function unarchive_message($user, $msgId, $dbsource = 'messages')
{
if (! $msgId) {
return false;
}
$dbsource = $this->get_archive_source($user, $msgId);
if ($dbsource == '') {
$dbsource = 'messages';
}
$columns = '`user`, `user_from`, `user_to`, `user_cc`, `subject`, `body`, `date`, `isRead`, `isReplied`, `isFlagged`, `priority`, `hash`, `replyto_hash`';
$query = 'insert into `messu_' . $dbsource . '` (' . $columns . ') select ' . $columns . ' from `messu_archive` where `user`=? and `msgId`=?';
$this->query($query, [$user, (int)$msgId]);
$query = 'delete from `messu_archive` where `user`=? and `msgId`=?';
return $this->query($query, [$user, (int)$msgId]);
}
/**
* Move read message older than x days from mailbox to users mail archive
*/
public function archive_messages($user, $days, $dbsource = 'messages')
{
if ($days < 1) {
return false;
}
if ($dbsource == '') {
$dbsource = 'messages';
}
$age = $this->now - ($days * 3600 * 24);
// TODO: only move as much msgs into archive as there is space left in there
$query = 'insert into `messu_archive` select * from `messu_' . $dbsource . '` where `user`=? and `isRead`=? and `date`<=?';
$this->query($query, [$user, 'y', (int)$age]);
$query = 'delete from `messu_' . $dbsource . '` where `user`=? and `isRead`=? and `date`<=?';
$this->query($query, [$user, 'y', (int)$age]);
}
/**
* Move forward to the next message and get it from the database
*/
public function get_next_message($user, $msgId, $sort_mode, $find, $flag, $flagval, $prio, $dbsource = 'messages')
{
if (! $msgId) {
return 0;
}
if ($dbsource == '') {
$dbsource = 'messages';
}
$mid = '';
$bindvars = [$user,(int)$msgId];
if ($prio) {
$mid .= ' and priority=? ';
$bindvars[] = $prio;
}
if ($flag) {
// Process the flags
$mid .= " and `$flag`=? ";
$bindvars[] = $flagval;
}
if ($find) {
$findesc = '%' . $find . '%';
$mid .= ' and (`subject` like ? or `body` like ?)';
$bindvars[] = $findesc;
$bindvars[] = $findesc;
}
$query = 'select min(`msgId`) as `nextmsg` from `messu_' . $dbsource . "` where `user`=? and `msgId` > ? $mid";
$result = $this->query($query, $bindvars, 1, 0);
$res = $result->fetchRow();
if (! $res) {
return false;
}
return $res['nextmsg'];
}
/**
* Move backward to the next message and get it from the database
*/
public function get_prev_message($user, $msgId, $sort_mode, $find, $flag, $flagval, $prio, $dbsource = 'messages')
{
if (! $msgId) {
return 0;
}
if ($dbsource == '') {
$dbsource = 'messages';
}
$mid = '';
$bindvars = [$user, (int)$msgId];
if ($prio) {
$mid .= ' and priority=? ';
$bindvars[] = $prio;
}
if ($flag) {
// Process the flags
$mid .= " and `$flag`=? ";
$bindvars[] = $flagval;
}
if ($find) {
$findesc = '%' . $find . '%';
$mid .= ' and (`subject` like ? or `body` like ?)';
$bindvars[] = $findesc;
$bindvars[] = $findesc;
}
$query = 'select max(`msgId`) as `prevmsg` from `messu_' . $dbsource . "` where `user`=? and `msgId` < ? $mid";
$result = $this->query($query, $bindvars, 1, 0);
$res = $result->fetchRow();
if (! $res) {
return false;
}
return $res['prevmsg'];
}
/**
* Get a message from the users mailbox or his mail archive (from which
* depends on $dbsource)
*/
public function get_message($user, $msgId, $dbsource = 'messages')
{
if ($dbsource == '') {
$dbsource = 'messages';
}
$bindvars = [$user, (int)$msgId];
$query = 'select * from `messu_' . $dbsource . '` where `user`=? and `msgId`=?';
$result = $this->query($query, $bindvars);
$res = $result->fetchRow();
$res['parsed'] = TikiLib::lib('parser')->parse_data($res['body']);
$res['len'] = strlen($res['parsed']);
if (empty($res['subject'])) {
$res['subject'] = tra('NONE');
}
return $res;
}
/**
* Get message from the users mailbox or his mail archive (from which
* depends on $dbsource)
*/
public function get_messages($user, $dbsource = 'messages', $subject = '', $to = '', $from = '')
{
if ($dbsource == '') {
$dbsource = 'messages';
}
$bindvars[] = $user;
$mid = '';
// find mails with a specific subject
if ($subject <> '') {
$findesc = '%' . $subject . '%';
$bindvars[] = $findesc;
$mid .= ' and `subject` like ?';
}
// find mails to a specific user (to, cc, bcc)
if ($to <> '') {
$findesc = '%' . $to . '%';
$bindvars[] = $findesc;
$bindvars[] = $findesc;
$bindvars[] = $findesc;
$mid .= ' and (`user_to` like ? or `user_cc` like ? or `user_bcc` like ?)';
}
// find mails from a specific user
if ($from <> '') {
$findesc = '%' . $from . '%';
$bindvars[] = $findesc;
$mid .= ' and `user_from` like ?';
}
$query = 'select * from `messu_' . $dbsource . "` where `user`=? $mid";
$result = $this->query($query, $bindvars);
$ret = [];
while ($res = $result->fetchRow()) {
$res['parsed'] = TikiLib::lib('parser')->parse_data($res['body']);
$res['len'] = strlen($res['parsed']);
if (empty($res['subject'])) {
$res['subject'] = tra('NONE');
}
$ret[] = $res;
}
return $ret;
}
/**
* Get mail source info from the mail archive
*/
public function get_archive_source($user, $msgId)
{
$dbsource = '';
$res = $this->get_message($user, $msgId, 'archive');
if ($res['user_from'] == $user) {
$dbsource = 'sent';
}
return $dbsource;
}
}