Completed
Push — master ( 9ceba4...dba48d )
by Biao
03:08
created

Laravel::createAppKernel()   B

Complexity

Conditions 10
Paths 24

Size

Total Lines 58
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 31
nc 24
nop 0
dl 0
loc 58
rs 7.6666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
namespace Hhxsv5\LaravelS\Illuminate;
4
5
use Hhxsv5\LaravelS\Illuminate\Cleaners\CleanerInterface;
6
use Illuminate\Container\Container;
7
use Illuminate\Contracts\Console\Kernel as ConsoleKernel;
8
use Illuminate\Contracts\Http\Kernel as HttpKernel;
9
use Illuminate\Http\Request as IlluminateRequest;
10
use Symfony\Component\HttpFoundation\BinaryFileResponse;
11
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
12
13
class Laravel
14
{
15
    /**@var Container */
16
    protected $app;
17
18
    /**@var Container */
19
    protected $snapshotApp;
20
21
    /**@var HttpKernel */
22
    protected $kernel;
23
24
    /**@var array */
25
    protected $conf = [];
26
27
    /**@var array */
28
    protected static $staticBlackList = [
29
        '/index.php'  => 1,
30
        '/.htaccess'  => 1,
31
        '/web.config' => 1,
32
    ];
33
34
    /**@var array */
35
    private $rawGlobals = [];
36
37
    public function __construct(array $conf = [])
38
    {
39
        $this->conf = $conf;
40
41
        // Merge $_ENV $_SERVER
42
        $server = isset($this->conf['_SERVER']) ? $this->conf['_SERVER'] : [];
43
        $env = isset($this->conf['_ENV']) ? $this->conf['_ENV'] : [];
44
        $this->rawGlobals['_SERVER'] = array_merge($_SERVER, $server);
45
        $this->rawGlobals['_ENV'] = array_merge($_ENV, $env);
46
    }
47
48
    public function prepareLaravel()
49
    {
50
51
        list($this->app, $this->kernel) = $this->createAppKernel();
52
        list($this->snapshotApp,) = $this->createAppKernel();
53
    }
54
55
    public function createAppKernel()
56
    {
57
        // Register autoload
58
        static::autoload($this->conf['root_path']);
59
60
        // Make kernel for Laravel
61
        $kernel = null;
62
        $app = require $this->conf['root_path'] . '/bootstrap/app.php';
63
        if (!$this->conf['is_lumen']) {
64
            $kernel = $app->make(HttpKernel::class);
65
        }
66
67
        // Load all Configurations for Lumen
68
        if ($this->conf['is_lumen']) {
69
            $cfgPaths = [
70
                // Framework default configuration
71
                $this->conf['root_path'] . '/vendor/laravel/lumen-framework/config/',
72
                // App configuration
73
                $this->conf['root_path'] . '/config/',
74
            ];
75
            $keys = [];
76
            foreach ($cfgPaths as $cfgPath) {
77
                $configs = (array)glob($cfgPath . '*.php');
78
                foreach ($configs as $config) {
79
                    $config = substr(basename($config), 0, -4);
80
                    $keys[$config] = $config;
81
                }
82
            }
83
            foreach ($keys as $key) {
84
                $app->configure($key);
85
            }
86
        }
87
88
        // Boot
89
        if ($this->conf['is_lumen']) {
90
            if (method_exists($app, 'boot')) {
91
                $app->boot();
92
            }
93
        } else {
94
            $app->make(ConsoleKernel::class)->bootstrap();
95
        }
96
97
        // Bind singleton cleaners
98
        foreach ($this->conf['cleaners'] as $cleaner) {
99
            $app->singleton($cleaner, function ($app) use ($cleaner) {
0 ignored issues
show
Unused Code introduced by
The parameter $app is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

99
            $app->singleton($cleaner, function (/** @scrutinizer ignore-unused */ $app) use ($cleaner) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
100
                if (!isset(class_implements($cleaner)[CleanerInterface::class])) {
101
                    throw new \InvalidArgumentException(sprintf(
102
                            '%s must implement the interface %s',
103
                            $cleaner,
104
                            CleanerInterface::class
105
                        )
106
                    );
107
                }
108
                return new $cleaner();
109
            });
110
        }
111
112
        return [$app, $kernel];
113
    }
114
115
    public static function autoload($rootPath)
116
    {
117
        $autoload = $rootPath . '/bootstrap/autoload.php';
118
        if (file_exists($autoload)) {
119
            require_once $autoload;
120
        } else {
121
            require_once $rootPath . '/vendor/autoload.php';
122
        }
123
    }
124
125
    public function getRawGlobals()
126
    {
127
        return $this->rawGlobals;
128
    }
129
130
    public function handleDynamic(IlluminateRequest $request)
131
    {
132
        ob_start();
133
134
        if ($this->conf['is_lumen']) {
135
            $response = $this->app->dispatch($request);
0 ignored issues
show
Bug introduced by
The method dispatch() does not exist on Illuminate\Container\Container. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

135
            /** @scrutinizer ignore-call */ 
136
            $response = $this->app->dispatch($request);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
136
            if ($response instanceof SymfonyResponse) {
137
                $content = $response->getContent();
138
            } else {
139
                $content = (string)$response;
140
            }
141
142
            $laravelReflect = new \ReflectionObject($this->app);
143
            $middleware = $laravelReflect->getProperty('middleware');
144
            $middleware->setAccessible(true);
145
            if (!empty($middleware->getValue($this->app))) {
146
                $callTerminableMiddleware = $laravelReflect->getMethod('callTerminableMiddleware');
147
                $callTerminableMiddleware->setAccessible(true);
148
                $callTerminableMiddleware->invoke($this->app, $response);
149
            }
150
        } else {
151
            $response = $this->kernel->handle($request);
152
            $content = $response->getContent();
153
            $this->kernel->terminate($request, $response);
154
        }
155
156
        // prefer content in response, secondly ob
157
        if (strlen($content) === 0 && ob_get_length() > 0) {
158
            $response->setContent(ob_get_contents());
159
        }
160
161
        ob_end_clean();
162
163
        return $response;
164
    }
165
166
    public function handleStatic(IlluminateRequest $request)
167
    {
168
        $uri = $request->getRequestUri();
169
        if (isset(self::$staticBlackList[$uri])) {
170
            return false;
171
        }
172
173
        $publicPath = $this->conf['static_path'];
174
        $requestFile = $publicPath . $uri;
175
        if (is_file($requestFile)) {
176
            return $this->createStaticResponse($requestFile, $request);
177
        } elseif (is_dir($requestFile)) {
178
            $indexFile = $this->lookupIndex($requestFile);
179
            if ($indexFile === false) {
180
                return false;
181
            } else {
182
                return $this->createStaticResponse($indexFile, $request);
183
            }
184
        } else {
185
            return false;
186
        }
187
    }
188
189
    protected function lookupIndex($folder)
190
    {
191
        $folder = rtrim($folder, '/') . '/';
192
        foreach (['index.html', 'index.htm'] as $index) {
193
            $tmpFile = $folder . $index;
194
            if (is_file($tmpFile)) {
195
                return $tmpFile;
196
            }
197
        }
198
        return false;
199
    }
200
201
    public function createStaticResponse($requestFile, IlluminateRequest $request)
202
    {
203
        $response = new BinaryFileResponse($requestFile);
204
        $response->prepare($request);
205
        $response->isNotModified($request);
206
        return $response;
207
    }
208
209
    protected function cleanProviders(array $providers, $force = false)
210
    {
211
        if ($this->conf['is_lumen']) {
212
            $laravelReflect = new \ReflectionObject($this->app);
213
            $loadedProviders = $laravelReflect->getProperty('loadedProviders');
214
            $loadedProviders->setAccessible(true);
215
            $oldLoadedProviders = $loadedProviders->getValue($this->app);
216
        }
217
218
        foreach ($providers as $provider) {
219
            if ($force || class_exists($provider, false)) {
220
                if ($this->conf['is_lumen']) {
221
                    unset($oldLoadedProviders[get_class(new $provider($this->app))]);
222
                }
223
                $this->app->register($provider, [], true);
0 ignored issues
show
introduced by
The method register() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

223
                $this->app->/** @scrutinizer ignore-call */ 
224
                            register($provider, [], true);
Loading history...
224
            }
225
        }
226
227
        if ($this->conf['is_lumen']) {
228
            $loadedProviders->setValue($this->app, $oldLoadedProviders);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $loadedProviders does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $oldLoadedProviders does not seem to be defined for all execution paths leading up to this point.
Loading history...
229
        }
230
    }
231
232
    public function clean()
233
    {
234
        foreach ($this->conf['cleaners'] as $cleanerCls) {
235
            /**@var CleanerInterface $cleaner */
236
            $cleaner = $this->app->make($cleanerCls);
237
            $cleaner->clean($this->app, $this->snapshotApp);
238
        }
239
240
        $this->cleanProviders($this->conf['register_providers']);
241
    }
242
243
    public function fireEvent($name, array $params = [])
244
    {
245
        $params[] = $this->app;
246
        return method_exists($this->app['events'], 'dispatch') ?
247
            $this->app['events']->dispatch($name, $params) : $this->app['events']->fire($name, $params);
0 ignored issues
show
Bug introduced by
The method dispatch() does not exist on Illuminate\Events\Dispatcher. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

247
            $this->app['events']->/** @scrutinizer ignore-call */ 
248
                                  dispatch($name, $params) : $this->app['events']->fire($name, $params);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
248
    }
249
250
    public function bindRequest(IlluminateRequest $request)
251
    {
252
        $this->app->instance('request', $request);
253
    }
254
255
    public function bindSwoole($swoole)
256
    {
257
        $this->app->singleton('swoole', function () use ($swoole) {
258
            return $swoole;
259
        });
260
    }
261
262
    public function make($abstract, array $parameters = [])
263
    {
264
        return $this->app->make($abstract, $parameters);
265
    }
266
267
    public function saveSession()
268
    {
269
        if ($this->app->offsetExists('session')) {
270
            $this->app['session']->save();
271
        }
272
    }
273
}
274