Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Wed, Jul 23, 12:23 PM

in-portal

Index: branches/RC/core/units/email_events/email_events_config.php
===================================================================
--- branches/RC/core/units/email_events/email_events_config.php (revision 9365)
+++ branches/RC/core/units/email_events/email_events_config.php (revision 9366)
@@ -1,106 +1,107 @@
<?php
$config = Array(
'Prefix' => 'emailevents',
'ItemClass' => Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
'ListClass' => Array('class'=>'kDBList','file'=>'','build_event'=>'OnListBuild'),
'EventHandlerClass' => Array('class'=>'EmailEventsEventsHandler','file'=>'email_events_event_handler.php','build_event'=>'OnBuild'),
'TagProcessorClass' => Array('class'=>'kDBTagProcessor','file'=>'','build_event'=>'OnBuild'),
'AutoLoad' => true,
'QueryString' => Array(
1 => 'id',
2 => 'page',
3 => 'event',
),
'IDField' => 'EventId',
'StatusField' => Array('Enabled'),
'TitleField' => 'Event',
'TitlePresets' => Array(
'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!'),
),
'FilterMenu' => Array(
'Groups' => Array(
Array('mode' => 'AND', 'filters' => Array('show_enabled','show_disabled','show_frontonly'), 'type' => WHERE_FILTER),
),
'Filters' => Array(
'show_enabled' => Array('label' =>'la_Enabled', 'on_sql' => '', 'off_sql' => '%1$s.Enabled != 1' ),
'show_disabled' => Array('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => '%1$s.Enabled != 0' ),
'show_frontonly' => Array('label' => 'la_Text_FrontOnly', 'on_sql' => '', 'off_sql' => '%1$s.Enabled != 2' ),
)
),
'TableName' => TABLE_PREFIX.'Events',
'CalculatedFields' => Array(
'' => Array (
'FromUser' => 'u.Login',
)
),
'ListSQLs' => Array( ''=>' SELECT %1$s.* %2$s
FROM %1$s
LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.FromUserId = u.PortalUserId',
), // key - special, value - list select sql),
'ItemSQLs' => Array( ''=>'SELECT * FROM %s'),
'ListSortings' => Array(
'' => Array('Sorting' => Array('Module' => 'asc', 'Description' => 'asc') ),
'module' => Array('Sorting' => Array('Description' => 'asc') ),
),
'Fields' => Array(
'EventId' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'Event' => Array('type' => 'string','not_null' => '1','default' => ''),
'ReplacementTags' => Array ('type' => 'string', 'default' => NULL),
'Enabled' => Array('type'=>'int', 'formatter'=>'kOptionsFormatter', 'options' => Array(1 => 'la_Enabled', 0 => 'la_Disabled', 2 => 'la_Text_FrontOnly'), 'use_phrases' => 1, 'default' => 1, 'not_null' => 1),
'FromUserId' => Array('type' => 'int', 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'options' => Array(-1=>'root'), 'left_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'required'=>1, 'not_null' => 1, 'default' => -1),
'Module' => Array('type' => 'string','not_null' => '1','default' => ''),
'Description' => Array('type' => 'string','not_null' => '1','default' => ''),
'Type' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options' => Array (1 => 'la_Text_Admin', 0 => 'la_Text_User'), 'use_phrases' => 1, 'default' => 0, 'not_null' => 1),
),
'VirtualFields' => Array(
'FromUser' => Array(),
),
'Grids' => Array(
'Default' => Array(
'Icons' => Array('default'=>'icon16_custom.gif'),
'Fields' => Array(
'Description' => Array( 'title'=>'la_col_Description', 'data_block' => 'label_grid_checkbox_td'),
'Event' => Array( 'title'=>'la_col_Event'),
'Module' => Array( 'title'=>'la_col_Module'),
'Type' => Array( 'title'=>'la_col_Type', 'filter_block' => 'grid_options_filter'),
'Enabled' => Array( 'title'=>'la_col_Status', 'filter_block' => 'grid_options_filter'),
),
),
'EmailSettings' => Array(
'Icons' => Array('default'=>'icon16_custom.gif'),
'Fields' => Array(
'Description' => Array('title'=>'la_col_Description', 'data_block' => 'label_grid_checkbox_td' ),
'Type' => Array('title'=>'la_col_Type'),
'Enabled' => Array('title'=>'la_col_Status'),
'FromUser' => Array('title'=>'la_col_FromToUser'),
),
),
),
);
if (defined('DEBUG_MODE') && DEBUG_MODE) {
$config['Grids']['EmailSettings']['Fields']['EventId'] = Array('title' => 'la_col_Id');
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/email_events/email_events_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.12.2.1
\ No newline at end of property
+1.12.2.2
\ No newline at end of property
Index: branches/RC/core/units/email_messages/email_messages_event_handler.php
===================================================================
--- branches/RC/core/units/email_messages/email_messages_event_handler.php (revision 9365)
+++ branches/RC/core/units/email_messages/email_messages_event_handler.php (revision 9366)
@@ -1,317 +1,368 @@
<?php
class EmailMessagesEventHandler extends kDBEventHandler
{
/**
* Replace id passed with id of email message
*
* @param kEvent $event
*/
function getPassedID(&$event)
{
$parent = parent::getPassedID($event);
if ($parent) return $parent;
$email_event_id = (int)$this->getEmailEventId();
$object =& $event->getObject();
$parent_info = $object->getLinkedInfo();
$sql = 'SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE ('.$parent_info['ForeignKey'].' = '.$parent_info['ParentId'].') AND (EventId = '.$email_event_id.')';
$id = (int)$this->Conn->GetOne($sql);
if(!$id)
{
$object->SetDBField('EventId', $email_event_id);
$object->SetDBField('Headers', $this->Application->ConfigValue('Smtp_DefaultHeaders') );
}
return $id;
}
function getEmailEventId()
{
return parent::getPassedID( new kEvent('emailevents:OnDummy') );
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @access protected
* @see OnListBuild
*/
function SetCustomQuery(&$event)
{
if ($event->Special == 'module') {
$object =& $event->getObject();
$module = $this->Application->GetVar('module');
$object->addFilter('module_filter', 'Module = '.$this->Conn->qstr($module));
}
}
/**
* If loading empty item, then set parent id
*
* @param kEvent $event
*/
function OnBeforeItemLoad(&$event)
{
if( !$event->getEventParam('id') )
{
$this->OnNew($event);
$event->status = erFATAL;
}
}
/**
* Parse message template (split into header, subject & body)
*
* @param kEvent $event
*/
function OnAfterItemLoad(&$event)
{
$object =& $event->getObject();
$lines = explode("\n", $object->GetDBField('Template') );
$headers = Array();
foreach($lines as $line)
{
if( strlen(trim($line)) == 0 || ($line == '.') ) break;
$parts = explode(':', $line, 2);
if(strtolower($parts[0]) == 'subject')
{
$object->SetDBField('Subject', trim($parts[1]) );
}
else
{
$headers[] = $line;
}
}
$object->SetDBField('Headers', implode("\n", $headers) );
$message_body = '';
while( (list($line_id,$line) = each($lines)) )
{
$message_body .= $line;
}
$object->SetDBField('Body', $message_body);
}
/**
* Merge body+subject+headers into message template
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
$this->parseVirtualFields($event);
}
/**
* Merge body+subject+headers into message template
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
$this->parseVirtualFields($event);
}
/**
* Merge body+subject+headers into message template
*
* @param kEvent $event
*/
function parseVirtualFields(&$event)
{
$object =& $event->getObject();
if( $object->GetDBField('Headers') || $object->GetDBField('Subject') || $object->GetDBField('Body') )
{
$ret = $object->GetDBField('Headers');
if($ret) $ret .= "\n";
$ret = $this->removeTrailingCRLF($ret);
$ret .= 'Subject: '.$object->GetDBField('Subject')."\n\n";
$ret .= $object->GetDBField('Body');
$object->SetDBField('Template', $ret);
}
}
/**
* Remove trailing CR/LF chars from string
*
* @param string $string
* @return string
*/
function removeTrailingCRLF($string)
{
return preg_replace('/(\n|\r)+/',"\\1",$string);
}
/**
* Prepares selected user(-s) or group(-s) for message sending
*
* @param kEvent $event
*/
function OnPrepareMassRecipients(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$object->Clear(0);
$event->redirect = false;
$this->Application->RemoveVar('recipient_ids');
$this->Application->RemoveVar('recipient_type');
$this->saveMassRecipients('u');
$this->saveMassRecipients('g', 'total');
}
function saveMassRecipients($prefix, $special = '')
{
$recipients = $this->Application->GetVar(rtrim($prefix.'_'.$special, '_'));
if ($recipients) {
$this->Application->StoreVar('recipient_ids', implode(',', array_keys($recipients)));
$this->Application->StoreVar('recipient_type', $prefix);
}
}
/**
* Sends mass mail
*
* @param kEvent $event
*/
function OnMassMail(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$object->setRequired('MassSubject', true);
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
list($id, $field_values) = each($items_info);
$object->SetFieldsFromHash($field_values);
}
if (!$object->Validate()) {
$event->redirect = false;
$event->status = erFAIL;
$object->setID($id);
return ;
}
- $esender =& $this->Application->recallObject('EmailSender');
- /* @var $esender kEmailSendingHelper */
-
$fields_hash = $object->GetFieldValues();
list ($fields_hash['FromEmail'], $fields_hash['FromName']) = $this->getSenderData();
if ($fields_hash['MassAttachment']) {
$field_options = $object->GetFieldOptions('MassAttachment');
$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);
- }
-
- // 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']);
- }
+ $this->Application->RemoveVar('email_prepare_progress');
+ $this->Application->StoreVar('email_prepare_fields', serialize($fields_hash));
- $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
*
* @return Array
*/
function getSenderData()
{
$user =& $this->Application->recallObject('u.current');
/* @var $user UsersItem */
if ($user->GetID() > 0) {
$email_address = $user->GetDBField('Email');
$name = $user->GetDBField('FirstName').' '.$user->GetDBField('LastName');
}
else {
$email_address = $this->Application->ConfigValue('Smtp_AdminMailFrom');
$name = strip_tags( $this->Application->ConfigValue('Site_Name') );
}
return Array ($email_address, $name);
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/email_messages/email_messages_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6.2.1
\ No newline at end of property
+1.6.2.2
\ No newline at end of property
Index: branches/RC/core/admin_templates/emails/prepare_queue.tpl
===================================================================
--- branches/RC/core/admin_templates/emails/prepare_queue.tpl (nonexistent)
+++ branches/RC/core/admin_templates/emails/prepare_queue.tpl (revision 9366)
@@ -0,0 +1,17 @@
+<inp2:m_include t="incs/header" nobody="yes"/>
+
+<body topmargin="0" leftmargin="8" marginheight="0" marginwidth="8" bgcolor="#FFFFFF">
+
+<inp2:m_RenderElement name="combined_header" section="in-portal:user_list" permission_type="advanced:send_email" prefix="emailevents" title_preset="email_prepare"/>
+
+ <script type="text/javascript" src="js/ajax.js"></script>
+ <inp2:m_RenderElement name="ajax_progress_bar" cancel_action="cancel_action();"/>
+ <script type="text/javascript">
+ function cancel_action() {
+ redirect('<inp2:m_Link template="emails/send_complete"/>');
+ }
+
+ $QueueProcessor = new AjaxProgressBar('<inp2:m_t template="index" emailmessages_event="OnPrepareEmailQueue" finish_template="emails/send_queue" pass="m,emailmessages" no_amp="1"/>');
+ </script>
+
+<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/emails/prepare_queue.tpl
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.2.1
\ No newline at end of property

Event Timeline