1
|
|
|
<?php
|
2
|
|
|
|
3
|
|
|
namespace Resta\Foundation;
|
4
|
|
|
|
5
|
|
|
use Resta\Support\Str;
|
6
|
|
|
use Resta\Config\Config;
|
7
|
|
|
use Resta\Support\Macro;
|
8
|
|
|
use DI\NotFoundException;
|
9
|
|
|
use Resta\Support\Command;
|
10
|
|
|
use DI\DependencyException;
|
11
|
|
|
use Resta\Traits\ApplicationPath;
|
12
|
|
|
use Illuminate\Support\Collection;
|
13
|
|
|
use Resta\Contracts\ApplicationContracts;
|
14
|
|
|
use Resta\Environment\EnvironmentProvider;
|
15
|
|
|
use Resta\Contracts\ConfigProviderContracts;
|
16
|
|
|
use Resta\Foundation\Bootstrapper\BootLoader;
|
17
|
|
|
use Resta\Contracts\ClosureDispatcherContracts;
|
18
|
|
|
use Resta\Foundation\Bootstrapper\Bootstrappers;
|
19
|
|
|
|
20
|
|
|
class Application extends Kernel implements ApplicationContracts
|
21
|
|
|
{
|
22
|
|
|
//get app paths
|
23
|
|
|
use ApplicationPath;
|
24
|
|
|
|
25
|
|
|
/**
|
26
|
|
|
* The Resta api designer version.
|
27
|
|
|
*
|
28
|
|
|
* @var string
|
29
|
|
|
*/
|
30
|
|
|
protected const VERSION = '1.0.0';
|
31
|
|
|
|
32
|
|
|
/**
|
33
|
|
|
* @var bool
|
34
|
|
|
*/
|
35
|
|
|
protected $console;
|
36
|
|
|
|
37
|
|
|
/**
|
38
|
|
|
* Application constructor.
|
39
|
|
|
*
|
40
|
|
|
* @param bool $console
|
41
|
|
|
*/
|
42
|
|
|
public function __construct($console=false)
|
43
|
|
|
{
|
44
|
|
|
//get console status for cli
|
45
|
|
|
$this->console = (is_bool($console)) ? $console : true;
|
|
|
|
|
46
|
|
|
|
47
|
|
|
// the bootstrapper method is the initial process
|
48
|
|
|
// that runs the individual methods that the application initiated.
|
49
|
|
|
new Bootstrappers($this);
|
50
|
|
|
}
|
51
|
|
|
|
52
|
|
|
/**
|
53
|
|
|
* check if the object in binding is available
|
54
|
|
|
*
|
55
|
|
|
* @param string $object
|
56
|
|
|
* @return bool
|
57
|
|
|
*/
|
58
|
|
|
public function checkBindings($object) : bool
|
59
|
|
|
{
|
60
|
|
|
// the booted objects are saved to the kernel.
|
61
|
|
|
// this method checks whether these objects are registered.
|
62
|
|
|
return (isset($this['bindings'],$this['bindings'][$object]));
|
63
|
|
|
}
|
64
|
|
|
|
65
|
|
|
/**
|
66
|
|
|
* handle application command
|
67
|
|
|
*
|
68
|
|
|
* @param string $command
|
69
|
|
|
* @param array $arguments
|
70
|
|
|
* @return mixed
|
71
|
|
|
*/
|
72
|
|
|
public function command($command, $arguments = array())
|
73
|
|
|
{
|
74
|
|
|
// the Process class executes a command in a sub-process,
|
75
|
|
|
// taking care of the differences between operating system
|
76
|
|
|
// and escaping arguments to prevent security issues.
|
77
|
|
|
// It replaces PHP functions like exec, passthru, shell_exec and system
|
78
|
|
|
return $this->resolve(Command::class,['command'=>$command,'args'=>$arguments])->handle();
|
79
|
|
|
}
|
80
|
|
|
|
81
|
|
|
/**
|
82
|
|
|
* get kernel command list
|
83
|
|
|
*
|
84
|
|
|
* @return array
|
85
|
|
|
*/
|
86
|
|
|
public function commandList() : array
|
87
|
|
|
{
|
88
|
|
|
//get command list from kernel
|
89
|
|
|
return $this->commandList;
|
90
|
|
|
}
|
91
|
|
|
|
92
|
|
|
/**
|
93
|
|
|
* get configuration values
|
94
|
|
|
*
|
95
|
|
|
* @param string $config
|
96
|
|
|
* @return mixed
|
97
|
|
|
*
|
98
|
|
|
* @throws DependencyException
|
99
|
|
|
* @throws NotFoundException
|
100
|
|
|
*/
|
101
|
|
|
public function config($config)
|
102
|
|
|
{
|
103
|
|
|
if($this->checkBindings(__FUNCTION__)){
|
104
|
|
|
|
105
|
|
|
/** @var Macro $macro */
|
106
|
|
|
$macro = $this['macro'];
|
107
|
|
|
|
108
|
|
|
// this includes the configuration macro class.
|
109
|
|
|
// therefore, you can expand your configuration settings from
|
110
|
|
|
// the application kernel identifier to the desired class.
|
111
|
|
|
return $macro->withStatic(Config::macro(),function() use($config){
|
112
|
|
|
return Config::make($config);
|
113
|
|
|
})->get();
|
114
|
|
|
|
115
|
|
|
}
|
116
|
|
|
|
117
|
|
|
// if the environment is not booted,
|
118
|
|
|
// it creates a direct missing ring
|
119
|
|
|
// and we have to reinstall the environment to remove it.
|
120
|
|
|
$this->loadIfNotExistBoot([__FUNCTION__]);
|
121
|
|
|
return $this->config($config);
|
122
|
|
|
}
|
123
|
|
|
|
124
|
|
|
/**
|
125
|
|
|
* console kernel object
|
126
|
|
|
*
|
127
|
|
|
* @return bool
|
128
|
|
|
*/
|
129
|
|
|
public function console() : bool
|
130
|
|
|
{
|
131
|
|
|
// controlling the console object is
|
132
|
|
|
// intended to make sure that the kernel bootstrap classes do not work.
|
133
|
|
|
return $this->console;
|
134
|
|
|
}
|
135
|
|
|
|
136
|
|
|
/**
|
137
|
|
|
* get container cache file
|
138
|
|
|
*
|
139
|
|
|
* @return mixed|string
|
140
|
|
|
*/
|
141
|
|
|
public function containerCacheFile()
|
142
|
|
|
{
|
143
|
|
|
if(!is_null(serviceJson())){
|
|
|
|
|
144
|
|
|
return serviceJson();
|
145
|
|
|
}
|
146
|
|
|
|
147
|
|
|
return $this['containerCacheFile'];
|
148
|
|
|
}
|
149
|
|
|
|
150
|
|
|
/**
|
151
|
|
|
* get core path
|
152
|
|
|
*
|
153
|
|
|
* @return mixed
|
154
|
|
|
*/
|
155
|
|
|
public function corePath()
|
156
|
|
|
{
|
157
|
|
|
// get the directory
|
158
|
|
|
// where kernel files are running to the kernel object.
|
159
|
|
|
return $this['corePath'] ?: null;
|
160
|
|
|
}
|
161
|
|
|
|
162
|
|
|
/**
|
163
|
|
|
* get environment variables
|
164
|
|
|
*
|
165
|
|
|
* @param array $environment
|
166
|
|
|
* @return mixed|string
|
167
|
|
|
*/
|
168
|
|
|
public function environment($environment=array())
|
169
|
|
|
{
|
170
|
|
|
if($this->checkBindings(__FUNCTION__)){
|
171
|
|
|
|
172
|
|
|
$arguments = (isset(func_get_args()[0]))
|
173
|
|
|
? func_get_args()[0] : func_get_args();
|
174
|
|
|
|
175
|
|
|
/** @var EnvironmentProvider $environmentContainer */
|
176
|
|
|
$environmentContainer = $this['environment'];
|
177
|
|
|
|
178
|
|
|
return $environmentContainer->environment(
|
179
|
|
|
$arguments,$this['environmentVariables']
|
180
|
|
|
);
|
181
|
|
|
}
|
182
|
|
|
|
183
|
|
|
// if the environment is not booted,
|
184
|
|
|
// it creates a direct missing ring
|
185
|
|
|
// and we have to reinstall the environment to remove it.
|
186
|
|
|
$this->loadIfNotExistBoot([__FUNCTION__]);
|
187
|
|
|
return $this->environment();
|
188
|
|
|
}
|
189
|
|
|
|
190
|
|
|
/**
|
191
|
|
|
* handle application
|
192
|
|
|
*
|
193
|
|
|
* @return mixed
|
194
|
|
|
*/
|
195
|
|
|
public function handle()
|
196
|
|
|
{
|
197
|
|
|
// this is the main calling place of your application.
|
198
|
|
|
// if you come via http, the kernel response value is appraised.
|
199
|
|
|
// if you come via console, the kernel console value is appraised.
|
200
|
|
|
return ($this->console()) ? null : $this['result'];
|
201
|
|
|
}
|
202
|
|
|
|
203
|
|
|
/**
|
204
|
|
|
* Determine if application locale is the given locale.
|
205
|
|
|
*
|
206
|
|
|
* @return bool
|
207
|
|
|
*/
|
208
|
|
|
public function isLocale() : bool
|
209
|
|
|
{
|
210
|
|
|
//check environment for local
|
211
|
|
|
return $this->environment() === 'local';
|
212
|
|
|
}
|
213
|
|
|
|
214
|
|
|
/**
|
215
|
|
|
* get all kernel bootstrapper groups keys
|
216
|
|
|
*
|
217
|
|
|
* @return array
|
218
|
|
|
*/
|
219
|
|
|
public function kernelGroupKeys() : array
|
220
|
|
|
{
|
221
|
|
|
$properties = [];
|
222
|
|
|
|
223
|
|
|
// with the help of reflection instance,
|
224
|
|
|
// we get the kernel properties extended with the application object.
|
225
|
|
|
foreach ($this['reflection']($this)->getProperties() as $property){
|
226
|
|
|
$properties[] = $property->getName();
|
227
|
|
|
}
|
228
|
|
|
|
229
|
|
|
// we get the names of
|
230
|
|
|
// the kernel properties ended with groups through the Collection class.
|
231
|
|
|
[$groups] = Collection::make($properties)->partition(function($properties){
|
232
|
|
|
return Str::endsWith($properties,'Groups');
|
233
|
|
|
});
|
234
|
|
|
|
235
|
|
|
//as a result, kernel groups are being returned.
|
236
|
|
|
return array_values($groups->all());
|
237
|
|
|
}
|
238
|
|
|
|
239
|
|
|
/**
|
240
|
|
|
* kernel groups name lists
|
241
|
|
|
*
|
242
|
|
|
* @return array
|
243
|
|
|
*/
|
244
|
|
|
public function kernelGroupList() : array
|
245
|
|
|
{
|
246
|
|
|
$list = [];
|
247
|
|
|
|
248
|
|
|
//get kernel group names with manifest method
|
249
|
|
|
foreach ($this->kernelGroupKeys() as $groupKey){
|
250
|
|
|
$list = array_merge($list,$this->manifest($groupKey));
|
251
|
|
|
}
|
252
|
|
|
|
253
|
|
|
return $list;
|
254
|
|
|
}
|
255
|
|
|
|
256
|
|
|
/**
|
257
|
|
|
* customer configuration loader for core
|
258
|
|
|
*
|
259
|
|
|
* @param callable $callback
|
260
|
|
|
* @return mixed|void
|
261
|
|
|
*/
|
262
|
|
|
public function loadConfig(callable $callback)
|
263
|
|
|
{
|
264
|
|
|
// it adds the values in path data specified
|
265
|
|
|
// by callback to the configuration values.
|
266
|
|
|
if($this['config'] instanceof ConfigProviderContracts){
|
267
|
|
|
|
268
|
|
|
//set your path for config loader
|
269
|
|
|
tap($this['config'],function(ConfigProviderContracts $config) use($callback) {
|
270
|
|
|
$config->setConfig(call_user_func($callback));
|
271
|
|
|
});
|
272
|
|
|
}
|
273
|
|
|
else{
|
274
|
|
|
//set config instance exception for application
|
275
|
|
|
exception()->unexpectedValue('config instance is not loaded for application container');
|
276
|
|
|
}
|
277
|
|
|
}
|
278
|
|
|
|
279
|
|
|
/**
|
280
|
|
|
* load if not exist boot
|
281
|
|
|
*
|
282
|
|
|
* @param array $loaders
|
283
|
|
|
* @return mixed|void
|
284
|
|
|
*/
|
285
|
|
|
public function loadIfNotExistBoot($loaders=array())
|
286
|
|
|
{
|
287
|
|
|
//get kernel group list from application
|
288
|
|
|
$kernelGroupList = $this->kernelGroupList();
|
289
|
|
|
|
290
|
|
|
/** @var ClosureDispatcherContracts $closureBootLoader */
|
291
|
|
|
$closureBootLoader = $this['closureBootLoader'];
|
292
|
|
|
|
293
|
|
|
foreach ($loaders as $loader){
|
294
|
|
|
|
295
|
|
|
// if a service needs another boot service,
|
296
|
|
|
// the service is directly installed here and the service needs are resolved.
|
297
|
|
|
if(isset($kernelGroupList[$loader]) && $this->checkBindings($loader)===false){
|
298
|
|
|
|
299
|
|
|
//with the boot loader kernel,we get the boot loader method.
|
300
|
|
|
$closureBootLoader->call(function() use($loader,$kernelGroupList) {
|
301
|
|
|
|
302
|
|
|
/** @var BootLoader $bootLoader */
|
303
|
|
|
$bootLoader = $this;
|
304
|
|
|
$bootLoader->setBootstrapper($kernelGroupList[$loader]);
|
305
|
|
|
$bootLoader->boot();
|
306
|
|
|
});
|
307
|
|
|
}
|
308
|
|
|
}
|
309
|
|
|
}
|
310
|
|
|
|
311
|
|
|
/**
|
312
|
|
|
* get kernel maker from manifest
|
313
|
|
|
*
|
314
|
|
|
* @param string $maker
|
315
|
|
|
* @return mixed
|
316
|
|
|
*/
|
317
|
|
|
public function manifest($maker)
|
318
|
|
|
{
|
319
|
|
|
/** @var Bootstrappers $bootstrapper */
|
320
|
|
|
$bootstrapper = $this['bootstrapper'];
|
321
|
|
|
|
322
|
|
|
//kernel manifest bootstrapper
|
323
|
|
|
return $bootstrapper->bootFire(null,$maker);
|
324
|
|
|
}
|
325
|
|
|
|
326
|
|
|
/**
|
327
|
|
|
* check if the request is console
|
328
|
|
|
*
|
329
|
|
|
* @return bool
|
330
|
|
|
*/
|
331
|
|
|
public function runningInConsole() : bool
|
332
|
|
|
{
|
333
|
|
|
//Determine if the application is running in the console.
|
334
|
|
|
return php_sapi_name() === 'cli' || php_sapi_name() === 'phpdbg';
|
335
|
|
|
}
|
336
|
|
|
|
337
|
|
|
/**
|
338
|
|
|
* get service providers
|
339
|
|
|
*
|
340
|
|
|
* @return array
|
341
|
|
|
*/
|
342
|
|
|
public function serviceProviders() : array
|
343
|
|
|
{
|
344
|
|
|
//get project providers from config kernel
|
345
|
|
|
$providers = (is_array(config('kernel.providers')))
|
346
|
|
|
? config('kernel.providers')
|
347
|
|
|
: [];
|
348
|
|
|
|
349
|
|
|
//core kernel providers and project providers have been merged
|
350
|
|
|
return array_merge($this->manifest('providers'),$providers);
|
351
|
|
|
}
|
352
|
|
|
|
353
|
|
|
/**
|
354
|
|
|
* application structure directory paths changing
|
355
|
|
|
*
|
356
|
|
|
* @param string $name
|
357
|
|
|
* @param string $path
|
358
|
|
|
* @return mixed|void
|
359
|
|
|
*/
|
360
|
|
|
public function setPaths($name,$path)
|
361
|
|
|
{
|
362
|
|
|
// save the globally identified paths to
|
363
|
|
|
// the global container object of the resta.
|
364
|
|
|
if(file_exists($path)){
|
365
|
|
|
$this->register('paths',$name,$path);
|
366
|
|
|
}
|
367
|
|
|
}
|
368
|
|
|
|
369
|
|
|
/**
|
370
|
|
|
* Get the version number of the application.
|
371
|
|
|
*
|
372
|
|
|
* @return mixed|string
|
373
|
|
|
*/
|
374
|
|
|
public function version()
|
375
|
|
|
{
|
376
|
|
|
//get resta application version number
|
377
|
|
|
return static::VERSION;
|
378
|
|
|
}
|
379
|
|
|
} |