blob: 60c1617dbb25c554159238cd5fbed92d0eb0c570 [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 /**
16 * @var mixed
17 */
18 private $resource;
19
20 /**
21 * @var null|MailboxInterface
22 */
23 private $mailbox;
24
25 /**
26 * @var null|string
27 */
28 private static $lastMailboxUsedCache;
29
30 /**
31 * Constructor.
32 *
33 * @param resource $resource
34 */
35 public function __construct($resource, MailboxInterface $mailbox = null)
36 {
37 $this->resource = $resource;
38 $this->mailbox = $mailbox;
39 }
40
41 /**
42 * Get IMAP resource stream.
43 *
44 * @throws InvalidResourceException
45 *
46 * @return resource
47 */
48 public function getStream()
49 {
50 if (false === \is_resource($this->resource) || 'imap' !== \get_resource_type($this->resource)) {
51 throw new InvalidResourceException('Supplied resource is not a valid imap resource');
52 }
53
54 $this->initMailbox();
55
56 return $this->resource;
57 }
58
59 /**
60 * Clear last mailbox used cache.
61 */
62 public function clearLastMailboxUsedCache(): void
63 {
64 self::$lastMailboxUsedCache = null;
65 }
66
67 /**
68 * If connection is not currently in this mailbox, switch it to this mailbox.
69 */
70 private function initMailbox(): void
71 {
72 if (null === $this->mailbox || self::isMailboxOpen($this->mailbox, $this->resource)) {
73 return;
74 }
75
76 \imap_reopen($this->resource, $this->mailbox->getFullEncodedName());
77
78 if (self::isMailboxOpen($this->mailbox, $this->resource)) {
79 return;
80 }
81
82 throw new ReopenMailboxException(\sprintf('Cannot reopen mailbox "%s"', $this->mailbox->getName()));
83 }
84
85 /**
86 * Check whether the current mailbox is open.
87 *
88 * @param mixed $resource
89 */
90 private static function isMailboxOpen(MailboxInterface $mailbox, $resource): bool
91 {
92 $currentMailboxName = $mailbox->getFullEncodedName();
93 if ($currentMailboxName === self::$lastMailboxUsedCache) {
94 return true;
95 }
96
97 self::$lastMailboxUsedCache = null;
98 $check = \imap_check($resource);
99 $return = false !== $check && $check->Mailbox === $currentMailboxName;
100
101 if (true === $return) {
102 self::$lastMailboxUsedCache = $currentMailboxName;
103 }
104
105 return $return;
106 }
107}