Completed
Push — master ( 15784c...b73c8f )
by Peter
02:13
created

TargetChecker   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Test Coverage

Coverage 86.21%

Importance

Changes 0
Metric Value
wmc 21
lcom 0
cbo 4
dl 0
loc 74
ccs 25
cts 29
cp 0.8621
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
D check() 0 63 21
1
<?php
2
3
/**
4
 * This software package is licensed under AGPL, Commercial license.
5
 *
6
 * @package maslosoft/addendum
7
 * @licence AGPL, Commercial
8
 * @copyright Copyright (c) Piotr Masełkowski <[email protected]> (Meta container, further improvements, bugfixes)
9
 * @copyright Copyright (c) Maslosoft (Meta container, further improvements, bugfixes)
10
 * @copyright Copyright (c) Jan Suchal (Original version, builder, parser)
11
 * @link https://maslosoft.com/addendum/ - maslosoft addendum
12
 * @link https://code.google.com/p/addendum/ - original addendum project
13
 */
14
15
namespace Maslosoft\Addendum\Utilities;
16
17
use Maslosoft\Addendum\Annotations\TargetAnnotation;
18
use Maslosoft\Addendum\Exceptions\TargetException;
19
use Maslosoft\Addendum\Interfaces\AnnotationInterface;
20
use Maslosoft\Addendum\Reflection\ReflectionAnnotatedClass;
21
use ReflectionClass;
22
use ReflectionMethod;
23
use ReflectionProperty;
24
25
/**
26
 * Check target constraints
27
 *
28
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
29
 */
30
class TargetChecker
31
{
32
33
	/**
34
	 * Check target constraints
35
	 * @param AnnotationInterface $annotation Annotation
36
	 * @param ReflectionClass|ReflectionMethod|ReflectionProperty|bool $target
37
	 * @throws TargetException
38
	 */
39 55
	public static function check($annotation, $target)
40
	{
41 55
		$reflection = new ReflectionAnnotatedClass($annotation);
42 55
		if (!$reflection->hasAnnotation('Target'))
43
		{
44 55
			return;
45
		}
46 16
		$value = $reflection->getAnnotation('Target')->value;
47 16
		$values = is_array($value) ? $value : [$value];
48
		
49 16
		foreach ($values as $value)
50
		{
51 16
			if ($value == TargetAnnotation::TargetClass && $target instanceof ReflectionClass)
52
			{
53 1
				return;
54
			}
55 15
			if ($value == TargetAnnotation::TargetMethod && $target instanceof ReflectionMethod)
56
			{
57 5
				return;
58
			}
59 13
			if ($value == TargetAnnotation::TargetProperty && $target instanceof ReflectionProperty)
60
			{
61 6
				return;
62
			}
63 10
			if ($value == TargetAnnotation::TargetNested && $target === false)
64
			{
65
				return;
66
			}
67
		}
68 7
		if ($target !== false && $value && !in_array($value, [
69 7
					TargetAnnotation::TargetClass,
70
					TargetAnnotation::TargetMethod,
71
					TargetAnnotation::TargetProperty,
72
					TargetAnnotation::TargetNested
73
				]))
74
		{
75 3
			if ($target instanceof ReflectionClass)
76
			{
77 3
				$interfaceTarget = $target;
78
			}
79
			else
80
			{
81
				/* @var $target ReflectionProperty */
82
				$interfaceTarget = new ReflectionClass($target->class);
83
			}
84 3
			if(!ClassChecker::exists($value))
85
			{
86
				throw new TargetException(sprintf('Annotation "%s" used in "%s" is only allowed on instances of "%s", but this class does not exists (see @Target)', basename($reflection->name), $interfaceTarget->name, $value));
87
			}
88 3
			if (!$interfaceTarget->implementsInterface($value))
89
			{
90 1
				throw new TargetException(sprintf('Annotation "%s" used in "%s" is only allowed on instances of "%s" (see @Target)',  basename($reflection->name), $interfaceTarget->name, $value));
91
			}
92
		}
93 6
		if ($target === false && $value == TargetAnnotation::TargetNested)
94
		{
95
			throw new TargetException("Annotation '" . get_class($annotation) . "' nesting not allowed");
96
		}
97 6
		elseif (in_array($value, TargetAnnotation::getTargets()))
98
		{
99 4
			throw new TargetException(sprintf("Annotation '%s' not allowed on %s, it's target is %s  (see @Target)", get_class($annotation), ReflectionName::createName($target), $value));
100
		}
101 2
	}
102
103
}
104