TransactionMiddleware::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Tactician\Doctrine\ORM;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use Exception;
9
use League\Tactician\Middleware;
10
use Throwable;
11
12
/**
13
 * Wraps command execution inside a Doctrine ORM transaction
14
 */
15
class TransactionMiddleware implements Middleware
16
{
17
    private EntityManagerInterface $entityManager;
18
19
    public function __construct(EntityManagerInterface $entityManager)
20
    {
21
        $this->entityManager = $entityManager;
22
    }
23
24
    /**
25
     * Executes the given command and optionally returns a value
26
     *
27
     * @return mixed
28
     *
29
     * @throws Throwable
30
     * @throws Exception
31
     */
32
    public function execute(object $command, callable $next)
33
    {
34
        $this->entityManager->beginTransaction();
35
36
        try {
37
            $returnValue = $next($command);
38
39
            $this->entityManager->flush();
40
            $this->entityManager->commit();
41
        } catch (Exception $e) {
42
            $this->rollbackTransaction();
43
44
            throw $e;
45
        } catch (Throwable $e) {
46
            $this->rollbackTransaction();
47
48
            throw $e;
49
        }
50
51
        return $returnValue;
52
    }
53
54
    /**
55
     * Rollback the current transaction and close the entity manager when possible.
56
     */
57
    protected function rollbackTransaction(): void
58
    {
59
        $this->entityManager->rollback();
60
61
        $connection = $this->entityManager->getConnection();
62
        if ($connection->isTransactionActive() && ! $connection->isRollbackOnly()) {
63
            return;
64
        }
65
66
        $this->entityManager->close();
67
    }
68
}
69