Completed
Pull Request — 1.x (#286)
by Alexander
02:43
created

DeclareParentsAdvisor::validateInterfaces()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30
Metric Value
dl 0
loc 17
ccs 0
cts 16
cp 0
rs 8.8571
cc 5
eloc 10
nc 5
nop 0
crap 30
1
<?php
2
/*
3
 * Go! AOP framework
4
 *
5
 * @copyright Copyright 2012, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Go\Aop\Support;
12
13
use InvalidArgumentException;
14
use ReflectionClass;
15
use Go\Aop\Advice;
16
use Go\Aop\PointFilter;
17
use Go\Aop\IntroductionInfo;
18
use Go\Aop\IntroductionAdvisor;
19
20
/**
21
 * Introduction advisor delegating to the given object.
22
 */
23
class DeclareParentsAdvisor implements IntroductionAdvisor
24
{
25
26
    /**
27
     * @var null|IntroductionInfo
28
     */
29
    private $advice = null;
30
31
    /**
32
     * Type pattern the introduction is restricted to
33
     *
34
     * @var PointFilter
35
     */
36
    private $classFilter;
37
38
    /**
39
     * Create a DefaultIntroductionAdvisor for the given advice.
40
     */
41
    public function __construct(PointFilter $classFilter, IntroductionInfo $info)
42
    {
43
        $this->classFilter = $classFilter;
44
        $this->advice      = $info;
45
    }
46
47
    /**
48
     * Can the advised interfaces be implemented by the introduction advice?
49
     *
50
     * Invoked before adding an IntroductionAdvisor.
51
     *
52
     * @return void
53
     * @throws \InvalidArgumentException if the advised interfaces can't be implemented by the introduction advice
54
     */
55
    public function validateInterfaces()
56
    {
57
        $refInterface      = new ReflectionClass(reset($this->advice->getInterfaces()));
0 ignored issues
show
Bug introduced by
$this->advice->getInterfaces() cannot be passed to reset() as the parameter $array expects a reference.
Loading history...
58
        $refImplementation = new ReflectionClass(reset($this->advice->getTraits()));
0 ignored issues
show
Bug introduced by
$this->advice->getTraits() cannot be passed to reset() as the parameter $array expects a reference.
Loading history...
59
        if (!$refInterface->isInterface()) {
60
            throw new \InvalidArgumentException("Only interface can be introduced");
61
        }
62
        if (!$refImplementation->isTrait()) {
63
            throw new \InvalidArgumentException("Only trait can be used as implementation");
64
        }
65
66
        foreach ($refInterface->getMethods() as $interfaceMethod) {
67
            if (!$refImplementation->hasMethod($interfaceMethod->name)) {
68
                throw new \DomainException("Implementation requires method {$interfaceMethod->name}");
69
            }
70
        }
71
    }
72
73
    /**
74
     * Returns an advice to apply
75
     *
76
     * @return Advice|IntroductionInfo|null
77
     */
78
    public function getAdvice()
79
    {
80
        return $this->advice;
81
    }
82
83
    /**
84
     * Return the filter determining which target classes this introduction should apply to.
85
     *
86
     * This represents the class part of a pointcut. Note that method matching doesn't make sense to introductions.
87
     *
88
     * @return PointFilter The class filter
89
     */
90
    public function getClassFilter()
91
    {
92
        return $this->classFilter;
93
    }
94
95
    /**
96
     * Set the class filter for advisor
97
     *
98
     * @param PointFilter $classFilter Filter for classes
99
     */
100
    public function setClassFilter(PointFilter $classFilter)
101
    {
102
        $this->classFilter = $classFilter;
103
    }
104
105
    /**
106
     * Return string representation of object
107
     *
108
     * @return string
109
     */
110
    public function __toString()
111
    {
112
        $adviceClass      = get_class($this->advice);
113
        $interfaceClasses = join(',', $this->advice->getInterfaces());
114
115
        return get_called_class() . ": advice [{$adviceClass}]; interfaces [{$interfaceClasses}] ";
116
    }
117
}
118