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

AbstractJoinpoint::flatAndSortAdvices()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4.0312

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 7
cts 8
cp 0.875
rs 9.7666
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4.0312
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