diff --git a/e107_admin/admin_log.php b/e107_admin/admin_log.php index c9fcb08a2..0aa93eafd 100644 --- a/e107_admin/admin_log.php +++ b/e107_admin/admin_log.php @@ -9,9 +9,9 @@ * Administration Area - Admin Log * * $Source: /cvs_backup/e107_0.8/e107_admin/admin_log.php,v $ - * $Revision: 1.32 $ - * $Date: 2009-11-18 01:04:24 $ - * $Author: e107coders $ + * $Revision: 1.33 $ + * $Date: 2009-11-30 20:40:02 $ + * $Author: e107steved $ * */ @@ -50,9 +50,9 @@ if(is_array($pref['logLanguageFile'])) //... and for any plugins which support i unset($qs); -require_once (e_ADMIN."auth.php"); -require_once (e_HANDLER."message_handler.php"); -require_once (e_HANDLER."form_handler.php"); +require_once (e_ADMIN.'auth.php'); +require_once (e_HANDLER.'message_handler.php'); +require_once (e_HANDLER.'form_handler.php'); $emessage = &eMessage::getInstance(); $frm = new e_form(false); @@ -122,6 +122,7 @@ if(isset($_POST['deleteitems']) && ($action == 'comments')) unset($c_list); } + // ****************** MAINTENANCE ****************** unset($back_count); if(isset($_POST['deleteoldadmin']) && isset($_POST['rolllog_clearadmin'])) @@ -357,18 +358,25 @@ if($action == "config") { // User Audit log options (for info) //======================= - // define('USER_AUDIT_SIGNUP',11); // User signed up - // define('USER_AUDIT_EMAILACK',12); // User responded to registration email - // define('USER_AUDIT_LOGIN',13); // User logged in - // define('USER_AUDIT_LOGOUT',14); // User logged out - // define('USER_AUDIT_NEW_DN',15); // User changed display name - // define('USER_AUDIT_NEW_PW',16); // User changed password - // define('USER_AUDIT_NEW_EML',17); // User changed email - // define('USER_AUDIT_NEW_SET',19); // User changed other settings (intentional gap in numbering) + // define('USER_AUDIT_SIGNUP',11); // User signed up + // define('USER_AUDIT_EMAILACK',12); // User responded to registration email + // define('USER_AUDIT_LOGIN',13); // User logged in + // define('USER_AUDIT_LOGOUT',14); // User logged out + // define('USER_AUDIT_NEW_DN',15); // User changed display name + // define('USER_AUDIT_NEW_PW',16); // User changed password + // define('USER_AUDIT_NEW_EML',17); // User changed email + // define('USER_AUDIT_NEW_SET',19); // User changed other settings (intentional gap in numbering) + // define('USER_AUDIT_ADD_ADMIN', 20); // User added by admin + // define('USER_AUDIT_MAIL_BOUNCE', 21); // User mail bounce + // define('USER_AUDIT_BANNED', 22); // User banned + // define('USER_AUDIT_BOUNCE_RESET', 23); // User bounce reset + // define('USER_AUDIT_TEMP_ACCOUNT', 24); // User temporary account $audit_checkboxes = array(USER_AUDIT_SIGNUP => RL_LAN_071, USER_AUDIT_EMAILACK => RL_LAN_072, USER_AUDIT_LOGIN => RL_LAN_073, // USER_AUDIT_LOGOUT => RL_LAN_074, // Logout is lumped in with login - USER_AUDIT_NEW_DN => RL_LAN_075, USER_AUDIT_NEW_PW => RL_LAN_076, USER_AUDIT_PW_RES => RL_LAN_078, USER_AUDIT_NEW_EML => RL_LAN_077, USER_AUDIT_NEW_SET => RL_LAN_079, USER_AUDIT_ADD_ADMIN => RL_LAN_080); + USER_AUDIT_NEW_DN => RL_LAN_075, USER_AUDIT_NEW_PW => RL_LAN_076, USER_AUDIT_PW_RES => RL_LAN_078, USER_AUDIT_NEW_EML => RL_LAN_077, USER_AUDIT_NEW_SET => RL_LAN_079, + USER_AUDIT_ADD_ADMIN => RL_LAN_080, USER_AUDIT_MAIL_BOUNCE => RL_LAN_081, USER_AUDIT_BANNED => RL_LAN_082, USER_AUDIT_BOUNCE_RESET => RL_LAN_083, + USER_AUDIT_TEMP_ACCOUNT => RL_LAN_084); if(! isset($e_userclass) && ! is_object($e_userclass)) { diff --git a/e107_admin/mailout.php b/e107_admin/mailout.php index 860204590..9c05431bb 100644 --- a/e107_admin/mailout.php +++ b/e107_admin/mailout.php @@ -9,8 +9,8 @@ * Administration - Site Maintenance * * $Source: /cvs_backup/e107_0.8/e107_admin/mailout.php,v $ - * $Revision: 1.30 $ - * $Date: 2009-11-27 21:42:46 $ + * $Revision: 1.31 $ + * $Date: 2009-11-30 20:40:02 $ * $Author: e107steved $ * */ @@ -18,7 +18,6 @@ /* TODO: 1. Improve maintenance page - 2. Option to copy completed email to saved email page */ /* @@ -122,6 +121,7 @@ $errors = array(); $subAction = ''; $midAction = ''; +$fromHold = FALSE; if (isset($_POST['mailaction'])) @@ -195,6 +195,20 @@ switch ($action) } break; + case 'mailcopy' : // Copy existing email and go to edit screen + if (isset($_POST['mailaction'])) + { + $action = 'makemail'; + $mailData = $mailAdmin->retrieveEmail($mailId); + if ($mailData === FALSE) + { + $emessage->add(LAN_MAILOUT_164.':'.$mailId, E_MESSAGE_ERROR); + break; + } + unset($mailData['mail_source_id']); + } + break; + case 'mailedit' : // Edit existing mail if (isset($_POST['mailaction'])) { @@ -325,9 +339,12 @@ switch ($action) } break; - case 'mailsendnow' : // Send mail previously on 'held' list. - $midAction = 'midMoveToSend'; - $action = 'pending'; + case 'mailsendnow' : // Send mail previously on 'held' list. Need to give opportunity to change time/date etc +// $midAction = 'midMoveToSend'; +// $action = 'pending'; + $action = 'marksend'; // This shows the email details for confirmation + $fromHold = TRUE; + $mailData['mail_source_id'] = $mailId; break; case 'maildeleteconfirm' : @@ -501,7 +518,7 @@ switch ($action) break; case 'marksend' : // Show the send confirmation page - $mailAdmin->sendEmailCircular($mailData); + $mailAdmin->sendEmailCircular($mailData, $fromHold); break; case 'recipients' : diff --git a/e107_handlers/admin_log_class.php b/e107_handlers/admin_log_class.php index a99b4999f..9037ce143 100644 --- a/e107_handlers/admin_log_class.php +++ b/e107_handlers/admin_log_class.php @@ -11,9 +11,9 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_handlers/admin_log_class.php,v $ - | $Revision: 1.19 $ - | $Date: 2009-11-18 01:04:43 $ - | $Author: e107coders $ + | $Revision: 1.20 $ + | $Date: 2009-11-30 20:40:03 $ + | $Author: e107steved $ To do: 1. Do we need to check for presence of elements of debug_backtrace() to avoid notices? 2. Reflect possible DB structure changes once finalised @@ -66,6 +66,7 @@ class e_admin_log define("LOG_TO_ROLLING", 4); // User audit logging (intentionally start at 10 - stick to 2 digits) + // The last two digits must match that for the corresponding log message define('USER_AUDIT_ADMIN', 10); // User data changed by admin define('USER_AUDIT_SIGNUP', 11); // User signed up define('USER_AUDIT_EMAILACK', 12); // User responded to registration email @@ -77,6 +78,10 @@ class e_admin_log define('USER_AUDIT_PW_RES', 18); // Password reset/resent activation email define('USER_AUDIT_NEW_SET', 19); // User changed other settings define('USER_AUDIT_ADD_ADMIN', 20); // User added by admin + define('USER_AUDIT_MAIL_BOUNCE', 21); // User mail bounce + define('USER_AUDIT_BANNED', 22); // User banned + define('USER_AUDIT_BOUNCE_RESET', 23); // User bounce reset + define('USER_AUDIT_TEMP_ACCOUNT', 24); // User temporary account } /** diff --git a/e107_handlers/mail_manager_class.php b/e107_handlers/mail_manager_class.php index f5db8e2fd..8f55bd636 100644 --- a/e107_handlers/mail_manager_class.php +++ b/e107_handlers/mail_manager_class.php @@ -9,8 +9,8 @@ * e107 Main * * $Source: /cvs_backup/e107_0.8/e107_handlers/mail_manager_class.php,v $ - * $Revision: 1.8 $ - * $Date: 2009-11-27 21:42:46 $ + * $Revision: 1.9 $ + * $Date: 2009-11-30 20:40:03 $ * $Author: e107steved $ */ @@ -32,7 +32,6 @@ will be included in preference to the current theme style. TODO: - Consider whether to extract links in text-only emails - makeEmailBody - could use regex to modify links - - call user API to set ban Event Triggers generated @@ -1122,30 +1121,12 @@ class e107MailManager $errors[] = 'Bad element count: '.count($vals); } elseif ($uid || $emailAddress) - { // Now log the bounce against the user - $this->checkDB(1); - $qry = ''; - if ($uid) { $qry = '`user_id`='.$uid; } - if ($emailAddress) { if ($qry) $qry .= ' OR '; $qry .= "`user_email` = '{$emailAddress}'"; } - if (FALSE === $this->db->db_Select('user', 'user_id, user_email', $qry)) + { // Now log the bounce against the user (user handler will do any required logging) + require_once(e_HANDLER.'user_handler.php'); + $result = userHandler::userStatusUpdate('bounce', $uid, $emailAddress); + if ($result) // Returns FALSE if update successful { - $errors[] = 'User not found: '.$uid.'/'.$emailAddress; - } - else - { - $row = $this->db->db_Fetch(MYSQL_ASSOC); - if ($uid && ($uid != $row['user_id'])) - { - $errors[] = 'UID mismatch: '.$uid.'/'.$row['user_id']; - } - elseif ($emailAddress && ($emailAddress != $row['user_email'])) - { - $errors[] = 'User email mismatch: '.$emailAddress.'/'.$row['user_email']; - } - else - { // Valid user! - $this->db->db_Update('user', '`user_ban` = 3 WHERE `user_id` = '.$row['user_id'].' LIMIT 1'); // TODO: Call via user API - } + $errors[] = $result; } } if (count($errors)) diff --git a/e107_handlers/mailout_admin_class.php b/e107_handlers/mailout_admin_class.php index e1f81a419..7475cbf9b 100644 --- a/e107_handlers/mailout_admin_class.php +++ b/e107_handlers/mailout_admin_class.php @@ -9,8 +9,8 @@ * Administration - Site Maintenance * * $Source: /cvs_backup/e107_0.8/e107_handlers/mailout_admin_class.php,v $ - * $Revision: 1.7 $ - * $Date: 2009-11-27 21:42:46 $ + * $Revision: 1.8 $ + * $Date: 2009-11-30 20:40:03 $ * $Author: e107steved $ * */ @@ -25,7 +25,6 @@ TODO: 1. Use API to downloads plugin to get available files (when available) 2. Fuller checking prior to send 3. May want more control over date display format - 4. Look at orphan removal query */ if (!defined('e107_INIT')) { exit; } @@ -129,7 +128,6 @@ class mailoutAdminClass extends e107MailManager 'maildelete' => LAN_DELETE ), 'pending' => array( -// 'mailsendnow' => LAN_MAILOUT_158, 'mailhold' => LAN_MAILOUT_159, 'mailcancel' => LAN_MAILOUT_160, 'mailtargets' => LAN_MAILOUT_181 @@ -140,7 +138,7 @@ class mailoutAdminClass extends e107MailManager 'mailtargets' => LAN_MAILOUT_181 ), 'sent' => array( - 'mailsendnow' => LAN_EDIT, + 'mailcopy' => LAN_MAILOUT_251, 'maildelete' => LAN_DELETE, 'mailtargets' => LAN_MAILOUT_181 ), @@ -1105,57 +1103,71 @@ class mailoutAdminClass extends e107MailManager * Generate a list of emails to send * Returns various information to display in a confirmation screen * - * The email and its recipients are stored in the DB with a tag of 'MAIL_STATUS-TEMP' + * The email and its recipients are stored in the DB with a tag of 'MAIL_STATUS_TEMP' of its a new email (no change if already on hold) * - * @param $mailData array Details of the email, selection criteria etc + * @param array $mailData - Details of the email, selection criteria etc + * @param boolean $fromHold - FALSE if this is a 'new' email to send, TRUE if its already been put on hold (selects processing path) * @return text for display */ - public function sendEmailCircular($mailData) + public function sendEmailCircular($mailData, $fromHold = FALSE) { - // Start by saving the email - $mailData['mail_content_status'] = MAIL_STATUS_TEMP; - $mailData['mail_create_app'] = 'core'; - $result = $this->saveEmail($mailData, TRUE); - if (is_numeric($result)) - { - $mailMainID = $mailData['mail_source_id'] = $result; + if ($fromHold) + { // Email data already generated + $mailMainID = $mailData['mail_source_id']; + if ($mailMainID == 0) return FALSE; + if (FALSE === ($mailData = $this->retrieveEmail($mailMainID))) // Get the new data + { + return FALSE; + } + $counters['add'] = $mailData['mail_togo_count']; // Set up the counters + $counters['dups'] = 0; } else { - // TODO: Handle error - } - - - $this->mailInitCounters($mailMainID); // Initialise counters for emails added - - foreach ($this->mailHandlers as $m) - { // Get email addresses from each handler in turn. Do them one at a time, so that all can use the $sql data object - if ($m->mailerEnabled && isset($mailData['mail_selectors'][$m->mailerSource])) + // Start by saving the email + $mailData['mail_content_status'] = MAIL_STATUS_TEMP; + $mailData['mail_create_app'] = 'core'; + $result = $this->saveEmail($mailData, TRUE); + if (is_numeric($result)) { - // Initialise - $mailerCount = $m->selectInit($mailData['mail_selectors'][$m->mailerSource]); - if ($mailerCount > 0) + $mailMainID = $mailData['mail_source_id'] = $result; + } + else + { + // TODO: Handle error + } + + + $this->mailInitCounters($mailMainID); // Initialise counters for emails added + + foreach ($this->mailHandlers as $m) + { // Get email addresses from each handler in turn. Do them one at a time, so that all can use the $sql data object + if ($m->mailerEnabled && isset($mailData['mail_selectors'][$m->mailerSource])) { - // Get email addresses - add to list, strip duplicates - while ($row = $m->selectAdd()) - { // Add email addresses to the database ready for sending (the body is never saved in the DB - it gets passed as a $_POST value) - $result = $this->mailAddNoDup($mailMainID, $row, MAIL_STATUS_TEMP); - if ($result === FALSE) - { - // Error + // Initialise + $mailerCount = $m->selectInit($mailData['mail_selectors'][$m->mailerSource]); + if ($mailerCount > 0) + { + // Get email addresses - add to list, strip duplicates + while ($row = $m->selectAdd()) + { // Add email addresses to the database ready for sending (the body is never saved in the DB - it gets passed as a $_POST value) + $result = $this->mailAddNoDup($mailMainID, $row, MAIL_STATUS_TEMP); + if ($result === FALSE) + { + // Error + } } } + $m->select_close(); // Close + // Update the stats after each handler + $this->mailUpdateCounters($mailMainID); } - $m->select_close(); // Close - // Update the stats after each handler - $this->mailUpdateCounters($mailMainID); } + + $counters = $this->mailRetrieveCounters($mailMainID); + // $this->e107->admin_log->log_event('MAIL_02','ID: '.$mailMainID.' '.$counters['add'].'[!br!]'.$_POST['email_from_name']." <".$_POST['email_from_email'],E_LOG_INFORMATIVE,''); } - $counters = $this->mailRetrieveCounters($mailMainID); - // $this->e107->admin_log->log_event('MAIL_02','ID: '.$mailMainID.' '.$counters['add'].'[!br!]'.$_POST['email_from_name']." <".$_POST['email_from_email'],E_LOG_INFORMATIVE,''); - - // We've got all the email addresses here - display a confirmation form // Include start/end dates for send @@ -1191,10 +1203,13 @@ class mailoutAdminClass extends e107MailManager $text .= $this->makeAdvancedOptions(TRUE); // Show the table of advanced options $text .= "
- -   -   -
+ "; + if (!$fromHold) + { + $text .= "  +  "; + } + $text .= " "; @@ -1422,7 +1437,7 @@ class mailoutAdminClass extends e107MailManager $results[] = 'Error '.$this->db2->mySQLlastErrNum.':'.$this->db2->mySQLlastErrText.' deleting orphaned records from mail_recipients'; $noError = FALSE; } - else + elseif ($res) { if ($res) $results[] = str_replace('--COUNT--', $res, LAN_MAILOUT_226); } diff --git a/e107_handlers/user_handler.php b/e107_handlers/user_handler.php index cac5538f3..04d068c4d 100644 --- a/e107_handlers/user_handler.php +++ b/e107_handlers/user_handler.php @@ -9,8 +9,8 @@ * Handler - user-related functions * * $Source: /cvs_backup/e107_0.8/e107_handlers/user_handler.php,v $ - * $Revision: 1.19 $ - * $Date: 2009-11-19 20:36:55 $ + * $Revision: 1.20 $ + * $Date: 2009-11-30 20:40:03 $ * $Author: e107steved $ * */ @@ -20,8 +20,6 @@ USER HANDLER CLASS - manages login and various user functions Vetting routines TODO: - user_sess processing - user_image processing user_xup processing - nothing special? */ @@ -70,6 +68,7 @@ class UserHandler 0 - Null method 1 - Check for duplicates 2 - Check against $pref['signup_disallow_text'] + 3 - Check email address against remote server, only if option enabled Index is the destination field name. If the source index name is different, specify 'srcName' in the array. @@ -643,10 +642,78 @@ Following fields auto-filled in code as required: $ret = TRUE; } } + } + + /** + * Updates user status, primarily the user_ban field, to reflect outside events + * @var string $start - 'ban', 'bounce' + * @var integer $uid - internal user ID, zero if not known + * @var string $emailAddress - email address (optional) + * @return boolean | string - FALSE if user found, error message if not + */ + public function userStatusUpdate($action, $uid, $emailAddress = '') + { + $db = e107::getDb(); + $qry = ''; + $error = FALSE; // Assume no error to start with + $uid = intval($uid); // Precautionary - should have already been done + switch ($action) + { + case 'ban' : + $newVal = USER_BANNED; + $logEvent = USER_AUDIT_BANNED; + break; + case 'bounce' : + $newVal = USER_EMAIL_BOUNCED; + $logEvent = USER_AUDIT_MAIL_BOUNCE; + break; + case 'reset' : + $newVal = USER_BOUNCED_RESET; + $logEvent = USER_AUDIT_BOUNCE_RESET; + break; + case 'temp' : + $newVal = USER_TEMPORARY_ACCOUNT; + $logEvent = USER_AUDIT_TEMP_ACCOUNT; + break; + default : + return 'Invalid action: '.$action; + } + if ($uid) { $qry = '`user_id`='.$uid; } + if ($emailAddress) { if ($qry) $qry .= ' OR '; $qry .= "`user_email` = '{$emailAddress}'"; } + if (FALSE === $db->db_Select('user', 'user_id, user_email, user_ban, user_loginname', $qry.' LIMIT 1')) + { + $error = 'User not found: '.$uid.'/'.$emailAddress; + } + else + { + $row = $db->db_Fetch(MYSQL_ASSOC); + if ($uid && ($uid != $row['user_id'])) + { + $error = 'UID mismatch: '.$uid.'/'.$row['user_id']; + } + elseif ($emailAddress && ($emailAddress != $row['user_email'])) + { + $error = 'User email mismatch: '.$emailAddress.'/'.$row['user_email']; + } + else + { // Valid user! + if ($row['user_ban'] != $newVal) // We could implement a hierarchy here, so that an important status isn't overridden by a lesser one + { // Only update if needed + $db->db_Update('user', '`user_ban` = '.$newVal.', `user_email` = \'\' WHERE `user_id` = '.$row['user_id'].' LIMIT 1'); + // Add to user audit log TODO: Should we log to admin log as well? + $adminLog = e107::getAdminLog(); + $adminLog->user_audit($logEvent, array('user_ban' => $newVal, 'user_email' => $row['user_email']), $row['user_id'], $row['user_loginname']); + } + } + } + return $error; } } + + + e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE."/admin/lan_administrator.php"); class e_userperms diff --git a/e107_languages/English/admin/help/mailout.php b/e107_languages/English/admin/help/mailout.php index 610f1d8f1..3587d8697 100644 --- a/e107_languages/English/admin/help/mailout.php +++ b/e107_languages/English/admin/help/mailout.php @@ -9,9 +9,9 @@ * * * $Source: /cvs_backup/e107_0.8/e107_languages/English/admin/help/mailout.php,v $ - * $Revision: 1.6 $ - * $Date: 2009-11-18 01:05:12 $ - * $Author: e107coders $ + * $Revision: 1.7 $ + * $Date: 2009-11-30 20:40:03 $ + * $Author: e107steved $ */ if (!defined('e107_INIT')) { exit; } @@ -32,7 +32,8 @@ $action = $e107->tp->toDB(varset($_GET['mode'],'makemail')); $text = 'Select and use a saved email template to send a mailshot. Delete any template no longer required'; break; case 'pending' : - $text = 'List of mailshots released for sending, together with current status.'; + $text = 'List of mailshots released for sending, together with current status. The mail scheduler task will process these emails as it is able, taking account of + the earliest and latest sending dates you set'; break; case 'held' : $text = 'List of emails which have been prepared for sending, but not yet released'; @@ -56,8 +57,16 @@ $action = $e107->tp->toDB(varset($_GET['mode'],'makemail')); A test email is sent using the current method and settings.

'; $text .= 'Emailing Method
Use SMTP to send mail if possible. The settings will depend on your host\'s mail server.

'; + $text .= 'Default email format
+ Emails may be sent either in plain text only, or in HTML format. The latter generally gives a better appearance, but is more prone to being filtered by various + security measures. If you select HTML, a separate plain text part is added.

'; + $text .= 'Bulk mail controls
+ The values you set here will depend on your host, and on the number of emails you send; it may be possible to set all values to zero so that the + mail queue is emptied virtually instantly.

'; $text .= 'Bounced Emails
- You can specify a POP3 account to receive the return response when an email is undeliverable. Normally this will be a standard + You can specify an email address to receive the return response when an email is undeliverable. If you have control over your server, you can specify the + separate scheduler-driven auto-processing script; this receives bounce messages as they arrive, and updates status instantly. Otherwise you can specify a separate email account, + which can be checked either periodically (using the scheduler), or manually via the user options menu. Normally this will be a standard POP3 account; use the TLS-related options only if specifically required by your host

'; $text .= 'Email Address Sources
If you have additional mail-related plugins, you can select which of them may contribute email addresses to the list.

'; diff --git a/e107_languages/English/admin/lan_admin_log.php b/e107_languages/English/admin/lan_admin_log.php index 8436bfdf1..5645b1a8b 100644 --- a/e107_languages/English/admin/lan_admin_log.php +++ b/e107_languages/English/admin/lan_admin_log.php @@ -1,6 +1,6 @@