Ejemplo n.º 1
0
/**
 * 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);
    }
}
Ejemplo n.º 2
0
/**
 * 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);
    }
}
Ejemplo n.º 3
0
/**
 * 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);
    }
}
Ejemplo n.º 4
0
Archivo: js.php Proyecto: samuell/Core
/**
 * This function implements the JavaScript output adapter for the Feed API.
 *
 * @param array $messages
 *     An array of messages to include in the feed.
 *
 * @param array $forums
 *     An array of related forums.
 *
 * @param string $url
 *     The URL that points to the feed's target.
 *
 * @param string $title
 *     The title to use for the feed.
 *
 * @param string $description
 *     The description to use for the feed.
 *
 * @param bool $replies
 *     Whether or not this is a feed that includes reply messages.
 *     If not, then it will only contain thread starter messages.
 *
 * @return array
 *     An array containing two elements:
 *     - The generated feed data (JavaScript code)
 *     - The Content-Type header to use for the feed.
 */
function phorum_api_feed_js($messages, $forums, $url, $title, $description, $replies)
{
    global $PHORUM;
    $feed = array('title' => $title, 'description' => $description, 'modified' => phorum_api_format_date($PHORUM['short_date'], time()));
    // Lookup the plain text usernames for the authenticated authors.
    $users = $messages['users'];
    unset($messages['users']);
    unset($users[0]);
    $users = phorum_api_user_get_display_name($users, '', PHORUM_FLAG_PLAINTEXT);
    foreach ($messages as $message) {
        $author = !empty($users[$message['user_id']]) ? $users[$message['user_id']] : $message['author'];
        // Created date.
        $fmt = $PHORUM['short_date'];
        $created = phorum_api_format_date($fmt, $message['datestamp']);
        // Updated date.
        if ($message['parent_id']) {
            if (!empty($message['meta']['edit_date'])) {
                $modified = $message['meta']['edit_date'];
            } else {
                $modified = $message['datestamp'];
            }
        } else {
            $modified = $message['modifystamp'];
        }
        $modified = phorum_api_format_date($fmt, $modified);
        $url = htmlspecialchars(phorum_api_url(PHORUM_FOREIGN_READ_URL, $message['forum_id'], $message['thread'], $message['message_id']));
        $item = array('title' => strip_tags($message['subject']), 'author' => $author, 'category' => $forums[$message['forum_id']]['name'], 'created' => $created, 'modified' => $modified, 'url' => $url, 'description' => $message['body']);
        if ($message["thread_count"]) {
            $replies = $message["thread_count"] - 1;
            $item["replies"] = $replies;
        }
        $feed["items"][] = $item;
    }
    // this is where we convert the array into js
    $buffer = 'phorum_feed = ' . phorum_api_json_encode($feed);
    return array($buffer, 'text/javascript');
}
Ejemplo n.º 5
0
        // too much to calculate here to avoid the full refresh
        $PHORUM['DB']->update_forum_stats(true);
    }
} else {
    // set some key fields to the same values as the first message in the thread
    $dbmessage["forum_id"] = $top_parent["forum_id"];
    $dbmessage["sort"] = $top_parent["sort"];
}
// Update the editing info in the meta data.
$dbmessage["meta"]["show_signature"] = $message["show_signature"];
// we are doing the diffs here to know about changes for edit-counts
// $origmessage loaded in check_permissions
$diff_body = phorum_api_diff($origmessage["body"], $message["body"]);
$diff_subject = phorum_api_diff($origmessage["subject"], $message["subject"]);
if (!empty($diff_body) || !empty($diff_subject)) {
    $name = phorum_api_user_get_display_name($PHORUM["user"]["user_id"], NULL, PHORUM_FLAG_PLAINTEXT);
    $dbmessage["meta"]["edit_count"] = isset($message["meta"]["edit_count"]) ? $message["meta"]["edit_count"] + 1 : 1;
    $dbmessage["meta"]["edit_date"] = time();
    $dbmessage["meta"]["edit_username"] = $name;
    $dbmessage["meta"]["edit_user_id"] = $PHORUM["user"]["user_id"];
    // perform diff if edit tracking is enabled
    if (!empty($PHORUM["track_edits"])) {
        $edit_data = array("diff_body" => $diff_body, "diff_subject" => $diff_subject, "time" => $dbmessage["meta"]["edit_date"], "user_id" => $PHORUM["user"]["user_id"], "message_id" => $dbmessage['message_id']);
        $PHORUM['DB']->add_message_edit($edit_data);
    }
}
// Update attachments in the meta data, link active attachments
// to the message and delete stale attachments.
$dbmessage["meta"]["attachments"] = array();
foreach ($message["attachments"] as $info) {
    if ($info["keep"]) {
Ejemplo n.º 6
0
Archivo: pm.php Proyecto: netovs/Core
function phorum_pm_quoteformat($orig_author, $orig_author_id, $message, $inreplyto = NULL)
{
    global $PHORUM;
    // Build the reply subject.
    if (substr($message["subject"], 0, 3) != "Re:") {
        $message["subject"] = "Re: " . $message["subject"];
    }
    // Lookup the plain text name that we have to use for the author that we reply to.
    $author = phorum_api_user_get_display_name($orig_author_id, '', PHORUM_FLAG_PLAINTEXT);
    // TODO we'll have to handle anonymous users in the PM box. Those are
    // TODO users which sent a PM to somebody, but signed out afterwards.
    // TODO Currently, there's no graceful handling for that I think
    // TODO (maybe it's handled already, but that would only be by accident).
    if (isset($PHORUM["hooks"]["quote"])) {
        $quote = phorum_api_hook("quote", array($author, $message["message"], $orig_author_id));
    }
    if (empty($quote) || is_array($quote)) {
        // Build a quoted version of the message body.
        $quote = phorum_api_format_strip($message["message"]);
        $quote = str_replace("\n", "\n> ", $quote);
        $quote = wordwrap(trim($quote), 50, "\n> ", true);
        $quote = "{$author} {$PHORUM['DATA']['LANG']['Wrote']}:\n" . str_repeat("-", 55) . "\n> {$quote}\n\n\n";
    }
    $quote = ($inreplyto != NULL ? "{$PHORUM['DATA']['LANG']['InReplyTo']} {$inreplyto}\n\n" : '') . $quote;
    $message["message"] = $quote;
    return $message;
}
Ejemplo n.º 7
0
function phorum_feed_make_js($messages, $forums, $feed_url, $feed_title, $feed_description)
{
    $PHORUM = $GLOBALS["PHORUM"];
    // build PHP array to later be turned into a JS object
    $feed["title"] = $feed_title;
    $feed["description"] = $feed_description;
    $feed["modified"] = phorum_date($PHORUM['short_date'], time());
    // Lookup the plain text usernames for the authenticated authors.
    $users = $messages['users'];
    unset($messages['users']);
    unset($users[0]);
    $users = phorum_api_user_get_display_name($users, '', PHORUM_FLAG_PLAINTEXT);
    foreach ($messages as $message) {
        $author = isset($users[$message['user_id']]) && $users[$message['user_id']] != '' ? $users[$message['user_id']] : $message['author'];
        $item = array("title" => strip_tags($message["subject"]), "author" => $author, "category" => $forums[$message["forum_id"]]["name"], "created" => phorum_date($PHORUM['short_date'], $message["datestamp"]), "modified" => phorum_date($PHORUM['short_date'], $message["modifystamp"]), "url" => phorum_get_url(PHORUM_FOREIGN_READ_URL, $message["forum_id"], $message["thread"], $message["message_id"]), "description" => $message["body"]);
        if ($message["thread_count"]) {
            $replies = $message["thread_count"] - 1;
            $item["replies"] = $replies;
        }
        $feed["items"][] = $item;
    }
    // this is where we convert the array into js
    $buffer = phorum_array_to_javascript("phorum_feed", $feed);
    return $buffer;
}
Ejemplo n.º 8
0
function phorum_email_moderators($message)
{
    $PHORUM = $GLOBALS["PHORUM"];
    $mail_users = phorum_api_user_list_moderators($PHORUM['forum_id'], $PHORUM['email_ignore_admin'], TRUE);
    if (count($mail_users)) {
        include_once "./include/format_functions.php";
        if ($message["status"] > 0) {
            // just notification of a new message
            $mailsubjecttpl = 'NewUnModeratedSubject';
            $mailmessagetpl = 'NewUnModeratedMessage';
            $mailsubject = $PHORUM["DATA"]["LANG"]['NewUnModeratedSubject'];
            $mailmessage = $PHORUM["DATA"]["LANG"]['NewUnModeratedMessage'];
        } else {
            // posts needing approval
            $mailsubjecttpl = 'NewModeratedSubject';
            $mailmessagetpl = 'NewModeratedMessage';
            $mailsubject = $PHORUM["DATA"]["LANG"]['NewModeratedSubject'];
            $mailmessage = $PHORUM["DATA"]["LANG"]['NewModeratedMessage'];
        }
        $mail_data = array("forumname" => strip_tags($PHORUM["DATA"]["NAME"]), "forum_id" => $PHORUM['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'], "full_body" => $message['body'], "plain_body" => phorum_strip_body($message['body']), "approve_url" => phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=messages"), "read_url" => phorum_get_url(PHORUM_READ_URL, $message['thread'], $message['message_id']), "mailmessage" => $mailmessage, "mailsubject" => $mailsubject, "mailmessagetpl" => $mailmessagetpl, "mailsubjecttpl" => $mailsubjecttpl, "language" => $PHORUM['language']);
        if (isset($_POST[PHORUM_SESSION_LONG_TERM])) {
            // strip any auth info from the read url
            $mail_data["read_url"] = preg_replace("!,{0,1}" . PHORUM_SESSION_LONG_TERM . "=" . urlencode($_POST[PHORUM_SESSION_LONG_TERM]) . "!", "", $mail_data["read_url"]);
            $mail_data["approve_url"] = preg_replace("!,{0,1}" . PHORUM_SESSION_LONG_TERM . "=" . urlencode($_POST[PHORUM_SESSION_LONG_TERM]) . "!", "", $mail_data["approve_url"]);
        }
        phorum_email_user($mail_users, $mail_data);
    }
}
Ejemplo n.º 9
0
if ($mode == "reply" || $mode == "quote") {
    // Set thread and parent information.
    $message["parent_id"] = $dbmessage["message_id"];
    $message["thread"] = $dbmessage["thread"];
    // Create Re: subject prefix.
    if (substr($dbmessage["subject"], 0, 4) != "Re: ") {
        $dbmessage["subject"] = "Re: " . $dbmessage["subject"];
    }
    $message["subject"] = $dbmessage["subject"];
    // Add a quoted version of the body for quoted reply messages.
    if ($mode == "quote") {
        // Lookup the name that we have to use for the author, if the
        // author is a registered user. The author field could be used
        // directly, but it can contain HTML formatting code, in case
        // some module uses the custom display name functionality.
        $author = phorum_api_user_get_display_name($dbmessage["user_id"], $dbmessage['author'], PHORUM_FLAG_PLAINTEXT);
        $quoted = 0;
        if (isset($PHORUM["hooks"]["quote"])) {
            $quoted = phorum_api_hook("quote", array($author, $dbmessage["body"], $dbmessage["user_id"]));
        }
        if (empty($quoted) || is_array($quoted)) {
            $quoted = phorum_api_format_strip($dbmessage["body"]);
            $quoted = str_replace("\n", "\n> ", $quoted);
            $quoted = wordwrap(trim($quoted), 50, "\n> ", true);
            $quoted = "{$author} " . "{$PHORUM["DATA"]["LANG"]["Wrote"]}:\n" . str_repeat("-", 55) . "\n> {$quoted}\n\n\n";
        }
        $message["body"] = $quoted;
    }
}
// Set message data for editing posts.
if ($mode == "edit" || $mode == "moderation") {
Ejemplo n.º 10
0
 function testUserApiDisplayName()
 {
     $user_id = phorum_api_user_search('username', 'testuser' . $this->sharedFixture, '=');
     // display-name handling
     $ret = phorum_api_user_get_display_name($user_id, NULL, PHORUM_FLAG_HTML);
     $this->assertType('string', $ret, 'Getting displayname for user (HTML).');
     $ret = phorum_api_user_get_display_name($user_id, NULL, PHORUM_FLAG_PLAINTEXT);
     $this->assertType('string', $ret, 'Getting displayname for user (Plaintext).');
 }
Ejemplo n.º 11
0
Archivo: rss.php Proyecto: samuell/Core
/**
 * This function implements the RSS output adapter for the Feed API.
 *
 * @param array $messages
 *     An array of messages to include in the feed.
 *
 * @param array $forums
 *     An array of related forums.
 *
 * @param string $url
 *     The URL that points to the feed's target.
 *
 * @param string $title
 *     The title to use for the feed.
 *
 * @param string $description
 *     The description to use for the feed.
 *
 * @param bool $replies
 *     Whether or not this is a feed that includes reply messages.
 *     If not, then it will only contain thread starter messages.
 *
 * @return array
 *     An array containing two elements:
 *     - The generated feed data (RSS XML).
 *     - The Content-Type header to use for the feed.
 */
function phorum_api_feed_rss($messages, $forums, $url, $title, $description, $replies)
{
    global $PHORUM;
    $hcharset = $PHORUM['DATA']['HCHARSET'];
    $url = htmlspecialchars($url, ENT_COMPAT, $hcharset);
    $title = htmlspecialchars($title, ENT_COMPAT, $hcharset);
    $description = htmlspecialchars($description, ENT_COMPAT, $hcharset);
    $builddate = htmlspecialchars(date('r'), ENT_COMPAT, $hcharset);
    $generator = htmlspecialchars('Phorum ' . PHORUM, ENT_COMPAT, $hcharset);
    $buffer = "<?xml version=\"1.0\" encoding=\"{$PHORUM['DATA']['CHARSET']}\"?>\n";
    $buffer .= "<rss version=\"2.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
    $buffer .= " <channel>\n";
    $buffer .= "  <title>{$title}</title>\n";
    $buffer .= "  <description>{$description}</description>\n";
    $buffer .= "  <link>{$url}</link>\n";
    $buffer .= "  <lastBuildDate>{$builddate}</lastBuildDate>\n";
    $buffer .= "  <generator>{$generator}</generator>\n";
    // Lookup the plain text usernames for the authenticated authors.
    $users = $messages['users'];
    unset($messages['users']);
    unset($users[0]);
    $users = phorum_api_user_get_display_name($users, '', PHORUM_FLAG_PLAINTEXT);
    foreach ($messages as $message) {
        // Include information about the number of replies to threads.
        $title = strip_tags($message['subject']);
        if (!$replies) {
            $lang = $PHORUM['DATA']['LANG'];
            switch ($message['thread_count']) {
                case 1:
                    $title .= " ({$lang['noreplies']})";
                    break;
                case 2:
                    $title .= " (1 {$lang['reply']})";
                    break;
                default:
                    $replies = $message['thread_count'] - 1;
                    $title .= " ({$replies} {$lang['replies']})";
            }
            $date = date('r', $message['modifystamp']);
        } else {
            $date = date('r', $message['datestamp']);
        }
        // Generate the URL for reading the message.
        $url = htmlspecialchars(phorum_api_url(PHORUM_FOREIGN_READ_URL, $message["forum_id"], $message["thread"], $message["message_id"]));
        // The forum in which the message is stored is used as the category.
        $category = htmlspecialchars($forums[$message['forum_id']]['name'], ENT_COMPAT, $hcharset);
        // Format the author.
        $author = !empty($users[$message['user_id']]) ? $users[$message['user_id']] : $message['author'];
        $author = htmlspecialchars($author, ENT_COMPAT, $hcharset);
        // Strip unprintable characters from the message body.
        $body = strtr($message['body'], "\v\f" . "", "????????????????????????????");
        $buffer .= "  <item>\n";
        $buffer .= "   <guid>{$url}</guid>\n";
        $buffer .= "   <title>{$title}</title>\n";
        $buffer .= "   <link>{$url}</link>\n";
        $buffer .= "   <description><![CDATA[{$body}]]></description>\n";
        $buffer .= "   <dc:creator>{$author}</dc:creator>\n";
        $buffer .= "   <category>{$category}</category>\n";
        $buffer .= "   <pubDate>{$date}</pubDate>\n";
        $buffer .= "  </item>\n";
    }
    $buffer .= " </channel>\n";
    $buffer .= "</rss>\n";
    return array($buffer, 'application/xml');
}
Ejemplo n.º 12
0
Archivo: atom.php Proyecto: netovs/Core
/**
 * This function implements the Atom output adapter for the Feed API.
 *
 * @param array $messages
 *     An array of messages to include in the feed.
 *
 * @param array $forums
 *     An array of related forums.
 *
 * @param string $url
 *     The URL that points to the feed's target.
 *
 * @param string $title
 *     The title to use for the feed.
 *
 * @param string $description
 *     The description to use for the feed.
 *
 * @param bool $replies
 *     Whether or not this is a feed that includes reply messages.
 *     If not, then it will only contain thread starter messages.
 *
 * @return array
 *     An array containing two elements:
 *     - The generated feed data (Atom XML).
 *     - The Content-Type header to use for the feed.
 */
function phorum_api_feed_atom($messages, $forums, $url, $title, $description, $replies)
{
    global $PHORUM;
    $hcharset = $PHORUM['DATA']['HCHARSET'];
    $selfurl = htmlspecialchars(phorum_api_url_current(), ENT_COMPAT, $hcharset);
    $url = htmlspecialchars($url, ENT_COMPAT, $hcharset);
    $title = htmlspecialchars($title, ENT_COMPAT, $hcharset);
    $description = htmlspecialchars($description, ENT_COMPAT, $hcharset);
    $builddate = htmlspecialchars(date('r'), ENT_COMPAT, $hcharset);
    $generator = htmlspecialchars('Phorum ' . PHORUM, ENT_COMPAT, $hcharset);
    $buffer = "<?xml version=\"1.0\" encoding=\"{$PHORUM['DATA']['CHARSET']}\"?>\n";
    $buffer .= "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n";
    $buffer .= " <title>{$title}</title>\n";
    $buffer .= " <subtitle>{$description}</subtitle>\n";
    $buffer .= " <link rel=\"self\" href=\"{$selfurl}\" />\n";
    $buffer .= " <id>{$url}</id>\n";
    $buffer .= " <updated>{$builddate}</updated>\n";
    $buffer .= " <generator>{$generator}</generator>\n";
    // Lookup the plain text usernames for the authenticated authors.
    $users = $messages['users'];
    unset($messages['users']);
    unset($users[0]);
    $users = phorum_api_user_get_display_name($users, '', PHORUM_FLAG_PLAINTEXT);
    foreach ($messages as $message) {
        // Include information about the number of replies to threads.
        $title = strip_tags($message['subject']);
        if (!$replies) {
            $lang = $PHORUM['DATA']['LANG'];
            switch ($message['thread_count']) {
                case 1:
                    $title .= " ({$lang['noreplies']})";
                    break;
                case 2:
                    $title .= " (1 {$lang['reply']})";
                    break;
                default:
                    $replies = $message['thread_count'] - 1;
                    $title .= " ({$replies} {$lang['replies']})";
            }
        }
        // Publish date.
        $published = date('r', $message['datestamp']);
        // Updated date.
        if ($message['parent_id']) {
            if (!empty($message['meta']['edit_date'])) {
                $updated = date('r', $message['meta']['edit_date']);
            } else {
                $updated = $published;
            }
        } else {
            $updated = date('r', $message['modifystamp']);
        }
        // Generate the URL for reading the message.
        $url = htmlspecialchars(phorum_api_url(PHORUM_FOREIGN_READ_URL, $message["forum_id"], $message["thread"], $message["message_id"]));
        // The forum in which the message is stored is used as the category.
        $category = htmlspecialchars($forums[$message['forum_id']]['name'], ENT_COMPAT, $hcharset);
        // Format the author.
        $author = !empty($users[$message['user_id']]) ? $users[$message['user_id']] : $message['author'];
        $author = htmlspecialchars($author, ENT_COMPAT, $hcharset);
        // Strip unprintable characters from the message body.
        $body = strtr($message['body'], "\v\f" . "", "????????????????????????????");
        $buffer .= " <entry>\n";
        $buffer .= "  <title type=\"html\">{$title}</title>\n";
        $buffer .= "  <link href=\"{$url}\" />\n";
        $buffer .= "  <category term=\"{$category}\" />\n";
        $buffer .= "  <published>{$published}</published>\n";
        $buffer .= "  <updated>{$updated}</updated>\n";
        $buffer .= "  <id>{$url}</id>\n";
        $buffer .= "  <author>\n";
        $buffer .= "  <name>{$author}</name>\n";
        $buffer .= "  </author>\n";
        $buffer .= "  <summary type=\"html\"><![CDATA[{$body}]]></summary>\n";
        $buffer .= " </entry>\n";
    }
    $buffer .= "</feed>\n";
    return array($buffer, 'application/xml');
}