setEventParam('raise_warnings', 0); $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.')'; return (int)$this->Conn->GetOne($sql); } 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) { $object =& $event->getObject(); /* @var $object kDBList */ if ($event->Special == 'module') { $module = $this->Application->GetVar('module'); $object->addFilter('module_filter', 'Module = ' . $this->Conn->qstr($module)); } if ($event->Special == 'st') { $object->addFilter('enabled_filter', TABLE_PREFIX . 'Events.Enabled <> ' . STATUS_DISABLED); } } /** * If loading empty item, then set parent id * * @param kEvent $event */ function OnBeforeItemLoad(&$event) { if (!$event->getEventParam('id')) { $this->OnNew($event); $event->status = erFATAL; } } /** * Sets event id * * @param kEvent $event */ function OnNew(&$event) { parent::OnNew($event); $object =& $event->getObject(); /* @var $object kDBItem */ $object->SetDBField('EventId', $this->getEmailEventId()); $object->SetDBField('Headers', $this->Application->ConfigValue('Smtp_DefaultHeaders') ); } /** * 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 ; } $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']; } $this->Application->RemoveVar('email_prepare_progress'); $this->Application->StoreVar('email_prepare_fields', serialize($fields_hash)); $event->redirect = 'emails/prepare_queue'; } /** * Generates email queue using progress bar * * @param kEvent $event * @todo Move to MailingList */ function OnPrepareEmailQueue(&$event) { $prepare_count = $this->Application->ConfigValue('MailingListQueuePerStep'); if ($prepare_count === false) { // 10 recipients per script run (if none defined in config) $prepare_count = 10; } $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 { list ($emails_prepared, $total_emails) = explode(':', $email_prepare_progress); } $recipient_emails = $this->getRecipientEmails(false, $emails_prepared.','.$prepare_count); $recipient_email_count = count($recipient_emails); if (!$recipient_email_count) { // no recipients left to prepare $this->finalizeQueuePreparing($fields_hash['MassAttachment']); } $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']); // 2. add attachment if any if ($fields_hash['MassAttachment']) { $esender->AddAttachment(FULL_PATH.$fields_hash['MassAttachment']); } foreach ($recipient_emails as $recipient_email) { // 3. set recipient specific fields $esender->SetTo($recipient_email, $recipient_email); $esender->Deliver(null, false, false); // 4. write to log $log_fields_hash = Array ( 'fromuser' => $fields_hash['FromName'], 'addressto' => $recipient_email, 'subject' => $fields_hash['MassSubject'], 'timestamp' => adodb_mktime(), 'event' => '', ); $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); } } ?>