18 require_once SQ_DATA_PATH.
'/private/conf/messaging_service.inc';
19 require_once
'Mail.php';
20 require_once
'Mail/mime.php';
22 define(
'SQ_MSG_UNREAD' ,
'U');
23 define(
'SQ_MSG_READ' ,
'R');
24 define(
'SQ_MSG_DELETED',
'D');
26 define(
'SQ_MSG_PRIORITY_VERY_LOW' , 1);
27 define(
'SQ_MSG_PRIORITY_LOW' , 2);
28 define(
'SQ_MSG_PRIORITY_NORMAL' , 3);
29 define(
'SQ_MSG_PRIORITY_HIGH' , 4);
30 define(
'SQ_MSG_PRIORITY_VERY_HIGH' , 5);
62 var $_emails = Array();
73 var $sending_queue = FALSE;
100 if (!isset($this->_tmp[
'message_type_logs'][$msg_type])) {
102 $this->_tmp[
'message_type_logs'][$msg_type] = Array();
104 $msg_type_list = explode(
'.', $msg_type);
106 foreach (Array(
'log_to_file',
'log_to_db',
'send_mail') as $log_type) {
108 $def_name_w =
'SQ_MS_'.strtoupper($log_type).
'_WHITE_LIST';
109 $def_name_b =
'SQ_MS_'.strtoupper($log_type).
'_BLACK_LIST';
110 $types_w = explode(
"\n", constant($def_name_w));
111 $types_b = explode(
"\n", constant($def_name_b));
113 if (in_array($msg_type, $types_w)) {
116 }
else if (in_array($msg_type, $types_b)) {
131 if (in_array(
'*', $types_w)) {
138 foreach ($msg_type_list as $code_part) {
139 if (!empty($check_code)) {
140 $check_code = trim($check_code,
'* ');
142 $check_code .= $code_part.
'.*';
143 if (in_array($check_code, $types_w)) {
147 }
else if (in_array($check_code, $types_b)) {
158 $this->_tmp[
'message_type_logs'][$msg_type][$log_type] = $allow_log;
164 return $this->_tmp[
'message_type_logs'][$msg_type];
181 array_push($this->_levels[
'queues'], Array());
196 $msgs = array_pop($this->_levels[
'queues']);
199 if (empty($this->_levels[
'queues'])) {
201 return $this->
send($msgs);
203 foreach ($msgs as $msg) {
204 array_push($this->_levels[
'queues'][count($this->_levels[
'queues']) - 1], $msg);
221 array_pop($this->_levels[
'queues']);
239 if (empty($this->_levels[
'queues'])) {
242 array_push($this->_levels[
'queues'][count($this->_levels[
'queues']) - 1], $message);
257 return $this->_levels[
'queues'][count($this->_levels[
'queues']) - 1];
274 array_push($this->_levels[
'logs'], Array());
289 $msgs = array_pop($this->_levels[
'logs']);
292 if (empty($this->_levels[
'logs'])) {
294 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
295 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
296 foreach ($msgs as $msg) {
298 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
299 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
303 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
304 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
308 foreach ($msgs as $msg) {
309 array_push($this->_levels[
'logs'][count($this->_levels[
'logs']) - 1], $msg);
327 array_pop($this->_levels[
'logs']);
345 array_push($this->_levels[
'logs'][count($this->_levels[
'logs']) - 1], $message);
360 return $this->_levels[
'logs'][count($this->_levels[
'logs']) - 1];
384 require_once SQ_INCLUDE_PATH.
'/internal_message.inc';
387 $new_message->sent = ts_iso8601(time());
388 $new_message->from = $GLOBALS[
'SQ_SYSTEM']->currentUserId();
389 $new_message->to = $to;
390 $new_message->type = $type;
391 $new_message->replacements = $reps;
410 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
411 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
412 $this->sending_queue = TRUE;
414 foreach ($msgs as $msg) {
418 $this->sending_queue = FALSE;
421 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
422 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
450 function getMessages($userid, $type=NULL, $statii=Array(), $messageids=Array(), $from=NULL, $to=NULL, $get_user_name=NULL, $parameters=Array(), $max_msgs=0, $count_only=FALSE)
454 if (!is_null($get_user_name) && $get_user_name !=
'name') {
455 $get_user_name =
'short_name';
459 $select_clause =
'm.msgid, m.userto, m.userfrom, m.subject, m.body, m.sent, m.priority, m.status, m.type, m.parameters';
460 if (is_string($get_user_name)) {
463 WHEN a.'.$get_user_name.
' IS NULL AND m.userfrom = \'0\' THEN '.
MatrixDAL::quote(SQ_SYSTEM_SHORT_NAME.
' System').
'
464 ELSE a.'.$get_user_name.
'
466 $select_clause .=
', CASE WHEN a.'.$get_user_name.
' IS NULL AND m.userfrom = \'0\' THEN \'root_user\''.
467 ' ELSE a.type_code END as type_code';
470 $select_clause =
'COUNT(msgid) AS message_count';
474 $sql =
'SELECT ' . $select_clause;
476 $sql .=
' FROM sq_internal_msg m';
477 if (is_null($userid)) {
478 $where =
'm.userto != \'0\'';
480 # See bug 5455 for why this is a bind var and not quoted.
481 # Basically - MatrixDAL::quote and Active directory DN's with backslashes in them
482 # don't play nicely. Changing it to be a bindvar makes them work together.
483 $where =
'm.userto = :userto';
484 $bindVars[
'userto'] = $userid;
489 if (is_string($get_user_name) && $count_only === FALSE) {
490 $sql .=
' LEFT OUTER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast a ON m.userfrom = a.assetid';
491 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
493 $where =
'WHERE '.$where;
496 if (!is_null($type)) {
497 if (substr($type, -2) ==
'.*') {
498 $where .=
' AND m.type LIKE '.MatrixDAL::quote(substr($type, 0, -1).
'%');
500 $where .=
' AND m.type = '.MatrixDAL::quote($type);
503 if (!empty($statii)) {
504 $statii_strs = Array();
505 for ($i = 0; $i < count($statii); $i++) {
506 $statii[$i] =
'\''.$statii[$i].
'\'';
508 $where .=
' AND m.status IN ('.implode(
', ', $statii).
')';
510 if (!empty($messageids)) {
511 for ($i = 0; $i < count($messageids); $i++) {
512 $messageids[$i] =
'\''.$messageids[$i].
'\'';
514 $where .=
' AND m.msgid IN ('.implode(
', ', $messageids).
')';
516 if (!empty($parameters)) {
517 foreach ($parameters as $param_key => $param_value) {
519 if ($param_key ==
'from_date' || $param_key ==
'to_date')
continue;
520 $where .=
' AND m.parameters LIKE '.MatrixDAL::quote(
'%'.$param_key.
':'.$param_value.
';%');
522 if (isset($parameters[
'assetid']) === TRUE) {
523 $where .=
' AND m.assetid='.MatrixDAL::quote($parameters[
'assetid']);
526 if (isset($parameters[
'from_date']) && $parameters[
'from_date'] !=
'') {
527 $where .=
' AND sent >= '.MatrixDAL::quote($parameters[
'from_date']);
529 if (isset($parameters[
'to_date']) && $parameters[
'to_date'] !=
'') {
530 $where .=
' AND sent <= '.MatrixDAL::quote($parameters[
'to_date']);
533 if (!is_null($from)) {
534 $where .=
' AND m.sent >= '.MatrixDAL::quote(ts_iso8601($from));
537 $where .=
' AND m.sent <= '.MatrixDAL::quote(ts_iso8601($to));
543 $sql .=
' ORDER BY m.sent DESC';
552 if (empty($bindVars) === TRUE) {
556 foreach ($bindVars as $bindVar => $bindValue) {
561 }
catch (Exception $e) {
562 throw new Exception(
'Unable to get message information due to database error: '.$e->getMessage());
566 return $result[0][
'message_count'];
569 for ($i = 0, $total = count($result); $i < $total; $i++) {
570 $result[$i][
'sent'] = iso8601_ts($result[$i][
'sent']);
574 if (is_string($get_user_name)) {
575 $id_parts = explode(
':', $result[$i][
'userfrom']);
576 if (isset($id_parts[1])) {
577 $bridgeid = $id_parts[0];
578 $bridge = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($bridgeid,
'', TRUE);
579 if (!is_null($bridge)) {
580 $shadow = $bridge->getAsset($result[$i][
'userfrom']);
581 if (!is_null($shadow)) {
582 $result[$i][
'from_name'] = $shadow->$get_user_name;
583 $result[$i][
'type_code'] = $shadow->type();
589 if (empty($result[$i][
'from_name'])) {
590 $result[$i][
'from_name'] =
'Unknown User';
594 if (empty($result[$i][
'type_code'])) {
595 $result[$i][
'type_code'] =
'user';
600 $body = $result[$i][
'body'];
601 $tagline_reg =
'|<SQ_MSG_TAGLINE[^>]*?>(.*?)</SQ_MSG_TAGLINE>|';
602 if (preg_match($tagline_reg, $body, $matches)) {
603 $asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($matches[1]);
604 if (is_null($asset)) {
605 $body = preg_replace($tagline_reg,
'AssetID #'.$matches[1], $body);
607 $body = preg_replace($tagline_reg, get_asset_tag_line($asset->id), $body);
608 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($asset);
610 $result[$i][
'body'] = $body;
635 return $this->
getMessages(0, $type, Array(), Array(), NULL, NULL,
'name', $parameters);
653 $message->load($messageid);
654 if (!$message->id)
return NULL;
671 if ($a[
'sent'] == $b[
'sent'])
return 0;
672 return ($a[
'sent'] > $b[
'sent']) ? -1 : 1;
688 function queueEmail($from, $to, $subject, $body, $reply_to=
'')
690 if (!isset($this->_emails[$from])) {
691 $this->_emails[$from] = Array();
694 if (!isset($this->_emails[$from][$to])) {
695 $this->_emails[$from][$to] = Array();
698 if (!isset($this->_emails[$from][$to][$subject])) {
699 $this->_emails[$from][$to][$subject] = Array();
702 if (!isset($this->_emails[
'reply_to']) && !empty($reply_to)) {
703 $this->_emails[
'reply_to'] = $reply_to;
706 $this->_emails[$from][$to][$subject][] = $body;
720 'head_charset' => SQ_CONF_DEFAULT_CHARACTER_SET,
721 'text_charset' => SQ_CONF_DEFAULT_CHARACTER_SET,
722 'html_charset' => SQ_CONF_DEFAULT_CHARACTER_SET,
725 $mime =
new Mail_mime($crlf);
727 foreach ($this->_emails as $from => $from_emails) {
728 if ($from ==
'reply_to')
continue;
730 $from_email = SQ_CONF_DEFAULT_EMAIL;
732 if ($from && assert_valid_assetid($from,
'', TRUE, FALSE)) {
733 $user_from = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($from);
734 if (!is_null($user_from)) {
735 $from_name = preg_replace(
'/[\[\]\(\)<>\@\,\;\:\\\"\.]+/',
'', $user_from->name);
736 $from_email = $user_from->attr(
'email');
737 $from_string = $from_name.
' <'.$from_email.
'>';
742 if (empty($from_email)) {
743 if (isset($_SERVER[
'HOSTNAME']) && isset($_SERVER[
'HTTP_HOST'])) {
744 $from_email =
'webmaster@'.((SQ_PHP_CLI) ? $_SERVER[
'HOSTNAME'] : $_SERVER[
'HTTP_HOST']);
746 $from_email = SQ_CONF_DEFAULT_EMAIL;
749 if (empty($from_string)) {
750 $from_string =
'"'.SQ_SYSTEM_SHORT_NAME.
' System" <'.$from_email.
'>';
753 if (isset($this->_emails[
'reply_to']) && !isset($reply_to_str)) {
754 $reply_to = $this->_emails[
'reply_to'];
755 if (assert_valid_assetid($reply_to,
'', TRUE, FALSE)) {
756 $user_reply_to = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($reply_to);
757 if (!is_null($user_reply_to)) {
758 $reply_to_name = preg_replace(
'/[\[\]\(\)<>\@\,\;\:\\\"\.]+/',
'', $user_reply_to->name);
759 $reply_to_email = $user_reply_to->attr(
'email');
760 $reply_to_str = $reply_to_name.
' <'.$reply_to_email.
'>';
763 $reply_to_str = $reply_to;
767 foreach ($from_emails as $to => $to_emails) {
771 $default = SQ_CONF_DEFAULT_EMAIL;
772 $tech = SQ_CONF_TECH_EMAIL;
775 if (!empty($default)) $to_email .= $default;
777 if (!empty($to_email)) $to_email .=
',';
782 if (empty($to_email)) {
787 $user = SQ_CONF_SYSTEM_OWNER;
789 $user = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($to);
790 if (is_null($user) || !$user->canAccessBackend())
continue;
791 $to_email = trim($user->attr(
'email'));
794 if (empty($to_email))
continue;
796 foreach ($to_emails as $subject => $bodies) {
798 $body = implode(
"\n\n".str_repeat(
'-', 50).
"\n\n", $bodies);
803 $mail = $mf->factory(
'mail',
"-f$from_email");
805 $mime =
new Mail_mime($crlf);
808 'From' => $from_string,
809 'Subject' => $subject,
812 if (isset($reply_to_str) && $reply_to_str !=
'') $hdrs[
'Reply-To'] = $reply_to_str;
814 $text_body = $this->
formatEmail($body, $user,
'text');
815 $html_body = $this->
formatEmail($body, $user,
'html');
817 $mime->setTXTBody(strip_tags($text_body));
818 $mime->setHTMLBody($html_body);
821 $body = $mime->get($mime_param);
822 $hdrs = $mime->headers($hdrs);
823 @$mail->send($to_email, $hdrs, $body);
831 unset($this->_emails);
832 $this->_emails = Array();
849 $term = ($type==
'text') ?
"\n" :
'<br />';
852 if (!is_null($user) && is_object($user) && ($user instanceof
User)) {
853 $header = $user->name.
','.$term.$term;
854 }
else if (is_string($user) && $user !=
'') {
855 $header = $user.
','.$term.$term;
858 if ($type ==
'html') {
859 $body = str_replace(
"\n\n".str_repeat(
'-', 50).
"\n\n",
'<hr />',$body);
863 if ($type ==
'html') $body = nl2br($body);
865 $line = ($type ==
'text') ? str_repeat(
'-', 20).$term :
'<hr />';
867 $footer = $term.$term.$line
868 .
'This is an automated message from '.SQ_CONF_SYSTEM_NAME.
' running '.SQ_SYSTEM_LONG_NAME.$term
869 .
'System Root URLs : '.$term.str_replace(
"\n", $term, SQ_CONF_SYSTEM_ROOT_URLS).$term
871 .
'Contact '.SQ_CONF_SYSTEM_OWNER.
' ('.SQ_CONF_TECH_EMAIL.
') for support.';
872 return $header.$body.$footer;