Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Fri, Feb 21, 12:16 PM

in-portal

Index: branches/RC/core/units/email_events/email_events_event_handler.php
===================================================================
--- branches/RC/core/units/email_events/email_events_event_handler.php (revision 10605)
+++ branches/RC/core/units/email_events/email_events_event_handler.php (revision 10606)
@@ -1,468 +1,468 @@
<?php
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'),
);
$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');
$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);
return parent::CheckPermission($event);
}
/**
* 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', '%1$s.Module = '.$this->Conn->qstr($module));
}
}
/**
* Sets status Front-End Only to selected email events
*
* @param kEvent $event
*/
function OnFrontOnly(&$event)
{
$ids = implode(',', $this->StoreSelectedIDs($event));
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'UPDATE '.$table_name.'
SET Enabled = 2
WHERE EventId IN ('.$ids.')';
$this->Conn->Query($sql);
}
/**
* Sets selected user to email events selected
*
* @param kEvent $event
*/
function OnSelectUser(&$event)
{
$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 sender & recipients ids plus event_id (as parameter by reference)
*
* @param kEvent $event
* @param int $event_id id of email event used
*
* @return mixed
*/
function GetMessageRecipients(&$event, &$event_id)
{
$email_event =& $event->getObject( Array('skip_autoload' => true) );
/* @var $email_event kDBItem */
// get event parameters by name & type
$load_keys = Array (
'Event' => $event->getEventParam('EmailEventName'),
'Type' => $event->getEventParam('EmailEventType'),
);
$email_event->Load($load_keys);
if (!$email_event->isLoaded()) {
// event record not found
return false;
}
$enabled = $email_event->GetDBField('Enabled');
if ($enabled == EVENT_STATUS_DISABLED) {
return false;
}
if ($enabled == EVENT_STATUS_FRONTEND && $this->Application->IsAdmin()) {
return false;
}
// initial values
$to_user_id = $event->getEventParam('EmailEventToUserId');
$from_user_id = $email_event->GetDBField('FromUserId');
if ($email_event->GetDBField('Type') == EVENT_TYPE_ADMIN) {
// For type "Admin" recipient is a user from field FromUserId which means From/To user in Email events list
$to_user_id = $from_user_id;
$from_user_id = -1;
}
$event_id = $email_event->GetDBField('EventId');
return Array ($from_user_id, $to_user_id);
}
/**
* Returns user name, email by id, or ones, that specified in $direct_params
*
* @param int $user_id
* @param string $user_type type of user = {to,from}
* @param Array $direct_params
* @return Array
*/
function GetRecipientInfo($user_id, $user_type, $direct_params = null)
{
// load user, because it can be addressed from email template tags
$user =& $this->Application->recallObject('u.email-'.$user_type, null, Array('skip_autoload' => true));
/* @var $user UsersItem */
$email = $name = '';
$result = $user_id > 0 ? $user->Load($user_id) : $user->Clear();
if ($user->IsLoaded()) {
$email = $user->GetDBField('Email');
$name = trim($user->GetDBField('FirstName').' '.$user->GetDBField('LastName'));
}
if (is_array($direct_params)) {
if (isset($direct_params[$user_type.'_email'])) {
$email = $direct_params[$user_type.'_email'];
}
if (isset($direct_params[$user_type.'_name'])) {
$name = $direct_params[$user_type.'_name'];
}
}
if (!$email) {
// if email is empty, then use admins email
$email = $this->Application->ConfigValue('Smtp_AdminMailFrom');
}
if (!$name) {
$name = $user_type == 'from' ? strip_tags($this->Application->ConfigValue('Site_Name')) : $email;
}
return Array ($email, $name);
}
/**
* Returns email event message by ID (headers & body in one piece)
*
* @param int $event_id
* @param string $message_type contains message type = {text,html}
*/
function GetMessageBody($event_id, &$message_type)
{
$current_language = $this->Application->GetVar('m_lang');
$message =& $this->Application->recallObject('emailmessages', null, Array('skip_autoload' => true));
/* @var $message kDBItem */
$message->Load( Array('EventId' => $event_id, 'LanguageId' => $current_language) );
if (!$message->isLoaded()) {
// event translation on required language not found
return false;
}
$message_type = $message->GetDBField('MessageType');
// 1. get message body
$message_body = $message->GetDBField('Template');
// 2. add footer
$sql = 'SELECT em.Template
FROM '.$message->TableName.' em
LEFT JOIN '.TABLE_PREFIX.'Events e ON e.EventId = em.EventId
WHERE em.LanguageId = '.$current_language.' AND e.Event = "COMMON.FOOTER"';
list (, $footer) = explode("\n\n", $this->Conn->GetOne($sql));
if ($message_type == 'text') {
$esender =& $this->Application->recallObject('EmailSender');
/* @var $esender kEmailSendingHelper */
$footer = $esender->ConvertToText($footer);
}
if ($footer) {
$message_body .= "\r\n".$footer;
}
// 3. 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 = $message->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;
}
/**
* 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 = null)
{
$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->Params = array_merge_recursive2($this->Application->Parser->Params, $direct_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->Params = $parser_params; // restore parser params
+ $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);
$headers = explode("\n", $headers);
foreach ($headers as $header) {
$header = explode(':', $header, 2);
$message_headers[ trim($header[0]) ] = trim($header[1]);
}
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);
}
// additional parameters from kApplication->EmailEvent
$send_params = $event->getEventParam('DirectSendParams');
// 1. get information about message sender and recipient
$recipients = $this->GetMessageRecipients($event, $event_id);
if ($recipients === false) {
// if not valid recipients found, then don't send event
return false;
}
list ($from_id, $to_id) = $recipients;
list ($from_email, $from_name) = $this->GetRecipientInfo($from_id, 'from', $send_params);
list ($to_email, $to_name) = $this->GetRecipientInfo($to_id, 'to', $send_params);
// 2. prepare message to be sent
$message_template = $this->GetMessageBody($event_id, $message_type);
if (!trim($message_template)) {
return false;
}
list ($message_headers, $message_body) = $this->ParseMessageBody($message_template, $send_params);
if (!trim($message_body)) {
return false;
}
// 3. set headers & send message
$esender =& $this->Application->recallObject('EmailSender');
/* @var $esender kEmailSendingHelper */
$esender->SetFrom($from_email, $from_name);
$esender->AddTo($to_email, $to_name);
$message_subject = isset($message_headers['Subject']) ? $message_headers['Subject'] : 'Mail message';
$esender->SetSubject($message_subject);
foreach ($message_headers as $header_name => $header_value) {
$esender->SetEncodedHeader($header_name, $header_value);
}
$esender->CreateTextHtmlPart($message_body, $message_type == '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');
}
$this->Application->removeObject('u.email-from');
$this->Application->removeObject('u.email-to');
}
/**
* Process emails from queue
*
* @param kEvent $event
*/
function OnProcessEmailQueue(&$event)
{
$deliver_count = $event->getEventParam('deliver_count');
if ($deliver_count === false) {
$deliver_count = $this->Application->ConfigValue('Smtp_ProcessEmailsPerStep');
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 < '.(adodb_mktime() - 7200).')';
$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 < '.(adodb_mktime() - 7200).')
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 ;
}
$esender =& $this->Application->recallObject('EmailSender');
/* @var $esender kEmailSendingHelper */
$i = 0;
$message = Array ();
while ($i < $message_count) {
$message[0] = unserialize($messages[$i]['MessageHeaders']);
$message[1] =& $messages[$i]['MessageBody'];
$delivered = $esender->Deliver($message, true); // immediate send!
if ($delivered) {
// send succseeded, delete from queue
$sql = 'DELETE FROM '.TABLE_PREFIX.'EmailQueue
WHERE EmailQueueId = '.$messages[$i]['EmailQueueId'];
$this->Conn->Query($sql);
}
else {
// send failed, increment retries counter
$sql = 'UPDATE '.TABLE_PREFIX.'EmailQueue
SET SendRetries = SendRetries + 1, LastSendRetry = '.adodb_mktime().'
WHERE EmailQueueId = '.$messages[$i]['EmailQueueId'];
$this->Conn->Query($sql);
}
$i++;
}
$wait_time = $this->Application->ConfigValue('Smtp_StepWaitTime');
if ($wait_time !== false) {
sleep((int)$wait_time);
}
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;
}
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/email_events/email_events_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.34.2.2
\ No newline at end of property
+1.34.2.3
\ No newline at end of property

Event Timeline