Array ('self' => 'edit'), 'OnGenerateEmailQueue' => Array ('self' => true), 'OnGetHtmlBody' => Array ('self' => 'edit'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Prepare recipient list * * @param kEvent $event * @return void * @access protected */ protected function OnNew(kEvent $event) { parent::OnNew($event); $recipient_type = $this->Application->GetVar('mailing_recipient_type'); if ( !$recipient_type ) { return; } $recipients = $this->Application->GetVar($recipient_type); if ( $recipients ) { /** @var kDBItem $object */ $object = $event->getObject(); $to = $recipient_type . '_' . implode(';' . $recipient_type . '_', array_keys($recipients)); $object->SetDBField('To', $to); } $this->setRequired($event); } /** * Prepare recipient list * * @param kEvent $event * @return void * @access protected */ protected function OnPreCreate(kEvent $event) { parent::OnPreCreate($event); $this->setRequired($event); } /** * Don't allow to delete mailings in progress * * @param kEvent $event * @param string $type * @return void * @access protected */ protected function customProcessing(kEvent $event, $type) { if ( $event->Name == 'OnMassDelete' && $type == 'before' ) { $ids = $event->getEventParam('ids'); if ( $ids ) { $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); $sql = 'SELECT ' . $id_field . ' FROM ' . $table_name . ' WHERE ' . $id_field . ' IN (' . implode(',', $ids) . ') AND Status <> ' . MailingList::PARTIALLY_PROCESSED; $allowed_ids = $this->Conn->GetCol($sql); $event->setEventParam('ids', $allowed_ids); } } } /** * Delete all related mails in email queue * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemDelete(kEvent $event) { parent::OnAfterItemDelete($event); $this->_deleteQueue($event); /** @var kDBItem $object */ $object = $event->getObject(); // delete mailing attachments after mailing is deleted $attachments = $object->GetField('Attachments', 'file_paths'); if ( $attachments ) { $attachments = explode('|', $attachments); foreach ($attachments as $attachment_file) { if ( file_exists($attachment_file) ) { unlink($attachment_file); } } } } /** * Cancels given mailing and deletes all it's email queue * * @param kEvent $event */ function OnCancelMailing($event) { /** @var kDBItem $object */ $object = $event->getObject( Array('skip_autoload' => true) ); $ids = $this->StoreSelectedIDs($event); if ($ids) { foreach ($ids as $id) { $object->Load($id); $object->SetDBField('Status', MailingList::CANCELLED); $object->Update(); } } $this->clearSelectedIDs($event); } /** * Checks, that at least one message text field is filled * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); /** @var kDBItem $object */ $object = $event->getObject(); if ( !$this->Application->GetVar('mailing_recipient_type') ) { // user manually typed email addresses -> normalize $recipients = str_replace(',', ';', $object->GetDBField('To')); $recipients = array_map('trim', explode(';', $recipients)); $object->SetDBField('To', implode(';', $recipients)); } // remember user, who created mailing, because of his name // is needed for "From" field, but mailing occurs from cron $user_id = $this->Application->RecallVar('user_id'); $object->SetDBField('PortalUserId', $user_id); $this->setRequired($event); } /** * Checks, that at least one message text field is filled * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); $this->setRequired($event); } /** * Dynamically changes required fields * * @param kEvent $event * @return void * @access protected */ protected function setRequired(kEvent $event) { /** @var kDBItem $object */ $object = $event->getObject(); $object->setRequired('MessageHtml', !$object->GetDBField('MessageText')); $object->setRequired('MessageText', !$object->GetDBField('MessageHtml')); } /** * Deletes mailing list email queue, when it becomes cancelled * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemUpdate(kEvent $event) { parent::OnAfterItemUpdate($event); /** @var kDBItem $object */ $object = $event->getObject(); $status = $object->GetDBField('Status'); if ( ($status != $object->GetOriginalField('Status')) && ($status == MailingList::CANCELLED) ) { $this->_deleteQueue($event); } } /** * Deletes email queue records related with given mailing list * * @param kEvent $event */ function _deleteQueue($event) { /** @var kDBItem $object */ $object = $event->getObject(); $sql = 'DELETE FROM ' . $this->Application->getUnitOption('email-queue', 'TableName') . ' WHERE MailingId = ' . $object->GetID(); $this->Conn->Query($sql); } /** * Generates email queue for active mailing lists * * @param kEvent $event */ function OnGenerateEmailQueue($event) { $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); $where_clause = Array ( 'Status NOT IN (' . MailingList::CANCELLED . ',' . MailingList::PROCESSED . ')', '(EmailsQueuedTotal < EmailsTotal) OR (EmailsTotal = 0)', '`To` <> ""', ); $sql = 'SELECT * FROM ' . $table_name . ' WHERE (' . implode(') AND (', $where_clause) . ') ORDER BY ' . $id_field . ' ASC'; $mailing_lists = $this->Conn->Query($sql, $id_field); if ( !$mailing_lists ) { return; } /** @var MailingListHelper $mailing_list_helper */ $mailing_list_helper = $this->Application->recallObject('MailingListHelper'); $to_queue = $mailing_list_helper->getSetting('MailingListQueuePerStep'); if ( !is_numeric($to_queue) ) { return; } foreach ($mailing_lists as $mailing_id => $mailing_data) { if ( $mailing_data['EmailsTotal'] == 0 ) { // no work performed on this mailing list -> calculate totals $updated_fields = $mailing_list_helper->generateRecipients($mailing_id, $mailing_data); $updated_fields['Status'] = MailingList::PARTIALLY_PROCESSED; $mailing_data = array_merge($mailing_data, $updated_fields); $this->Conn->doUpdate($updated_fields, $table_name, $id_field . ' = ' . $mailing_id); } $emails = unserialize($mailing_data['ToParsed']); if ( !$emails ) { continue; } // queue allowed count of emails $i = 0; $process_count = count($emails) >= $to_queue ? $to_queue : count($emails); while ($i < $process_count) { $mailing_list_helper->queueEmail($emails[$i], $mailing_id, $mailing_data); $i++; } // remove processed emails from array $to_queue -= $process_count; // decrement available for processing email count array_splice($emails, 0, $process_count); $updated_fields = Array ( 'ToParsed' => serialize($emails), 'EmailsQueuedTotal' => $mailing_data['EmailsQueuedTotal'] + $process_count, ); $this->Conn->doUpdate($updated_fields, $table_name, $id_field . ' = ' . $mailing_id); if ( !$to_queue ) { // emails to be queued per step reached -> leave break; } } } /** * Returns HTML of sent e-mail for iframe * * @param kEvent $event * @return void * @access protected */ protected function OnGetHtmlBody(kEvent $event) { $event->status = kEvent::erSTOP; /** @var kDBItem $object */ $object = $event->getObject(); echo $object->GetDBField('MessageHtml'); } }