imap_client.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <?php
  2. class ImapClient {
  3. /*PhpImap\Mailbox */
  4. private $mailbox;
  5. public function __construct($imapPath, $login, $password) {
  6. $this->mailbox = new PhpImap\Mailbox($imapPath, $login, $password);
  7. }
  8. /**
  9. * returns all mails for the given $user.
  10. * @param $user User
  11. * @return array
  12. */
  13. public function get_emails(User $user): array {
  14. // Search for mails with the recipient $address in TO or CC.
  15. $mailsIdsTo = imap_sort($this->mailbox->getImapStream(), SORTARRIVAL, true, SE_UID, 'TO "' . $user->address . '"');
  16. $mailsIdsCc = imap_sort($this->mailbox->getImapStream(), SORTARRIVAL, true, SE_UID, 'CC "' . $user->address . '"');
  17. $mail_ids = array_merge($mailsIdsTo, $mailsIdsCc);
  18. $emails = $this->_load_emails($mail_ids, $user);
  19. return $emails;
  20. }
  21. /**
  22. * deletes emails by id and username. The address must match the recipient in the email.
  23. *
  24. * @param $mailid integer imap email id
  25. * @param $user User
  26. * @internal param the $username matching username
  27. * @return true if success
  28. */
  29. public function delete_email(string $mailid, User $user): bool {
  30. if ($this->load_one_email($mailid, $user) !== null) {
  31. $this->mailbox->deleteMail($mailid);
  32. $this->mailbox->expungeDeletedMails();
  33. return true;
  34. } else {
  35. return false;
  36. }
  37. }
  38. /**
  39. * Load exactly one email, the $address in TO or CC has to match.
  40. */
  41. public function load_one_email(int $mailid, User $user): ?\PhpImap\IncomingMail {
  42. // in order to avoid https://www.owasp.org/index.php/Top_10_2013-A4-Insecure_Direct_Object_References
  43. // the recipient in the email has to match the $address.
  44. @$emails = $this->_load_emails(array($mailid), $user);
  45. return count($emails) === 1 ? $emails[0] : null;
  46. }
  47. public function load_one_email_fully($download_email_id, $user): ?string {
  48. if ($this->load_one_email($download_email_id, $user) !== null) {
  49. $headers = imap_fetchheader($this->mailbox->getImapStream(), $download_email_id, FT_UID);
  50. $body = imap_body($this->mailbox->getImapStream(), $download_email_id, FT_UID);
  51. return $headers . "\n" . $body;
  52. } else {
  53. return null;
  54. }
  55. }
  56. /**
  57. * Load emails using the $mail_ids, the mails have to match the $address in TO or CC.
  58. * @param $mail_ids array of integer ids
  59. * @param $user User
  60. * @return array of emails
  61. */
  62. private function _load_emails(array $mail_ids, User $user) {
  63. $emails = array();
  64. foreach ($mail_ids as $id) {
  65. $mail = $this->mailbox->getMail($id);
  66. // imap_search also returns partials matches. The mails have to be filtered again:
  67. if (array_key_exists($user->address, $mail->to) || array_key_exists($user->address, $mail->cc)) {
  68. $emails[] = $mail;
  69. }
  70. }
  71. return $emails;
  72. }
  73. /**
  74. * deletes messages older than X days.
  75. */
  76. public function delete_old_messages(string $delete_messages_older_than) {
  77. $ids = $this->mailbox->searchMailbox('BEFORE ' . date('d-M-Y', strtotime($delete_messages_older_than)));
  78. foreach ($ids as $id) {
  79. $this->mailbox->deleteMail($id);
  80. }
  81. $this->mailbox->expungeDeletedMails();
  82. }
  83. }