Completed
Push — master ( 3d9b8b...c8d44c )
by Biao
03:12
created

Laravel::setLaravel()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 8
nop 0
dl 0
loc 11
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace Hhxsv5\LaravelS\Illuminate;
4
5
use Hhxsv5\LaravelS\Illuminate\Cleaners\SessionCleaner;
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 HttpKernel */
19
    protected $kernel;
20
21
    /**@var array */
22
    protected $snapshots = [];
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
42
    public function prepareLaravel()
43
    {
44
        static::autoload($this->conf['root_path']);
45
        $this->createApp();
46
        $this->createKernel();
47
        $this->setLaravel();
48
        $this->loadAllConfigurations();
49
        $this->bootstrap();
50
        $this->saveSnapshots();
51
    }
52
53
    public static function autoload($rootPath)
54
    {
55
        $autoload = $rootPath . '/bootstrap/autoload.php';
56
        if (file_exists($autoload)) {
57
            require_once $autoload;
58
        } else {
59
            require_once $rootPath . '/vendor/autoload.php';
60
        }
61
    }
62
63
    protected function createApp()
64
    {
65
        $this->app = require $this->conf['root_path'] . '/bootstrap/app.php';
66
    }
67
68
    protected function createKernel()
69
    {
70
        if (!$this->conf['is_lumen']) {
71
            $this->kernel = $this->app->make(HttpKernel::class);
72
        }
73
    }
74
75
    protected function setLaravel()
76
    {
77
        // Load configuration laravel.php manually for Lumen
78
        if ($this->conf['is_lumen'] && file_exists($this->conf['root_path'] . '/config/laravels.php')) {
79
            $this->app->configure('laravels');
0 ignored issues
show
Bug introduced by
The method configure() 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

79
            $this->app->/** @scrutinizer ignore-call */ 
80
                        configure('laravels');

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...
80
        }
81
82
        $server = isset($this->conf['_SERVER']) ? $this->conf['_SERVER'] : [];
83
        $env = isset($this->conf['_ENV']) ? $this->conf['_ENV'] : [];
84
        $this->rawGlobals['_SERVER'] = array_merge($_SERVER, $server);
85
        $this->rawGlobals['_ENV'] = array_merge($_ENV, $env);
86
    }
87
88
    protected function bootstrap()
89
    {
90
        if ($this->conf['is_lumen']) {
91
            if (method_exists($this->app, 'boot')) {
92
                $this->app->boot();
93
            }
94
        } else {
95
            $this->app->make(ConsoleKernel::class)->bootstrap();
96
        }
97
98
        foreach ($this->conf['cleaners'] as $cleanerCls) {
99
            $this->app->singleton($cleanerCls, function ($app) use ($cleanerCls) {
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
            $this->app->singleton($cleanerCls, function (/** @scrutinizer ignore-unused */ $app) use ($cleanerCls) {

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
                return new $cleanerCls();
101
            });
102
        }
103
    }
104
105
    public function loadAllConfigurations()
106
    {
107
        if (!$this->conf['is_lumen']) {
108
            return;
109
        }
110
111
        $cfgPaths = [
112
            // Framework default configuration
113
            $this->conf['root_path'] . '/vendor/laravel/lumen-framework/config/',
114
            // App configuration
115
            $this->conf['root_path'] . '/config/',
116
        ];
117
        $keys = [];
118
        foreach ($cfgPaths as $cfgPath) {
119
            $configs = (array)glob($cfgPath . '*.php');
120
            foreach ($configs as $config) {
121
                $config = substr(basename($config), 0, -4);
122
                $keys[$config] = $config;
123
            }
124
        }
125
        foreach ($keys as $key) {
126
            $this->app->configure($key);
127
        }
128
    }
129
130
    protected function saveSnapshots()
131
    {
132
        $this->snapshots['config'] = $this->app['config']->all();
133
    }
134
135
    protected function applySnapshots()
136
    {
137
        $this->app['config']->set($this->snapshots['config']);
138
        if (isset($this->app['cookie'])) {
139
            foreach ($this->app['cookie']->getQueuedCookies() as $name => $cookie) {
140
                $this->app['cookie']->unqueue($name);
141
            }
142
        }
143
    }
144
145
    public function getRawGlobals()
146
    {
147
        return $this->rawGlobals;
148
    }
149
150
    public function handleDynamic(IlluminateRequest $request)
151
    {
152
        $this->applySnapshots();
153
154
        ob_start();
155
156
        if ($this->conf['is_lumen']) {
157
            $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

157
            /** @scrutinizer ignore-call */ 
158
            $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...
158
            if ($response instanceof SymfonyResponse) {
159
                $content = $response->getContent();
160
            } else {
161
                $content = (string)$response;
162
            }
163
164
            $laravelReflect = new \ReflectionObject($this->app);
165
            $middleware = $laravelReflect->getProperty('middleware');
166
            $middleware->setAccessible(true);
167
            if (!empty($middleware->getValue($this->app))) {
168
                $callTerminableMiddleware = $laravelReflect->getMethod('callTerminableMiddleware');
169
                $callTerminableMiddleware->setAccessible(true);
170
                $callTerminableMiddleware->invoke($this->app, $response);
171
            }
172
        } else {
173
            $response = $this->kernel->handle($request);
174
            $content = $response->getContent();
175
            $this->kernel->terminate($request, $response);
176
        }
177
178
        // prefer content in response, secondly ob
179
        if (strlen($content) === 0 && ob_get_length() > 0) {
180
            $response->setContent(ob_get_contents());
181
        }
182
183
        ob_end_clean();
184
185
        return $response;
186
    }
187
188
    public function handleStatic(IlluminateRequest $request)
189
    {
190
        $uri = $request->getRequestUri();
191
        if (isset(self::$staticBlackList[$uri])) {
192
            return false;
193
        }
194
195
        $publicPath = $this->conf['static_path'];
196
        $requestFile = $publicPath . $uri;
197
        if (is_file($requestFile)) {
198
            return $this->createStaticResponse($requestFile, $request);
199
        } elseif (is_dir($requestFile)) {
200
            $indexFile = $this->lookupIndex($requestFile);
201
            if ($indexFile === false) {
202
                return false;
203
            } else {
204
                return $this->createStaticResponse($indexFile, $request);
205
            }
206
        } else {
207
            return false;
208
        }
209
    }
210
211
    protected function lookupIndex($folder)
212
    {
213
        $folder = rtrim($folder, '/') . '/';
214
        foreach (['index.html', 'index.htm'] as $index) {
215
            $tmpFile = $folder . $index;
216
            if (is_file($tmpFile)) {
217
                return $tmpFile;
218
            }
219
        }
220
        return false;
221
    }
222
223
    public function createStaticResponse($requestFile, IlluminateRequest $request)
224
    {
225
        $response = new BinaryFileResponse($requestFile);
226
        $response->prepare($request);
227
        $response->isNotModified($request);
228
        return $response;
229
    }
230
231
    protected function cleanProviders(array $providers, $force = false)
232
    {
233
        if ($this->conf['is_lumen']) {
234
            $laravelReflect = new \ReflectionObject($this->app);
235
            $loadedProviders = $laravelReflect->getProperty('loadedProviders');
236
            $loadedProviders->setAccessible(true);
237
            $oldLoadedProviders = $loadedProviders->getValue($this->app);
238
        }
239
240
        foreach ($providers as $provider) {
241
            if ($force || class_exists($provider, false)) {
242
                if ($this->conf['is_lumen']) {
243
                    unset($oldLoadedProviders[get_class(new $provider($this->app))]);
244
                }
245
                $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

245
                $this->app->/** @scrutinizer ignore-call */ 
246
                            register($provider, [], true);
Loading history...
246
            }
247
        }
248
249
        if ($this->conf['is_lumen']) {
250
            $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...
251
        }
252
    }
253
254
    public function clean()
255
    {
256
        foreach ($this->conf['cleaners'] as $cleanerCls) {
257
            /**@var \Hhxsv5\LaravelS\Illuminate\Cleaners\CleanerInterface $cleaner */
258
            $cleaner = $this->app->make($cleanerCls);
259
            $cleaner->clean($this->app);
260
        }
261
262
        $this->cleanProviders($this->conf['register_providers']);
263
    }
264
265
    public function fireEvent($name, array $params = [])
266
    {
267
        $params[] = $this->app;
268
        return method_exists($this->app['events'], 'dispatch') ?
269
            $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

269
            $this->app['events']->/** @scrutinizer ignore-call */ 
270
                                  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...
270
    }
271
272
    public function bindRequest(IlluminateRequest $request)
273
    {
274
        $this->app->instance('request', $request);
275
    }
276
277
    public function bindSwoole($swoole)
278
    {
279
        $this->app->singleton('swoole', function () use ($swoole) {
280
            return $swoole;
281
        });
282
    }
283
284
    public function make($abstract, array $parameters = [])
285
    {
286
        return $this->app->make($abstract, $parameters);
287
    }
288
289
    public function cleanSession()
290
    {
291
        /**@var \Hhxsv5\LaravelS\Illuminate\Cleaners\CleanerInterface $cleaner */
292
        $cleaner = $this->app->make(SessionCleaner::class);
293
        $cleaner->clean($this->app);
294
    }
295
296
    public function saveSession()
297
    {
298
        if ($this->app->offsetExists('session')) {
299
            $this->app['session']->save();
300
        }
301
    }
302
}
303