Passed
Push — master ( 95d545...35bca5 )
by Dmitry
04:09
created

EmailReceiveCheck::getPersistCollection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace TonicHealthCheck\Check\Email\Receive;
4
5
use DateTime;
6
use Doctrine\ORM\EntityManager;
7
use PhpImap\Mailbox;
8
use TonicHealthCheck\Check\Email\AbstractEmailCheck;
9
use TonicHealthCheck\Check\Email\Entity\EmailSendReceive;
10
use PhpImap\Exception as ImapException;
11
use TonicHealthCheck\Check\Email\Entity\EmailSendReceiveCollection;
12
use TonicHealthCheck\Check\Email\Persist\PersistCollectionInterface;
13
14
/**
15
 * Class EmailReceiveCheck
16
 * @package TonicHealthCheck\Check\Email\Send
17
 */
18
class EmailReceiveCheck extends AbstractEmailCheck
19
{
20
    const CHECK = 'email-receive-check';
21
    const RECEIVE_MAX_TIME = 300;
22
23
    /**
24
     * @var bool
25
     */
26
    private $firstFailSkip = true;
27
28
    /**
29
     * @var int
30
     */
31
    private $receiveMaxTime;
32
33
    /**
34
     * @var Mailbox;
35
     */
36
    private $mailbox;
37
38
39
    /**
40
     * @var PersistCollectionInterface
41
     */
42
    private $persistCollection;
43
44
    /**
45
     * @var EmailSendReceiveCollection
46
     */
47
    private $emailSendReceiveCollection;
48
49
    /**
50
     * @param string                     $checkNode
51
     * @param Mailbox                    $mailbox
52
     * @param PersistCollectionInterface $persistCollection
53
     * @param int                        $receiveMaxTime
54
     */
55 8
    public function __construct(
56
        $checkNode,
57
        Mailbox $mailbox,
58
        PersistCollectionInterface $persistCollection,
59
        $receiveMaxTime = self::RECEIVE_MAX_TIME
60
    ) {
61 8
        parent::__construct($checkNode);
62
63 8
        $this->setMailbox($mailbox);
64 8
        $this->setPersistCollection($persistCollection);
65 8
        $this->setReceiveMaxTime($receiveMaxTime);
66 8
    }
67
68
    /**
69
     * Check email can send and receive messages
70
     * @return bool|void
71
     * @throws EmailReceiveCheckException
72
     */
73 7
    public function check()
74
    {
75 7
        $this->setEmailSendReceiveColl($this->getPersistCollection()->load());
76
77
        /** @var EmailSendReceive $emailSendCheckI */
78 7
        foreach ($this->getEmailSendReceiveColl() as $emailSendCheckI) {
79 7
            $this->performReceive($emailSendCheckI);
80 4
        }
81 4
    }
82
83
    /**
84
     * @return Mailbox
85
     */
86 7
    public function getMailbox()
87
    {
88 7
        return $this->mailbox;
89
    }
90
91
    /**
92
     * @return PersistCollectionInterface
93
     */
94 7
    public function getPersistCollection()
95
    {
96 7
        return $this->persistCollection;
97
    }
98
99
    /**
100
     * @return int
101
     */
102 4
    public function getReceiveMaxTime()
103
    {
104 4
        return $this->receiveMaxTime;
105
    }
106
107
    /**
108
     * @return EmailSendReceiveCollection
109
     */
110 7
    public function getEmailSendReceiveColl()
111
    {
112 7
        return $this->emailSendReceiveCollection;
113
    }
114
115
    /**
116
     * @return boolean
117
     */
118 4
    public function isFirstFailSkip()
119
    {
120 4
        return $this->firstFailSkip;
121
    }
122
123
    /**
124
     * @param Mailbox $mailbox
125
     */
126 8
    protected function setMailbox(Mailbox $mailbox)
127
    {
128 8
        $this->mailbox = $mailbox;
129 8
    }
130
131
    /**
132
     * @param PersistCollectionInterface $persistCollection
133
     */
134 8
    protected function setPersistCollection(PersistCollectionInterface $persistCollection)
135
    {
136 8
        $this->persistCollection = $persistCollection;
137 8
    }
138
139
    /**
140
     * @param int $receiveMaxTime
141
     */
142 8
    protected function setReceiveMaxTime($receiveMaxTime)
143
    {
144 8
        $this->receiveMaxTime = $receiveMaxTime;
145 8
    }
146
147
    /**
148
     * @param boolean $firstFailSkip
149
     */
150 4
    protected function setFirstFailSkip($firstFailSkip)
151
    {
152 4
        $this->firstFailSkip = $firstFailSkip;
153 4
    }
154
155
    /**
156
     * @param EmailSendReceiveCollection $emailSendReceiveC
157
     */
158 7
    protected function setEmailSendReceiveColl(EmailSendReceiveCollection $emailSendReceiveC)
159
    {
160 7
        $this->emailSendReceiveCollection = $emailSendReceiveC;
161 7
    }
162
163
    /**
164
     * @param EmailSendReceive $emailSendCheckI
165
     * @throws EmailReceiveCheckException
166
     */
167 4
    protected function timeReceiveCheck(EmailSendReceive $emailSendCheckI)
168
    {
169 4
        $timeLeft = time() - $emailSendCheckI->getSentAt()->getTimestamp();
170 4
        if ($timeLeft > $this->getReceiveMaxTime()) {
171
172 4
            $emailSendCheckI->setStatus(EmailSendReceive::STATUS_EXPIRED);
173 4
            $emailSendCheckI->setReceivedAt(new DateTime());
174 4
            $this->getEmailSendReceiveColl()->remove(
175 4
                $this->findSameItemCallback($emailSendCheckI)
176 4
            );
177 4
            $this->getPersistCollection()->flush();
178
179 4
            if (!$this->isFirstFailSkip()) {
180 1
                throw EmailReceiveCheckException::receivingMaxTimeExpire(
181 1
                    $emailSendCheckI->getSubject(),
182 1
                    $timeLeft,
183 1
                    $this->getReceiveMaxTime()
184 1
                );
185
            } else {
186 4
                $this->setFirstFailSkip(false);
187
            }
188 4
        }
189 4
    }
190
191
    /**
192
     * @param $mails
193
     * @param EmailSendReceive $emailSendCheckI
194
     */
195 4
    private function deleteReceivedEmails($mails, EmailSendReceive $emailSendCheckI)
196
    {
197 4
        foreach ($mails as $mailId) {
198 4
            $this->getMailbox()->deleteMail($mailId);
199 4
            $emailSendCheckI->setStatus(EmailSendReceive::STATUS_RECEIVED);
200 4
            $this->getEmailSendReceiveColl()->remove(
201 4
                $this->findSameItemCallback($emailSendCheckI)
202 4
            );
203 4
            $this->getPersistCollection()->flush();
204 4
        }
205 4
    }
206
207
    /**
208
     * @param EmailSendReceive $emailSendCheckI
209
     * @throws EmailReceiveCheckException
210
     */
211 7
    private function performReceive(EmailSendReceive $emailSendCheckI)
212
    {
213
        try {
214 7
            $mails = $this->getMailbox()->searchMailbox(
215 7
                'FROM '.$emailSendCheckI->getFrom().' SUBJECT '.$emailSendCheckI->getSubject()
216 7
            );
217
218 4
            $this->timeReceiveCheck($emailSendCheckI);
219
220 4
            if (count($mails) > 0) {
221 4
                $this->deleteReceivedEmails($mails, $emailSendCheckI);
222 4
            }
223
224 7
        } catch (ImapException $e) {
225 2
            $emailSendCheckI->setStatus(EmailSendReceive::STATUS_RECEIVED_ERROR);
226 2
            $this->getEmailSendReceiveColl()->remove(
227 2
                $this->findSameItemCallback($emailSendCheckI)
228 2
            );
229 2
            $this->getPersistCollection()->flush();
230 2
            throw EmailReceiveCheckException::internalProblem($e);
231
        }
232 4
    }
233
234
    /**
235
     * @param EmailSendReceive $emailSendCheckI
236
     * @return \Closure
237
     */
238
    private function findSameItemCallback(EmailSendReceive $emailSendCheckI)
239
    {
240 6
        return function (EmailSendReceive $emailSendCheckItem) use ($emailSendCheckI) {
241 6
            return $emailSendCheckItem === $emailSendCheckI;
242 6
        };
243
    }
244
}
245