Completed
Push — 2.x ( 98b57b...8b2aa1 )
by Alexander
05:24
created

GoAspectContainer   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 15

Test Coverage

Coverage 76.4%

Importance

Changes 0
Metric Value
wmc 16
lcom 2
cbo 15
dl 0
loc 220
ccs 68
cts 89
cp 0.764
rs 9.1666
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
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
B __construct() 0 93 5
1
<?php
2
/*
3
 * Go! AOP framework
4
 *
5
 * @copyright Copyright 2012, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Go\Core;
12
13
use Doctrine\Common\Annotations\CachedReader;
14
use Doctrine\Common\Cache as DoctrineCache;
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
    public function __construct()
46
    {
47
        // Register all services in the container
48 10
        $this->share('aspect.loader', function (Container $container) {
49 2
            $aspectLoader = new AspectLoader(
50 2
                $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 10
        });
62
63 10
        $this->share('aspect.cached.loader', function (Container $container) {
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
            } else {
72
                $loader = $container->get('aspect.loader');
73
            }
74
75
            return $loader;
76 10
        });
77
78 10
        $this->share('aspect.advisor.accessor', function (Container $container) {
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
                $container->get('aspect.cached.loader')
82
            );
83 10
        });
84
85 10
        $this->share('aspect.advice_matcher', function (Container $container) {
86 1
            return new AdviceMatcher(
87 1
                $container->get('aspect.loader'),
88 1
                $container->get('kernel.interceptFunctions')
89
            );
90 10
        });
91
92 10
        $this->share('aspect.annotation.cache', function (Container $container) {
93 5
            $options = $container->get('kernel.options');
94
95 5
            if (!empty($options['annotationCache'])) {
96
                return $options['annotationCache'];
97
            }
98
99 5
            if (!empty($options['cacheDir'])) {
100
                return new DoctrineCache\FilesystemCache(
101
                    $options['cacheDir'] . DIRECTORY_SEPARATOR . '_annotations' . DIRECTORY_SEPARATOR,
102
                    '.annotations.cache',
103
                    0777 & (~$options['cacheFileMode'])
104
                );
105
            }
106
107 5
            return new DoctrineCache\ArrayCache();
108 10
        });
109
110 10
        $this->share('aspect.annotation.reader', function (Container $container) {
111 4
            $options = $container->get('kernel.options');
112 4
            $options['debug'] = isset($options['debug']) ? $options['debug'] : false;
113
114 4
            return new CachedReader(
115 4
                new AnnotationReader(),
116 4
                $container->get('aspect.annotation.cache'),
117 4
                $options['debug']
118
            );
119 10
        });
120
121 10
        $this->share('aspect.cache.path.manager', function (Container $container) {
122
            return new CachePathManager($container->get('kernel'));
123 10
        });
124
125
        // Pointcut services
126 10
        $this->share('aspect.pointcut.lexer', function () {
127 3
            return new PointcutLexer();
128 10
        });
129 10
        $this->share('aspect.pointcut.parser', function (Container $container) {
130 3
            return new PointcutParser(
131 3
                new PointcutGrammar(
132 3
                    $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...
133 3
                    $container->get('aspect.annotation.reader')
134
                )
135
            );
136 10
        });
137 10
    }
138
139
    /**
140
     * Returns a pointcut by identifier
141
     *
142
     * @param string $id Pointcut identifier
143
     *
144
     * @return Aop\Pointcut
145
     */
146 1
    public function getPointcut($id)
147
    {
148 1
        return $this->get("pointcut.{$id}");
149
    }
150
151
    /**
152
     * Store the pointcut in the container
153
     *
154
     * @param Aop\Pointcut $pointcut Instance
155
     * @param string $id Key for pointcut
156
     */
157 1
    public function registerPointcut(Aop\Pointcut $pointcut, $id)
158
    {
159 1
        $this->set("pointcut.{$id}", $pointcut, ['pointcut']);
160 1
    }
161
162
    /**
163
     * Returns an advisor by identifier
164
     *
165
     * @param string $id Advisor identifier
166
     *
167
     * @return Aop\Advisor
168
     */
169
    public function getAdvisor($id)
170
    {
171
        return $this->get("advisor.{$id}");
172
    }
173
174
    /**
175
     * Store the advisor in the container
176
     *
177
     * @param Aop\Advisor $advisor Instance
178
     * @param string $id Key for advisor
179
     */
180 1
    public function registerAdvisor(Aop\Advisor $advisor, $id)
181
    {
182 1
        $this->set("advisor.{$id}", $advisor, ['advisor']);
183 1
    }
184
185
    /**
186
     * Returns an aspect by id or class name
187
     *
188
     * @param string $aspectName Aspect name
189
     *
190
     * @return Aop\Aspect
191
     */
192 1
    public function getAspect($aspectName)
193
    {
194 1
        return $this->get("aspect.{$aspectName}");
195
    }
196
197
    /**
198
     * Register an aspect in the container
199
     *
200
     * @param Aop\Aspect $aspect Instance of concrete aspect
201
     */
202 1
    public function registerAspect(Aop\Aspect $aspect)
203
    {
204 1
        $refAspect = new ReflectionClass($aspect);
205 1
        $this->set("aspect.{$refAspect->name}", $aspect, ['aspect']);
206 1
        $this->addResource($refAspect->getFileName());
207 1
    }
208
209
    /**
210
     * Add an AOP resource to the container
211
     *
212
     * Resources is used to check the freshness of AOP cache
213
     */
214 2
    public function addResource($resource)
215
    {
216 2
        $this->resources[]  = $resource;
217 2
        $this->maxTimestamp = 0;
218 2
    }
219
220
    /**
221
     * Returns list of AOP resources
222
     *
223
     * @return array
224
     */
225
    public function getResources()
226
    {
227
        return $this->resources;
228
    }
229
230
    /**
231
     * Checks the freshness of AOP cache
232
     *
233
     * @param integer $timestamp
234
     *
235
     * @return bool Whether or not concrete file is fresh
236
     */
237 1
    public function isFresh($timestamp)
238
    {
239 1
        if (!$this->maxTimestamp && !empty($this->resources)) {
240 1
            $this->maxTimestamp = max(array_map('filemtime', $this->resources));
241
        }
242
243 1
        return $this->maxTimestamp <= $timestamp;
244
    }
245
}
246