blob: 123ea2396dba06bbf3026cae6fe95449382f3ca6 [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001<?php
2
3declare(strict_types=1);
4
5namespace Ddeboer\Imap;
6
7use Ddeboer\Imap\Exception\InvalidResourceException;
8use Ddeboer\Imap\Exception\ReopenMailboxException;
9
10/**
11 * An imap resource stream.
12 */
13final class ImapResource implements ImapResourceInterface
14{
15 /**
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020016 * @var resource
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010017 */
18 private $resource;
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020019 private ?MailboxInterface $mailbox = null;
20 private static ?string $lastMailboxUsedCache = null;
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010021
22 /**
23 * Constructor.
24 *
25 * @param resource $resource
26 */
27 public function __construct($resource, MailboxInterface $mailbox = null)
28 {
29 $this->resource = $resource;
30 $this->mailbox = $mailbox;
31 }
32
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010033 public function getStream()
34 {
35 if (false === \is_resource($this->resource) || 'imap' !== \get_resource_type($this->resource)) {
36 throw new InvalidResourceException('Supplied resource is not a valid imap resource');
37 }
38
39 $this->initMailbox();
40
41 return $this->resource;
42 }
43
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010044 public function clearLastMailboxUsedCache(): void
45 {
46 self::$lastMailboxUsedCache = null;
47 }
48
49 /**
50 * If connection is not currently in this mailbox, switch it to this mailbox.
51 */
52 private function initMailbox(): void
53 {
54 if (null === $this->mailbox || self::isMailboxOpen($this->mailbox, $this->resource)) {
55 return;
56 }
57
58 \imap_reopen($this->resource, $this->mailbox->getFullEncodedName());
59
60 if (self::isMailboxOpen($this->mailbox, $this->resource)) {
61 return;
62 }
63
64 throw new ReopenMailboxException(\sprintf('Cannot reopen mailbox "%s"', $this->mailbox->getName()));
65 }
66
67 /**
68 * Check whether the current mailbox is open.
69 *
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020070 * @param resource $resource
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010071 */
72 private static function isMailboxOpen(MailboxInterface $mailbox, $resource): bool
73 {
74 $currentMailboxName = $mailbox->getFullEncodedName();
75 if ($currentMailboxName === self::$lastMailboxUsedCache) {
76 return true;
77 }
78
79 self::$lastMailboxUsedCache = null;
80 $check = \imap_check($resource);
81 $return = false !== $check && $check->Mailbox === $currentMailboxName;
82
83 if (true === $return) {
84 self::$lastMailboxUsedCache = $currentMailboxName;
85 }
86
87 return $return;
88 }
89}