Page MenuHomeIn-Portal Phabricator

mailing_list_helper.php
No OneTemporary

File Metadata

Created
Mon, Aug 18, 4:02 PM

mailing_list_helper.php

<?php
/**
* @version $Id: mailing_list_helper.php 16600 2017-07-29 06:19:27Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class MailingListHelper extends kHelper {
var $_mailingId = false;
/**
* Adds new email from given mailing to emails queue
*
* @param string $email
* @param int $mailing_id
* @param Array $mailing_data
*/
function queueEmail($email, $mailing_id, &$mailing_data)
{
/** @var kEmailSendingHelper $esender */
$esender = $this->Application->recallObject('EmailSender');
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']);
if ( !$mailing_data['MessageText'] ) {
$mailing_data['MessageText'] = $esender->ConvertToText($mailing_data['MessageHtml']);
}
$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);
if ( $this->Application->ConfigValue('EnableEmailLog') ) {
// 4. write to log
$log_fields_hash = Array (
'From' => $mailing_data['FromName'] . '(' . $mailing_data['FromEmail'] . ')',
'To' => $email,
'Subject' => $mailing_data['Subject'],
'HtmlBody' => $mailing_data['MessageHtml'],
'TextBody' => $mailing_data['MessageText'],
'SentOn' => TIMENOW,
'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 ) {
/** @var UsersItem $sender */
$sender = $this->Application->recallObject('u.-item', null, Array ('skip_autoload' => true));
$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('DefaultEmailSender');
}
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 Id.
* @param Array $fields_hash Fields hash.
*
* @return array
*/
function generateRecipients($id, $fields_hash)
{
// for each group convert ids to names
$recipient_emails = Array ();
$recipients_grouped = $this->groupRecipientsByType(explode(';', $fields_hash['To']));
foreach ($recipients_grouped as $recipient_type => $group_recipients) {
$recipient_emails = array_merge($recipient_emails, $this->_getRecipientEmails($recipient_type, $group_recipients));
}
$recipient_emails = array_unique($recipient_emails);
return Array (
'ToParsed' => serialize($recipient_emails),
'EmailsTotal' => count($recipient_emails),
);
}
/**
* Groups recipients by type
*
* @param Array $recipients
* @return Array
* @access public
*/
public function groupRecipientsByType($recipients)
{
$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;
}
return $recipients_grouped;
}
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 . 'Users
WHERE (PortalUserId IN (' . implode(',', $recipient_ids) . ')) AND (Email <> "")';
break;
case 'g':
$sql = 'SELECT u.Email
FROM ' . TABLE_PREFIX . 'UserGroupRelations ug
LEFT JOIN ' . TABLE_PREFIX . 'Users 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;
}
$config = $this->Application->getUnitConfig($recipient_type);
$id_field = $config->getIDField();
$table_name = $config->getTableName();
$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]);
}
$config = $this->Application->getUnitConfig('mailing-list');
$table_name = $config->getTableName();
// 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 ' . $config->getIDField() . ' = ' . $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|null $messages Messages.
*
* @return integer
*/
function processQueue(&$messages = null)
{
/** @var kEmailSendingHelper $esender */
$esender = $this->Application->recallObject('EmailSender');
if ( !isset($messages) ) {
$messages = $this->getMessages();
}
else {
kUtil::deprecatedArgument(__METHOD__, '5.2.2-B2', 'The "$messages" parameter is deprecated.');
}
$message_count = count($messages);
if ( !$message_count ) {
return 0;
}
$i = 0;
$message = Array();
$mailing_totals = Array();
$queue_table = $this->Application->getUnitConfig('email-queue')->getTableName();
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 = ' . time() . '
WHERE EmailQueueId = ' . $messages[$i]['EmailQueueId'];
$this->Conn->Query($sql);
}
$i++;
}
$this->_updateSentTotals($mailing_totals);
return $message_count;
}
/**
* Returns queued messages (or their count), that can be sent
*
* @param bool $count_only
*
* @return Array|int
* @access public
*/
public function getMessages($count_only = false)
{
$deliver_count = $this->getSetting('MailingListSendPerStep');
if ( !is_numeric($deliver_count) ) {
return $count_only ? 0 : Array();
}
$queue_table = $this->Application->getUnitConfig('email-queue')->getTableName();
if ( $count_only ) {
$sql = 'SELECT COUNT(*)
FROM ' . $queue_table . '
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')';
return $this->Conn->GetOne($sql);
}
// regular e-mails are pressed before mailing generated ones !
$sql = 'SELECT *
FROM ' . $queue_table . '
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')
ORDER BY MailingId ASC
LIMIT 0,' . $deliver_count;
return $this->Conn->Query($sql);
}
/**
* Allows to safely get mailing configuration variable
*
* @param string $variable_name
*
* @return int
* @access public
*/
public function getSetting($variable_name)
{
$value = $this->Application->ConfigValue($variable_name);
if ( $value === false ) {
// ensure default value, when configuration variable is missing
return 10;
}
if ( !$value ) {
// configuration variable found, but it's value is empty or zero
return false;
}
return $value;
}
}

Event Timeline