Completed
Push — 1.x ( 378c34...640f8a )
by Akihito
12s
created

Compiler::scanClass()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 11
nc 3
nop 4
1
<?php
2
/**
3
 * This file is part of the BEAR.Package package.
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace BEAR\Package;
8
9
use BEAR\AppMeta\AppMeta;
10
use BEAR\Resource\Exception\ParameterException;
11
use BEAR\Resource\NamedParameterInterface;
12
use Doctrine\Common\Annotations\AnnotationReader;
13
use Doctrine\Common\Annotations\Reader;
14
use Doctrine\Common\Cache\Cache;
15
use Ray\Di\InjectorInterface;
16
17
final class Compiler
18
{
19
    /**
20
     * Compile application
21
     *
22
     * @param string $appName application name "MyVendor|MyProject"
23
     * @param string $context application context "prod-app"
24
     * @param string $appDir  application path
25
     */
26
    public function __invoke($appName, $context, $appDir)
27
    {
28
        $appMeta = new AppMeta($appName, $context, $appDir);
29
        $injector = new AppInjector($appName, $context);
30
        $cache = $injector->getInstance(Cache::class);
31
        $reader = $injector->getInstance(AnnotationReader::class);
32
        /* @var $reader \Doctrine\Common\Annotations\Reader */
33
        $namedParams = $injector->getInstance(NamedParameterInterface::class);
34
        /* @var $namedParams NamedParameterInterface */
35
36
        // create DI factory class and AOP compiled class for all resources and save $app cache.
37
        (new Bootstrap)->newApp($appMeta, $context, $cache);
38
39
        // check resource injection and create annotation cache
40
        foreach ($appMeta->getResourceListGenerator() as list($className)) {
41
            $this->scanClass($injector, $reader, $namedParams, $className);
42
        }
43
    }
44
45
    /**
46
     * @param InjectorInterface       $injector
47
     * @param Reader                  $reader
48
     * @param NamedParameterInterface $namedParams
49
     * @param string                  $className
50
     */
51
    private function scanClass(InjectorInterface $injector, Reader $reader, NamedParameterInterface $namedParams, $className)
52
    {
53
        $instance = $injector->getInstance($className);
54
        $class = new \ReflectionClass($className);
55
        $reader->getClassAnnotations($class);
56
        $methods = $class->getMethods();
57
        foreach ($methods as $method) {
58
            $methodName = $method->getName();
0 ignored issues
show
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
59
            if ($this->isMagicMethod($methodName)) {
60
                continue;
61
            }
62
            $this->saveNamedParam($namedParams, $instance, $methodName);
63
            // method annotation
64
            $reader->getMethodAnnotations($method);
65
        }
66
    }
67
68
    private function isMagicMethod($method)
69
    {
70
        return in_array($method, ['__sleep', '__wakeup', 'offsetGet', 'offsetSet', 'offsetExists', 'offsetUnset', 'count', 'ksort', 'asort', 'jsonSerialize'], true);
71
    }
72
73
    private function saveNamedParam(NamedParameterInterface $namedParameter, $instance, $method)
74
    {
75
        // named parameter
76
        if (! in_array($method, ['onGet', 'onPost', 'onPut', 'onPatch', 'onDelete', 'onHead'], true)) {
77
            return;
78
        }
79
        try {
80
            $namedParameter->getParameters([$instance, $method], []);
81
        } catch (ParameterException $e) {
82
            return;
83
        }
84
    }
85
}
86