Index: branches/RC/core/admin_templates/emails/prepare_queue.tpl =================================================================== diff -u --- branches/RC/core/admin_templates/emails/prepare_queue.tpl (revision 0) +++ branches/RC/core/admin_templates/emails/prepare_queue.tpl (revision 9366) @@ -0,0 +1,17 @@ + + + + + + + + + + + \ No newline at end of file Index: branches/RC/core/units/email_events/email_events_config.php =================================================================== diff -u -r9047 -r9366 --- branches/RC/core/units/email_events/email_events_config.php (.../email_events_config.php) (revision 9047) +++ branches/RC/core/units/email_events/email_events_config.php (.../email_events_config.php) (revision 9366) @@ -24,7 +24,8 @@ 'email_settings_list' => Array('prefixes' => Array('emailevents.module_List'), 'format' => '!la_title_EmailSettings! (#emailevents.module_recordcount#)'), 'email_send_form' => Array('prefixes' => Array(), 'format' => '!la_title_SendEmail!'), - 'email_send' => Array('prefixes' => Array(), 'format' => '!la_title_PleaseWait!'), + 'email_prepare' => Array('prefixes' => Array(), 'format' => '!la_title_PreparingEmailsForSending!. !la_title_PleaseWait!'), + 'email_send' => Array('prefixes' => Array(), 'format' => '!la_title_SendingPreparedEmails!. !la_title_PleaseWait!'), 'email_send_complete' => Array('prefixes' => Array(), 'format' => '!la_title_SendMailComplete!'), ), Index: branches/RC/core/units/email_messages/email_messages_event_handler.php =================================================================== diff -u -r9047 -r9366 --- branches/RC/core/units/email_messages/email_messages_event_handler.php (.../email_messages_event_handler.php) (revision 9047) +++ branches/RC/core/units/email_messages/email_messages_event_handler.php (.../email_messages_event_handler.php) (revision 9366) @@ -207,9 +207,6 @@ return ; } - $esender =& $this->Application->recallObject('EmailSender'); - /* @var $esender kEmailSendingHelper */ - $fields_hash = $object->GetFieldValues(); list ($fields_hash['FromEmail'], $fields_hash['FromName']) = $this->getSenderData(); @@ -218,79 +215,133 @@ $fields_hash['MassAttachment'] = $field_options['upload_dir'].$fields_hash['MassAttachment']; } - $recipients = $this->getRecipientEmails(); - foreach ($recipients as $recipient_email) { - $this->sendMessage($fields_hash, $recipient_email, $esender); - } + $this->Application->RemoveVar('email_prepare_progress'); + $this->Application->StoreVar('email_prepare_fields', serialize($fields_hash)); - // remove any temporary data - $this->Application->RemoveVar('recipient_ids'); - $this->Application->RemoveVar('recipient_type'); - $this->Application->RemoveVar('email_queue_progress'); - if ($fields_hash['MassAttachment']) { - unlink(FULL_PATH.$fields_hash['MassAttachment']); - } - - $event->redirect = 'emails/send_queue'; + $event->redirect = 'emails/prepare_queue'; } - - function getRecipientEmails() + /** + * Generates email queue using progress bar + * + * @param kEvent $event + */ + function OnPrepareEmailQueue(&$event) { - $recipient_type = $this->Application->RecallVar('recipient_type'); - $recipient_ids = $this->Application->RecallVar('recipient_ids'); + $prepare_count = 10; // 10 recipients per script run - if ($recipient_type == 'u') { - $sql = 'SELECT Email - FROM '.TABLE_PREFIX.'PortalUser - WHERE PortalUserId IN ('.$recipient_ids.')'; + $email_prepare_progress = $this->Application->RecallVar('email_prepare_progress'); + if ($email_prepare_progress === false) { + $emails_prepared = 0; + $total_emails = $this->getRecipientEmails(true); + $this->Application->StoreVar('email_prepare_progress', $emails_prepared.':'.$total_emails); } else { - $sql = 'SELECT u.Email - FROM '.TABLE_PREFIX.'UserGroup ug - LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON ug.PortalUserId = u.PortalUserId - WHERE ug.GroupId IN ('.$recipient_ids.')'; + list ($emails_prepared, $total_emails) = explode(':', $email_prepare_progress); } - return $this->Conn->GetCol($sql); - } + $recipient_emails = $this->getRecipientEmails(false, $emails_prepared.','.$prepare_count); + $recipient_email_count = count($recipient_emails); - /** - * Puts message to email queue for sending - * - * @param Array $fields_hash - * @param string $to_email recipient's email address - * @param kEmailSendingHelper $esender - */ - function sendMessage($fields_hash, $to_email, &$esender) - { - $esender->SetFrom($fields_hash['FromEmail'], $fields_hash['FromName']); + if (!$recipient_email_count) { + // no recipients left to prepare + $this->finalizeQueuePreparing($fields_hash['MassAttachment']); + } - $esender->AddTo($to_email); + $fields_hash = unserialize($this->Application->RecallVar('email_prepare_fields')); + + $esender =& $this->Application->recallObject('EmailSender'); + /* @var $esender kEmailSendingHelper */ + + // 1. set headers same for all emails + $esender->SetFrom($fields_hash['FromEmail'], $fields_hash['FromName']); $esender->SetSubject($fields_hash['MassSubject']); $esender->SetBody($fields_hash['MassHtmlMessage'], $fields_hash['MassTextMessage']); - // add attachment if any + // 2. add attachment if any if ($fields_hash['MassAttachment']) { $esender->AddAttachment(FULL_PATH.$fields_hash['MassAttachment']); } - $status = $esender->Deliver(null, false); + foreach ($recipient_emails as $recipient_email) { + // 3. set recipient specific fields + $esender->SetEncodedEmailHeader('To', $recipient_email, $recipient_email); + $esender->Deliver(null, false, false); - if ($status) { - // write to log - $fields_hash = Array ( + // 4. write to log + $log_fields_hash = Array ( 'fromuser' => $fields_hash['FromName'], - 'addressto' => $to_email, + 'addressto' => $recipient_email, 'subject' => $fields_hash['MassSubject'], 'timestamp' => adodb_mktime(), 'event' => '', ); - $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'EmailLog'); + $this->Conn->doInsert($log_fields_hash, TABLE_PREFIX.'EmailLog'); } + + $emails_prepared += $recipient_email_count; + if ($emails_prepared >= $total_emails) { + $this->finalizeQueuePreparing($fields_hash['MassAttachment']); + } + + $this->Application->StoreVar('email_prepare_progress', $emails_prepared.':'.$total_emails); + $event->status = erSTOP; + echo ($emails_prepared / $total_emails) * 100; } + function finalizeQueuePreparing($attachment_file = null) + { + // variables from users/groups grid + $this->Application->RemoveVar('recipient_ids'); + $this->Application->RemoveVar('recipient_type'); + + if ($attachment_file) { + unlink(FULL_PATH.$attachment_file); + } + + // variables from email preparing process +// $this->Application->RemoveVar('email_prepare_progress'); +// $this->Application->RemoveVar('email_prepare_fields'); + + // variables from email delivering process (not yet executed) + $this->Application->RemoveVar('email_queue_progress'); + + $this->Application->Redirect($this->Application->GetVar('finish_template')); + } + + function getRecipientEmails($for_counting = false, $limit = null) + { + $recipient_type = $this->Application->RecallVar('recipient_type'); + $recipient_ids = $this->Application->RecallVar('recipient_ids'); + + if (!$recipient_ids) { + return $for_counting ? 0 : Array (); + } + + if ($recipient_type == 'u') { + $sql = 'SELECT '.($for_counting ? 'COUNT(*)' : 'Email').' + FROM '.TABLE_PREFIX.'PortalUser + WHERE PortalUserId IN ('.$recipient_ids.')'; + } + else { + $sql = 'SELECT '.($for_counting ? 'COUNT(*)' : 'u.Email').' + FROM '.TABLE_PREFIX.'UserGroup ug + LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON ug.PortalUserId = u.PortalUserId + WHERE ug.GroupId IN ('.$recipient_ids.')'; + } + + if ($for_counting) { + return $this->Conn->GetOne($sql); + } + + if (isset($limit)) { + $sql .= ' LIMIT '.$limit; + } + + return $this->Conn->GetCol($sql); + } + /** * Returns mass mail sender name & email *