/** * Saves emails into the database * * @param Email[] $emails * @param ImapEmailFolder $imapFolder */ protected function saveEmails(array $emails, ImapEmailFolder $imapFolder) { $this->emailEntityBuilder->removeEmails(); $folder = $imapFolder->getFolder(); $existingUids = $this->getExistingUids($folder, $emails); $isMultiFolder = $this->manager->hasCapability(Imap::CAPABILITY_MSG_MULTI_FOLDERS); $messageIds = $this->getMessageIds($emails); $existingImapEmails = $this->getExistingImapEmails($folder->getOrigin(), $messageIds); $existingEmailUsers = $this->getExistingEmailUsers($folder, $messageIds); /** @var ImapEmail[] $newImapEmails */ $newImapEmails = []; foreach ($emails as $email) { if (!$this->checkOnOldEmailForMailbox($folder, $email, $folder->getOrigin()->getMailbox())) { continue; } if (!$this->checkOnExistsSavedEmail($email, $existingUids)) { continue; } /** @var ImapEmail[] $relatedExistingImapEmails */ $relatedExistingImapEmails = array_filter($existingImapEmails, function (ImapEmail $imapEmail) use($email) { return $imapEmail->getEmail()->getMessageId() === $email->getMessageId(); }); $existingImapEmail = $this->findExistingImapEmail($relatedExistingImapEmails, $folder->getType()); if ($this->isMovableToOtherFolder($existingImapEmail, $isMultiFolder, $email)) { $this->moveEmailToOtherFolder($existingImapEmail, $imapFolder, $email->getId()->getUid()); } else { try { if (!isset($existingEmailUsers[$email->getMessageId()])) { $emailUser = $this->addEmailUser($email, $folder, $email->hasFlag("\\Seen"), $this->currentUser, $this->currentOrganization); } else { $emailUser = $existingEmailUsers[$email->getMessageId()]; $emailUser->addFolder($folder); } $imapEmail = $this->createImapEmail($email->getId()->getUid(), $emailUser->getEmail(), $imapFolder); $newImapEmails[] = $imapEmail; $this->em->persist($imapEmail); $this->logger->notice(sprintf('The "%s" (UID: %d) email was persisted.', $email->getSubject(), $email->getId()->getUid())); } catch (\Exception $e) { $this->logger->warning(sprintf('Failed to persist "%s" (UID: %d) email. Error: %s', $email->getSubject(), $email->getId()->getUid(), $e->getMessage())); } } $this->removeEmailFromOutdatedFolders($relatedExistingImapEmails); } $this->emailEntityBuilder->getBatch()->persist($this->em); // update references if needed $changes = $this->emailEntityBuilder->getBatch()->getChanges(); foreach ($newImapEmails as $imapEmail) { foreach ($changes as $change) { if ($change['old'] instanceof EmailEntity && $imapEmail->getEmail() === $change['old']) { $imapEmail->setEmail($change['new']); } } } $this->em->flush(); $this->cleanUp(); }
/** * Saves emails into the database * * @param Email[] $emails * @param ImapEmailFolder $imapFolder */ protected function saveEmails(array $emails, ImapEmailFolder $imapFolder) { $this->emailEntityBuilder->removeEmails(); $folder = $imapFolder->getFolder(); $existingUids = $this->getExistingUids($folder, $emails); $isMultiFolder = $this->manager->hasCapability(Imap::CAPABILITY_MSG_MULTI_FOLDERS); $existingImapEmails = $this->getExistingImapEmails($folder->getOrigin(), $this->getNewMessageIds($emails, $existingUids), $isMultiFolder); /** @var ImapEmail[] $newImapEmails */ $newImapEmails = []; foreach ($emails as $email) { if (in_array($email->getId()->getUid(), $existingUids)) { $this->log->notice(sprintf('Skip "%s" (UID: %d) email, because it is already synchronised.', $email->getSubject(), $email->getId()->getUid())); continue; } /** @var ImapEmail[] $relatedExistingImapEmails */ $relatedExistingImapEmails = array_filter($existingImapEmails, function (ImapEmail $imapEmail) use($email) { return $imapEmail->getEmail()->getMessageId() === $email->getMessageId(); }); $existingImapEmail = $this->findExistingImapEmail($relatedExistingImapEmails, $folder->getType(), $isMultiFolder); if ($existingImapEmail) { $this->moveEmailToOtherFolder($existingImapEmail, $imapFolder, $email->getId()->getUid()); } else { $this->log->notice(sprintf('Persisting "%s" email (UID: %d) ...', $email->getSubject(), $email->getId()->getUid())); $imapEmail = $this->createImapEmail($email->getId()->getUid(), $this->addEmail($email, $folder), $imapFolder); $newImapEmails[] = $imapEmail; $this->em->persist($imapEmail); $this->log->notice(sprintf('The "%s" email was persisted.', $email->getSubject())); } $this->removeEmailFromOutdatedFolders($relatedExistingImapEmails); } $this->emailEntityBuilder->getBatch()->persist($this->em); // update references if needed $changes = $this->emailEntityBuilder->getBatch()->getChanges(); foreach ($newImapEmails as $imapEmail) { foreach ($changes as $change) { if ($change['old'] instanceof EmailEntity && $imapEmail->getEmail() === $change['old']) { $imapEmail->setEmail($change['new']); } } } $this->em->flush(); }