Completed
Pull Request — master (#320)
by Alexander
03:17
created

GoAspectContainer   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 205
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 13

Test Coverage

Coverage 86.67%

Importance

Changes 0
Metric Value
wmc 14
lcom 2
cbo 13
dl 0
loc 205
ccs 52
cts 60
cp 0.8667
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 78 3
A getPointcut() 0 4 1
A registerPointcut() 0 4 1
A getAdvisor() 0 4 1
A registerAdvisor() 0 4 1
A getAspect() 0 4 1
A registerAspect() 0 6 1
A addResource() 0 5 1
A getResources() 0 4 1
A isFresh() 0 8 3
1
<?php
2
declare(strict_types = 1);
3
/*
4
 * Go! AOP framework
5
 *
6
 * @copyright Copyright 2012, Lisachenko Alexander <[email protected]>
7
 *
8
 * This source file is subject to the license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Go\Core;
13
14
use Doctrine\Common\Annotations\FileCacheReader;
15
use ReflectionClass;
16
use Go\Aop;
17
use Go\Aop\Pointcut\PointcutLexer;
18
use Go\Aop\Pointcut\PointcutGrammar;
19
use Go\Aop\Pointcut\PointcutParser;
20
use Go\Instrument\ClassLoading\CachePathManager;
21
use Doctrine\Common\Annotations\AnnotationReader;
22
23
/**
24
 * Aspect container contains list of all pointcuts and advisors
25
 */
26
class GoAspectContainer extends Container implements AspectContainer
27
{
28
    /**
29
     * List of resources for application
30
     *
31
     * @var array
32
     */
33
    protected $resources = [];
34
35
    /**
36
     * Cached timestamp for resources
37
     *
38
     * @var integer
39
     */
40
    protected $maxTimestamp = 0;
41
42
    /**
43
     * Constructor for container
44
     */
45 9
    public function __construct()
46
    {
47
        // Register all services in the container
48
        $this->share('aspect.loader', function(Container $container) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
49 2
            $aspectLoader = new AspectLoader(
50
                $container,
0 ignored issues
show
Documentation introduced by
$container is of type object<Go\Core\Container>, but the function expects a object<Go\Core\AspectContainer>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
51 2
                $container->get('aspect.annotation.reader')
52
            );
53 2
            $lexer  = $container->get('aspect.pointcut.lexer');
54 2
            $parser = $container->get('aspect.pointcut.parser');
55
56
            // Register general aspect loader extension
57 2
            $aspectLoader->registerLoaderExtension(new GeneralAspectLoaderExtension($lexer, $parser));
58 2
            $aspectLoader->registerLoaderExtension(new IntroductionAspectExtension($lexer, $parser));
59
60 2
            return $aspectLoader;
61 9
        });
62
63
        $this->share('aspect.cached.loader', function(Container $container) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
64
            $options = $container->get('kernel.options');
65
            if (!empty($options['cacheDir'])) {
66
                $loader = new CachedAspectLoader(
67
                    $container,
0 ignored issues
show
Documentation introduced by
$container is of type object<Go\Core\Container>, but the function expects a object<Go\Core\AspectContainer>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
68
                    'aspect.loader',
69
                    $container->get('kernel.options')
70
                );
71 9
            } else {
72
                $loader = $container->get('aspect.loader');
73
            }
74
75
            return $loader;
76
        });
77
78 9
        $this->share('aspect.advisor.accessor', function(Container $container) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
79
            return new LazyAdvisorAccessor(
80
                $container,
0 ignored issues
show
Documentation introduced by
$container is of type object<Go\Core\Container>, but the function expects a object<Go\Core\AspectContainer>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
81 1
                $container->get('aspect.cached.loader')
82 1
            );
83 1
        });
84
85 9
        $this->share('aspect.advice_matcher', function(Container $container) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
86
            return new AdviceMatcher(
87
                $container->get('aspect.loader'),
88 4
                $container->get('kernel.interceptFunctions')
89 4
            );
90 4
        });
91
92
        $this->share('aspect.annotation.reader', function(Container $container) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
93
            $options = $container->get('kernel.options');
94
            $reader  = new AnnotationReader();
95
            if (!empty($options['cacheDir'])) {
96
                $reader = new FileCacheReader(
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Annotations\FileCacheReader has been deprecated with message: the FileCacheReader is deprecated and will be removed in version 2.0.0 of doctrine/annotations. Please use the {@see \Doctrine\Common\Annotations\CachedReader} instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
97
                    $reader,
98
                    $options['cacheDir'] . DIRECTORY_SEPARATOR . '_annotations' . DIRECTORY_SEPARATOR,
99 4
                    $options['debug'],
100 9
                    0777 & (~$options['cacheFileMode'])
101
                );
102
            }
103 9
104
            return $reader;
105
        });
106
        $this->share('aspect.cache.path.manager', function(Container $container) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
107 3
            return new CachePathManager($container->get('kernel'));
108 9
        });
109 9
110 3
        // Pointcut services
111 3
        $this->share('aspect.pointcut.lexer', function() {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
112
            return new PointcutLexer();
113 3
        });
114
        $this->share('aspect.pointcut.parser', function(Container $container) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
115
            return new PointcutParser(
116 9
                new PointcutGrammar(
117 9
                    $container,
0 ignored issues
show
Documentation introduced by
$container is of type object<Go\Core\Container>, but the function expects a object<Go\Core\AspectContainer>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
118
                    $container->get('aspect.annotation.reader')
119
                )
120
            );
121
        });
122
    }
123
124
    /**
125
     * Returns a pointcut by identifier
126 1
     *
127
     * @param string $id Pointcut identifier
128 1
     *
129
     * @return Aop\Pointcut
130
     */
131
    public function getPointcut($id)
132
    {
133
        return $this->get("pointcut.{$id}");
134
    }
135
136
    /**
137 1
     * Store the pointcut in the container
138
     *
139 1
     * @param Aop\Pointcut $pointcut Instance
140 1
     * @param string $id Key for pointcut
141
     */
142
    public function registerPointcut(Aop\Pointcut $pointcut, $id)
143
    {
144
        $this->set("pointcut.{$id}", $pointcut, ['pointcut']);
145
    }
146
147
    /**
148
     * Returns an advisor by identifier
149
     *
150
     * @param string $id Advisor identifier
151
     *
152
     * @return Aop\Advisor
153
     */
154
    public function getAdvisor($id)
155
    {
156
        return $this->get("advisor.{$id}");
157
    }
158
159
    /**
160 1
     * Store the advisor in the container
161
     *
162 1
     * @param Aop\Advisor $advisor Instance
163 1
     * @param string $id Key for advisor
164
     */
165
    public function registerAdvisor(Aop\Advisor $advisor, $id)
166
    {
167
        $this->set("advisor.{$id}", $advisor, ['advisor']);
168
    }
169
170
    /**
171
     * Returns an aspect by id or class name
172 1
     *
173
     * @param string $aspectName Aspect name
174 1
     *
175
     * @return Aop\Aspect
176
     */
177
    public function getAspect($aspectName)
178
    {
179
        return $this->get("aspect.{$aspectName}");
180
    }
181
182 1
    /**
183
     * Register an aspect in the container
184 1
     *
185 1
     * @param Aop\Aspect $aspect Instance of concrete aspect
186 1
     */
187 1
    public function registerAspect(Aop\Aspect $aspect)
188
    {
189
        $refAspect = new ReflectionClass($aspect);
190
        $this->set("aspect.{$refAspect->name}", $aspect, ['aspect']);
191
        $this->addResource($refAspect->getFileName());
192
    }
193
194 2
    /**
195
     * Add an AOP resource to the container
196 2
     *
197 2
     * Resources is used to check the freshness of AOP cache
198 2
     */
199
    public function addResource($resource)
200
    {
201
        $this->resources[]  = $resource;
202
        $this->maxTimestamp = 0;
203
    }
204
205
    /**
206
     * Returns list of AOP resources
207
     *
208
     * @return array
209
     */
210
    public function getResources()
211
    {
212
        return $this->resources;
213
    }
214
215
    /**
216
     * Checks the freshness of AOP cache
217 1
     *
218
     * @param integer $timestamp
219 1
     *
220 1
     * @return bool Whether or not concrete file is fresh
221
     */
222
    public function isFresh($timestamp)
223 1
    {
224
        if (!$this->maxTimestamp && !empty($this->resources)) {
225
            $this->maxTimestamp = max(array_map('filemtime', $this->resources));
226
        }
227
228
        return $this->maxTimestamp <= $timestamp;
229
    }
230
}
231