Completed
Pull Request — master (#463)
by Alexander
30:17 queued 05:15
created

GoAspectContainer::__construct()   B

Complexity

Conditions 4
Paths 1

Size

Total Lines 91

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 50
CRAP Score 4.0009

Importance

Changes 0
Metric Value
dl 0
loc 91
ccs 50
cts 52
cp 0.9615
rs 8.1963
c 0
b 0
f 0
cc 4
nc 1
nop 0
crap 4.0009

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types = 1);
4
/*
5
 * Go! AOP framework
6
 *
7
 * @copyright Copyright 2012, Lisachenko Alexander <[email protected]>
8
 *
9
 * This source file is subject to the license that is bundled
10
 * with this source code in the file LICENSE.
11
 */
12
13
namespace Go\Core;
14
15
use Doctrine\Common\Annotations\AnnotationReader;
16
use Doctrine\Common\Annotations\CachedReader;
17
use Doctrine\Common\Cache as DoctrineCache;
18
use Go\Aop\Advisor;
19
use Go\Aop\Aspect;
20
use Go\Aop\Pointcut;
21
use Go\Aop\Pointcut\PointcutGrammar;
22
use Go\Aop\Pointcut\PointcutLexer;
23
use Go\Aop\Pointcut\PointcutParser;
24
use Go\Instrument\ClassLoading\CachePathManager;
25
use ReflectionClass;
26
27
/**
28
 * Aspect container contains list of all pointcuts and advisors
29
 */
30
class GoAspectContainer extends Container
31
{
32
    /**
33
     * List of resources for application
34
     *
35
     * @var string[]
36
     */
37
    protected array $resources = [];
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_ARRAY, expecting T_FUNCTION or T_CONST
Loading history...
38
39
    /**
40
     * Cached timestamp for resources
41
     */
42
    protected int $maxTimestamp = 0;
43
44
    /**
45
     * Constructor for container
46
     */
47
    public function __construct()
48 11
    {
49
        // Register all services in the container
50
        $this->share('aspect.loader', function (Container $container) {
51
            $aspectLoader = new AspectLoader(
52 2
                $container,
53 2
                $container->get('aspect.annotation.reader')
54 2
            );
55
            $lexer  = $container->get('aspect.pointcut.lexer');
56 2
            $parser = $container->get('aspect.pointcut.parser');
57 2
58
            // Register general aspect loader extension
59
            $aspectLoader->registerLoaderExtension(new GeneralAspectLoaderExtension($lexer, $parser));
60 2
            $aspectLoader->registerLoaderExtension(new IntroductionAspectExtension($lexer, $parser));
61 2
62
            return $aspectLoader;
63 2
        });
64 11
65
        $this->share('aspect.cached.loader', function (Container $container) {
66
            $options = $container->get('kernel.options');
67 1
            if (!empty($options['cacheDir'])) {
68 1
                $loader = new CachedAspectLoader(
69 1
                    $container,
70 1
                    'aspect.loader',
71 1
                    $container->get('kernel.options')
72 1
                );
73
            } else {
74
                $loader = $container->get('aspect.loader');
75
            }
76
77
            return $loader;
78 1
        });
79 11
80
        $this->share('aspect.advisor.accessor', fn(Container $container) => new LazyAdvisorAccessor(
81
            $container,
82 1
            $container->get('aspect.cached.loader')
83 1
        ));
84 1
85
        $this->share('aspect.advice_matcher', fn(Container $container) => new AdviceMatcher(
86 11
            $container->get('kernel.interceptFunctions')
87
        ));
88
89 2
        $this->share('aspect.annotation.cache', function (Container $container) {
90 2
            $options = $container->get('kernel.options');
91
92 11
            if (!empty($options['annotationCache'])) {
93
                return $options['annotationCache'];
94
            }
95 5
96
            if (!empty($options['cacheDir'])) {
97 5
                return new DoctrineCache\FilesystemCache(
98
                    $options['cacheDir'] . DIRECTORY_SEPARATOR . '_annotations' . DIRECTORY_SEPARATOR,
99
                    '.annotations.cache',
100
                    0777 & (~$options['cacheFileMode'])
101 5
                );
102 1
            }
103 1
104 1
            return new DoctrineCache\ArrayCache();
105 1
        });
106
107
        $this->share('aspect.annotation.reader', function (Container $container) {
108
            $options = $container->get('kernel.options');
109 4
110 11
            return new CachedReader(
111
                new AnnotationReader(),
112
                $container->get('aspect.annotation.cache'),
113 4
                $options['debug'] ?? false
114
            );
115 4
        });
116 4
117 4
        $this->share('aspect.cache.path.manager', fn(Container $container) => new CachePathManager($container->get('kernel')));
118 4
119
        // Pointcut services
120 11
        $this->share('aspect.pointcut.lexer', fn() => new PointcutLexer());
121
        $this->share('aspect.pointcut.parser', fn(Container $container) => new PointcutParser(
122
            new PointcutGrammar(
123 1
                $container,
124 11
                $container->get('aspect.annotation.reader')
125
            )
126
        ));
127
    }
128 3
129 11
    /**
130
     * Returns a pointcut by identifier
131 3
     */
132 3
    public function getPointcut(string $id): Pointcut
133 3
    {
134 3
        return $this->get("pointcut.{$id}");
135
    }
136
137 11
    /**
138 11
     * Store the pointcut in the container
139
     */
140
    public function registerPointcut(Pointcut $pointcut, string $id): void
141
    {
142
        $this->set("pointcut.{$id}", $pointcut, ['pointcut']);
143 1
    }
144
145 1
    /**
146
     * Returns an advisor by identifier
147
     */
148
    public function getAdvisor(string $id): Advisor
149
    {
150
        return $this->get("advisor.{$id}");
151 1
    }
152
153 1
    /**
154 1
     * Store the advisor in the container
155
     */
156
    public function registerAdvisor(Advisor $advisor, string $id): void
157
    {
158
        $this->set("advisor.{$id}", $advisor, ['advisor']);
159
    }
160
161
    /**
162
     * Returns an aspect by id or class name
163
     */
164
    public function getAspect(string $aspectName): Aspect
165
    {
166
        return $this->get("aspect.{$aspectName}");
167 2
    }
168
169 2
    /**
170 2
     * Register an aspect in the container
171
     */
172
    public function registerAspect(Aspect $aspect): void
173
    {
174
        $refAspect = new ReflectionClass($aspect);
175 1
        $this->set("aspect.{$refAspect->name}", $aspect, ['aspect']);
176
        $this->addResource($refAspect->getFileName());
177 1
    }
178
179
    /**
180
     * Add an AOP resource to the container
181
     * Resources is used to check the freshness of AOP cache
182
     *
183 2
     * @param string $resource Path to the resource
184
     */
185 2
    public function addResource(string $resource): void
186 2
    {
187 2
        $this->resources[]  = $resource;
188 2
        $this->maxTimestamp = 0;
189
    }
190
191
    /**
192
     * Returns list of AOP resources
193
     */
194
    public function getResources(): array
195
    {
196 3
        return $this->resources;
197
    }
198 3
199 3
    /**
200 3
     * Checks the freshness of AOP cache
201
     *
202
     * @return bool Whether or not concrete file is fresh
203
     */
204
    public function isFresh(int $timestamp): bool
205
    {
206
        if (!$this->maxTimestamp && !empty($this->resources)) {
207
            $this->maxTimestamp = max(array_map('filemtime', $this->resources));
208
        }
209
210
        return $this->maxTimestamp <= $timestamp;
211
    }
212
}
213