Index: trunk/core/units/email_events/email_events_event_handler.php =================================================================== diff -u -N --- trunk/core/units/email_events/email_events_event_handler.php (revision 8594) +++ trunk/core/units/email_events/email_events_event_handler.php (revision 0) @@ -1,467 +0,0 @@ - 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 ( - ' ' ' '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); - - $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 - - // 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('Invalid email event name '.$email_event_name.'. Use only UPPERCASE characters and dots 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 = 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++; - } - - 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