Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Thu, Feb 6, 9:11 AM

in-portal

Index: branches/5.1.x/core/units/email_events/email_events_event_handler.php
===================================================================
--- branches/5.1.x/core/units/email_events/email_events_event_handler.php (revision 13665)
+++ branches/5.1.x/core/units/email_events/email_events_event_handler.php (revision 13666)
@@ -1,1071 +1,1085 @@
<?php
/**
* @version $Id$
* @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 EmailEventsEventsHandler extends kDBEventHandler
{
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnFrontOnly' => Array ('self' => 'edit'),
'OnSaveSelected' => Array ('self' => 'view'),
'OnProcessEmailQueue' => Array ('self' => 'add|edit'),
'OnSuggestAddress' => Array ('self' => 'add|edit'),
// events only for developers
'OnPreCreate' => Array ('self' => 'debug'),
'OnDelete' => Array ('self' => 'debug'),
'OnDeleteAll' => Array ('self' => 'debug'),
'OnMassDelete' => Array ('self' => 'debug'),
'OnMassApprove' => Array ('self' => 'debug'),
'OnMassDecline' => Array ('self' => 'debug'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Changes permission section to one from REQUEST, not from config
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
$module = $this->Application->GetVar('module');
if (strlen($module) > 0) {
// checking permission when lising module email events in separate section
$module = explode(':', $module, 2);
if (count($module) == 1) {
$main_prefix = $this->Application->findModule('Name', $module[0], 'Var');
}
else {
$exceptions = Array('Category' => 'c', 'Users' => 'u');
$main_prefix = $exceptions[ $module[1] ];
}
$section = $this->Application->getUnitOption($main_prefix.'.email', 'PermSection');
$event->setEventParam('PermSection', $section);
}
// checking permission when listing all email events when editing language
return parent::CheckPermission($event);
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @access protected
* @see OnListBuild
*/
function SetCustomQuery(&$event)
{
$object =& $event->getObject();
/* @var $object kDBList */
if ($event->Special == 'module') {
$module = $this->Application->GetVar('module');
$object->addFilter('module_filter', '%1$s.Module = '.$this->Conn->qstr($module));
}
if (!$event->Special && !$this->Application->isDebugMode()) {
// no special
$object->addFilter('enabled_filter', '%1$s.Enabled <> ' . STATUS_DISABLED);
}
}
/**
* Sets event id
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
parent::OnPreCreate($event);
$object =& $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('Headers', $this->Application->ConfigValue('Smtp_DefaultHeaders'));
}
/**
* Sets status Front-End Only to selected email events
*
* @param kEvent $event
*/
function OnFrontOnly(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$event->status = erFAIL;
return ;
}
$ids = implode(',', $this->StoreSelectedIDs($event));
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'UPDATE '.$table_name.'
SET FrontEndOnly = 1
WHERE EventId IN ('.$ids.')';
$this->Conn->Query($sql);
$this->clearSelectedIDs($event);
}
/**
* Sets selected user to email events selected
*
* @param kEvent $event
*/
function OnSelectUser(&$event)
{
if ($event->Special != 'module') {
parent::OnSelectUser($event);
return ;
}
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$event->status = erFAIL;
return ;
}
$items_info = $this->Application->GetVar('u');
if ($items_info) {
$user_id = array_shift( array_keys($items_info) );
$selected_ids = $this->getSelectedIDs($event, true);
$ids = $this->Application->RecallVar($event->getPrefixSpecial().'_selected_ids');
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'UPDATE '.$table_name.'
SET '.$this->Application->RecallVar('dst_field').' = '.$user_id.'
WHERE '.$id_field.' IN ('.$ids.')';
$this->Conn->Query($sql);
}
$this->finalizePopup($event);
}
/**
* Saves selected ids to session
*
* @param kEvent $event
*/
function OnSaveSelected(&$event)
{
$this->StoreSelectedIDs($event);
}
/**
* Returns email event object based on given kEvent object
*
* @param kEvent $event
* @return kDBItem
*/
function &_getEmailEvent(&$event)
{
$false = false;
$name = $event->getEventParam('EmailEventName');
$type = $event->getEventParam('EmailEventType');
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
if (!$object->isLoaded() || ($object->GetDBField('Event') != $name || $object->GetDBField('Type') != $type)) {
// get event parameters by name & type
$load_keys = Array ('Event' => $name, 'Type' => $type);
$object->Load($load_keys);
if (!$object->isLoaded() || ($object->GetDBField('Enabled') == STATUS_DISABLED)) {
// event record not found OR is disabled
return $false;
}
if ($object->GetDBField('FrontEndOnly') && $this->Application->isAdmin) {
return $false;
}
}
return $object;
}
/**
* Processes email sender
*
* @param kEvent $event
* @param Array $direct_params
*/
function _processSender(&$event, $direct_params = Array ())
{
$this->Application->removeObject('u.email-from');
$object =& $this->_getEmailEvent($event);
/* @var $object kDBItem */
$email = $name = '';
// set defaults from event
if ($object->GetDBField('CustomSender')) {
$address = $object->GetDBField('SenderAddress');
$address_type = $object->GetDBField('SenderAddressType');
switch ($address_type) {
case ADDRESS_TYPE_EMAIL:
$email = $address;
break;
case ADDRESS_TYPE_USER:
$sql = 'SELECT FirstName, LastName, Email, PortalUserId
FROM ' . TABLE_PREFIX . 'PortalUser
WHERE Login = ' . $this->Conn->qstr($address);
$user_info = $this->Conn->GetRow($sql);
if ($user_info) {
// user still exists
$email = $user_info['Email'];
$name = trim($user_info['FirstName'] . ' ' . $user_info['LastName']);
$user =& $this->Application->recallObject('u.email-from', null, Array('skip_autoload' => true));
/* @var $user UsersItem */
$user->Load($user_info['PortalUserId']);
}
break;
}
if ($object->GetDBField('SenderName')) {
$name = $object->GetDBField('SenderName');
}
}
// update with custom data given during event execution
if (array_key_exists('from_email', $direct_params)) {
$email = $direct_params['from_email'];
}
if (array_key_exists('from_name', $direct_params)) {
$name = $direct_params['from_name'];
}
// still nothing, set defaults
if (!$email) {
$email = $this->Application->ConfigValue('Smtp_AdminMailFrom');
}
if (!$name) {
$name = strip_tags( $this->Application->ConfigValue('Site_Name') );
}
$esender =& $this->Application->recallObject('EmailSender');
/* @var $esender kEmailSendingHelper */
$esender->SetFrom($email, $name);
return Array ($email, $name);
}
/**
* Processes email recipients
*
* @param kEvent $event
* @param Array $direct_params
*/
function _processRecipients(&$event, $direct_params = Array ())
{
$this->Application->removeObject('u.email-to');
$object =& $this->_getEmailEvent($event);
/* @var $object kDBItem */
$to_email = $to_name = '';
$all_recipients = Array ();
$recipients_xml = $object->GetDBField('Recipients');
if ($recipients_xml) {
$minput_helper =& $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
// group recipients by type
$records = $minput_helper->parseMInputXML($recipients_xml);
foreach ($records as $record) {
$recipient_type = $record['RecipientType'];
if (!array_key_exists($recipient_type, $all_recipients)) {
$all_recipients[$recipient_type] = Array ();
}
$all_recipients[$recipient_type][] = $record;
}
}
if (!array_key_exists(RECIPIENT_TYPE_TO, $all_recipients)) {
$all_recipients[RECIPIENT_TYPE_TO] = Array ();
}
// remove all "To" recipients, when not allowed
$overwrite_to_email = array_key_exists('overwrite_to_email', $direct_params) ? $direct_params['overwrite_to_email'] : false;
if (!$object->GetDBField('CustomRecipient') || $overwrite_to_email) {
$all_recipients[RECIPIENT_TYPE_TO] = Array ();
}
// update with custom data given during event execution (user_id)
$to_user_id = $event->getEventParam('EmailEventToUserId');
if ($to_user_id > 0) {
$sql = 'SELECT FirstName, LastName, Email
FROM ' . TABLE_PREFIX . 'PortalUser
WHERE PortalUserId = ' . $to_user_id;
$user_info = $this->Conn->GetRow($sql);
if ($user_info) {
$add_recipient = Array (
'RecipientAddressType' => ADDRESS_TYPE_EMAIL,
'RecipientAddress' => $user_info['Email'],
'RecipientName' => trim($user_info['FirstName'] . ' ' . $user_info['LastName']),
);
array_unshift($all_recipients[RECIPIENT_TYPE_TO], $add_recipient);
$user =& $this->Application->recallObject('u.email-to', null, Array('skip_autoload' => true));
/* @var $user UsersItem */
$user->Load($to_user_id);
}
}
+ elseif (is_numeric($to_user_id)) {
+ // recipient is system user with negative ID (root, guest, etc.) -> send to admin
+ array_unshift($all_recipients[RECIPIENT_TYPE_TO], $this->_getDefaultRepipient());
+ }
// update with custom data given during event execution (email + name)
$add_recipient = Array ();
if (array_key_exists('to_email', $direct_params)) {
$add_recipient['RecipientName'] = '';
$add_recipient['RecipientAddressType'] = ADDRESS_TYPE_EMAIL;
$add_recipient['RecipientAddress'] = $direct_params['to_email'];
}
if (array_key_exists('to_name', $direct_params)) {
$add_recipient['RecipientName'] = $direct_params['to_name'];
}
if ($add_recipient) {
array_unshift($all_recipients[RECIPIENT_TYPE_TO], $add_recipient);
}
if (($object->GetDBField('Type') == EVENT_TYPE_ADMIN) && !$all_recipients[RECIPIENT_TYPE_TO]) {
// admin email event without direct recipient -> send to admin
- $all_recipients[RECIPIENT_TYPE_TO][] = Array (
- 'RecipientName' => $this->Application->ConfigValue('Smtp_AdminMailFrom'),
- 'RecipientAddressType' => ADDRESS_TYPE_EMAIL,
- 'RecipientAddress' => $this->Application->ConfigValue('Smtp_AdminMailFrom'),
- );
+ array_unshift($all_recipients[RECIPIENT_TYPE_TO], $this->_getDefaultRepipient());
}
$esender =& $this->Application->recallObject('EmailSender');
/* @var $esender kEmailSendingHelper */
$header_mapping = Array (
RECIPIENT_TYPE_TO => 'To',
RECIPIENT_TYPE_CC => 'Cc',
RECIPIENT_TYPE_BCC => 'Bcc',
);
$default_email = $this->Application->ConfigValue('Smtp_AdminMailFrom');
foreach ($all_recipients as $recipient_type => $recipients) {
// add recipients to email
$pairs = Array ();
foreach ($recipients as $recipient) {
$address = $recipient['RecipientAddress'];
$address_type = $recipient['RecipientAddressType'];
$repipient_name = $recipient['RecipientName'];
switch ($address_type) {
case ADDRESS_TYPE_EMAIL:
$pairs[] = Array ('email' => $address, 'name' => $repipient_name);
break;
case ADDRESS_TYPE_USER:
$sql = 'SELECT FirstName, LastName, Email
FROM ' . TABLE_PREFIX . 'PortalUser
WHERE Login = ' . $this->Conn->qstr($address);
$user_info = $this->Conn->GetRow($sql);
if ($user_info) {
// user still exists
$name = trim($user_info['FirstName'] . ' ' . $user_info['LastName']);
$pairs[] = Array (
'email' => $user_info['Email'],
'name' => $name ? $name : $repipient_name,
);
}
break;
case ADDRESS_TYPE_GROUP:
$sql = 'SELECT u.FirstName, u.LastName, u.Email
FROM ' . TABLE_PREFIX . 'PortalGroup g
JOIN ' . TABLE_PREFIX . 'UserGroup ug ON ug.GroupId = g.GroupId
JOIN ' . TABLE_PREFIX . 'PortalUser u ON u.PortalUserId = ug.PortalUserId
WHERE g.Name = ' . $this->Conn->qstr($address);
$users = $this->Conn->Query($sql);
foreach ($users as $user) {
$name = trim($user_info['FirstName'] . ' ' . $user_info['LastName']);
$pairs[] = Array (
'email' => $user_info['Email'],
'name' => $name ? $name : $repipient_name,
);
}
break;
}
}
if (!$pairs) {
continue;
}
if ($recipient_type == RECIPIENT_TYPE_TO) {
$to_email = $pairs[0]['email'] ? $pairs[0]['email'] : $default_email;
$to_name = $pairs[0]['name'] ? $pairs[0]['name'] : $to_email;
}
$header_name = $header_mapping[$recipient_type];
foreach ($pairs as $pair) {
$email = $pair['email'] ? $pair['email'] : $default_email;
$name = $pair['name'] ? $pair['name'] : $email;
$esender->AddRecipient($header_name, $email, $name);
}
}
return Array ($to_email, $to_name);
}
/**
+ * This is default recipient, when we can't determine actual one
+ *
+ * @return Array
+ */
+ function _getDefaultRepipient()
+ {
+ return Array (
+ 'RecipientName' => $this->Application->ConfigValue('Smtp_AdminMailFrom'),
+ 'RecipientAddressType' => ADDRESS_TYPE_EMAIL,
+ 'RecipientAddress' => $this->Application->ConfigValue('Smtp_AdminMailFrom'),
+ );
+ }
+
+ /**
* Returns email event message by ID (headers & body in one piece)
*
* @param kEvent $event
* @param int $language_id
*/
function _getMessageBody(&$event, $language_id = null)
{
if (!isset($language_id)) {
$language_id = $this->Application->GetVar('m_lang');
}
$object =& $this->_getEmailEvent($event);
// 1. get message body
$message_body = $this->_formMessageBody($object, $language_id, $object->GetDBField('MessageType'));
// 2. replace tags if needed
$default_replacement_tags = Array (
'<inp:touser _Field="password"' => '<inp2:u_Field name="Password_plain"',
'<inp:touser _Field="UserName"' => '<inp2:u_Field name="Login"',
'<inp:touser _Field' => '<inp2:u_Field name',
);
$replacement_tags = $object->GetDBField('ReplacementTags');
$replacement_tags = $replacement_tags ? unserialize($replacement_tags) : Array ();
$replacement_tags = array_merge_recursive2($default_replacement_tags, $replacement_tags);
foreach ($replacement_tags as $replace_from => $replace_to) {
$message_body = str_replace($replace_from, $replace_to, $message_body);
}
return $message_body;
}
/**
* Prepare email message body
*
* @param kDBItem $object
* @param int $language_id
* @return string
*/
function _formMessageBody(&$object, $language_id)
{
$default_language_id = $this->Application->GetDefaultLanguageId();
$fields_hash = Array (
'Headers' => $object->GetDBField('Headers'),
);
// prepare subject
$subject = $object->GetDBField('l' . $language_id . '_Subject');
if (!$subject) {
$subject = $object->GetDBField('l' . $default_language_id . '_Subject');
}
$fields_hash['Subject'] = $subject;
// prepare body
$body = $object->GetDBField('l' . $language_id . '_Body');
if (!$body) {
$body = $object->GetDBField('l' . $default_language_id . '_Body');
}
$fields_hash['Body'] = $body;
$email_message_helper =& $this->Application->recallObject('EmailMessageHelper');
/* @var $email_message_helper EmailMessageHelper */
$ret = $email_message_helper->buildTemplate($fields_hash);
// add footer
$footer = $this->_getFooter($language_id, $object->GetDBField('MessageType'));
if ($ret && $footer) {
$ret .= "\r\n" . $footer;
}
return $ret;
}
/**
* Returns email footer
*
* @param int $language_id
* @param string $message_type
* @return string
*/
function _getFooter($language_id, $message_type)
{
static $footer = null;
if (!isset($footer)) {
$default_language_id = $this->Application->GetDefaultLanguageId();
$sql = 'SELECT l' . $language_id . '_Body, l' . $default_language_id . '_Body
FROM ' . $this->Application->getUnitOption('emailevents', 'TableName') . ' em
WHERE Event = "COMMON.FOOTER"';
$footer_data = $this->Conn->GetRow($sql);
$footer = $footer_data['l' . $language_id . '_Body'];
if (!$footer) {
$footer = $footer_data['l' . $default_language_id . '_Body'];
}
if ($message_type == 'text') {
$esender =& $this->Application->recallObject('EmailSender');
/* @var $esender kEmailSendingHelper */
$footer = $esender->ConvertToText($footer);
}
}
return $footer;
}
/**
* Parse message template and return headers (as array) and message body part
*
* @param string $message
* @param Array $direct_params
* @return Array
*/
function ParseMessageBody($message, $direct_params = Array ())
{
$message_language = $this->_getSendLanguage($direct_params);
$this->_changeLanguage($message_language);
$direct_params['message_text'] = isset($direct_params['message']) ? $direct_params['message'] : ''; // parameter alias
// 1. parse template
$this->Application->InitParser();
$parser_params = $this->Application->Parser->Params; // backup parser params
$this->Application->Parser->SetParams( array_merge_recursive2($parser_params, $direct_params) );
$message = implode('&|&', explode("\n\n", $message, 2)); // preserves double \n in case when tag is located in subject field
$message = $this->Application->Parser->Parse($message, 'email_template', 0);
$this->Application->Parser->SetParams($parser_params); // restore parser params
// 2. replace line endings, that are send with data submitted via request
$message = str_replace("\r\n", "\n", $message); // possible case
$message = str_replace("\r", "\n", $message); // impossible case, but just in case replace this too
// 3. separate headers from body
$message_headers = Array ();
list($headers, $message_body) = explode('&|&', $message, 2);
$category_helper =& $this->Application->recallObject('CategoryHelper');
/* @var $category_helper CategoryHelper */
$message_body = $category_helper->replacePageIds($message_body);
$headers = explode("\n", $headers);
foreach ($headers as $header) {
$header = explode(':', $header, 2);
$message_headers[ trim($header[0]) ] = trim($header[1]);
}
$this->_changeLanguage();
return Array ($message_headers, $message_body);
}
/**
* Raised when email message shoul be sent
*
* @param kEvent $event
*/
function OnEmailEvent(&$event)
{
$email_event_name = $event->getEventParam('EmailEventName');
if (strpos($email_event_name, '_') !== false) {
trigger_error('<span class="debug_error">Invalid email event name</span> <b>'.$email_event_name.'</b>. Use only <b>UPPERCASE characters</b> and <b>dots</b> as email event names', E_USER_ERROR);
}
$object =& $this->_getEmailEvent($event);
if (!is_object($object)) {
// email event not found OR it's won't be send under given circumstances
return false;
}
// additional parameters from kApplication->EmailEvent
$send_params = $event->getEventParam('DirectSendParams');
// 1. get information about message sender and recipient
list ($from_email, $from_name) = $this->_processSender($event, $send_params);
list ($to_email, $to_name) = $this->_processRecipients($event, $send_params);
// 2. prepare message to be sent
$message_language = $this->_getSendLanguage($send_params);
$message_template = $this->_getMessageBody($event, $message_language);
if (!trim($message_template)) {
trigger_error('Message template is empty', E_USER_WARNING);
return false;
}
list ($message_headers, $message_body) = $this->ParseMessageBody($message_template, $send_params);
if (!trim($message_body)) {
trigger_error('Message template is empty after parsing', E_USER_WARNING);
return false;
}
// 3. set headers & send message
$esender =& $this->Application->recallObject('EmailSender');
/* @var $esender kEmailSendingHelper */
$message_subject = isset($message_headers['Subject']) ? $message_headers['Subject'] : 'Mail message';
$esender->SetSubject($message_subject);
if ($this->Application->isDebugMode()) {
// set special header with event name, so it will be easier to determite what's actually was received
$message_headers['X-Event-Name'] = $email_event_name . ' - ' . ($object->GetDBField('Type') == EVENT_TYPE_ADMIN ? 'ADMIN' : 'USER');
}
foreach ($message_headers as $header_name => $header_value) {
$esender->SetEncodedHeader($header_name, $header_value);
}
$esender->CreateTextHtmlPart($message_body, $object->GetDBField('MessageType') == 'html');
$event->status = $esender->Deliver() ? erSUCCESS : erFAIL;
if ($event->status == erSUCCESS) {
// all keys, that are not used in email sending are written to log record
$send_keys = Array ('from_email', 'from_name', 'to_email', 'to_name', 'message');
foreach ($send_keys as $send_key) {
unset($send_params[$send_key]);
}
$fields_hash = Array (
'fromuser' => $from_name.' ('.$from_email.')',
'addressto' => $to_name.' ('.$to_email.')',
'subject' => $message_subject,
'timestamp' => adodb_mktime(),
'event' => $email_event_name,
'EventParams' => serialize($send_params),
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'EmailLog');
}
}
function _getSendLanguage($send_params)
{
if (array_key_exists('language_id', $send_params)) {
return $send_params['language_id'];
}
return $this->Application->GetVar('m_lang');
}
function _changeLanguage($language_id = null)
{
static $prev_language_id = null;
if (!isset($language_id)) {
// restore language
$language_id = $prev_language_id;
}
$this->Application->SetVar('m_lang', $language_id);
$language =& $this->Application->recallObject('lang.current');
/* @var $lang_object kDBItem */
$language->Load($language_id);
$this->Application->Phrases->LanguageId = $language_id;
$this->Application->Phrases->Phrases = Array();
$prev_language_id = $language_id; // for restoring it later
}
/**
* Process emails from queue
*
* @param kEvent $event
* @todo Move to MailingList
*/
function OnProcessEmailQueue(&$event)
{
$deliver_count = $event->getEventParam('deliver_count');
if ($deliver_count === false) {
$deliver_count = $this->Application->ConfigValue('MailingListSendPerStep');
if ($deliver_count === false) {
$deliver_count = 10; // 10 emails per script run (if not specified directly)
}
}
$processing_type = $this->Application->GetVar('type');
if ($processing_type = 'return_progress') {
$email_queue_progress = $this->Application->RecallVar('email_queue_progress');
if ($email_queue_progress === false) {
$emails_sent = 0;
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'EmailQueue
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')';
$total_emails = $this->Conn->GetOne($sql);
$this->Application->StoreVar('email_queue_progress', $emails_sent.':'.$total_emails);
}
else {
list ($emails_sent, $total_emails) = explode(':', $email_queue_progress);
}
}
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'EmailQueue
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')
LIMIT 0,' . $deliver_count;
$messages = $this->Conn->Query($sql);
$message_count = count($messages);
if (!$message_count) {
// no messages left to send in queue
if ($processing_type = 'return_progress') {
$this->Application->RemoveVar('email_queue_progress');
$this->Application->Redirect($this->Application->GetVar('finish_template'));
}
return ;
}
$mailing_list_helper =& $this->Application->recallObject('MailingListHelper');
/* @var $mailing_list_helper MailingListHelper */
$mailing_list_helper->processQueue($messages);
if ($processing_type = 'return_progress') {
$emails_sent += $message_count;
if ($emails_sent >= $total_emails) {
$this->Application->RemoveVar('email_queue_progress');
$this->Application->Redirect($this->Application->GetVar('finish_template'));
}
$this->Application->StoreVar('email_queue_progress', $emails_sent.':'.$total_emails);
$event->status = erSTOP;
echo ($emails_sent / $total_emails) * 100;
}
}
/**
* Prefills module dropdown
*
* @param kEvent $event
*/
function OnAfterConfigRead(&$event)
{
parent::OnAfterConfigRead($event);
$options = Array ();
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
if ($module_name == 'In-Portal') {
continue;
}
$options[$module_name] = $module_name;
}
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$fields['Module']['options'] = $options;
$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
if ($this->Application->GetVar('regional')) {
$this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true);
}
}
/**
* Prepare temp tables and populate it
* with items selected in the grid
*
* @param kEvent $event
*/
function OnEdit(&$event)
{
parent::OnEdit($event);
// use language from grid, instead of primary language used by default
$event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang'));
}
/**
* Fixes default recipient type
*
* @param kEvent $event
*/
function OnAfterItemLoad(&$event)
{
parent::OnAfterItemLoad($event);
$object =& $event->getObject();
/* @var $object kDBItem */
if (!$this->Application->isDebugMode(false)) {
if ($object->GetDBField('AllowChangingRecipient')) {
$object->SetDBField('RecipientType', RECIPIENT_TYPE_TO);
}
else {
$object->SetDBField('RecipientType', RECIPIENT_TYPE_CC);
}
}
// process replacement tags
$records = Array ();
$replacement_tags = $object->GetDBField('ReplacementTags');
$replacement_tags = $replacement_tags ? unserialize($replacement_tags) : Array ();
foreach ($replacement_tags as $tag => $replacement) {
$records[] = Array ('Tag' => $tag, 'Replacement' => $replacement);
}
$minput_helper =& $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
$xml = $minput_helper->prepareMInputXML($records, Array ('Tag', 'Replacement'));
$object->SetDBField('ReplacementTagsXML', $xml);
}
/**
* Performs custom validation + keep read-only fields
*
* @param kEvent $event
*/
function _itemChanged(&$event)
{
$object =& $event->getObject();
/* @var $object kDBItem */
if ($object->GetDBField('CustomSender')) {
$this->_validateAddress($event, 'Sender');
}
$this->_validateAddress($event, 'Recipient');
if (!$this->Application->isDebugMode(false)) {
// only allow to enable/disable event while in debug mode
$to_restore = Array ('Enabled', 'AllowChangingSender', 'AllowChangingRecipient');
if (!$object->GetOriginalField('AllowChangingSender')) {
$to_restore = array_merge($to_restore, Array ('CustomSender', 'SenderName', 'SenderAddressType', 'SenderAddress'));
}
if (!$object->GetOriginalField('AllowChangingRecipient')) {
$to_restore = array_merge($to_restore, Array ('CustomRecipient'/*, 'Recipients'*/));
}
// prevent specific fields from editing
foreach ($to_restore as $restore_field) {
$original_value = $object->GetOriginalField($restore_field);
if ($object->GetDBField($restore_field) != $original_value) {
$object->SetDBField($restore_field, $original_value);
}
}
}
// process replacement tags
$minput_helper =& $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
$replacement_tags = Array ();
$records = $minput_helper->parseMInputXML( $object->GetDBField('ReplacementTagsXML') );
foreach ($records as $record) {
$replacement_tags[ trim($record['Tag']) ] = trim($record['Replacement']);
}
$object->SetDBField('ReplacementTags', $replacement_tags ? serialize($replacement_tags) : NULL);
}
/**
* Validates address using given field prefix
*
* @param kEvent $event
* @param string $field_prefix
*/
function _validateAddress(&$event, $field_prefix)
{
$object =& $event->getObject();
/* @var $object kDBItem */
$address_type = $object->GetDBField($field_prefix . 'AddressType');
$object->setRequired($field_prefix . 'Address', $address_type > 0);
$address = $object->GetDBField($field_prefix . 'Address');
if (!$address) {
// don't validate against empty address
return ;
}
switch ($address_type) {
case ADDRESS_TYPE_EMAIL:
if (!preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $address)) {
$object->SetError($field_prefix . 'Address', 'invalid_email');
}
break;
case ADDRESS_TYPE_USER:
$sql = 'SELECT PortalUserId
FROM ' . TABLE_PREFIX . 'PortalUser
WHERE Login = ' . $this->Conn->qstr($address);
if (!$this->Conn->GetOne($sql)) {
$object->SetError($field_prefix . 'Address', 'invalid_user');
}
break;
case ADDRESS_TYPE_GROUP:
$sql = 'SELECT GroupId
FROM ' . TABLE_PREFIX . 'PortalGroup
WHERE Name = ' . $this->Conn->qstr($address);
if (!$this->Conn->GetOne($sql)) {
$object->SetError($field_prefix . 'Address', 'invalid_group');
}
break;
}
}
/**
* Don't allow to enable/disable events in non-debug mode
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
parent::OnBeforeItemCreate($event);
$this->_itemChanged($event);
}
/**
* Don't allow to enable/disable events in non-debug mode
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
parent::OnBeforeItemUpdate($event);
$this->_itemChanged($event);
}
/**
* Suggest address based on typed address and selected address type
*
* @param kEvent $event
*/
function OnSuggestAddress(&$event)
{
$event->status = erSTOP;
$address_type = $this->Application->GetVar('type');
$address = $this->Application->GetVar('value');
$limit = $this->Application->GetVar('limit');
if (!$limit) {
$limit = 20;
}
switch ($address_type) {
case ADDRESS_TYPE_EMAIL:
$field = 'Email';
$table_name = TABLE_PREFIX . 'PortalUser';
break;
case ADDRESS_TYPE_USER:
$field = 'Login';
$table_name = TABLE_PREFIX . 'PortalUser';
break;
case ADDRESS_TYPE_GROUP:
$field = 'Name';
$table_name = TABLE_PREFIX . 'PortalGroup';
break;
}
if (isset($field)) {
$sql = 'SELECT DISTINCT ' . $field . '
FROM ' . $table_name . '
WHERE ' . $field . ' LIKE ' . $this->Conn->qstr($address . '%') . '
ORDER BY ' . $field . ' ASC
LIMIT 0,' . $limit;
$data = $this->Conn->GetCol($sql);
}
else {
$data = Array ();
}
$this->Application->XMLHeader();
echo '<suggestions>';
foreach ($data as $item) {
echo '<item>' . htmlspecialchars($item) . '</item>';
}
echo '</suggestions>';
}
}
\ No newline at end of file

Event Timeline