Completed
Push — master ( 91676c...354384 )
by Alexander
02:23
created

AbstractJoinpoint::sortAdvices()   B

Complexity

Conditions 10
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 10

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 13
cts 13
cp 1
rs 7.6666
c 0
b 0
f 0
cc 10
nc 1
nop 1
crap 10

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types = 1);
3
/*
4
 * Go! AOP framework
5
 *
6
 * @copyright Copyright 2011, Lisachenko Alexander <[email protected]>
7
 *
8
 * This source file is subject to the license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Go\Aop\Framework;
13
14
use Go\Aop\Advice;
15
use Go\Aop\AdviceAfter;
16
use Go\Aop\AdviceAround;
17
use Go\Aop\AdviceBefore;
18
use Go\Aop\Intercept\Interceptor;
19
use Go\Aop\Intercept\Joinpoint;
20
use function is_array;
21
22
/**
23
 *  Abstract joinpoint for framework
24
 *
25
 * Join points are points in the execution of the system, such as method calls,
26
 * where behavior supplied by aspects is combined. A join point is a point in
27
 * the execution of the program, which is used to define the dynamic structure
28
 * of a crosscutting concern.
29
 *
30
 * @link http://en.wikipedia.org/wiki/Aspect-oriented_software_development#Join_point_model
31
 */
32
abstract class AbstractJoinpoint implements Joinpoint
33
{
34
    /**
35
     * List of advices
36
     *
37
     * @var array|Advice[]|Interceptor[]
38
     */
39
    protected $advices = [];
40
41
    /**
42
     * Current advice index
43
     *
44
     * @var int
45
     */
46
    protected $current = 0;
47
48
    /**
49
     * Stack frames to work with recursive calls or with cross-calls inside object
50
     *
51
     * @var array
52
     */
53
    protected $stackFrames = [];
54
55
    /**
56
     * Recursion level for invocation
57
     *
58
     * @var int
59
     */
60
    protected $level = 0;
61
62
    /**
63
     * Initializes list of advices for current joinpoint
64
     *
65
     * @param array $advices List of advices
66
     */
67 27
    public function __construct(array $advices)
68
    {
69 27
        $this->advices = $advices;
70 27
    }
71
72
    /**
73
     * Sorts advices by priority
74
     *
75
     * @param array|Advice[] $advices
76
     * @return array|Advice[] Sorted list of advices
77
     */
78 14
    public static function sortAdvices(array $advices): array
79
    {
80 14
        $sortedAdvices = $advices;
81
        uasort($sortedAdvices, function (Advice $first, Advice $second) {
82
            switch (true) {
83 9
                case $first instanceof AdviceBefore && !($second instanceof AdviceBefore):
84 4
                    return -1;
85
86 6
                case $first instanceof AdviceAround && !($second instanceof AdviceAround):
87 3
                    return 1;
88
89 4
                case $first instanceof AdviceAfter && !($second instanceof AdviceAfter):
90 2
                    return $second instanceof AdviceBefore ? 1 : -1;
91
92 2
                case ($first instanceof OrderedAdvice && $second instanceof OrderedAdvice):
93 1
                    return $first->getAdviceOrder() - $second->getAdviceOrder();
94
95
                default:
96 1
                    return 0;
97
            }
98 14
        });
99
100 14
        return $sortedAdvices;
101
    }
102
103
    /**
104
     * Replace concrete advices with list of ids
105
     *
106
     * @param Advice[][][] $advices List of advices
107
     */
108 6
    public static function flatAndSortAdvices(array $advices): array
109
    {
110 6
        $flattenAdvices = [];
111 6
        foreach ($advices as $type => $typedAdvices) {
112 6
            foreach ($typedAdvices as $name => $concreteAdvices) {
113 6
                if (is_array($concreteAdvices)) {
114 6
                    $flattenAdvices[$type][$name] = array_keys(self::sortAdvices($concreteAdvices));
115
                } else {
116
                    $flattenAdvices[$type][$name] = $concreteAdvices;
117
                }
118
            }
119
        }
120
121 6
        return $flattenAdvices;
122
    }
123
}
124