Completed
Push — master ( a2c36c...334094 )
by yuuki
01:58
created

RayAspectKernel::aspectConfiguration()   C

Complexity

Conditions 7
Paths 14

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 15
nc 14
nop 0
1
<?php
2
3
/**
4
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10
 * THE SOFTWARE.
11
 *
12
 * This software consists of voluntary contributions made by many individuals
13
 * and is licensed under the MIT license.
14
 *
15
 * Copyright (c) 2015-2016 Yuuki Takezawa
16
 *
17
 */
18
namespace Ytake\LaravelAspect;
19
20
use Ray\Aop\Compiler;
21
use Illuminate\Filesystem\Filesystem;
22
use Illuminate\Contracts\Container\Container;
23
use Ytake\LaravelAspect\Modules\AspectModule;
24
use Ytake\LaravelAspect\Exception\ClassNotFoundException;
25
26
/**
27
 * Class RayAspectKernel
28
 */
29
class RayAspectKernel implements AspectDriverInterface
30
{
31
    /** @var Container|\Illuminate\Container\Container */
32
    protected $app;
33
34
    /** @var array */
35
    protected $configure;
36
37
    /** @var Compiler */
38
    protected $compiler;
39
40
    /** @var Filesystem */
41
    protected $filesystem;
42
43
    /** @var bool */
44
    protected $cacheable = false;
45
46
    /** @var AspectModule */
47
    protected $aspectResolver;
48
49
    /** @var AspectModule[] */
50
    protected $registerModules = [];
51
52
    /** @var AspectModule[] */
53
    protected $modules = [];
54
55
    /** @var string */
56
    private $mapFile = 'aspect.map.serialize';
57
58
    /**
59
     * RayAspectKernel constructor.
60
     *
61
     * @param Container  $app
62
     * @param Filesystem $filesystem
63
     * @param array      $configure
64
     */
65
    public function __construct(Container $app, Filesystem $filesystem, array $configure)
66
    {
67
        $this->app = $app;
68
        $this->filesystem = $filesystem;
69
        $this->configure = $configure;
70
        $this->makeCompileDir();
71
        $this->makeCacheableDir();
72
        $this->registerAspectModule();
73
    }
74
75
    /**
76
     * @param null|string $module
77
     *
78
     * @throws ClassNotFoundException
79
     */
80
    public function register($module = null)
81
    {
82
        if (!class_exists($module)) {
83
            throw new ClassNotFoundException($module);
84
        }
85
        $this->modules[] = new $module;
86
    }
87
88
    /**
89
     * weaving
90
     */
91
    public function weave()
92
    {
93
        if (!count($this->modules)) {
94
            return;
95
        }
96
        $compiler = $this->getCompiler();
97
        $container = $this->containerAdaptor($this->app);
98
        foreach ($this->aspectConfiguration() as $class => $pointcuts) {
99
            $bind = (new AspectBind($this->filesystem, $this->configure['cache_dir'], $this->cacheable))
100
                ->bind($class, $pointcuts);
0 ignored issues
show
Documentation introduced by
$pointcuts is of type string, but the function expects a array.

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...
101
            $container->intercept($class, $bind, $compiler->compile($class, $bind));
102
        }
103
    }
104
105
    /**
106
     * @deprecated
107
     * boot aspect kernel
108
     */
109
    public function dispatch()
110
    {
111
        $this->weave();
112
    }
113
114
    /**
115
     * @param Container $container
116
     *
117
     * @return ContainerInterceptor
118
     */
119
    protected function containerAdaptor(Container $container)
120
    {
121
        return new ContainerInterceptor($container);
0 ignored issues
show
Compatibility introduced by
$container of type object<Illuminate\Contracts\Container\Container> is not a sub-type of object<Illuminate\Container\Container>. It seems like you assume a concrete implementation of the interface Illuminate\Contracts\Container\Container to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
122
    }
123
124
    /**
125
     * @return Compiler
126
     */
127
    protected function getCompiler()
128
    {
129
        return new Compiler($this->configure['compile_dir']);
130
    }
131
132
    /**
133
     * make source compile file directory
134
     */
135
    protected function makeCompileDir()
136
    {
137
        $this->makeDirectories($this->configure['compile_dir'], 0775);
138
    }
139
140
    /**
141
     * make aspect cache directory
142
     *
143
     * @codeCoverageIgnore
144
     */
145
    protected function makeCacheableDir()
146
    {
147
        if ($this->configure['cache']) {
148
            $this->makeDirectories($this->configure['cache_dir'], 0775);
149
            $this->cacheable = true;
150
        }
151
    }
152
153
    /**
154
     * @param string $dir
155
     * @param int    $mode
156
     */
157
    private function makeDirectories($dir, $mode = 0777)
158
    {
159
        // @codeCoverageIgnoreStart
160
        if (!$this->filesystem->exists($dir)) {
161
            $this->filesystem->makeDirectory($dir, $mode, true);
162
        }
163
        // @codeCoverageIgnoreEnd
164
    }
165
166
    /**
167
     * register Aspect Module
168
     */
169
    protected function registerAspectModule()
170
    {
171
        if (isset($this->configure['modules'])) {
172
            foreach ($this->configure['modules'] as $module) {
173
                $this->register($module);
174
            }
175
        }
176
    }
177
178
    /**
179
     * @return string[]
180
     * @codeCoverageIgnore
181
     */
182
    protected function aspectConfiguration()
183
    {
184
        $map = [];
185
        $file = $this->configure['cache_dir'] . "/{$this->mapFile}";
186
        if ($this->configure['cache']) {
187
            if ($this->filesystem->exists($file)) {
188
                foreach ($this->modules as $module) {
189
                    $module->registerPointCut()->configure($this->app);
190
                }
191
192
                return unserialize($this->filesystem->get($file));
193
            }
194
        }
195
        foreach ($this->modules as $module) {
196
            $pointcut = $module->registerPointCut()->configure($this->app);
197
            foreach ($module->target() as $class) {
198
                $map[$class][] = $pointcut;
199
            }
200
        }
201
        if ($this->configure['cache']) {
202
            $this->filesystem->put($file, serialize($map));
203
        }
204
205
        return $map;
206
    }
207
}
208