Completed
Pull Request — master (#5)
by Pavel
04:05
created

AnnotationClassLoader   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 74.58%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 20
c 2
b 0
f 0
lcom 1
cbo 5
dl 0
loc 112
ccs 44
cts 59
cp 0.7458
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C load() 0 34 7
A getParentAnnotations() 0 21 4
A addRoute() 0 19 2
A supports() 0 6 4
A getResolver() 0 3 1
A setResolver() 0 3 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: batanov.pavel
5
 * Date: 16.02.2016
6
 * Time: 13:01
7
 */
8
9
namespace Bankiru\Api\Rpc\Routing\Loader;
10
11
use Bankiru\Api\Rpc\Routing\Annotation\Method;
12
use Bankiru\Api\Rpc\Routing\LoaderInterface;
13
use Bankiru\Api\Rpc\Routing\MethodCollection;
14
use Bankiru\Api\Rpc\Routing\Route;
15
use Doctrine\Common\Annotations\Reader;
16
use Symfony\Component\Config\Resource\FileResource;
17
18
class AnnotationClassLoader implements LoaderInterface
19
{
20
    /** @var  Reader */
21
    private $reader;
22
23
    /**
24
     * Constructor.
25
     *
26
     * @param Reader $reader
27
     */
28 8
    public function __construct(Reader $reader)
29
    {
30 8
        $this->reader = $reader;
31 8
    }
32
33
34
    /** {@inheritdoc} */
35 8
    public function load($class, $type = null)
36
    {
37 8
        if (!class_exists($class)) {
38
            throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
39
        }
40
41 8
        $class = new \ReflectionClass($class);
42 8
        if ($class->isAbstract()) {
43
            throw new \InvalidArgumentException(
44
                sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class->getName())
0 ignored issues
show
Bug introduced by
Consider using $class->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
45
            );
46
        }
47
48 8
        $parents = $this->getParentAnnotations($class);
49
50 8
        $collection = new MethodCollection();
51 8
        $collection->addResource(new FileResource($class->getFileName()));
52
53 8
        foreach ($class->getMethods() as $method) {
54 8
            if (!$method->isPublic()) {
55 8
                continue;
56
            }
57
            
58 8
            foreach ($this->reader->getMethodAnnotations($method) as $annot) {
59 8
                if ($annot instanceof Method) {
60 8
                    $this->addRoute($collection, $annot, $parents, $class, $method);
61 8
                }
62 8
            }
63 8
        }
64
65 8
        $collection->addPrefix($parents['method']);
66
67 8
        return $collection;
68
    }
69
70 8
    protected function getParentAnnotations(\ReflectionClass $class)
71
    {
72
        $parents = [
73 8
            'method'          => '',
74 8
            'context'         => [],
75 8
            'default_context' => true,
76 8
        ];
77
78
        /** @var Method $annot */
79 8
        if ($annot = $this->reader->getClassAnnotation($class, Method::class)) {
80
            if (null !== $annot->getMethod()) {
81
                $parents['method'] = $annot->getMethod();
82
            }
83
84
            if (null !== $annot->getContext()) {
85
                $parents['context'] = $annot->getContext();
86
            }
87
        }
88
89 8
        return $parents;
90
    }
91
92 8
    protected function addRoute(
93
        MethodCollection $collection,
94
        Method $annot,
95
        array $parents,
96
        \ReflectionClass $class,
97
        \ReflectionMethod $method
98
    )
99
    {
100 8
        $collection->add(
101 8
            $annot->getMethod(),
102 8
            new Route(
103 8
                $annot->getMethod(),
104 8
                $class->getName() . '::' . $method->getName(),
0 ignored issues
show
Bug introduced by
Consider using $class->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
105 8
                array_merge($parents['context'], $annot->getContext()),
106 8
                $parents['default_context'] && $annot->isDefaultContext(),
107 8
                $annot->isInherit()
108 8
            )
109 8
        );
110 8
    }
111
112
    /** {@inheritdoc} */
113 8
    public function supports($resource, $type = null)
114
    {
115 8
        return is_string($resource) &&
116 8
               preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) &&
117 8
               (!$type || 'annotation' === $type);
0 ignored issues
show
Bug Best Practice introduced by
The expression $type of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
118
    }
119
120
    /** {@inheritdoc} */
121
    public function getResolver()
122
    {
123
    }
124
125
    /** {@inheritdoc} */
126
    public function setResolver($resolver)
127
    {
128
    }
129
}
130