/** * Save email message * This method should be protected, but we made it public for unit testing, so don't call it outside this class. * @param ImapMessage $message * @throws NotSupportedException * @return boolean */ public function saveEmailMessage(ImapMessage $message) { // Get owner for message try { $emailOwner = EmailArchivingUtil::resolveOwnerOfEmailMessage($message); } catch (CException $e) { // User not found, so inform user about issue and continue with next email. $this->resolveMessageSubjectAndContentAndSendSystemMessage('OwnerNotExist', $message); return false; } $emailSenderOrRecipientEmailFoundInSystem = false; $userCanAccessContacts = RightsUtil::canUserAccessModule('ContactsModule', $emailOwner); $userCanAccessLeads = RightsUtil::canUserAccessModule('LeadsModule', $emailOwner); $userCanAccessAccounts = RightsUtil::canUserAccessModule('AccountsModule', $emailOwner); $senderInfo = EmailArchivingUtil::resolveEmailSenderFromEmailMessage($message); if (!$senderInfo) { $this->resolveMessageSubjectAndContentAndSendSystemMessage('SenderNotExtracted', $message); return false; } else { $sender = EmailArchivingUtil::createEmailMessageSender($senderInfo, $userCanAccessContacts, $userCanAccessLeads, $userCanAccessAccounts); if ($sender->personsOrAccounts->count() > 0) { $emailSenderOrRecipientEmailFoundInSystem = true; } } try { $recipientsInfo = EmailArchivingUtil::resolveEmailRecipientsFromEmailMessage($message); } catch (NotSupportedException $exception) { $this->resolveMessageSubjectAndContentAndSendSystemMessage('RecipientNotExtracted', $message); return false; } $emailMessage = new EmailMessage(); $emailMessage->owner = $emailOwner; $emailMessage->subject = $message->subject; $emailContent = new EmailMessageContent(); $emailContent->textContent = $message->textBody; $emailContent->htmlContent = $message->htmlBody; $emailMessage->content = $emailContent; $emailMessage->sender = $sender; $emailRecipientFoundInSystem = false; foreach ($recipientsInfo as $recipientInfo) { $recipient = EmailArchivingUtil::createEmailMessageRecipient($recipientInfo, $userCanAccessContacts, $userCanAccessLeads, $userCanAccessAccounts); $emailMessage->recipients->add($recipient); // Check if at least one recipient email can't be found in Contacts, Leads, Account and User emails // so we will save email message in EmailFolder::TYPE_ARCHIVED_UNMATCHED folder, and user will // be able to match emails with items(Contacts, Accounts...) emails in systems if ($recipient->personsOrAccounts->count() > 0) { $emailRecipientFoundInSystem = true; } } // Override $emailSenderOrRecipientEmailFoundInSystem only if there are no errors if ($emailSenderOrRecipientEmailFoundInSystem == true) { $emailSenderOrRecipientEmailFoundInSystem = $emailRecipientFoundInSystem; } if ($emailOwner instanceof User) { $box = EmailBoxUtil::getDefaultEmailBoxByUser($emailOwner); } else { $box = EmailBox::resolveAndGetByName(EmailBox::NOTIFICATIONS_NAME); } if (!$emailSenderOrRecipientEmailFoundInSystem) { $emailMessage->folder = EmailFolder::getByBoxAndType($box, EmailFolder::TYPE_ARCHIVED_UNMATCHED); $notificationMessage = new NotificationMessage(); $notificationMessage->textContent = Zurmo::t('EmailMessagesModule', 'At least one archived email message does ' . 'not match any records in the system. ' . 'To manually match them use this link: {url}.', array('{url}' => Yii::app()->createUrl('emailMessages/default/matchingList'))); $notificationMessage->htmlContent = Zurmo::t('EmailMessagesModule', 'At least one archived email message does ' . 'not match any records in the system. ' . '<a href="{url}" target="_blank">Click here</a> to manually match them.', array('{url}' => Yii::app()->createUrl('emailMessages/default/matchingList'))); if ($emailOwner instanceof User) { $rules = new EmailMessageArchivingEmailAddressNotMatchingNotificationRules(); $rules->addUser($emailOwner); NotificationsUtil::submit($notificationMessage, $rules); } } else { $emailMessage->folder = EmailFolder::getByBoxAndType($box, EmailFolder::TYPE_ARCHIVED); } if (!empty($message->attachments)) { foreach ($message->attachments as $attachment) { if (!$attachment['is_attachment']) { continue; } $file = EmailArchivingUtil::createEmailAttachment($attachment); if ($file instanceof FileModel) { $emailMessage->files->add($file); } } } $emailMessage->sentDateTime = DateTimeUtil::convertTimestampToDbFormatDateTime(time()); $validated = $emailMessage->validate(); if (!$validated) { // Email message couldn't be validated(some related models can't be validated). Email user. $this->resolveMessageSubjectAndContentAndSendSystemMessage('EmailMessageNotValidated', $message); return false; } EmailArchivingUtil::resolveSanitizeFromImapToUtf8($emailMessage); $saved = $emailMessage->save(); try { if (!$saved) { throw new NotSupportedException(); } if (isset($message->uid)) { $this->imapManager->deleteMessage($message->uid); $this->getMessageLogger()->addDebugMessage('Deleted Message id: ' . $message->uid); } } catch (NotSupportedException $e) { // Email message couldn't be saved. Email user. $this->resolveMessageSubjectAndContentAndSendSystemMessage('EmailMessageNotSaved', $message); return false; } return true; }
/** * Create new model * @param $data * @return ApiResult * @throws ApiException */ protected function processCreate($data) { try { $model = new EmailMessage(); $emailMessage = $this->getImapMessageFromEmailData($data); if (isset($data['sentFrom'])) { unset($data['sentFrom']); } if (isset($data['recipients'])) { unset($data['recipients']); } if (isset($data['attachments'])) { unset($data['attachments']); } if (isset($data['owner']['id'])) { try { $emailOwner = User::getById((int) $data['owner']['id']); } catch (CException $e) { $message = Zurmo::t('ZurmoModule', 'Owner not found.'); throw new ApiException($message); } } else { $emailOwner = Yii::app()->user->userModel; } $emailSenderOrRecipientEmailFoundInSystem = false; $userCanAccessContacts = RightsUtil::canUserAccessModule('ContactsModule', $emailOwner); $userCanAccessLeads = RightsUtil::canUserAccessModule('LeadsModule', $emailOwner); $userCanAccessAccounts = RightsUtil::canUserAccessModule('AccountsModule', $emailOwner); if (!empty($emailMessage->fromEmail)) { $senderInfo['email'] = $emailMessage->fromEmail; $senderInfo['name'] = $emailMessage->fromName; $sender = EmailArchivingUtil::createEmailMessageSender($senderInfo, $userCanAccessContacts, $userCanAccessLeads, $userCanAccessAccounts); if ($sender->personsOrAccounts->count() > 0) { $emailSenderOrRecipientEmailFoundInSystem = true; } } else { $message = Zurmo::t('ZurmoModule', 'Sender not found.'); throw new ApiException($message); } try { $recipientsInfo = EmailArchivingUtil::resolveEmailRecipientsFromEmailMessage($emailMessage); } catch (NotSupportedException $exception) { $message = Zurmo::t('ZurmoModule', 'No recipients found.'); throw new ApiException($message); } $emailRecipientFoundInSystem = false; foreach ($recipientsInfo as $recipientInfo) { $recipient = EmailArchivingUtil::createEmailMessageRecipient($recipientInfo, $userCanAccessContacts, $userCanAccessLeads, $userCanAccessAccounts); $model->recipients->add($recipient); // Check if at least one recipient email can't be found in Contacts, Leads, Account and User emails // so we will save email message in EmailFolder::TYPE_ARCHIVED_UNMATCHED folder, and user will // be able to match emails with items(Contacts, Accounts...) emails in systems if ($recipient->personsOrAccounts->count() > 0) { $emailRecipientFoundInSystem = true; } } if ($emailSenderOrRecipientEmailFoundInSystem == true) { $emailSenderOrRecipientEmailFoundInSystem = $emailRecipientFoundInSystem; } if ($emailOwner instanceof User) { $box = EmailBoxUtil::getDefaultEmailBoxByUser($emailOwner); } else { $box = EmailBox::resolveAndGetByName(EmailBox::NOTIFICATIONS_NAME); } if (!$emailSenderOrRecipientEmailFoundInSystem) { $model->folder = EmailFolder::getByBoxAndType($box, EmailFolder::TYPE_ARCHIVED_UNMATCHED); $this->sendArchivedUnmatchedNotificationToEmailOwner($emailOwner); } else { $model->folder = EmailFolder::getByBoxAndType($box, EmailFolder::TYPE_ARCHIVED); } $model->sender = $sender; if (isset($data['textContent']) || isset($data['htmlContent'])) { $emailContent = new EmailMessageContent(); if (isset($data['textContent'])) { $emailContent->textContent = $data['textContent']; } else { $emailContent->textContent = ''; } if (isset($data['htmlContent'])) { $emailContent->htmlContent = $data['htmlContent']; } else { $emailContent->htmlContent = ''; } $model->content = $emailContent; unset($data['textContent']); unset($data['htmlContent']); } else { $message = Zurmo::t('ZurmoModule', 'No email content found.'); throw new ApiException($message); } if (!empty($emailMessage->attachments)) { foreach ($emailMessage->attachments as $attachment) { if (isset($attachment['filename']) && isset($attachment['attachment'])) { $file = EmailArchivingUtil::createEmailAttachment($attachment, true); if ($file instanceof FileModel) { $model->files->add($file); } } } } if (!isset($data['sentDateTime'])) { $model->sentDateTime = DateTimeUtil::convertTimestampToDbFormatDateTime(time()); } $this->setModelScenarioFromData($model, $data); $model = $this->attemptToSaveModelFromData($model, $data, null, false); $id = $model->id; $model->forget(); if (!count($model->getErrors())) { $data = array('id' => $id); $result = new ApiResult(ApiResponse::STATUS_SUCCESS, $data, null, null); } else { $errors = $model->getErrors(); $message = Zurmo::t('ZurmoModule', 'Model was not created.'); $result = new ApiResult(ApiResponse::STATUS_FAILURE, null, $message, $errors); } } catch (Exception $e) { $message = $e->getMessage(); throw new ApiException($message); } return $result; }
public function testCreateEmailMessageRecipient() { $user = UserTestHelper::createBasicUser('recipientTestUser'); Yii::app()->user->userModel = $user; $account = AccountTestHelper::createAccountByNameForOwner('RecipientAccount', $user); $account->primaryEmail->emailAddress = '*****@*****.**'; $this->assertTrue($account->save()); $contact = ContactTestHelper::createContactByNameForOwner('RecipientContact', $user); $contact->primaryEmail->emailAddress = '*****@*****.**'; $this->assertTrue($contact->save()); $recipientInfo = array('name' => 'Recipient Name', 'email' => '*****@*****.**', 'type' => EmailMessageRecipient::TYPE_CC); $emailMessageRecipient = EmailArchivingUtil::createEmailMessageRecipient($recipientInfo, true, true, true); $this->assertTrue($emailMessageRecipient instanceof EmailMessageRecipient); $this->assertEquals($emailMessageRecipient->toAddress, $recipientInfo['email']); $this->assertEquals($emailMessageRecipient->toName, $recipientInfo['name']); $this->assertEquals($emailMessageRecipient->type, $recipientInfo['type']); $this->assertTrue($emailMessageRecipient->personsOrAccounts[0]->isSame($contact)); $this->assertTrue($emailMessageRecipient->personsOrAccounts[1]->isSame($account)); $this->assertEquals($emailMessageRecipient->personsOrAccounts->count(), 2); // Test when user can't access Contacts $recipientInfo['type'] = EmailMessageRecipient::TYPE_TO; $emailMessageRecipient = EmailArchivingUtil::createEmailMessageRecipient($recipientInfo, false, true, true); $this->assertTrue($emailMessageRecipient instanceof EmailMessageRecipient); $this->assertEquals($emailMessageRecipient->toAddress, $recipientInfo['email']); $this->assertEquals($emailMessageRecipient->toName, $recipientInfo['name']); $this->assertEquals($emailMessageRecipient->type, $recipientInfo['type']); $this->assertEquals($emailMessageRecipient->personsOrAccounts->count(), 1); $this->assertTrue($emailMessageRecipient->personsOrAccounts[0]->isSame($account)); // Test when user can't access Contacts $recipientInfo['type'] = EmailMessageRecipient::TYPE_BCC; $emailMessageRecipient = EmailArchivingUtil::createEmailMessageRecipient($recipientInfo, false, true, false); $this->assertTrue($emailMessageRecipient instanceof EmailMessageRecipient); $this->assertEquals($emailMessageRecipient->toAddress, $recipientInfo['email']); $this->assertEquals($emailMessageRecipient->toName, $recipientInfo['name']); $this->assertEquals($emailMessageRecipient->type, $recipientInfo['type']); $this->assertEquals($emailMessageRecipient->personsOrAccounts->count(), 0); $recipientInfo = array('name' => 'Recipient Name', 'email' => '*****@*****.**', 'type' => EmailMessageRecipient::TYPE_CC); $emailMessageRecipient = EmailArchivingUtil::createEmailMessageRecipient($recipientInfo, true, true, true); $this->assertTrue($emailMessageRecipient instanceof EmailMessageRecipient); $this->assertEquals($emailMessageRecipient->toAddress, $recipientInfo['email']); $this->assertEquals($emailMessageRecipient->toName, $recipientInfo['name']); $this->assertEquals($emailMessageRecipient->type, $recipientInfo['type']); $this->assertEquals($emailMessageRecipient->personsOrAccounts->count(), 0); }