TransactionalPointcut   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 11
lcom 2
cbo 2
dl 0
loc 94
ccs 44
cts 44
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A matchesClass() 0 4 2
C matchesMethod() 0 44 8
1
<?php
2
3
/**
4
 * Copyright 2016 Inneair
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 *
18
 * @license http://www.apache.org/licenses/LICENSE-2.0.html Apache-2.0
19
 */
20
21
namespace Inneair\TransactionBundle\Aop;
22
23
use Doctrine\Common\Annotations\Reader;
24
use JMS\AopBundle\Aop\PointcutInterface;
25
use Psr\Log\LoggerInterface;
26
use ReflectionClass;
27
use ReflectionMethod;
28
use Inneair\TransactionBundle\Annotation\Transactional;
29
use Inneair\TransactionBundle\Annotation\TransactionalAwareInterface;
30
31
/**
32
 * This class defines a pointcut specification for transaction management.
33
 */
34
class TransactionalPointcut implements PointcutInterface
35
{
36
    /**
37
     * Annotation reader in PHP class.
38
     * @var Reader
39
     */
40
    private $reader;
41
    /**
42
     * Logger.
43
     * @var LoggerInterface
44
     */
45
    private $logger;
46
    /**
47
     * Whether target classes must also implement the {@link TransactionalAwareInterface} interface.
48
     * @var boolean
49
     */
50
    private $strictModeEnabled;
51
52
    /**
53
     * Creates a transactional pointcut.
54
     *
55
     * @param Reader $reader An annotations reader.
56
     * @param LoggerInterface $logger Logger.
57
     * @param boolean $strictModeEnabled
58
     * @see TransactionalAwareInterface
59
     */
60 10
    public function __construct(Reader $reader, LoggerInterface $logger, $strictModeEnabled = false)
61
    {
62 10
        $this->reader = $reader;
63 10
        $this->logger = $logger;
64 10
        $this->strictModeEnabled = $strictModeEnabled;
65 10
    }
66
67
    /**
68
     * The interceptor is activated for any classes (if strict mode is disabled), or classes implementing the
69
     * {@link TransactionalAwareInterface} interface.
70
     *
71
     * {@inheritDoc}
72
     */
73 3
    public function matchesClass(ReflectionClass $class)
74
    {
75 3
        return (!$this->strictModeEnabled || $class->implementsInterface(TransactionalAwareInterface::class));
76
    }
77
78
    /**
79
     * The interceptor is activated for public methods in Transactional annotated components.
80
     *
81
     * {@inheritDoc}
82
     */
83 7
    public function matchesMethod(ReflectionMethod $method)
84
    {
85 7
        $transactionalEnabled = false;
86 7
        if ($method->isPublic()) {
87
            // Gets method-level annotation.
88
            /** @var Transactional $annotation */
89 6
            $annotation = $this->reader->getMethodAnnotation($method, Transactional::class);
90 6
            $transactionalEnabled = ($annotation !== null);
91 6
            if (!$transactionalEnabled) {
92
                // If there is no method-level annotation, gets class-level annotation.
93 2
                $annotation = $this->reader->getClassAnnotation($method->getDeclaringClass(), Transactional::class);
94 2
                $transactionalEnabled = ($annotation !== null);
95 2
            }
96
97 6
            if ($transactionalEnabled) {
98 5
                switch ($annotation->getPolicy()) {
99 5
                    case Transactional::NOT_REQUIRED:
100 1
                        $policyName = 'not required';
101 1
                        break;
102 4
                    case Transactional::REQUIRED:
103 1
                        $policyName = 'required';
104 1
                        break;
105 3
                    case Transactional::NESTED:
106 1
                        $policyName = 'nested';
107 1
                        break;
108 2
                    default:
109 2
                        $policyName = 'default';
110 5
                }
111 5
                $methodString = $method->getDeclaringClass()->name . '::' . $method->name;
112 5
                $this->logger->debug('TX policy for \'' . $methodString . '\': ' . $policyName);
113 5
                $noRollbackExceptionsStr = implode(
114 5
                    ', ',
115 5
                    ($annotation->getNoRollbackExceptions() === null)
116 5
                        ? ['default']
117 5
                        : $annotation->getNoRollbackExceptions()
118 5
                );
119 5
                $this->logger->debug(
120 5
                    'TX no-rollback exceptions for \'' . $methodString . '\': ' . $noRollbackExceptionsStr
121 5
                );
122 5
            }
123 6
        }
124
125 7
        return $transactionalEnabled;
126
    }
127
}
128