/** * Sends an email to User * * @param integer Recipient ID. * @param string Subject of the mail * @param string Email template name * @param array Email template params * @param boolean Force to send this email even if the user is not activated. By default not activated user won't get emails. * Pasword reset, and account activation emails must be always forced. * @param array Additional headers ( headername => value ). Take care of injection! * @return boolean True if mail could be sent (not necessarily delivered!), false if not - (return value of {@link mail()}) */ function send_mail_to_User($user_ID, $subject, $template_name, $template_params = array(), $force_on_non_activated = false, $headers = array()) { global $UserSettings, $Settings, $current_charset; $UserCache =& get_UserCache(); if ($User = $UserCache->get_by_ID($user_ID)) { if (!$User->check_status('can_receive_any_message')) { // user status doesn't allow to receive nor emails nor private messages return false; } if (!($User->check_status('is_validated') || $force_on_non_activated)) { // user is not activated and non activated users should not receive emails, unless force_on_non_activated is turned on return false; } // UserSettings update is not required yet $update_settings = false; // Check if a new email to User with the corrensponding email type is allowed switch ($template_name) { case 'account_activate': if ($Settings->get('validation_process') == 'easy' && !$template_params['is_reminder']) { // this is not a notification email break; } case 'private_message_new': case 'private_messages_unread_reminder': case 'post_new': case 'comment_new': case 'account_activated': case 'account_closed': case 'account_reported': // this is a notificaiton email if (!check_allow_new_email('notification_email_limit', 'last_notification_email', $User->ID)) { // more notification email is not allowed today return false; } $update_settings = true; break; case 'newsletter': // this is a newsletter email if (!check_allow_new_email('newsletter_limit', 'last_newsletter', $User->ID)) { // more newsletter email is not allowed today return false; } $update_settings = true; break; } // Update notification sender's info from General settings $User->update_sender(); switch ($UserSettings->get('email_format', $User->ID)) { // Set Content-Type from user's setting "Email format" case 'auto': $template_params['boundary'] = 'b2evo-' . md5(rand()); $headers['Content-Type'] = 'multipart/mixed; boundary="' . $template_params['boundary'] . '"'; break; case 'html': $headers['Content-Type'] = 'text/html; charset=' . $current_charset; break; case 'text': $headers['Content-Type'] = 'text/plain; charset=' . $current_charset; break; } // Get a message text from template file $message = mail_template($template_name, $UserSettings->get('email_format', $User->ID), $template_params, $User); // Autoinsert user's data $subject = mail_autoinsert_user_data($subject, $User); $message = mail_autoinsert_user_data($message, $User); if (send_mail($User->email, NULL, $subject, $message, NULL, NULL, $headers, $user_ID)) { // email was sent, update last email settings; if ($update_settings) { // User Settings need to be updated $UserSettings->dbupdate(); } return true; } } // No user or email could not be sent return false; }
/** * Send email notifications to subscribed users: * * efy-asimo> moderatation and subscription notifications have been separated * * @param boolean true if send only moderation email, false otherwise * @param boolean true if send for everyone else but not for moterators, because a moderation email was sent for them * @param integer the user ID who executed the action which will be notified, or NULL if it was executed by an anonymous user */ function send_email_notifications($only_moderators = false, $except_moderators = false, $executed_by_userid = NULL) { global $DB, $admin_url, $baseurl, $debug, $Debuglog, $htsrv_url; global $Settings, $UserSettings; if ($only_moderators && $except_moderators) { // at least one of them must be false return; } $edited_Item =& $this->get_Item(); $edited_Blog =& $edited_Item->get_Blog(); $owner_User = $edited_Blog->get_owner_User(); $notify_users = array(); $moderators = array(); if ($only_moderators || $except_moderators) { // we need the list of moderators: $sql = 'SELECT DISTINCT user_email, user_ID, uset_value as notify_moderation FROM T_users LEFT JOIN T_coll_user_perms ON bloguser_user_ID = user_ID LEFT JOIN T_coll_group_perms ON bloggroup_group_ID = user_grp_ID LEFT JOIN T_users__usersettings ON uset_user_ID = user_ID AND uset_name = "notify_comment_moderation" LEFT JOIN T_groups ON grp_ID = user_grp_ID WHERE ( ( bloguser_blog_ID = ' . $edited_Blog->ID . ' AND bloguser_perm_edit_cmt IN ( "anon", "lt", "le", "all" ) ) OR ( bloggroup_blog_ID = ' . $edited_Blog->ID . ' AND bloggroup_perm_edit_cmt IN ( "anon", "lt", "le", "all" ) ) OR ( grp_perm_blogs = "editall" ) ) AND LENGTH(TRIM(user_email)) > 0'; $moderators_to_notify = $DB->get_results($sql); foreach ($moderators_to_notify as $moderator) { $notify_moderator = is_null($moderator->notify_moderation) ? $Settings->get('def_notify_comment_moderation') : $moderator->notify_moderation; if ($notify_moderator) { // add user to notify $moderators[] = $moderator->user_ID; } } if ($UserSettings->get('notify_comment_moderation', $owner_User->ID) && is_email($owner_User->get('email'))) { // add blog owner $moderators[] = $owner_User->ID; } // Load all moderators, and check each edit permission on this comment $UserCache =& get_UserCache(); $UserCache->load_list($moderators); foreach ($moderators as $index => $moderator_ID) { $moderator_User = $UserCache->get_by_ID($moderator_ID, false); if (!$moderator_User || !$moderator_User->check_perm('comment!CURSTATUS', 'edit', false, $this)) { // User doesn't exists any more, or has no permission to edit this comment! unset($moderators[$index]); } elseif ($only_moderators) { $notify_users[$moderator_ID] = 'moderator'; } } } if (!$only_moderators) { // Not only moderators needs to be notified: $except_condition = ''; if ($except_moderators && !empty($moderators)) { // Set except moderators condition. Exclude moderators who already got a notification email. $except_condition = ' AND user_ID NOT IN ( "' . implode('", "', $moderators) . '" )'; } // Check if we need to include the item creator user: $creator_User =& $edited_Item->get_creator_User(); if ($UserSettings->get('notify_published_comments', $creator_User->ID) && !empty($creator_User->email) && !in_array($creator_User->ID, $moderators)) { // Post creator wants to be notified, and post author is not a moderator... $notify_users[$creator_User->ID] = 'creator'; } // Get list of users who want to be notified about the this post comments: if ($edited_Blog->get_setting('allow_item_subscriptions')) { // item subscriptions is allowed $sql = 'SELECT DISTINCT user_ID FROM T_items__subscriptions INNER JOIN T_users ON isub_user_ID = user_ID WHERE isub_item_ID = ' . $edited_Item->ID . ' AND isub_comments <> 0 AND LENGTH(TRIM(user_email)) > 0' . $except_condition; $notify_list = $DB->get_results($sql); // Preprocess list: foreach ($notify_list as $notification) { $notify_users[$notification->user_ID] = 'item_subscription'; } } // Get list of users who want to be notfied about this blog comments: if ($edited_Blog->get_setting('allow_subscriptions')) { // blog subscription is allowed $sql = 'SELECT DISTINCT user_ID FROM T_subscriptions INNER JOIN T_users ON sub_user_ID = user_ID WHERE sub_coll_ID = ' . $edited_Blog->ID . ' AND sub_comments <> 0 AND LENGTH(TRIM(user_email)) > 0' . $except_condition; $notify_list = $DB->get_results($sql); // Preprocess list: foreach ($notify_list as $notification) { $notify_users[$notification->user_ID] = 'blog_subscription'; } } } if ($executed_by_userid != NULL && isset($notify_users[$executed_by_userid])) { // don't notify the user who just created/updated this comment unset($notify_users[$executed_by_userid]); } if (!count($notify_users)) { // No-one to notify: return false; } /* * We have a list of user IDs to notify: */ // TODO: dh> this reveals the comments author's email address to all subscribers!! // $notify_from should get used by default, unless the user has opted in to be the sender! // fp>If the subscriber has permission to moderate the comments, he SHOULD receive the email address. // Get author email address. It will be visible for moderators/blog/post owners only -- NOT for other subscribers if ($this->get_author_User()) { // Comment from a registered user: $reply_to = $this->author_User->get('email'); $author_name = $this->author_User->get('login'); $author_ID = $this->author_User->ID; } elseif (!empty($this->author_email)) { // non-member, but with email address: $reply_to = $this->author_email; $author_name = $this->dget('author'); $author_ID = NULL; } else { // Fallback (we have no email address): fp>TODO: or the subscriber is not allowed to view it. $reply_to = NULL; $author_name = $this->dget('author'); $author_ID = NULL; } // Load all users who will be notified, becasuse another way the send_mail_to_User funtion would load them one by one $UserCache =& get_UserCache(); $UserCache->load_list(array_keys($notify_users)); // Load a list with the blocked emails in cache load_blocked_emails(array_keys($notify_users)); // Send emails: foreach ($notify_users as $notify_user_ID => $notify_type) { // get data content $notify_User = $UserCache->get_by_ID($notify_user_ID); $notify_email = $notify_User->get('email'); // init notification setting locale_temp_switch($notify_User->get('locale')); $notify_user_Group = $notify_User->get_Group(); $notify_full = $notify_type == 'moderator' && $notify_user_Group->check_perm('comment_moderation_notif', 'full') || $notify_user_Group->check_perm('comment_subscription_notif', 'full'); switch ($this->type) { case 'trackback': /* TRANS: Subject of the mail to send on new trackbacks. First %s is the blog's shortname, the second %s is the item's title. */ $subject = T_('[%s] New trackback on "%s"'); break; default: /* TRANS: Subject of the mail to send on new comments. */ // In case of full notification the first %s is blog name, the second %s is the item's title. // In case of short notification the first %s is author login, the second %s is the item's title. $subject = $notify_full ? T_('[%s] New comment on "%s"') : T_('%s posted a new comment on "%s"'); if ($only_moderators) { if ($this->status == 'draft') { $subject = $notify_full ? T_('[%s] New comment awaiting moderation on "%s"') : T_('New comment awaiting moderation: ') . $subject; } else { $subject = $notify_full ? T_('[%s] New comment may need moderation on "%s"') : T_('New comment may need moderation: ') . $subject; } } } if ($notify_type == 'moderator') { // moderation email $user_reply_to = $reply_to; } else { if ($notify_type == 'blog_subscription') { // blog subscription $user_reply_to = NULL; } else { if ($notify_type == 'item_subscription') { // item subscription $user_reply_to = NULL; } else { if ($notify_type == 'creator') { // user is the creator of the post $user_reply_to = $reply_to; } else { debug_die('Unknown user subscription type'); } } } } $subject = sprintf($subject, $notify_full ? $edited_Blog->get('shortname') : $author_name, $edited_Item->get('title')); $email_template_params = array('notify_full' => $notify_full, 'Comment' => $this, 'Blog' => $edited_Blog, 'Item' => $edited_Item, 'author_name' => $author_name, 'author_ID' => $author_ID, 'notify_type' => $notify_type); if ($debug) { $notify_message = mail_template('comment_new', 'text', $email_template_params); $mail_dump = "Sending notification to {$notify_email}:<pre>Subject: {$subject}\n{$notify_message}</pre>"; if ($debug >= 2) { // output mail content - NOTE: this will kill sending of headers. echo "<p>{$mail_dump}</p>"; } $Debuglog->add($mail_dump, 'notification'); } // Send the email: // Note: Note activated users won't get notification email send_mail_to_User($notify_user_ID, $subject, 'comment_new', $email_template_params, false, array('Reply-To' => $user_reply_to)); blocked_emails_memorize($notify_User->email); locale_restore_previous(); } blocked_emails_display(); }
locale_temp_switch($recipient_User->locale); } else { // Visitor: // We don't know the recipient's language - Change the locale so the email is in the blog's language: locale_temp_switch($Blog->locale); } // Trigger event: a Plugin could add a $category="error" message here.. $Plugins->trigger_event('MessageFormSent', array('recipient_ID' => $recipient_id, 'item_ID' => $post_id, 'comment_ID' => $comment_id, 'subject' => &$subject, 'message' => &$message, 'Blog' => &$Blog, 'sender_name' => &$sender_name, 'sender_email' => &$sender_address)); $success_message = !$Messages->has_errors(); if ($success_message) { // no errors, try to send the message $email_template_params = array('sender_name' => $sender_name, 'sender_address' => $sender_address, 'Blog' => $Blog, 'message' => $message, 'comment_id' => $comment_id, 'post_id' => $post_id, 'recipient_User' => $recipient_User, 'Comment' => $Comment); if (empty($recipient_User)) { // Send mail to visitor // Get a message text from template file $message = mail_template('contact_message_new', 'text', $email_template_params); $success_message = send_mail($recipient_address, $recipient_name, $subject, $message, NULL, NULL, array('Reply-To' => $sender_address)); } else { // Send mail to registered user $success_message = send_mail_to_User($recipient_User->ID, $subject, 'contact_message_new', $email_template_params, false, array('Reply-To' => $sender_address)); } // restore the locale to the blog visitor language, before we would display an error message locale_restore_previous(); if ($success_message) { // Email has been sent successfully if (!is_logged_in()) { // We should save a counter (only for anonymous users) antispam_increase_counter('contact_email'); } } else { // Could not send email
$edited_EmailCampaign->send_all_emails(); $Form->end_fieldset(); } $Form->begin_fieldset(T_('Review and Send') . get_manual_link('creating-an-email-campaign')); $Form->info(T_('Name'), $edited_EmailCampaign->get('name')); $Form->info(T_('Email title'), $edited_EmailCampaign->get('email_title')); $Form->info(T_('Campaign created'), mysql2localedatetime_spans($edited_EmailCampaign->get('date_ts'), 'M-d')); $Form->info(T_('Last sent'), $edited_EmailCampaign->get('sent_ts') ? mysql2localedatetime_spans($edited_EmailCampaign->get('sent_ts'), 'M-d') : T_('Not sent yet')); echo '<div style="display:table;width:100%;table-layout:fixed;">'; echo '<div class="floatleft" style="width:50%">'; echo '<p><b>' . T_('HTML message') . ':</b></p>'; echo '<div style="overflow:auto">' . mail_template('newsletter', 'html', array('message_html' => $edited_EmailCampaign->get('email_html'), 'include_greeting' => false), $current_User) . '</div>'; echo '</div>'; echo '<div class="floatright" style="width:49%">'; echo '<p><b>' . T_('Plain-text message') . ':</b></p>'; echo '<div style="font-family:monospace;overflow:auto">' . nl2br(mail_template('newsletter', 'text', array('message_text' => $edited_EmailCampaign->get('email_text'), 'include_greeting' => false), $current_User)) . '</div>'; echo '</div>'; echo '</div>'; $Form->end_fieldset(); $Form->begin_fieldset(T_('Newsletter recipients')); $Form->info(T_('Currently selected recipients'), $edited_EmailCampaign->get_users_count(), '(' . T_('Accounts which accept newsletter emails') . ') - <a href="' . $admin_url . '?ctrl=campaigns&action=change_users&ecmp_ID=' . $edited_EmailCampaign->ID . '">' . T_('Change selection') . ' >></a>'); $Form->info(T_('Already received'), $edited_EmailCampaign->get_users_count('accept'), '(' . T_('Accounts which have already been sent this newsletter') . ')'); $Form->info(T_('Ready to send'), $edited_EmailCampaign->get_users_count('wait'), '(' . T_('Accounts which have not been sent this newsletter yet') . ')'); $Form->end_fieldset(); $buttons = array(); if ($current_User->check_perm('emails', 'edit')) { // User must has a permission to edit emails $Form->begin_fieldset(T_('Send test email')); $Form->text_input('test_email_address', $Session->get('test_campaign_email'), 30, T_('Email address'), T_('Fill your email address and press button "Send test email" if you want to test this newsletter'), array('maxlength' => 255)); $Form->end_fieldset(); $buttons[] = array('submit', 'actionArray[test]', T_('Send test email'), 'SaveButton');
/** * Send email notifications to subscribed users * * @todo fp>> shall we notify suscribers of blog were this is in extra-cat? blueyed>> IMHO yes. * * @param boolean Display notification messages or not * @param array Already notified user ids, or NULL if it is not the case */ function send_email_notifications($display = true, $already_notified = NULL) { global $DB, $admin_url, $baseurl, $debug, $Debuglog; $edited_Blog =& $this->get_Blog(); if (!$edited_Blog->get_setting('allow_subscriptions')) { // Subscriptions not enabled! return; } if ($display) { echo "<div class=\"panelinfo\">\n"; echo '<h3>', T_('Notifying subscribed users...'), "</h3>\n"; } // Create condition to not select already notified modertor users $except_users_condition = empty($already_notified) ? '' : ' AND sub_user_ID NOT IN ( ' . implode(',', $already_notified) . ' )'; // Get list of users who want to be notfied: // TODO: also use extra cats/blogs?? $sql = 'SELECT DISTINCT sub_user_ID FROM T_subscriptions WHERE sub_coll_ID = ' . $this->get_blog_ID() . ' AND sub_items <> 0' . $except_users_condition; $notify_users = $DB->get_col($sql); if (empty($notify_users)) { // No-one to notify: if ($display) { echo '<p>', T_('No-one to notify.'), "</p>\n</div>\n"; } return false; } // Load all users who will be notified $UserCache =& get_UserCache(); $UserCache->load_list($notify_users); /* * We have a list of user IDs to notify: */ $this->get_creator_User(); // Load a list with the blocked emails in cache load_blocked_emails($notify_users); // Send emails: $cache_by_locale = array(); foreach ($notify_users as $user_ID) { $notify_User = $UserCache->get_by_ID($user_ID, false, false); if (empty($notify_User)) { // skip invalid users continue; } $notify_email = $notify_User->get('email'); if (empty($notify_email)) { // skip users with empty email address continue; } $notify_locale = $notify_User->get('locale'); $notify_user_Group = $notify_User->get_Group(); $notify_full = $notify_user_Group->check_perm('post_subscription_notif', 'full'); if (!isset($cache_by_locale[$notify_locale])) { // No message for this locale generated yet: locale_temp_switch($notify_locale); $cache_by_locale[$notify_locale]['subject']['short'] = sprintf(T_('%s created a new post in blog "%s"'), $this->creator_User->get('login'), $edited_Blog->get('shortname')); $cache_by_locale[$notify_locale]['subject']['full'] = sprintf(T_('[%s] New post: "%s"'), $edited_Blog->get('shortname'), $this->get('title')); locale_restore_previous(); } $email_template_params = array('locale' => $notify_locale, 'notify_full' => $notify_full, 'Item' => $this, 'recipient_User' => $notify_User, 'notify_type' => 'subscription'); if ($display) { echo T_('Notifying:') . $notify_email . "<br />\n"; } if ($debug >= 2) { $message_content = mail_template('post_new', 'txt', $email_template_params); echo "<p>Sending notification to {$notify_email}:<pre>{$message_content}</pre>"; } $subject_type = $notify_full ? 'full' : 'short'; send_mail_to_User($user_ID, $cache_by_locale[$notify_locale]['subject'][$subject_type], 'post_new', $email_template_params); blocked_emails_memorize($notify_User->email); } blocked_emails_display(); if ($display) { echo '<p>', T_('Done.'), "</p>\n</div>\n"; } }
} $AdminUI->breadcrumbpath_init(false); // fp> I'm playing with the idea of keeping the current blog in the path here... $AdminUI->breadcrumbpath_add(T_('Users'), '?ctrl=users'); $AdminUI->breadcrumbpath_add(T_('List'), '?ctrl=users'); $AdminUI->breadcrumbpath_add(T_('Newsletter'), '?ctrl=newsletter'); $AdminUI->set_path('users', 'users'); // Display <html><head>...</head> section! (Note: should be done early if actions do not redirect) $AdminUI->disp_html_head(); // Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions) $AdminUI->disp_body_top(); $AdminUI->disp_payload_begin(); /* * Display appropriate payload: */ switch ($action) { case 'preview': $email_newsletter_params = array('message' => $Session->get('newsletter_message')); $newsletter = array('title' => mail_autoinsert_user_data($Session->get('newsletter_title'), $current_User), 'html' => mail_autoinsert_user_data(mail_template('newsletter', 'html', $email_newsletter_params, $current_User), $current_User), 'text' => mail_autoinsert_user_data(mail_template('newsletter', 'text', $email_newsletter_params, $current_User), $current_User)); $AdminUI->disp_view('newsletter/views/_newsletter_preview.view.php'); break; case 'send': $AdminUI->disp_view('newsletter/views/_newsletter_report.view.php'); break; default: $AdminUI->disp_view('newsletter/views/_newsletter.form.php'); break; } $AdminUI->disp_payload_end(); // Display body bottom, debug info and close </html>: $AdminUI->disp_global_footer();
/** * Send one email * * @param integer User ID * @param string Email address * @param string Mode: 'test' - to send test email newsletter * @return boolean TRUE on success */ function send_email($user_ID, $email_address = '', $mode = '') { $newsletter_params = array('include_greeting' => false, 'message_html' => $this->get('email_html'), 'message_text' => $this->get('email_text')); if ($mode == 'test') { // Send a test newsletter global $current_User; $newsletter_params['boundary'] = 'b2evo-' . md5(rand()); $headers = array('Content-Type' => 'multipart/mixed; boundary="' . $newsletter_params['boundary'] . '"'); $UserCache =& get_UserCache(); if ($test_User =& $UserCache->get_by_ID($user_ID, false, false)) { // Send a test email only when test user exists $message = mail_template('newsletter', 'auto', $newsletter_params, $test_User); return send_mail($email_address, NULL, $this->get('email_title'), $message, NULL, NULL, $headers); } else { // No test user found return false; } } else { // Send a newsletter to real user return send_mail_to_User($user_ID, $this->get('email_title'), 'newsletter', $newsletter_params, false, array(), $email_address); } }