Index: branches/RC/core/install/install_schema.sql
===================================================================
diff -u -r11290 -r11319
--- branches/RC/core/install/install_schema.sql (.../install_schema.sql) (revision 11290)
+++ branches/RC/core/install/install_schema.sql (.../install_schema.sql) (revision 11319)
@@ -87,9 +87,11 @@
Queued int(10) unsigned NOT NULL default '0',
SendRetries int(10) unsigned NOT NULL default '0',
LastSendRetry int(10) unsigned NOT NULL default '0',
+ MailingId int(10) unsigned NOT NULL,
PRIMARY KEY (EmailQueueId),
KEY LastSendRetry (LastSendRetry),
- KEY SendRetries (SendRetries)
+ KEY SendRetries (SendRetries),
+ KEY MailingId (MailingId)
);
CREATE TABLE EmailSubscribers (
Index: branches/RC/core/kernel/utility/email_send.php
===================================================================
diff -u -r10098 -r11319
--- branches/RC/core/kernel/utility/email_send.php (.../email_send.php) (revision 10098)
+++ branches/RC/core/kernel/utility/email_send.php (.../email_send.php) (revision 11319)
@@ -1905,7 +1905,7 @@
* Performs mail delivery (supports delayed delivery)
*
* @param string $mesasge message, if not given, then use composed one
- * @param bool $immediate_send send message now
+ * @param bool $immediate_send send message now or MailingId
* @param bool $immediate_clear clear message parts after message is sent
*
*/
@@ -1933,7 +1933,7 @@
}
if ($composed) {
- if ($immediate_send) {
+ if ($immediate_send === true) {
$send_method = 'Send'.$this->sendMethod;
$result = $this->$send_method($message_headers, $message_body);
@@ -1949,6 +1949,7 @@
'Queued' => adodb_mktime(),
'SendRetries' => 0,
'LastSendRetry' => 0,
+ 'MailingId' => (int)$immediate_send,
);
$fields_hash['MessageHeaders'] = serialize($message_headers);
$fields_hash['MessageBody'] =& $message_body;
@@ -1961,7 +1962,7 @@
}
// if not immediate send, then send result is positive :)
- return !$immediate_send ? true : false;
+ return $immediate_send !== true ? true : false;
}
}
Index: branches/RC/core/units/mailing_lists/mailing_list_eh.php
===================================================================
diff -u
--- branches/RC/core/units/mailing_lists/mailing_list_eh.php (revision 0)
+++ branches/RC/core/units/mailing_lists/mailing_list_eh.php (revision 11319)
@@ -0,0 +1,311 @@
+ Array ('self' => 'edit'),
+ 'OnGenerateEmailQueue' => Array ('self' => true),
+ 'OnProcessEmailQueue' => Array ('self' => true),
+ );
+
+ $this->permMapping = array_merge($this->permMapping, $permissions);
+ }
+
+ /**
+ * Prepare recipient list
+ *
+ * @param kEvent $event
+ */
+ function OnNew(&$event)
+ {
+ parent::OnNew($event);
+
+ $recipient_type = $this->Application->GetVar('mailing_recipient_type');
+ if (!$recipient_type) {
+ return ;
+ }
+
+ $recipients = $this->Application->GetVar($recipient_type);
+ if ($recipients) {
+ $object =& $event->getObject();
+ /* @var $object kDBItem */
+
+ $to = $recipient_type . '_' . implode(';' . $recipient_type . '_', array_keys($recipients));
+
+ $object->SetDBField('To', $to);
+ }
+ }
+
+ /**
+ * Don't allow to delete mailings in progress
+ *
+ * @param kEvent $event
+ */
+ function customProcessing(&$event, $type)
+ {
+ if ($event->Name == 'OnMassDelete' && $type == 'before') {
+ $ids = $event->getEventParam('ids');
+ if ($ids) {
+ $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
+ $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
+
+ $sql = 'SELECT ' . $id_field . '
+ FROM ' . $table_name . '
+ WHERE ' . $id_field . ' IN (' . implode(',', $ids) . ') AND Status <> ' . MAILING_LIST_PARTIALLY_PROCESSED;
+ $allowed_ids = $this->Conn->GetCol($sql);
+
+ $event->setEventParam('ids', $allowed_ids);
+ }
+ }
+ }
+
+ /**
+ * Delete all realted mails in email queue
+ *
+ * @param kEvent $event
+ */
+ function OnAfterItemDelete(&$event)
+ {
+ parent::OnAfterItemDelete($event);
+
+ $this->_deleteQueue($event);
+
+ $object =& $event->getObject();
+ /* @var $object kDBItem */
+
+ // delete mailing attachments after mailing is deleted
+ $attachments = $object->GetField('Attachments', 'file_paths');
+ if ($attachments) {
+ $attachments = explode('|', $attachments);
+
+ foreach ($attachments as $attachment_file) {
+ if (file_exists($attachment_file)) {
+ unlink($attachment_file);
+ }
+ }
+ }
+ }
+
+ /**
+ * Cancels given mailing and deletes all it's email queue
+ *
+ * @param kEvent $event
+ */
+ function OnCancelMailing(&$event)
+ {
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+ /* @var $object kDBItem */
+
+ $ids = $this->StoreSelectedIDs($event);
+
+ if ($ids) {
+ foreach ($ids as $id) {
+ $object->Load($id);
+ $object->SetDBField('Status', MAILING_LIST_CANCELLED);
+ $object->Update();
+ }
+ }
+
+ $this->clearSelectedIDs($event);
+ }
+
+ /**
+ * Checks, that at least one message text field is filled
+ *
+ * @param kEvent $event
+ */
+ function OnBeforeItemCreate(&$event)
+ {
+ parent::OnBeforeItemCreate($event);
+
+ $object =& $event->getObject();
+ /* @var $object kDBItem */
+
+ if (!$this->Application->GetVar('mailing_recipient_type')) {
+ // user manually typed email addresses -> normalize
+ $recipients = str_replace(',', ';', $object->GetDBField('To'));
+ $recipients = array_map('trim', explode(';', $recipients));
+
+ $object->SetDBField('To', implode(';', $recipients));
+ }
+
+ if (!$object->GetDBField('MessageText')) {
+ $object->setRequired('MessageHtml', true);
+ }
+
+ // remember user, who created mailing, because of his name
+ // is needed for "From" field, but mailing occurs from cron
+ $user_id = $this->Application->RecallVar('user_id');
+ $object->SetDBField('PortalUserId', $user_id);
+ }
+
+ /**
+ * Deletes mailing list email queue, when it becomes cancelled
+ *
+ * @param kEvent $event
+ */
+ function OnAfterItemUpdate(&$event)
+ {
+ parent::OnAfterItemUpdate($event);
+
+ $object =& $event->getObject();
+ /* @var $object kDBItem */
+
+ $status = $object->GetDBField('Status');
+ if (($status != $object->GetOriginalField('Status')) && ($status == MAILING_LIST_CANCELLED)) {
+ $this->_deleteQueue($event);
+ }
+ }
+
+ /**
+ * Deletes email queue records related with given mailing list
+ *
+ * @param kEvent $event
+ */
+ function _deleteQueue(&$event)
+ {
+ $object =& $event->getObject();
+ /* @var $object kDBItem */
+
+ $sql = 'DELETE FROM ' . $this->Application->getUnitOption('email-queue', 'TableName') . '
+ WHERE MailingId = ' . $object->GetID();
+ $this->Conn->Query($sql);
+ }
+
+ /**
+ * Allows to safely get mailing configuration variables
+ *
+ * @param string $variable_name
+ * @return int
+ */
+ function _ensureDefault($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;
+ }
+
+ /**
+ * Generates email queue for active mailing lists
+ *
+ * @param kEvent $event
+ */
+ function OnGenerateEmailQueue(&$event)
+ {
+ $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
+ $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
+
+ $where_clause = Array (
+ 'Status NOT IN (' . MAILING_LIST_CANCELLED . ',' . MAILING_LIST_PROCESSED . ')',
+ '(EmailsQueued < EmailsTotal) OR (EmailsTotal = 0)',
+ '`To` <> ""',
+ );
+
+ $sql = 'SELECT *
+ FROM ' . $table_name . '
+ WHERE (' . implode(') AND (', $where_clause) . ')
+ ORDER BY ' . $id_field . ' ASC';
+ $mailing_lists = $this->Conn->Query($sql, $id_field);
+ if (!$mailing_lists) {
+ return ;
+ }
+
+ // queue 10 emails per step summary from all mailing lists (FIFO logic)
+ $to_queue = $this->_ensureDefault('MailingListQueuePerStep');
+ if ($to_queue === false) {
+ return ;
+ }
+
+ $mailing_list_helper =& $this->Application->recallObject('MailingListHelper');
+ /* @var $mailing_list_helper MailingListHelper */
+
+ foreach ($mailing_lists as $mailing_id => $mailing_data) {
+ if ($mailing_data['EmailsTotal'] == 0) {
+ // no work performed on this mailing list -> calculate totals
+ $updated_fields = $mailing_list_helper->generateRecipients($mailing_id, $mailing_data);
+ $updated_fields['Status'] = MAILING_LIST_PARTIALLY_PROCESSED;
+ $mailing_data = array_merge_recursive2($mailing_data, $updated_fields);
+
+ $this->Conn->doUpdate($updated_fields, $table_name, $id_field . ' = ' . $mailing_id);
+ }
+
+ $emails = unserialize( $mailing_data['ToParsed'] );
+ if (!$emails) {
+ continue;
+ }
+
+ // queue allowed count of emails
+ $i = 0;
+ $process_count = count($emails) >= $to_queue ? $to_queue : count($emails);
+
+ while ($i < $process_count) {
+ $mailing_list_helper->queueEmail($emails[$i], $mailing_id, $mailing_data);
+ $i++;
+ }
+
+ // remove processed emails from array
+ $to_queue -= $process_count; // decrement available for processing email count
+ array_splice($emails, 0, $process_count);
+ $updated_fields = Array (
+ 'ToParsed' => serialize($emails),
+ 'EmailsQueued' => $mailing_data['EmailsQueued'] + $process_count,
+ );
+ $mailing_data = array_merge_recursive2($mailing_data, $updated_fields);
+ $this->Conn->doUpdate($updated_fields, $table_name, $id_field . ' = ' . $mailing_id);
+
+ if (!$to_queue) {
+ // emails to be queued per step reached -> leave
+ break;
+ }
+ }
+ }
+
+ /**
+ * Process email queue from cron
+ *
+ * @param kEvent $event
+ */
+ function OnProcessEmailQueue(&$event)
+ {
+ $deliver_count = $this->_ensureDefault('MailingListSendPerStep');
+ if ($deliver_count === false) {
+ return ;
+ }
+
+ $queue_table = $this->Application->getUnitOption('email-queue', 'TableName');
+
+ // get queue part to send
+ $sql = 'SELECT *
+ FROM ' . $queue_table . '
+ WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')
+ LIMIT 0,' . $deliver_count;
+ $messages = $this->Conn->Query($sql);
+
+ if (!$messages) {
+ // no more messages left in queue
+ return ;
+ }
+
+ $mailing_list_helper =& $this->Application->recallObject('MailingListHelper');
+ /* @var $mailing_list_helper MailingListHelper */
+
+ $mailing_list_helper->processQueue($messages);
+ }
+ }
\ No newline at end of file
Index: branches/RC/core/units/email_queue/email_queue_config.php
===================================================================
diff -u -r11154 -r11319
--- branches/RC/core/units/email_queue/email_queue_config.php (.../email_queue_config.php) (revision 11154)
+++ branches/RC/core/units/email_queue/email_queue_config.php (.../email_queue_config.php) (revision 11319)
@@ -28,7 +28,7 @@
'Sections' => Array (
'in-portal:email_queue' => Array (
- 'parent' => 'in-portal:email_folder',
+ 'parent' => 'in-portal:mailing_folder',
'icon' => 'email_log',
'label' => 'la_tab_EmailQueue',
'url' => Array('t' => 'logs/email_logs/email_queue_list', 'pass' => 'm'),
@@ -57,6 +57,7 @@
'Queued' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'not_null' => 1, 'default' => 0),
'SendRetries' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'LastSendRetry' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'not_null' => 1, 'default' => 0),
+ 'MailingId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
),
'Grids' => Array (
@@ -70,6 +71,7 @@
'Queued' => Array ('title' => 'la_col_Queued', 'filter_block' => 'grid_date_range_filter', ),
'SendRetries' => Array ('title' => 'la_col_SendRetries', 'filter_block' => 'grid_range_filter', ),
'LastSendRetry' => Array ('title' => 'la_col_LastSendRetry', 'filter_block' => 'grid_date_range_filter', ),
+ 'MailingId' => Array ('title' => 'la_col_MailingList', 'filter_block' => 'grid_range_filter', ),
),
),
),
Fisheye: Tag 11319 refers to a dead (removed) revision in file `branches/RC/core/admin_templates/logs/email_logs/email_log_tabs.tpl'.
Fisheye: No comparison available. Pass `N' to diff?
Index: branches/RC/core/admin_templates/logs/email_logs/email_log_list.tpl
===================================================================
diff -u -r11226 -r11319
--- branches/RC/core/admin_templates/logs/email_logs/email_log_list.tpl (.../email_log_list.tpl) (revision 11226)
+++ branches/RC/core/admin_templates/logs/email_logs/email_log_list.tpl (.../email_log_list.tpl) (revision 11319)
@@ -1,6 +1,6 @@
-
+