Passed
Push — issue#785 ( 73515d...f798de )
by Guilherme
04:17
created

LongPollingUtils::runTimeLimited()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 8
nop 2
dl 0
loc 21
ccs 15
cts 15
cp 1
crap 5
rs 8.7624
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LoginCidadao\CoreBundle\LongPolling;
12
13
use Doctrine\ORM\EntityManagerInterface;
14
use LoginCidadao\APIBundle\Exception\RequestTimeoutException;
15
use LoginCidadao\CoreBundle\Model\PersonInterface;
16
use LoginCidadao\CoreBundle\Tests\LongPolling\LongPollableInterface;
17
18
class LongPollingUtils
19
{
20
    /** @var EntityManagerInterface */
21
    private $em;
22
23
    /** @var int */
24
    private $maxExecutionTime;
25
26
    /**
27
     * LongPollingUtils constructor.
28
     * @param EntityManagerInterface $em
29
     * @param null $maxExecutionTime
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $maxExecutionTime is correct as it would always require null to be passed?
Loading history...
30
     */
31 6
    public function __construct(EntityManagerInterface $em, $maxExecutionTime = null)
32
    {
33 6
        $this->em = $em;
34 6
        $this->maxExecutionTime = $maxExecutionTime;
35
36 6
        if ($maxExecutionTime === null) {
37 4
            $this->maxExecutionTime = ini_get('max_execution_time');
0 ignored issues
show
Documentation Bug introduced by
The property $maxExecutionTime was declared of type integer, but ini_get('max_execution_time') is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
38
        }
39 6
    }
40
41 3
    public function runTimeLimited($callback, $waitTime = 1)
42
    {
43 3
        $maxExecutionTime = $this->maxExecutionTime;
44 3
        $limit = $maxExecutionTime ? $maxExecutionTime - 2 : 60;
45 3
        $startTime = time();
46 3
        while ($limit > 0) {
47 3
            $result = call_user_func($callback);
48 3
            $delta = time() - $startTime;
49
50 3
            if ($result !== false) {
51 2
                return $result;
52
            }
53
54 3
            $limit -= $delta;
55 3
            if ($limit <= 0) {
56 1
                break;
57
            }
58 3
            $startTime = time();
59 3
            sleep($waitTime);
60
        }
61 1
        throw new RequestTimeoutException("Request Timeout");
62
    }
63
64
    /**
65
     * @param PersonInterface $user
66
     * @param \DateTime $updatedAt
67
     * @return bool
68
     * @throws RequestTimeoutException
69
     */
70 2
    public function waitValidEmail(PersonInterface $user, \DateTime $updatedAt)
71
    {
72 2
        if ($user->getEmailConfirmedAt() instanceof \DateTime) {
0 ignored issues
show
introduced by
$user->getEmailConfirmedAt() is always a sub-type of DateTime.
Loading history...
73 1
            return true;
74
        }
75
76 1
        $person = $this->runTimeLimited(
77 1
            $this->getEntityUpdateCheckerCallback($user, $updatedAt)
78
        );
79
80 1
        return $person->getEmailConfirmedAt() instanceof \DateTime;
81
    }
82
83 3
    public function getEntityUpdateCheckerCallback(LongPollableInterface $entity, $updatedAt)
84
    {
85 3
        $id = $entity->getId();
86 3
        $em = $this->em;
87 3
        $repository = $em->getRepository(get_class($entity));
88
89 3
        return function () use ($em, $repository, $id, $updatedAt) {
90 3
            $em->clear();
91
92
            /** @var LongPollableInterface $entity */
93 3
            $entity = $repository->find($id);
94 3
            if (!$entity->getUpdatedAt()) {
95 1
                return false;
96
            }
97
98 2
            if ($entity->getUpdatedAt() > $updatedAt) {
99 2
                return $entity;
100
            }
101
102 1
            return false;
103 3
        };
104
    }
105
}
106