/** * Send a new forum message notification by mail to subscribed users. * * @param array $message * An array containing the data for a forum message. */ function phorum_api_mail_message_notify($message) { // Not "global $PHORUM", because we do not want the loading of language // files to override our already loaded language file. $PHORUM = $GLOBALS['PHORUM']; // Check if email notifications are allowed for the current forum. if (empty($PHORUM['allow_email_notify'])) { return; } $recipients = phorum_api_user_list_subscribers($PHORUM['forum_id'], $message['thread'], PHORUM_SUBSCRIPTION_MESSAGE); // No subscribers? Then we are done. if (empty($recipients)) { return; } $mail_data = array('forumname' => strip_tags($PHORUM['DATA']['NAME']), 'forum_id' => $message['forum_id'], "thread_id" => $message['thread'], 'message_id' => $message['message_id'], 'author' => phorum_api_user_get_display_name($message['user_id'], $message['author'], PHORUM_FLAG_PLAINTEXT), 'subject' => $message['subject'], 'fully_body' => $message['body'], 'plain_body' => wordwrap(phorum_api_format_strip($message['body']), 72), 'read_url' => phorum_api_url_no_uri_auth(PHORUM_READ_URL, $message['thread'], $message['message_id']), 'remove_url' => phorum_api_url_no_uri_auth(PHORUM_FOLLOW_URL, $message['thread'], 'stop=1'), 'noemail_url' => phorum_api_url_no_uri_auth(PHORUM_FOLLOW_URL, $message['thread'], 'noemail=1'), 'followed_threads_url' => phorum_api_url_no_uri_auth(PHORUM_CONTROLCENTER_URL, 'panel=' . PHORUM_CC_SUBSCRIPTION_THREADS), 'msgid' => $message['msgid'], 'mailmessagetpl' => 'NewReplyMessage', 'mailsubjecttpl' => 'NewReplySubject'); foreach ($recipients as $language => $addresses) { $language = basename($language); if (file_exists(PHORUM_PATH . "/include/lang/{$language}.php")) { $mail_data['language'] = $language; include PHORUM_PATH . "/include/lang/{$language}.php"; } else { $mail_data['language'] = $PHORUM['language']; include PHORUM_PATH . "/include/lang/{$PHORUM['language']}.php"; } $mail_data['mailmessage'] = $PHORUM['DATA']['LANG']['NewReplyMessage']; $mail_data['mailsubject'] = $PHORUM['DATA']['LANG']['NewReplySubject']; phorum_api_mail($addresses, $mail_data); } }
/** * Send a new forum message for moderation to the moderator(s). * * @param array $message * An array containing the data for a forum message. */ function phorum_api_mail_message_moderate($message) { // Not "global $PHORUM", because we do not want the loading of language // files to override our already loaded language file. $PHORUM = $GLOBALS['PHORUM']; // Retrieve the list of moderators for the current forum. $moderators = phorum_api_user_list_moderators($PHORUM['forum_id'], $PHORUM['email_ignore_admin'], TRUE); // The list moderators function returns user_id => mail address. // We want the full user info, so we can lookup the preferred // language for the moderators. $moderators = phorum_api_user_get(array_keys($moderators)); // Sort all moderators by their preferred language. $recipients = array(); foreach ($moderators as $moderator) { if (!isset($recipients[$moderator['user_language']])) { $recipients[$moderator['user_language']] = array($moderator['email']); } else { $recipients[$moderator['user_language']][] = $moderator['email']; } } // No moderators (oomph)? Then we are done. if (empty($recipients)) { return; } if ($message['status'] > 0) { $mailsubjecttpl = 'NewUnModeratedSubject'; $mailmessagetpl = 'NewUnModeratedMessage'; } else { $mailsubjecttpl = 'NewModeratedSubject'; $mailmessagetpl = 'NewModeratedMessage'; } $mail_data = array('forumname' => strip_tags($PHORUM['DATA']['NAME']), 'forum_id' => $message['forum_id'], 'message_id' => $message['message_id'], 'author' => phorum_api_user_get_display_name($message['user_id'], $message['author'], PHORUM_FLAG_PLAINTEXT), 'subject' => $message['subject'], 'fully_body' => $message['body'], 'plain_body' => wordwrap(phorum_api_format_strip($message['body']), 72), 'approve_url' => phorum_api_url_no_uri_auth(PHORUM_CONTROLCENTER_URL, 'panel=messages'), 'read_url' => phorum_api_url_no_uri_auth(PHORUM_READ_URL, $message['thread'], $message['message_id']), 'mailmessagetpl' => $mailmessagetpl, 'mailsubjecttpl' => $mailsubjecttpl); foreach ($recipients as $language => $addresses) { $language = basename($language); if (file_exists(PHORUM_PATH . "/include/lang/{$language}.php")) { $mail_data['language'] = $language; include PHORUM_PATH . "/include/lang/{$language}.php"; } else { $mail_data['language'] = $PHORUM['language']; include PHORUM_PATH . "/include/lang/{$PHORUM['language']}.php"; } $mail_data['mailmessage'] = $PHORUM['DATA']['LANG'][$mailmessagetpl]; $mail_data['mailsubject'] = $PHORUM['DATA']['LANG'][$mailsubjecttpl]; phorum_api_mail($addresses, $mail_data); } }
/** * Send a PM notification by mail. * * @param array $message * An array containing the private message data. * * @param array $recipients * An array of users that have received the PM. */ function phorum_api_mail_pm_notify($message, $recipients) { // Not "global $PHORUM", because we do not want the loading of language // files to override our already loaded language file. $PHORUM = $GLOBALS['PHORUM']; // Sort all recipients that want a notification by their preferred language. $recipients_by_lang = array(); foreach ($recipients as $recipient) { if ($recipient['pm_email_notify']) { if (!isset($recipients_by_lang[$recipient['user_language']])) { $recipients_by_lang[$recipient['user_language']] = array($recipient); } else { $recipients_by_lang[$recipient['user_language']][] = $recipient; } } } // No users found that want a notification? Then we are done. if (empty($recipients_by_lang)) { return; } // Build the data array for phorum_api_mail(). $mail_data = array('pm_message_id' => $message['pm_message_id'], 'author' => phorum_api_user_get_display_name($message['user_id'], $message['from_username'], PHORUM_FLAG_PLAINTEXT), 'subject' => $message['subject'], 'full_body' => $message['message'], 'plain_body' => wordwrap(phorum_api_format_strip($message['message']), 72), 'read_url' => phorum_api_url_no_uri_auth(PHORUM_PM_URL, 'page=read', 'pm_id=' . $message['pm_message_id']), 'mailmessagetpl' => 'PMNotifyMessage', 'mailsubjecttpl' => 'PMNotifySubject'); foreach ($recipients_by_lang as $language => $users) { $language = basename($language); if (file_exists(PHORUM_PATH . "/include/lang/{$language}.php")) { $mail_data['language'] = $language; include PHORUM_PATH . "/include/lang/{$language}.php"; } else { $mail_data['language'] = $PHORUM['language']; include PHORUM_PATH . "/include/lang/{$PHORUM['language']}.php"; } $mail_data['mailmessage'] = $PHORUM['DATA']['LANG']['PMNotifyMessage']; $mail_data['mailsubject'] = $PHORUM['DATA']['LANG']['PMNotifySubject']; $addresses = array(); foreach ($users as $user) { $addresses[] = $user['email']; } phorum_api_mail($addresses, $mail_data); } }
// files. Up to Phorum 5.2, we had LostPassEmailBody1 and // LostPassEmailBody2 for defining the lost password mail body. // In 5.3, we switched to a single variable LostPassEmailBody. // Eventually, the variable replacements need to be handled // by the mail API layer. if (isset($PHORUM['DATA']['LANG']['LostPassEmailBody'])) { $mail_data['mailmessage'] = wordwrap(str_replace(array('%title%', '%username%', '%password%', '%login_url%'), array($PHORUM['title'], $user['username'], $newpass, phorum_api_url(PHORUM_LOGIN_URL)), $PHORUM['DATA']['LANG']['LostPassEmailBody']), 72); } else { // Hide the deprecated language strings from the // amin language tool by not using the full syntax // for those. $lang = $PHORUM['DATA']['LANG']; $mail_data['mailmessage'] = wordwrap($lang['LostPassEmailBody1'], 72) . "\n\n" . $lang['Username'] . ": {$user['username']}\n" . $lang['Password'] . ": {$newpass}" . "\n\n" . wordwrap($lang['LostPassEmailBody2'], 72); } $mail_data['mailsubject'] = $PHORUM['DATA']['LANG']['LostPassEmailSubject']; phorum_api_mail($user['email'], $mail_data); $okmsg = $PHORUM['DATA']['LANG']['LostPassSent']; $hook_args = array('status' => 'new_password', 'email' => $_POST['lostpass'], 'user' => $user, 'secret' => $newpass); } } else { $error = $PHORUM['DATA']['LANG']['LostPassError']; $focus = 'lostpass'; $hook_args = array('status' => 'user_unknown', 'email' => $_POST['lostpass'], 'user' => NULL, 'secret' => NULL); } /* * [hook] * password_reset * * [availability] * Phorum 5 >= 5.2.13 *
// Remember this for the template. if (isset($PHORUM['DATA']['PROFILE']['email_temp_part'])) { $email_temp_part = $PHORUM['DATA']['PROFILE']['email_temp_part']; } // do we need to send a confirmation-mail? if (isset($PHORUM['DATA']['PROFILE']['email_temp_part']) && !empty($_POST['email_verify_code']) && $PHORUM['DATA']['PROFILE']['email_temp_part'] . "|" . $_POST['email_verify_code'] == $PHORUM['DATA']['PROFILE']['email_temp']) { $_POST['email'] = $PHORUM['DATA']['PROFILE']['email_temp_part']; $_POST['email_temp'] = ""; $email_temp_part = ""; } elseif ($PHORUM['registration_control'] && !empty($_POST['email']) && strtolower($_POST['email']) != strtolower($PHORUM["DATA"]["PROFILE"]['email'])) { // ... generate the confirmation-code ... // $conf_code = mt_rand(1000000, 9999999); $_POST['email_temp'] = $_POST['email'] . "|" . $conf_code; // ... send email ... // $maildata = array('mailmessage' => wordwrap($PHORUM['DATA']['LANG']['EmailVerifyBody'], 72), 'mailsubject' => $PHORUM['DATA']['LANG']['EmailVerifySubject'], 'uname' => $PHORUM['DATA']['PROFILE']['username'], 'username' => $PHORUM['DATA']['PROFILE']['username'], 'newmail' => $_POST['email'], 'mailcode' => $conf_code, 'cc_url' => phorum_api_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_MAIL)); phorum_api_mail($_POST['email'], $maildata); // Remember this for the template. $email_temp_part = $_POST['email']; unset($_POST['email']); } list($error, $okmsg) = phorum_controlcenter_user_save($panel); } } if (!empty($email_temp_part)) { $PHORUM['DATA']['PROFILE']['email_temp_part'] = $email_temp_part; } // TEMPLATETODO // flip this due to db vs. UI wording. if (!empty($PHORUM['DATA']['PROFILE']["hide_email"])) { $PHORUM["DATA"]["PROFILE"]["hide_email_checked"] = ""; } else {
} $mail_users = phorum_api_user_list_moderators($PHORUM['forum_id'], $PHORUM['email_ignore_admin'], TRUE); if (count($mail_users)) { $mail_data = array("mailmessage" => $PHORUM["DATA"]["LANG"]['ReportPostEmailBody'], "mailsubject" => $PHORUM["DATA"]["LANG"]['ReportPostEmailSubject'], "forumname" => $PHORUM["DATA"]["NAME"], "reportedby" => $PHORUM["user"]["display_name"], "author" => $message["author"], "subject" => $message["subject"], "body" => wordwrap($message["body"], 72), "ip" => $message["ip"], "raw_date" => $message["datestamp"], "date" => phorum_api_format_date($PHORUM["short_date_time"], $message["datestamp"]), "explanation" => wordwrap($_POST["explanation"], 72), "url" => phorum_api_url(PHORUM_READ_URL, $message["thread"], $message_id), "delete_url" => phorum_api_url(PHORUM_MODERATION_URL, PHORUM_DELETE_MESSAGE, $message_id), "hide_url" => phorum_api_url(PHORUM_MODERATION_URL, PHORUM_HIDE_POST, $message_id), "edit_url" => phorum_api_url(PHORUM_POSTING_URL, 'moderation', $message_id), "reporter_url" => phorum_api_url(PHORUM_PROFILE_URL, $PHORUM["user"]["user_id"]), "message" => $message); if (isset($_POST[PHORUM_SESSION_LONG_TERM])) { // strip any auth info from the created urls $mail_data["url"] = preg_replace("!,{0,1}" . PHORUM_SESSION_LONG_TERM . "=" . urlencode($_POST[PHORUM_SESSION_LONG_TERM]) . "!", "", $mail_data["url"]); $mail_data["delete_url"] = preg_replace("!,{0,1}" . PHORUM_SESSION_LONG_TERM . "=" . urlencode($_POST[PHORUM_SESSION_LONG_TERM]) . "!", "", $mail_data["delete_url"]); $mail_data["hide_url"] = preg_replace("!,{0,1}" . PHORUM_SESSION_LONG_TERM . "=" . urlencode($_POST[PHORUM_SESSION_LONG_TERM]) . "!", "", $mail_data["hide_url"]); $mail_data["edit_url"] = preg_replace("!,{0,1}" . PHORUM_SESSION_LONG_TERM . "=" . urlencode($_POST[PHORUM_SESSION_LONG_TERM]) . "!", "", $mail_data["edit_url"]); $mail_data["reporter_url"] = preg_replace("!,{0,1}" . PHORUM_SESSION_LONG_TERM . "=" . urlencode($_POST[PHORUM_SESSION_LONG_TERM]) . "!", "", $mail_data["reporter_url"]); } if (isset($PHORUM["hooks"]["report"])) { $mail_data = phorum_api_hook("report", $mail_data); } phorum_api_mail($mail_users, $mail_data); $PHORUM["DATA"]["URL"]["REDIRECT"] = phorum_api_url(PHORUM_FOREIGN_READ_URL, $message["forum_id"], $message["thread"], $message['message_id']); $PHORUM["DATA"]["BACKMSG"] = $PHORUM["DATA"]["LANG"]["BackToThread"]; $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["ReportPostSuccess"]; $template = "message"; $report = true; } } else { $PHORUM["DATA"]["ReportPostMessage"] = $PHORUM["DATA"]["LANG"]['ReportPostNotAllowed']; } } // format message list($message) = phorum_api_format_messages(array($message)); $PHORUM["DATA"]["PostSubject"] = $message["subject"]; $PHORUM["DATA"]["PostAuthor"] = $message["author"]; $PHORUM["DATA"]["PostBody"] = $message["body"];
/** * @deprecated Replaced by {@link phorum_api_mail()}. */ function phorum_email_user($addresses, $data) { require_once PHORUM_PATH . '/include/api/mail.php'; return phorum_api_mail($addresses, $data); }
if (!empty($_POST["user_ids"])) { foreach ($_POST["user_ids"] as $user_id) { // initialize it $userdata = array(); $user = phorum_api_user_get($user_id, TRUE); if (!isset($_POST["approve"]) && $user['active'] != PHORUM_USER_ACTIVE) { $userdata["active"] = PHORUM_USER_INACTIVE; } else { if ($user["active"] == PHORUM_USER_PENDING_BOTH) { $userdata["active"] = PHORUM_USER_PENDING_EMAIL; } elseif ($user["active"] == PHORUM_USER_PENDING_MOD) { $userdata["active"] = PHORUM_USER_ACTIVE; // send reg approved message $maildata["mailsubject"] = $PHORUM["DATA"]["LANG"]["RegApprovedSubject"]; $maildata["mailmessage"] = wordwrap($PHORUM["DATA"]["LANG"]["RegApprovedEmailBody"], 72); phorum_api_mail(array($user["email"]), $maildata); } } $userdata["user_id"] = $user_id; // only save it if something was changed if (isset($userdata['active'])) { phorum_api_user_save($userdata); } } } if (empty($users)) { $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["NoUnapprovedUsers"]; } else { // get a fresh list to update any changes $users = $PHORUM['DB']->user_get_unapproved(); // XSS prevention.
/** * Database error handling function. * * @param string $error * The database error message. */ function phorum_api_error_database($error) { global $PHORUM; $hcharset = $PHORUM['DATA']['HCHARSET']; // Clear any output that we buffered so far (e.g. in the admin interface, // we might already have sent the page header). phorum_api_buffer_clear(); /* * [hook] * database_error * * [description] * Give modules a chance to handle or process database errors. * This can be useful to implement addional logging backends and/or * alerting mechanisms. Another option is to fully override Phorum's * default database error handling by handling the error and then * calling exit() from the hook to prevent the default Phorum code * from running.<sbr/> * <sbr/> * Note: If you decide to use the full override scenario, then * it is best to make your module run the database_error hook * last, so other modules can still run their hook handling * before the script exits. To accomplish this, add this to your * module info: * <programlisting> * priority: run hook database_error after * * </programlisting> * * [category] * Miscellaneous * * [when] * At the start of the function * <literal>phorum_api_error_database</literal> (which you can find in * <filename>include/api/error.php</filename>). This function is called * from the database layer when some database error occurs. * * [input] * The error message that was returned from the database layer. * This error is not HTML escaped, so if you send it to the browser, * be sure to preprocess it using <phpfunc>htmlspecialchars</phpfunc>. * * [output] * Same as input. * * [example] * <hookcode> * function phorum_mod_foo_database_error($error) * { * // Log database errors to syslog facility "LOCAL0". * openlog("Phorum", LOG_PID | LOG_PERROR, LOG_LOCAL0); * syslog(LOG_ERR, $error); * * return $error; * } * </hookcode> */ if (isset($PHORUM["hooks"]["database_error"])) { phorum_api_hook("database_error", $error); } // Find out what type of error handling is configured. // If no type if set, then we use "screen" by default. $logopt = isset($PHORUM["error_logging"]) ? $PHORUM["error_logging"] : 'screen'; // Create a backtrace report, so it's easier to find out where // a problem is coming from. $backtrace = phorum_api_error_backtrace(2); // Error page header. if (PHP_SAPI != "cli") { // Start the error page. ?> <html><head><title>Phorum Database Error</title></head><body> <h1>Phorum Database Error</h1> Sorry, a Phorum database error occurred.<br/> <?php // In admin scripts, we will always include the // error message inside a comment in the page. if (defined("PHORUM_ADMIN")) { print "<!-- " . htmlspecialchars($error, ENT_COMPAT, $hcharset) . " -->"; } } else { // In CLI mode, we always show the error message on screen. // No need to be hiding this info from a user that can run CLI code. print "Sorry, a Phorum database error occurred:\n"; print "------------------------------------------------------\n"; print "Error: {$error}\n"; if ($backtrace !== NULL) { print "------------------------------------------------------\n"; print "Backtrace:\n" . $backtrace . "\n"; } print "------------------------------------------------------\n"; } switch ($logopt) { // Log the database error to a logfile. case "file": $cache_dir = $PHORUM['CACHECONFIG']['directory']; $logfile = $cache_dir . '/phorum-sql-errors.log'; if ($fp = @fopen($logfile, "a")) { fputs($fp, "Time: " . time() . "\n" . "Error: {$error}\n" . ($backtrace !== NULL ? "Back trace:\n{$backtrace}\n\n" : "")); fclose($fp); if (PHP_SAPI != 'cli') { print "The error message has been logged<br/>" . "to the phorum-sql-errors.log error log.<br/>" . "Please, try again later!"; } else { print "The error message has been logged to the db error log:\n"; print "{$logfile}\n"; } } else { trigger_error("phorum_api_error_database(): cannot write to {$logfile}", E_USER_ERROR); } break; // Display the database error on screen. // Display the database error on screen. case "screen": // For CLI scripts, the error was already shown on screen. if (PHP_SAPI != 'cli') { $htmlbacktrace = $backtrace === NULL ? NULL : nl2br(htmlspecialchars($backtrace, ENT_COMPAT, $hcharset)); print "Please try again later!" . "<h3>Error:</h3>" . htmlspecialchars($error, ENT_COMPAT, $hcharset) . ($backtrace !== NULL ? "<h3>Backtrace:</h3>\n{$htmlbacktrace}" : ""); } break; // Send a mail to the administrator about the database error. // Send a mail to the administrator about the database error. case "mail": default: require_once PHORUM_PATH . '/include/api/mail.php'; $data = array('mailmessage' => "A database error occured in your Phorum installation\n" . htmlspecialchars($PHORUM['http_path']) . ":\n" . "\n" . "Error message:\n" . (require_once "--------------\n" . "\n" . "{$error}\n" . "\n" . ($backtrace !== NULL ? "Backtrace:\n" . "----------\n" . "\n" . "{$backtrace}\n" : "")), 'mailsubject' => 'Phorum: A database error occured'); $adminmail = $PHORUM['system_email_from_address']; phorum_api_mail($adminmail, $data); if (PHP_SAPI != 'cli') { print "The administrator of this forum has been<br/>" . "notified by email about the error.<br/>" . "Please, try again later!"; } else { print "The error message was sent by mail to {$adminmail}\n"; } break; } // Error page footer. if (PHP_SAPI != "cli") { print '</body></html>'; } exit; }
// language files. Up to Phorum 5.2, we had // VerifyRegEmailBody1 and VerifyRegEmailBody2 for // defining the lost password mail body. In 5.3, we // switched to a single variable VerifyRegEmailBody. // Eventually, the variable replacements need to be // handled by the mail API layer. if (isset($PHORUM['DATA']['LANG']['VerifyRegEmailBody'])) { $maildata['mailmessage'] = wordwrap(str_replace(array('%title%', '%username%', '%display_name%', '%verify_url%', '%login_url%'), array($PHORUM['title'], $user_new['username'], $user_new['display_name'], $verify_url, phorum_api_url(PHORUM_LOGIN_URL)), $PHORUM['DATA']['LANG']['VerifyRegEmailBody']), 72); } else { // Hide the deprecated language strings from the // amin language tool by not using the full syntax // for those. $lang = $PHORUM['DATA']['LANG']; $maildata["mailmessage"] = wordwrap(str_replace(array('%title%', '%username%', '%display_name%', '%verify_url%', '%login_url%'), array($PHORUM['title'], $user_new['username'], $user_new['display_name'], $verify_url, phorum_api_url(PHORUM_LOGIN_URL)), $lang['VerifyRegEmailBody1']), 72) . "\n\n{$verify_url}\n\n" . wordwrap(str_replace(array('%title%', '%username%', '%display_name%', '%verify_url%', '%login_url%'), array($PHORUM['title'], $user_new['username'], $user_new['display_name'], $verify_url, phorum_api_url(PHORUM_LOGIN_URL)), $lang['VerifyRegEmailBody2']), 72); } phorum_api_mail($userdata["email"], $maildata); } $PHORUM["DATA"]["BACKMSG"] = $PHORUM["DATA"]["LANG"]["RegBack"]; $PHORUM["DATA"]["URL"]["REDIRECT"] = phorum_api_url(PHORUM_LOGIN_URL); /* * [hook] * after_register * * [description] * This hook can be used for performing tasks (like logging * and notification) after a successful user registration. * * [category] * User data handling * * [when]