1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Hhxsv5\LaravelS\Illuminate; |
4
|
|
|
|
5
|
|
|
use Illuminate\Support\Facades\Facade; |
6
|
|
|
use Illuminate\Http\Request as IlluminateRequest; |
7
|
|
|
use Illuminate\Contracts\Http\Kernel as HttpKernel; |
8
|
|
|
use Illuminate\Contracts\Console\Kernel as ConsoleKernel; |
9
|
|
|
use Symfony\Component\HttpFoundation\BinaryFileResponse; |
10
|
|
|
use Symfony\Component\HttpFoundation\Response as SymfonyResponse; |
11
|
|
|
|
12
|
|
|
class Laravel |
13
|
|
|
{ |
14
|
|
|
protected $app; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @var HttpKernel $laravelKernel |
18
|
|
|
*/ |
19
|
|
|
protected $laravelKernel; |
20
|
|
|
|
21
|
|
|
protected static $snapshotKeys = ['config', 'cookie', 'auth', /*'auth.password'*/]; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @var array $snapshots |
25
|
|
|
*/ |
26
|
|
|
protected $snapshots = []; |
27
|
|
|
|
28
|
|
|
protected $conf = []; |
29
|
|
|
|
30
|
|
|
protected static $staticBlackList = [ |
31
|
|
|
'/index.php' => 1, |
32
|
|
|
'/.htaccess' => 1, |
33
|
|
|
'/web.config' => 1, |
34
|
|
|
]; |
35
|
|
|
|
36
|
|
|
private $rawGlobals = []; |
37
|
|
|
|
38
|
|
|
public function __construct(array $conf = []) |
39
|
|
|
{ |
40
|
|
|
$this->conf = $conf; |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
public function prepareLaravel() |
44
|
|
|
{ |
45
|
|
|
$this->autoload(); |
46
|
|
|
$this->createApp(); |
47
|
|
|
$this->createKernel(); |
48
|
|
|
$this->setLaravel(); |
49
|
|
|
$this->loadAllConfigurations(); |
50
|
|
|
$this->consoleKernelBootstrap(); |
51
|
|
|
$this->saveSnapshots(); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
protected function autoload() |
55
|
|
|
{ |
56
|
|
|
$autoload = $this->conf['root_path'] . '/bootstrap/autoload.php'; |
57
|
|
|
if (file_exists($autoload)) { |
58
|
|
|
require_once $autoload; |
59
|
|
|
} else { |
60
|
|
|
require_once $this->conf['root_path'] . '/vendor/autoload.php'; |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
protected function createApp() |
65
|
|
|
{ |
66
|
|
|
$this->app = require $this->conf['root_path'] . '/bootstrap/app.php'; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
protected function createKernel() |
70
|
|
|
{ |
71
|
|
|
if (!$this->conf['is_lumen']) { |
72
|
|
|
$this->laravelKernel = $this->app->make(HttpKernel::class); |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
protected function setLaravel() |
77
|
|
|
{ |
78
|
|
|
// Load configuration laravel.php manually for Lumen |
79
|
|
|
if ($this->conf['is_lumen'] && file_exists($this->conf['root_path'] . '/config/laravels.php')) { |
80
|
|
|
$this->app->configure('laravels'); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
$server = isset($this->conf['_SERVER']) ? $this->conf['_SERVER'] : []; |
84
|
|
|
$env = isset($this->conf['_ENV']) ? $this->conf['_ENV'] : []; |
85
|
|
|
$this->rawGlobals['_SERVER'] = array_merge($_SERVER, $server); |
86
|
|
|
$this->rawGlobals['_ENV'] = array_merge($_ENV, $env); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
protected function consoleKernelBootstrap() |
90
|
|
|
{ |
91
|
|
|
if (!$this->conf['is_lumen']) { |
92
|
|
|
$this->app->make(ConsoleKernel::class)->bootstrap(); |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
public function loadAllConfigurations() |
97
|
|
|
{ |
98
|
|
|
if (!$this->conf['is_lumen']) { |
99
|
|
|
return; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$cfgPaths = [ |
103
|
|
|
// Framework default configuration |
104
|
|
|
$this->conf['root_path'] . '/vendor/laravel/lumen-framework/config/', |
105
|
|
|
// App configuration |
106
|
|
|
$this->conf['root_path'] . '/config/', |
107
|
|
|
]; |
108
|
|
|
$keys = []; |
109
|
|
|
foreach ($cfgPaths as $cfgPath) { |
110
|
|
|
$configs = (array)glob($cfgPath . '*.php'); |
111
|
|
|
foreach ($configs as $config) { |
112
|
|
|
$config = substr(basename($config), 0, -4); |
113
|
|
|
$keys[$config] = $config; |
114
|
|
|
} |
115
|
|
|
} |
116
|
|
|
foreach ($keys as $key) { |
117
|
|
|
$this->app->configure($key); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
protected function saveSnapshots() |
122
|
|
|
{ |
123
|
|
|
$this->snapshots = []; |
124
|
|
|
foreach (self::$snapshotKeys as $key) { |
125
|
|
|
if (isset($this->app[$key])) { |
126
|
|
|
if (is_object($this->app[$key])) { |
127
|
|
|
$this->snapshots[$key] = clone $this->app[$key]; |
128
|
|
|
} else { |
129
|
|
|
$this->snapshots[$key] = $this->app[$key]; |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
protected function applySnapshots() |
136
|
|
|
{ |
137
|
|
|
foreach ($this->snapshots as $key => $value) { |
138
|
|
|
if (is_object($value)) { |
139
|
|
|
$this->app[$key] = clone $value; |
140
|
|
|
} else { |
141
|
|
|
$this->app[$key] = $value; |
142
|
|
|
} |
143
|
|
|
Facade::clearResolvedInstance($key); |
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
public function getRawGlobals() |
148
|
|
|
{ |
149
|
|
|
return $this->rawGlobals; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
public function handleDynamic(IlluminateRequest $request) |
153
|
|
|
{ |
154
|
|
|
$this->applySnapshots(); |
155
|
|
|
|
156
|
|
|
ob_start(); |
157
|
|
|
|
158
|
|
|
if ($this->conf['is_lumen']) { |
159
|
|
|
$response = $this->app->dispatch($request); |
160
|
|
|
if ($response instanceof SymfonyResponse) { |
161
|
|
|
$content = $response->getContent(); |
162
|
|
|
} else { |
163
|
|
|
$content = (string)$response; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
$laravelReflect = new \ReflectionObject($this->app); |
167
|
|
|
$middleware = $laravelReflect->getProperty('middleware'); |
168
|
|
|
$middleware->setAccessible(true); |
169
|
|
|
if (!empty($middleware->getValue($this->app))) { |
170
|
|
|
$callTerminableMiddleware = $laravelReflect->getMethod('callTerminableMiddleware'); |
171
|
|
|
$callTerminableMiddleware->setAccessible(true); |
172
|
|
|
$callTerminableMiddleware->invoke($this->app, $response); |
173
|
|
|
} |
174
|
|
|
} else { |
175
|
|
|
$response = $this->laravelKernel->handle($request); |
176
|
|
|
$content = $response->getContent(); |
177
|
|
|
$this->laravelKernel->terminate($request, $response); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
// prefer content in response, secondly ob |
181
|
|
|
if (strlen($content) === 0 && ob_get_length() > 0) { |
182
|
|
|
$response->setContent(ob_get_contents()); |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
ob_end_clean(); |
186
|
|
|
|
187
|
|
|
return $response; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
public function handleStatic(IlluminateRequest $request) |
191
|
|
|
{ |
192
|
|
|
$uri = $request->getRequestUri(); |
193
|
|
|
if (isset(self::$staticBlackList[$uri])) { |
194
|
|
|
return false; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
$publicPath = $this->conf['static_path']; |
198
|
|
|
$requestFile = $publicPath . $uri; |
199
|
|
|
if (is_file($requestFile)) { |
200
|
|
|
return $this->createStaticResponse($requestFile, $request); |
201
|
|
|
} elseif (is_dir($requestFile)) { |
202
|
|
|
$indexFile = $this->lookupIndex($requestFile); |
203
|
|
|
if ($indexFile === false) { |
204
|
|
|
return false; |
205
|
|
|
} else { |
206
|
|
|
return $this->createStaticResponse($indexFile, $request); |
207
|
|
|
} |
208
|
|
|
} else { |
209
|
|
|
return false; |
210
|
|
|
} |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
protected function lookupIndex($folder) |
214
|
|
|
{ |
215
|
|
|
$folder = rtrim($folder, '/') . '/'; |
216
|
|
|
foreach (['index.html', 'index.htm'] as $index) { |
217
|
|
|
$tmpFile = $folder . $index; |
218
|
|
|
if (is_file($tmpFile)) { |
219
|
|
|
return $tmpFile; |
220
|
|
|
} |
221
|
|
|
} |
222
|
|
|
return false; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
public function createStaticResponse($requestFile, IlluminateRequest $request) |
226
|
|
|
{ |
227
|
|
|
$response = new BinaryFileResponse($requestFile); |
228
|
|
|
$response->prepare($request); |
229
|
|
|
$response->isNotModified($request); |
230
|
|
|
return $response; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
public function reRegisterServiceProvider($providerCls, array $clearFacades = [], $force = false) |
234
|
|
|
{ |
235
|
|
|
if (class_exists($providerCls, false) || $force) { |
236
|
|
|
if ($this->conf['is_lumen']) { |
237
|
|
|
$laravelReflect = new \ReflectionObject($this->app); |
238
|
|
|
$loadedProviders = $laravelReflect->getProperty('loadedProviders'); |
239
|
|
|
$loadedProviders->setAccessible(true); |
240
|
|
|
$oldLoadedProviders = $loadedProviders->getValue($this->app); |
241
|
|
|
unset($oldLoadedProviders[get_class(new $providerCls($this->app))]); |
242
|
|
|
$loadedProviders->setValue($this->app, $oldLoadedProviders); |
243
|
|
|
} |
244
|
|
|
foreach ($clearFacades as $facade) { |
245
|
|
|
Facade::clearResolvedInstance($facade); |
246
|
|
|
} |
247
|
|
|
$this->app->register($providerCls, [], true); |
248
|
|
|
} |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
public function cleanRequest(IlluminateRequest $request) |
252
|
|
|
{ |
253
|
|
|
// Clean laravel session |
254
|
|
|
if ($request->hasSession()) { |
255
|
|
|
$session = $request->getSession(); |
256
|
|
|
if (method_exists($session, 'clear')) { |
257
|
|
|
$session->clear(); |
258
|
|
|
} elseif (method_exists($session, 'flush')) { |
259
|
|
|
$session->flush(); |
260
|
|
|
} |
261
|
|
|
// TODO: clear session for other versions |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
// Re-register auth |
265
|
|
|
//$this->reRegisterServiceProvider('\Illuminate\Auth\AuthServiceProvider', ['auth', 'auth.driver']); |
|
|
|
|
266
|
|
|
//$this->reRegisterServiceProvider('\Illuminate\Auth\Passwords\PasswordResetServiceProvider', ['auth.password']); |
|
|
|
|
267
|
|
|
|
268
|
|
|
// Re-register passport |
269
|
|
|
$this->reRegisterServiceProvider('\Laravel\Passport\PassportServiceProvider'); |
270
|
|
|
|
271
|
|
|
// Re-register some singleton providers |
272
|
|
|
foreach ($this->conf['register_providers'] as $provider) { |
273
|
|
|
$this->reRegisterServiceProvider($provider); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
// Clear request |
277
|
|
|
$this->app->forgetInstance('request'); |
278
|
|
|
Facade::clearResolvedInstance('request'); |
279
|
|
|
|
280
|
|
|
//... |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
public function fireEvent($name, array $params = []) |
284
|
|
|
{ |
285
|
|
|
$params[] = $this->app; |
286
|
|
|
return $this->app->events->fire($name, $params); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
public function bindRequest(IlluminateRequest $request) |
290
|
|
|
{ |
291
|
|
|
$this->app->instance('request', $request); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
public function bindSwoole($swoole) |
295
|
|
|
{ |
296
|
|
|
$this->app->singleton('swoole', function () use ($swoole) { |
297
|
|
|
return $swoole; |
298
|
|
|
}); |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
public function make($abstract, array $parameters = []) |
302
|
|
|
{ |
303
|
|
|
return $this->app->make($abstract, $parameters); |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
public function resetSession() |
307
|
|
|
{ |
308
|
|
|
if (!empty($this->app['session'])) { |
309
|
|
|
$reflection = new \ReflectionObject($this->app['session']); |
310
|
|
|
$drivers = $reflection->getProperty('drivers'); |
311
|
|
|
$drivers->setAccessible(true); |
312
|
|
|
$drivers->setValue($this->app['session'], []); |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
public function saveSession() |
317
|
|
|
{ |
318
|
|
|
if (!empty($this->app['session'])) { |
319
|
|
|
$this->app['session']->save(); |
320
|
|
|
} |
321
|
|
|
} |
322
|
|
|
|
323
|
|
|
public function __clone() |
324
|
|
|
{ |
325
|
|
|
$this->app = clone $this->app; |
326
|
|
|
$this->laravelKernel = clone $this->laravelKernel; |
327
|
|
|
} |
328
|
|
|
} |
329
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.