/** * 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; }
/** * @depends testResolveEmailSenderFromForwardedEmailMessage */ public function testResolveEmailSenderFromEmailMessage() { Yii::app()->imap->imapUsername = '******'; $imapMessage = new ImapMessage(); $imapMessage->subject = "Test subject"; $imapMessage->fromEmail = "*****@*****.**"; $imapMessage->cc[0]['email'] = '*****@*****.**'; $from = EmailArchivingUtil::resolveEmailSenderFromEmailMessage($imapMessage); $this->assertEquals($imapMessage->fromEmail, $from['email']); $imapMessage = new ImapMessage(); $imapMessage->fromEmail = "*****@*****.**"; $imapMessage->to[0]['email'] = '*****@*****.**'; // Outlook, Yahoo, Outlook express format $imapMessage->textBody = "\nFrom: John Smith [mailto:john@example.com]\nSent: 02 March 2012 AM 01:23\nTo: 'Steve Tytler' <*****@*****.**>, Peter Smith <*****@*****.**>\nCc: Peter Smith <*****@*****.**>\nSubject: Hello Steve"; $imapMessage->subject = "FW: Test subject"; $from = EmailArchivingUtil::resolveEmailSenderFromEmailMessage($imapMessage); $this->assertEquals('*****@*****.**', $from['email']); $this->assertEquals('John Smith', $from['name']); //Google, Thunderbird format $imapMessage->textBody = "\nFrom: John Smith <*****@*****.**>\nDate: Thu, Apr 19, 2012 at 5:22 PM\nSubject: Hello Steve\nTo: 'Steve Tytler' <*****@*****.**>, Peter Smith <*****@*****.**>\nCc: 'John Wein' <*****@*****.**>, Peter Smith <*****@*****.**>"; $from = EmailArchivingUtil::resolveEmailSenderFromEmailMessage($imapMessage); $this->assertEquals('*****@*****.**', $from['email']); $this->assertEquals('John Smith', $from['name']); $imapMessage = new ImapMessage(); $imapMessage->subject = "Fwd: Test subject"; $imapMessage->to[0]['email'] = '*****@*****.**'; // Begin Not Coding Standard $imapMessage->htmlBody = "\n\n -------- Original Message --------\n Subject: Test\n Date: Mon, 28 May 2012 15:43:39 +0200\n From: John Smith <*****@*****.**>\n To: 'Steve'\n "; // End Not Coding Standard $from = EmailArchivingUtil::resolveEmailSenderFromEmailMessage($imapMessage); $this->assertEquals('*****@*****.**', $from['email']); $this->assertEquals('John Smith', $from['name']); $imapMessage = new ImapMessage(); $imapMessage->to[0]['email'] = '*****@*****.**'; $imapMessage->subject = "Fwd: Test subject"; // Begin Not Coding Standard $imapMessage->textBody = "\n-------- Original Message --------\nSubject: Test\nDate: Mon, 28 May 2012 15:43:39 +0200\nFrom: John Smith <*****@*****.**>\nTo: 'Steve Tytler' <*****@*****.**>, Peter Smith <*****@*****.**>\nCc: 'John Wein' <*****@*****.**>, Peter Smith <*****@*****.**>\n"; // End Not Coding Standard $from = EmailArchivingUtil::resolveEmailSenderFromEmailMessage($imapMessage); $this->assertEquals('*****@*****.**', $from['email']); $this->assertEquals('John Smith', $from['name']); }