TransactionManager   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 80.48%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 2
dl 0
loc 87
ccs 33
cts 41
cp 0.8048
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A beginTransaction() 0 4 1
A commitTransaction() 0 21 4
A rollbackTransaction() 0 14 3
A isInTransaction() 0 4 1
A transactional() 0 20 3
A setLogger() 0 4 1
1
<?php
2
3
namespace Dontdrinkandroot\Repository;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Exception;
7
use InvalidArgumentException;
8
use Psr\Log\LoggerInterface;
9
use Psr\Log\NullLogger;
10
11
/**
12
 * @author Philip Washington Sorst <[email protected]>
13
 */
14
class TransactionManager
15
{
16
    /** @var LoggerInterface */
17
    private $logger;
18
19
    /** @var EntityManagerInterface */
20
    private $entityManager;
21
22 22
    public function __construct(EntityManagerInterface $entityManager)
23
    {
24 22
        $this->entityManager = $entityManager;
25 22
        $this->logger = new NullLogger();
26 22
    }
27
28 22
    public function beginTransaction(): void
29
    {
30 22
        $this->entityManager->beginTransaction();
31 22
    }
32
33 20
    public function commitTransaction(bool $forceFlush = false): bool
34
    {
35 20
        $nestingLevel = $this->entityManager->getConnection()->getTransactionNestingLevel();
36
37
        /* No active transaction */
38 20
        if (!$this->isInTransaction()) {
39
            $this->logger->warning('No active Transaction for commit');
40
41
            return false;
42
        }
43
44 20
        $flushed = false;
45
        /* Topmost transaction, flush */
46 20
        if (1 === $nestingLevel || $forceFlush) {
47 20
            $flushed = true;
48 20
            $this->entityManager->flush();
49
        }
50 20
        $this->entityManager->commit();
51
52 20
        return $flushed;
53
    }
54
55 2
    public function rollbackTransaction(bool $closeEmOnException = true): void
56
    {
57
        /* No active transaction */
58 2
        if (!$this->isInTransaction()) {
59
            $this->logger->warning('No active Transaction for commit');
60
61
            return;
62
        }
63
64 2
        if ($closeEmOnException) {
65 2
            $this->entityManager->close();
66
        }
67 2
        $this->entityManager->rollback();
68 2
    }
69
70 22
    public function isInTransaction(): bool
71
    {
72 22
        return 0 !== $this->entityManager->getConnection()->getTransactionNestingLevel();
73
    }
74
75 22
    public function transactional(Callable $func, bool $forceFlush = false, bool $closeEmOnException = true)
76
    {
77 22
        if (!is_callable($func)) {
78
            throw new InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"');
79
        }
80
81 22
        $this->beginTransaction();
82
83
        try {
84 22
            $return = call_user_func($func, $this);
85
86 20
            $this->commitTransaction($forceFlush);
87
88 20
            return $return;
89 2
        } catch (Exception $e) {
90 2
            $this->rollbackTransaction($closeEmOnException);
91
92 2
            throw $e;
93
        }
94
    }
95
96
    public function setLogger(LoggerInterface $logger): void
97
    {
98
        $this->logger = $logger;
99
    }
100
}
101