Failed Conditions
Push — master ( ebb1ea...d49c03 )
by Bernhard
06:05
created

InterceptedOperation   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 89.47%
Metric Value
wmc 7
lcom 1
cbo 3
dl 0
loc 66
ccs 17
cts 19
cp 0.8947
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A execute() 0 16 3
A rollback() 0 9 2
1
<?php
2
3
/*
4
 * This file is part of the puli/manager package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Manager\Transaction;
13
14
use Exception;
15
use Puli\Manager\Assert\Assert;
16
17
/**
18
 * Adds support for interceptors to an atomic operation.
19
 *
20
 * The operation and its interceptors are passed to the constructor. All
21
 * interceptors must implement {@link OperationInterceptor}.
22
 *
23
 * The {@link OperationInterceptor} interface supports two methods:
24
 *
25
 *  * {@link OperationInterceptor::postExecute()} is invoked after executing
26
 *    the operation. If the execution fails, the interceptor is not invoked.
27
 *    If the interceptor fails, the operation is rolled back.
28
 *  * {@link OperationInterceptor::postRollback()} is invoked after rolling
29
 *    back the operation. Consequently, this method is also called when
30
 *    {@link OperationInterceptor::postExecute()} fails.
31
 *
32
 * @since  1.0
33
 *
34
 * @author Bernhard Schussek <[email protected]>
35
 */
36
class InterceptedOperation implements AtomicOperation
37
{
38
    /**
39
     * @var AtomicOperation
40
     */
41
    private $operation;
42
43
    /**
44
     * @var OperationInterceptor[]
45
     */
46
    private $interceptors;
47
48
    /**
49
     * @var OperationInterceptor[]
50
     */
51
    private $interceptorsForRollback;
52
53
    /**
54
     * Adds support for interceptors to an atomic operation.
55
     *
56
     * @param AtomicOperation                             $operation    The operation.
57
     * @param OperationInterceptor|OperationInterceptor[] $interceptors The interceptor(s).
58
     */
59 74
    public function __construct(AtomicOperation $operation, $interceptors)
60
    {
61 74
        $interceptors = is_array($interceptors) ? $interceptors : array($interceptors);
62
63 74
        Assert::allIsInstanceOf($interceptors, __NAMESPACE__.'\OperationInterceptor');
64
65 74
        $this->operation = $operation;
66 74
        $this->interceptors = $interceptors;
67 74
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 74
    public function execute()
73
    {
74
        // no rollback if execute() fails
75 74
        $this->operation->execute();
76
77
        try {
78
            // rollback if postExecute() fails, since execute() is already
79
            // completed
80 74
            foreach ($this->interceptors as $interceptor) {
81 74
                $this->interceptorsForRollback[] = $interceptor;
82 74
                $interceptor->postExecute();
83
            }
84
        } catch (Exception $e) {
85
            $this->rollback();
86
        }
87 74
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92 7
    public function rollback()
93
    {
94 7
        $this->operation->rollback();
95
96
        // Only launch interceptors whose postExecute() method was called
97 7
        foreach ($this->interceptorsForRollback as $interceptor) {
98 7
            $interceptor->postRollback();
99
        }
100 7
    }
101
}
102