Passed
Push — master ( 830ff2...cc85f4 )
by Dmitry
02:46
created

EmailReceiveCheck::isFirstFailSkip()   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 2
Bugs 0 Features 0
Metric Value
c 2
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 int
25
     */
26
    private $receiveMaxTime;
27
28
    /**
29
     * @var Mailbox;
30
     */
31
    private $mailbox;
32
33
34
    /**
35
     * @var PersistCollectionInterface
36
     */
37
    private $persistCollection;
38
39
    /**
40
     * @var EmailSendReceiveCollection
41
     */
42
    private $emailSendReceiveCollection;
43
44
    /**
45
     * @param string                     $checkNode
46
     * @param Mailbox                    $mailbox
47
     * @param PersistCollectionInterface $persistCollection
48
     * @param int                        $receiveMaxTime
49
     */
50 8
    public function __construct(
51
        $checkNode,
52
        Mailbox $mailbox,
53
        PersistCollectionInterface $persistCollection,
54
        $receiveMaxTime = self::RECEIVE_MAX_TIME
55
    ) {
56 8
        parent::__construct($checkNode);
57
58 8
        $this->setMailbox($mailbox);
59 8
        $this->setPersistCollection($persistCollection);
60 8
        $this->setReceiveMaxTime($receiveMaxTime);
61 8
    }
62
63
    /**
64
     * Check email can send and receive messages
65
     * @return bool|void
66
     * @throws EmailReceiveCheckException
67
     */
68 7
    public function check()
69
    {
70 7
        $this->setEmailSendReceiveColl($this->getPersistCollection()->load());
71
72
        /** @var EmailSendReceive $emailSendCheckI */
73 7
        foreach ($this->getEmailSendReceiveColl() as $emailSendCheckI) {
74 7
            $this->performReceive($emailSendCheckI);
75 3
        }
76 3
    }
77
78
    /**
79
     * @return Mailbox
80
     */
81 7
    public function getMailbox()
82
    {
83 7
        return $this->mailbox;
84
    }
85
86
    /**
87
     * @return PersistCollectionInterface
88
     */
89 7
    public function getPersistCollection()
90
    {
91 7
        return $this->persistCollection;
92
    }
93
94
    /**
95
     * @return int
96
     */
97 4
    public function getReceiveMaxTime()
98
    {
99 4
        return $this->receiveMaxTime;
100
    }
101
102
    /**
103
     * @return EmailSendReceiveCollection
104
     */
105 7
    public function getEmailSendReceiveColl()
106
    {
107 7
        return $this->emailSendReceiveCollection;
108
    }
109
110
    /**
111
     * @param Mailbox $mailbox
112
     */
113 8
    protected function setMailbox(Mailbox $mailbox)
114
    {
115 8
        $this->mailbox = $mailbox;
116 8
    }
117
118
    /**
119
     * @param PersistCollectionInterface $persistCollection
120
     */
121 8
    protected function setPersistCollection(PersistCollectionInterface $persistCollection)
122
    {
123 8
        $this->persistCollection = $persistCollection;
124 8
    }
125
126
    /**
127
     * @param int $receiveMaxTime
128
     */
129 8
    protected function setReceiveMaxTime($receiveMaxTime)
130
    {
131 8
        $this->receiveMaxTime = $receiveMaxTime;
132 8
    }
133
134
    /**
135
     * @param EmailSendReceiveCollection $emailSendReceiveC
136
     */
137 7
    protected function setEmailSendReceiveColl(EmailSendReceiveCollection $emailSendReceiveC)
138
    {
139 7
        $this->emailSendReceiveCollection = $emailSendReceiveC;
140 7
    }
141
142
    /**
143
     * @param EmailSendReceive $emailSendCheckI
144
     * @throws EmailReceiveCheckException
145
     */
146 4
    protected function timeReceiveCheck(EmailSendReceive $emailSendCheckI)
147
    {
148 4
        $timeLeft = time() - $emailSendCheckI->getSentAt()->getTimestamp();
149 4
        if ($timeLeft > $this->getReceiveMaxTime()) {
150
151 2
            $emailSendCheckI->setStatus(EmailSendReceive::STATUS_EXPIRED);
152 2
            $emailSendCheckI->setReceivedAt(new DateTime());
153 2
            $this->getEmailSendReceiveColl()->remove(
154 2
                $this->findSameItemCallback($emailSendCheckI)
155 2
            );
156 2
            $this->getPersistCollection()->flush();
157 2
                throw EmailReceiveCheckException::receivingMaxTimeExpire(
158 2
                    $emailSendCheckI->getSubject(),
159 2
                    $timeLeft,
160 2
                    $this->getReceiveMaxTime()
161 2
                );
162
        }
163 3
    }
164
165
    /**
166
     * @param $mails
167
     * @param EmailSendReceive $emailSendCheckI
168
     */
169 3
    private function deleteReceivedEmails($mails, EmailSendReceive $emailSendCheckI)
170
    {
171 3
        foreach ($mails as $mailId) {
172 3
            $this->getMailbox()->deleteMail($mailId);
173 3
            $emailSendCheckI->setStatus(EmailSendReceive::STATUS_RECEIVED);
174 3
            $this->getEmailSendReceiveColl()->remove(
175 3
                $this->findSameItemCallback($emailSendCheckI)
176 3
            );
177 3
            $this->getPersistCollection()->flush();
178 3
        }
179 3
    }
180
181
    /**
182
     * @param EmailSendReceive $emailSendCheckI
183
     * @throws EmailReceiveCheckException
184
     */
185 7
    private function performReceive(EmailSendReceive $emailSendCheckI)
186
    {
187
        try {
188 7
            $mails = $this->getMailbox()->searchMailbox(
189 7
                'FROM '.$emailSendCheckI->getFrom().' SUBJECT '.$emailSendCheckI->getSubject()
190 7
            );
191
192 4
            $this->timeReceiveCheck($emailSendCheckI);
193
194 3
            if (count($mails) > 0) {
195 3
                $this->deleteReceivedEmails($mails, $emailSendCheckI);
196 3
            }
197
198 7
        } catch (ImapException $e) {
199 2
            $emailSendCheckI->setStatus(EmailSendReceive::STATUS_RECEIVED_ERROR);
200 2
            $this->getPersistCollection()->flush();
201 2
            throw EmailReceiveCheckException::internalProblem($e);
202
        }
203 3
    }
204
205
    /**
206
     * @param EmailSendReceive $emailSendCheckI
207
     * @return \Closure
208
     */
209
    private function findSameItemCallback(EmailSendReceive $emailSendCheckI)
210
    {
211 4
        return function (EmailSendReceive $emailSendCheckItem) use ($emailSendCheckI) {
212 4
            return $emailSendCheckItem === $emailSendCheckI;
213 4
        };
214
    }
215
}
216