Application->recallObject('EmailSender'); /* @var $esender kEmailSendingHelper */ if ($this->_mailingId != $mailing_id) { if (is_numeric($this->_mailingId)) { // clear fields after previous mailing processing $esender->Clear(); } // 1. set headers same for all emails list ($mailing_data['FromName'], $mailing_data['FromEmail']) = $this->_getSenderData($mailing_data); $esender->SetFrom($mailing_data['FromEmail'], $mailing_data['FromName']); $esender->SetSubject($mailing_data['Subject']); $esender->SetBody($mailing_data['MessageHtml'], $mailing_data['MessageText']); // 2. add attachment if any $attachments = $mailing_data['Attachments'] ? explode('|', $mailing_data['Attachments']) : Array (); foreach ($attachments as $attachment) { $esender->AddAttachment(FULL_PATH . ITEM_FILES_PATH . $attachment); } $this->_mailingId = $mailing_id; } // 3. set recipient specific fields $esender->SetTo($email, $email); // 4. write to log $log_fields_hash = Array ( 'fromuser' => $mailing_data['FromName'] . '<' . $mailing_data['FromEmail'] . '>', 'addressto' => $email, 'subject' => $mailing_data['Subject'], 'timestamp' => adodb_mktime(), 'EventParams' => serialize( Array ('MailingId' => $mailing_id) ), ); $esender->setLogData($log_fields_hash); $esender->Deliver(null, $mailing_id, false); } /** * Returns mass mail sender name & email * * @param Array $mailing_data * @return Array * @access protected */ protected function _getSenderData(&$mailing_data) { $is_root = true; $email_address = $name = ''; if ( $mailing_data['PortalUserId'] > 0 ) { $sender =& $this->Application->recallObject('u.-item', null, Array ('skip_autoload' => true)); /* @var $sender UsersItem */ $sender->Load($mailing_data['PortalUserId']); $email_address = $sender->GetDBField('Email'); $name = trim($sender->GetDBField('FirstName') . ' ' . $sender->GetDBField('LastName')); $is_root = false; } if ( $is_root || !$email_address ) { $email_address = $this->Application->ConfigValue('Smtp_AdminMailFrom'); } if ( $is_root || !$name ) { $name = strip_tags($this->Application->ConfigValue('Site_Name')); } return Array ($name, $email_address); } /** * Generates recipients emails based on "To" field value * * @param int $id * @param Array $fields_hash */ function generateRecipients($id, $fields_hash) { $recipients = explode(';', $fields_hash['To']); // 1. group recipients by types $recipients_grouped = Array (); foreach ($recipients as $recipient) { if (strpos($recipient, '_') !== false) { list ($recipient_type, $recipient_id) = explode('_', $recipient); } else { $recipient_type = 'direct'; $recipient_id = $recipient; } if (!array_key_exists($recipient_type, $recipients_grouped)) { $recipients_grouped[$recipient_type] = Array (); } $recipients_grouped[$recipient_type][] = $recipient_id; } // for each group convert ids to names $recpient_emails = Array (); foreach ($recipients_grouped as $recipient_type => $group_recipients) { $recpient_emails = array_merge($recpient_emails, $this->_getRecipientEmails($recipient_type, $group_recipients)); } $recpient_emails = array_unique($recpient_emails); return Array ( 'ToParsed' => serialize($recpient_emails), 'EmailsTotal' => count($recpient_emails), ); } function _getRecipientEmails($recipient_type, $recipient_ids) { if (strpos($recipient_type, '.') !== false) { // remove special list ($recipient_type, ) = explode('.', $recipient_type); } if ($recipient_type != 'u' && $recipient_type != 'g') { // these are already emails return $recipient_ids; } switch ($recipient_type) { case 'u': $sql = 'SELECT Email FROM ' . TABLE_PREFIX . 'PortalUser WHERE (PortalUserId IN (' . implode(',', $recipient_ids) . ')) AND (Email <> "")'; break; case 'g': $sql = 'SELECT u.Email FROM ' . TABLE_PREFIX . 'UserGroup ug LEFT JOIN ' . TABLE_PREFIX . 'PortalUser u ON u.PortalUserId = ug.PortalUserId WHERE (ug.GroupId IN (' . implode(',', $recipient_ids) . ')) AND (u.Email <> "")'; break; default: $sql = ''; break; } return $this->Conn->GetCol($sql); } function getRecipientNames($recipient_type, $recipient_ids) { if (strpos($recipient_type, '.') !== false) { // remove special list ($recipient_type, ) = explode('.', $recipient_type); } switch ($recipient_type) { case 'u': $title_field = 'Email'; break; case 'g': $title_field = 'Name'; break; default: $title_field = false; break; } if ($title_field === false || !$recipient_ids) { return $recipient_ids; } $id_field = $this->Application->getUnitOption($recipient_type, 'IDField'); $table_name = $this->Application->getUnitOption($recipient_type, 'TableName'); $sql = 'SELECT ' . $title_field . ' FROM ' . $table_name . ' WHERE ' . $id_field . ' IN (' . implode(',', $recipient_ids) . ')'; return $this->Conn->GetCol($sql); } /** * Updates information about sent email count based on given totals by mailings * * @param Array $mailing_totals */ function _updateSentTotals($mailing_totals) { if (array_key_exists(0, $mailing_totals)) { // don't update sent email count for mails queued directly (not via mailing lists) unset($mailing_totals[0]); } $id_field = $this->Application->getUnitOption('mailing-list', 'IDField'); $table_name = $this->Application->getUnitOption('mailing-list', 'TableName'); // update sent email count for each processed mailing foreach ($mailing_totals as $mailing_id => $mailing_total) { $sql = 'UPDATE ' . $table_name . ' SET EmailsSent = EmailsSent + ' . $mailing_total . ' WHERE ' . $id_field . ' = ' . $mailing_id; $this->Conn->Query($sql); } // mark mailings, that were processed completely $sql = 'UPDATE ' . $table_name . ' SET Status = ' . MailingList::PROCESSED . ' WHERE (Status = ' . MailingList::PARTIALLY_PROCESSED . ') AND (EmailsSent = EmailsTotal)'; $this->Conn->Query($sql); } /** * Sent given messages from email queue * * @param Array $messages */ function processQueue(&$messages) { $esender =& $this->Application->recallObject('EmailSender'); /* @var $esender kEmailSendingHelper */ $queue_table = $this->Application->getUnitOption('email-queue', 'TableName'); $i = 0; $message = Array (); $mailing_totals = Array (); $message_count = count($messages); while ($i < $message_count) { $message[0] = unserialize($messages[$i]['MessageHeaders']); $message[1] =& $messages[$i]['MessageBody']; $esender->setLogData( unserialize($messages[$i]['LogData']) ); $delivered = $esender->Deliver($message, true); // immediate send! if ($delivered) { // send succeeded, delete from queue $sql = 'DELETE FROM ' . $queue_table . ' WHERE EmailQueueId = ' . $messages[$i]['EmailQueueId']; $this->Conn->Query($sql); $mailing_id = $messages[$i]['MailingId']; if (!array_key_exists($mailing_id, $mailing_totals)) { $mailing_totals[$mailing_id] = 0; } $mailing_totals[$mailing_id]++; } else { // send failed, increment retries counter $sql = 'UPDATE ' . $queue_table . ' SET SendRetries = SendRetries + 1, LastSendRetry = ' . adodb_mktime() . ' WHERE EmailQueueId = ' . $messages[$i]['EmailQueueId']; $this->Conn->Query($sql); } $i++; } $this->_updateSentTotals($mailing_totals); } }