/**
  * 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']);
 }