Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 1464 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Foundation;
4
 
5
use Closure;
6
use Illuminate\Container\Container;
7
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
8
use Illuminate\Contracts\Foundation\CachesConfiguration;
9
use Illuminate\Contracts\Foundation\CachesRoutes;
10
use Illuminate\Contracts\Foundation\MaintenanceMode as MaintenanceModeContract;
11
use Illuminate\Contracts\Http\Kernel as HttpKernelContract;
12
use Illuminate\Events\EventServiceProvider;
13
use Illuminate\Filesystem\Filesystem;
14
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
15
use Illuminate\Foundation\Events\LocaleUpdated;
16
use Illuminate\Http\Request;
17
use Illuminate\Log\LogServiceProvider;
18
use Illuminate\Routing\RoutingServiceProvider;
19
use Illuminate\Support\Arr;
20
use Illuminate\Support\Collection;
21
use Illuminate\Support\Env;
22
use Illuminate\Support\ServiceProvider;
23
use Illuminate\Support\Str;
24
use Illuminate\Support\Traits\Macroable;
25
use RuntimeException;
26
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
27
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
28
use Symfony\Component\HttpKernel\Exception\HttpException;
29
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
30
use Symfony\Component\HttpKernel\HttpKernelInterface;
31
 
32
class Application extends Container implements ApplicationContract, CachesConfiguration, CachesRoutes, HttpKernelInterface
33
{
34
    use Macroable;
35
 
36
    /**
37
     * The Laravel framework version.
38
     *
39
     * @var string
40
     */
1663 lars 41
    const VERSION = '9.52.7';
148 lars 42
 
43
    /**
44
     * The base path for the Laravel installation.
45
     *
46
     * @var string
47
     */
48
    protected $basePath;
49
 
50
    /**
51
     * Indicates if the application has been bootstrapped before.
52
     *
53
     * @var bool
54
     */
55
    protected $hasBeenBootstrapped = false;
56
 
57
    /**
58
     * Indicates if the application has "booted".
59
     *
60
     * @var bool
61
     */
62
    protected $booted = false;
63
 
64
    /**
65
     * The array of booting callbacks.
66
     *
67
     * @var callable[]
68
     */
69
    protected $bootingCallbacks = [];
70
 
71
    /**
72
     * The array of booted callbacks.
73
     *
74
     * @var callable[]
75
     */
76
    protected $bootedCallbacks = [];
77
 
78
    /**
79
     * The array of terminating callbacks.
80
     *
81
     * @var callable[]
82
     */
83
    protected $terminatingCallbacks = [];
84
 
85
    /**
86
     * All of the registered service providers.
87
     *
88
     * @var \Illuminate\Support\ServiceProvider[]
89
     */
90
    protected $serviceProviders = [];
91
 
92
    /**
93
     * The names of the loaded service providers.
94
     *
95
     * @var array
96
     */
97
    protected $loadedProviders = [];
98
 
99
    /**
100
     * The deferred services and their providers.
101
     *
102
     * @var array
103
     */
104
    protected $deferredServices = [];
105
 
106
    /**
107
     * The custom application path defined by the developer.
108
     *
109
     * @var string
110
     */
111
    protected $appPath;
112
 
113
    /**
114
     * The custom database path defined by the developer.
115
     *
116
     * @var string
117
     */
118
    protected $databasePath;
119
 
120
    /**
121
     * The custom language file path defined by the developer.
122
     *
123
     * @var string
124
     */
125
    protected $langPath;
126
 
127
    /**
128
     * The custom storage path defined by the developer.
129
     *
130
     * @var string
131
     */
132
    protected $storagePath;
133
 
134
    /**
135
     * The custom environment path defined by the developer.
136
     *
137
     * @var string
138
     */
139
    protected $environmentPath;
140
 
141
    /**
142
     * The environment file to load during bootstrapping.
143
     *
144
     * @var string
145
     */
146
    protected $environmentFile = '.env';
147
 
148
    /**
149
     * Indicates if the application is running in the console.
150
     *
151
     * @var bool|null
152
     */
153
    protected $isRunningInConsole;
154
 
155
    /**
156
     * The application namespace.
157
     *
158
     * @var string
159
     */
160
    protected $namespace;
161
 
162
    /**
163
     * The prefixes of absolute cache paths for use during normalization.
164
     *
165
     * @var string[]
166
     */
167
    protected $absoluteCachePathPrefixes = ['/', '\\'];
168
 
169
    /**
170
     * Create a new Illuminate application instance.
171
     *
172
     * @param  string|null  $basePath
173
     * @return void
174
     */
175
    public function __construct($basePath = null)
176
    {
177
        if ($basePath) {
178
            $this->setBasePath($basePath);
179
        }
180
 
181
        $this->registerBaseBindings();
182
        $this->registerBaseServiceProviders();
183
        $this->registerCoreContainerAliases();
184
    }
185
 
186
    /**
187
     * Get the version number of the application.
188
     *
189
     * @return string
190
     */
191
    public function version()
192
    {
193
        return static::VERSION;
194
    }
195
 
196
    /**
197
     * Register the basic bindings into the container.
198
     *
199
     * @return void
200
     */
201
    protected function registerBaseBindings()
202
    {
203
        static::setInstance($this);
204
 
205
        $this->instance('app', $this);
206
 
207
        $this->instance(Container::class, $this);
208
        $this->singleton(Mix::class);
209
 
210
        $this->singleton(PackageManifest::class, function () {
211
            return new PackageManifest(
212
                new Filesystem, $this->basePath(), $this->getCachedPackagesPath()
213
            );
214
        });
215
    }
216
 
217
    /**
218
     * Register all of the base service providers.
219
     *
220
     * @return void
221
     */
222
    protected function registerBaseServiceProviders()
223
    {
224
        $this->register(new EventServiceProvider($this));
225
        $this->register(new LogServiceProvider($this));
226
        $this->register(new RoutingServiceProvider($this));
227
    }
228
 
229
    /**
230
     * Run the given array of bootstrap classes.
231
     *
232
     * @param  string[]  $bootstrappers
233
     * @return void
234
     */
235
    public function bootstrapWith(array $bootstrappers)
236
    {
237
        $this->hasBeenBootstrapped = true;
238
 
239
        foreach ($bootstrappers as $bootstrapper) {
240
            $this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]);
241
 
242
            $this->make($bootstrapper)->bootstrap($this);
243
 
244
            $this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]);
245
        }
246
    }
247
 
248
    /**
249
     * Register a callback to run after loading the environment.
250
     *
251
     * @param  \Closure  $callback
252
     * @return void
253
     */
254
    public function afterLoadingEnvironment(Closure $callback)
255
    {
256
        $this->afterBootstrapping(
257
            LoadEnvironmentVariables::class, $callback
258
        );
259
    }
260
 
261
    /**
262
     * Register a callback to run before a bootstrapper.
263
     *
264
     * @param  string  $bootstrapper
265
     * @param  \Closure  $callback
266
     * @return void
267
     */
268
    public function beforeBootstrapping($bootstrapper, Closure $callback)
269
    {
270
        $this['events']->listen('bootstrapping: '.$bootstrapper, $callback);
271
    }
272
 
273
    /**
274
     * Register a callback to run after a bootstrapper.
275
     *
276
     * @param  string  $bootstrapper
277
     * @param  \Closure  $callback
278
     * @return void
279
     */
280
    public function afterBootstrapping($bootstrapper, Closure $callback)
281
    {
282
        $this['events']->listen('bootstrapped: '.$bootstrapper, $callback);
283
    }
284
 
285
    /**
286
     * Determine if the application has been bootstrapped before.
287
     *
288
     * @return bool
289
     */
290
    public function hasBeenBootstrapped()
291
    {
292
        return $this->hasBeenBootstrapped;
293
    }
294
 
295
    /**
296
     * Set the base path for the application.
297
     *
298
     * @param  string  $basePath
299
     * @return $this
300
     */
301
    public function setBasePath($basePath)
302
    {
303
        $this->basePath = rtrim($basePath, '\/');
304
 
305
        $this->bindPathsInContainer();
306
 
307
        return $this;
308
    }
309
 
310
    /**
311
     * Bind all of the application paths in the container.
312
     *
313
     * @return void
314
     */
315
    protected function bindPathsInContainer()
316
    {
317
        $this->instance('path', $this->path());
318
        $this->instance('path.base', $this->basePath());
319
        $this->instance('path.config', $this->configPath());
320
        $this->instance('path.public', $this->publicPath());
321
        $this->instance('path.storage', $this->storagePath());
322
        $this->instance('path.database', $this->databasePath());
323
        $this->instance('path.resources', $this->resourcePath());
324
        $this->instance('path.bootstrap', $this->bootstrapPath());
325
 
326
        $this->useLangPath(value(function () {
327
            if (is_dir($directory = $this->resourcePath('lang'))) {
328
                return $directory;
329
            }
330
 
331
            return $this->basePath('lang');
332
        }));
333
    }
334
 
335
    /**
336
     * Get the path to the application "app" directory.
337
     *
338
     * @param  string  $path
339
     * @return string
340
     */
341
    public function path($path = '')
342
    {
343
        $appPath = $this->appPath ?: $this->basePath.DIRECTORY_SEPARATOR.'app';
344
 
345
        return $appPath.($path != '' ? DIRECTORY_SEPARATOR.$path : '');
346
    }
347
 
348
    /**
349
     * Set the application directory.
350
     *
351
     * @param  string  $path
352
     * @return $this
353
     */
354
    public function useAppPath($path)
355
    {
356
        $this->appPath = $path;
357
 
358
        $this->instance('path', $path);
359
 
360
        return $this;
361
    }
362
 
363
    /**
364
     * Get the base path of the Laravel installation.
365
     *
366
     * @param  string  $path
367
     * @return string
368
     */
369
    public function basePath($path = '')
370
    {
371
        return $this->basePath.($path != '' ? DIRECTORY_SEPARATOR.$path : '');
372
    }
373
 
374
    /**
375
     * Get the path to the bootstrap directory.
376
     *
377
     * @param  string  $path
378
     * @return string
379
     */
380
    public function bootstrapPath($path = '')
381
    {
382
        return $this->basePath.DIRECTORY_SEPARATOR.'bootstrap'.($path != '' ? DIRECTORY_SEPARATOR.$path : '');
383
    }
384
 
385
    /**
386
     * Get the path to the application configuration files.
387
     *
388
     * @param  string  $path
389
     * @return string
390
     */
391
    public function configPath($path = '')
392
    {
393
        return $this->basePath.DIRECTORY_SEPARATOR.'config'.($path != '' ? DIRECTORY_SEPARATOR.$path : '');
394
    }
395
 
396
    /**
397
     * Get the path to the database directory.
398
     *
399
     * @param  string  $path
400
     * @return string
401
     */
402
    public function databasePath($path = '')
403
    {
404
        return ($this->databasePath ?: $this->basePath.DIRECTORY_SEPARATOR.'database').($path != '' ? DIRECTORY_SEPARATOR.$path : '');
405
    }
406
 
407
    /**
408
     * Set the database directory.
409
     *
410
     * @param  string  $path
411
     * @return $this
412
     */
413
    public function useDatabasePath($path)
414
    {
415
        $this->databasePath = $path;
416
 
417
        $this->instance('path.database', $path);
418
 
419
        return $this;
420
    }
421
 
422
    /**
423
     * Get the path to the language files.
424
     *
425
     * @param  string  $path
426
     * @return string
427
     */
428
    public function langPath($path = '')
429
    {
430
        return $this->langPath.($path != '' ? DIRECTORY_SEPARATOR.$path : '');
431
    }
432
 
433
    /**
434
     * Set the language file directory.
435
     *
436
     * @param  string  $path
437
     * @return $this
438
     */
439
    public function useLangPath($path)
440
    {
441
        $this->langPath = $path;
442
 
443
        $this->instance('path.lang', $path);
444
 
445
        return $this;
446
    }
447
 
448
    /**
449
     * Get the path to the public / web directory.
450
     *
451
     * @return string
452
     */
453
    public function publicPath()
454
    {
455
        return $this->basePath.DIRECTORY_SEPARATOR.'public';
456
    }
457
 
458
    /**
459
     * Get the path to the storage directory.
460
     *
461
     * @param  string  $path
462
     * @return string
463
     */
464
    public function storagePath($path = '')
465
    {
466
        return ($this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage')
467
                            .($path != '' ? DIRECTORY_SEPARATOR.$path : '');
468
    }
469
 
470
    /**
471
     * Set the storage directory.
472
     *
473
     * @param  string  $path
474
     * @return $this
475
     */
476
    public function useStoragePath($path)
477
    {
478
        $this->storagePath = $path;
479
 
480
        $this->instance('path.storage', $path);
481
 
482
        return $this;
483
    }
484
 
485
    /**
486
     * Get the path to the resources directory.
487
     *
488
     * @param  string  $path
489
     * @return string
490
     */
491
    public function resourcePath($path = '')
492
    {
493
        return $this->basePath.DIRECTORY_SEPARATOR.'resources'.($path != '' ? DIRECTORY_SEPARATOR.$path : '');
494
    }
495
 
496
    /**
497
     * Get the path to the views directory.
498
     *
499
     * This method returns the first configured path in the array of view paths.
500
     *
501
     * @param  string  $path
502
     * @return string
503
     */
504
    public function viewPath($path = '')
505
    {
506
        $basePath = $this['config']->get('view.paths')[0];
507
 
508
        return rtrim($basePath, DIRECTORY_SEPARATOR).($path != '' ? DIRECTORY_SEPARATOR.$path : '');
509
    }
510
 
511
    /**
512
     * Get the path to the environment file directory.
513
     *
514
     * @return string
515
     */
516
    public function environmentPath()
517
    {
518
        return $this->environmentPath ?: $this->basePath;
519
    }
520
 
521
    /**
522
     * Set the directory for the environment file.
523
     *
524
     * @param  string  $path
525
     * @return $this
526
     */
527
    public function useEnvironmentPath($path)
528
    {
529
        $this->environmentPath = $path;
530
 
531
        return $this;
532
    }
533
 
534
    /**
535
     * Set the environment file to be loaded during bootstrapping.
536
     *
537
     * @param  string  $file
538
     * @return $this
539
     */
540
    public function loadEnvironmentFrom($file)
541
    {
542
        $this->environmentFile = $file;
543
 
544
        return $this;
545
    }
546
 
547
    /**
548
     * Get the environment file the application is using.
549
     *
550
     * @return string
551
     */
552
    public function environmentFile()
553
    {
554
        return $this->environmentFile ?: '.env';
555
    }
556
 
557
    /**
558
     * Get the fully qualified path to the environment file.
559
     *
560
     * @return string
561
     */
562
    public function environmentFilePath()
563
    {
564
        return $this->environmentPath().DIRECTORY_SEPARATOR.$this->environmentFile();
565
    }
566
 
567
    /**
568
     * Get or check the current application environment.
569
     *
399 lars 570
     * @param  string|array  ...$environments
148 lars 571
     * @return string|bool
572
     */
573
    public function environment(...$environments)
574
    {
575
        if (count($environments) > 0) {
576
            $patterns = is_array($environments[0]) ? $environments[0] : $environments;
577
 
578
            return Str::is($patterns, $this['env']);
579
        }
580
 
581
        return $this['env'];
582
    }
583
 
584
    /**
585
     * Determine if the application is in the local environment.
586
     *
587
     * @return bool
588
     */
589
    public function isLocal()
590
    {
591
        return $this['env'] === 'local';
592
    }
593
 
594
    /**
595
     * Determine if the application is in the production environment.
596
     *
597
     * @return bool
598
     */
599
    public function isProduction()
600
    {
601
        return $this['env'] === 'production';
602
    }
603
 
604
    /**
605
     * Detect the application's current environment.
606
     *
607
     * @param  \Closure  $callback
608
     * @return string
609
     */
610
    public function detectEnvironment(Closure $callback)
611
    {
612
        $args = $_SERVER['argv'] ?? null;
613
 
614
        return $this['env'] = (new EnvironmentDetector)->detect($callback, $args);
615
    }
616
 
617
    /**
618
     * Determine if the application is running in the console.
619
     *
620
     * @return bool
621
     */
622
    public function runningInConsole()
623
    {
624
        if ($this->isRunningInConsole === null) {
625
            $this->isRunningInConsole = Env::get('APP_RUNNING_IN_CONSOLE') ?? (\PHP_SAPI === 'cli' || \PHP_SAPI === 'phpdbg');
626
        }
627
 
628
        return $this->isRunningInConsole;
629
    }
630
 
631
    /**
632
     * Determine if the application is running unit tests.
633
     *
634
     * @return bool
635
     */
636
    public function runningUnitTests()
637
    {
638
        return $this->bound('env') && $this['env'] === 'testing';
639
    }
640
 
641
    /**
642
     * Determine if the application is running with debug mode enabled.
643
     *
644
     * @return bool
645
     */
646
    public function hasDebugModeEnabled()
647
    {
648
        return (bool) $this['config']->get('app.debug');
649
    }
650
 
651
    /**
652
     * Register all of the configured providers.
653
     *
654
     * @return void
655
     */
656
    public function registerConfiguredProviders()
657
    {
658
        $providers = Collection::make($this->make('config')->get('app.providers'))
399 lars 659
                        ->partition(fn ($provider) => str_starts_with($provider, 'Illuminate\\'));
148 lars 660
 
661
        $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);
662
 
663
        (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
664
                    ->load($providers->collapse()->toArray());
665
    }
666
 
667
    /**
668
     * Register a service provider with the application.
669
     *
670
     * @param  \Illuminate\Support\ServiceProvider|string  $provider
671
     * @param  bool  $force
672
     * @return \Illuminate\Support\ServiceProvider
673
     */
674
    public function register($provider, $force = false)
675
    {
676
        if (($registered = $this->getProvider($provider)) && ! $force) {
677
            return $registered;
678
        }
679
 
680
        // If the given "provider" is a string, we will resolve it, passing in the
681
        // application instance automatically for the developer. This is simply
682
        // a more convenient way of specifying your service provider classes.
683
        if (is_string($provider)) {
684
            $provider = $this->resolveProvider($provider);
685
        }
686
 
687
        $provider->register();
688
 
689
        // If there are bindings / singletons set as properties on the provider we
690
        // will spin through them and register them with the application, which
691
        // serves as a convenience layer while registering a lot of bindings.
692
        if (property_exists($provider, 'bindings')) {
693
            foreach ($provider->bindings as $key => $value) {
694
                $this->bind($key, $value);
695
            }
696
        }
697
 
698
        if (property_exists($provider, 'singletons')) {
699
            foreach ($provider->singletons as $key => $value) {
700
                $key = is_int($key) ? $value : $key;
701
 
702
                $this->singleton($key, $value);
703
            }
704
        }
705
 
706
        $this->markAsRegistered($provider);
707
 
708
        // If the application has already booted, we will call this boot method on
709
        // the provider class so it has an opportunity to do its boot logic and
710
        // will be ready for any usage by this developer's application logic.
711
        if ($this->isBooted()) {
712
            $this->bootProvider($provider);
713
        }
714
 
715
        return $provider;
716
    }
717
 
718
    /**
719
     * Get the registered service provider instance if it exists.
720
     *
721
     * @param  \Illuminate\Support\ServiceProvider|string  $provider
722
     * @return \Illuminate\Support\ServiceProvider|null
723
     */
724
    public function getProvider($provider)
725
    {
726
        return array_values($this->getProviders($provider))[0] ?? null;
727
    }
728
 
729
    /**
730
     * Get the registered service provider instances if any exist.
731
     *
732
     * @param  \Illuminate\Support\ServiceProvider|string  $provider
733
     * @return array
734
     */
735
    public function getProviders($provider)
736
    {
737
        $name = is_string($provider) ? $provider : get_class($provider);
738
 
399 lars 739
        return Arr::where($this->serviceProviders, fn ($value) => $value instanceof $name);
148 lars 740
    }
741
 
742
    /**
743
     * Resolve a service provider instance from the class name.
744
     *
745
     * @param  string  $provider
746
     * @return \Illuminate\Support\ServiceProvider
747
     */
748
    public function resolveProvider($provider)
749
    {
750
        return new $provider($this);
751
    }
752
 
753
    /**
754
     * Mark the given provider as registered.
755
     *
756
     * @param  \Illuminate\Support\ServiceProvider  $provider
757
     * @return void
758
     */
759
    protected function markAsRegistered($provider)
760
    {
761
        $this->serviceProviders[] = $provider;
762
 
763
        $this->loadedProviders[get_class($provider)] = true;
764
    }
765
 
766
    /**
767
     * Load and boot all of the remaining deferred providers.
768
     *
769
     * @return void
770
     */
771
    public function loadDeferredProviders()
772
    {
773
        // We will simply spin through each of the deferred providers and register each
774
        // one and boot them if the application has booted. This should make each of
775
        // the remaining services available to this application for immediate use.
776
        foreach ($this->deferredServices as $service => $provider) {
777
            $this->loadDeferredProvider($service);
778
        }
779
 
780
        $this->deferredServices = [];
781
    }
782
 
783
    /**
784
     * Load the provider for a deferred service.
785
     *
786
     * @param  string  $service
787
     * @return void
788
     */
789
    public function loadDeferredProvider($service)
790
    {
791
        if (! $this->isDeferredService($service)) {
792
            return;
793
        }
794
 
795
        $provider = $this->deferredServices[$service];
796
 
797
        // If the service provider has not already been loaded and registered we can
798
        // register it with the application and remove the service from this list
799
        // of deferred services, since it will already be loaded on subsequent.
800
        if (! isset($this->loadedProviders[$provider])) {
801
            $this->registerDeferredProvider($provider, $service);
802
        }
803
    }
804
 
805
    /**
806
     * Register a deferred provider and service.
807
     *
808
     * @param  string  $provider
809
     * @param  string|null  $service
810
     * @return void
811
     */
812
    public function registerDeferredProvider($provider, $service = null)
813
    {
814
        // Once the provider that provides the deferred service has been registered we
815
        // will remove it from our local list of the deferred services with related
816
        // providers so that this container does not try to resolve it out again.
817
        if ($service) {
818
            unset($this->deferredServices[$service]);
819
        }
820
 
821
        $this->register($instance = new $provider($this));
822
 
823
        if (! $this->isBooted()) {
824
            $this->booting(function () use ($instance) {
825
                $this->bootProvider($instance);
826
            });
827
        }
828
    }
829
 
830
    /**
831
     * Resolve the given type from the container.
832
     *
833
     * @param  string  $abstract
834
     * @param  array  $parameters
835
     * @return mixed
836
     */
837
    public function make($abstract, array $parameters = [])
838
    {
839
        $this->loadDeferredProviderIfNeeded($abstract = $this->getAlias($abstract));
840
 
841
        return parent::make($abstract, $parameters);
842
    }
843
 
844
    /**
845
     * Resolve the given type from the container.
846
     *
847
     * @param  string  $abstract
848
     * @param  array  $parameters
849
     * @param  bool  $raiseEvents
850
     * @return mixed
851
     */
852
    protected function resolve($abstract, $parameters = [], $raiseEvents = true)
853
    {
854
        $this->loadDeferredProviderIfNeeded($abstract = $this->getAlias($abstract));
855
 
856
        return parent::resolve($abstract, $parameters, $raiseEvents);
857
    }
858
 
859
    /**
860
     * Load the deferred provider if the given type is a deferred service and the instance has not been loaded.
861
     *
862
     * @param  string  $abstract
863
     * @return void
864
     */
865
    protected function loadDeferredProviderIfNeeded($abstract)
866
    {
867
        if ($this->isDeferredService($abstract) && ! isset($this->instances[$abstract])) {
868
            $this->loadDeferredProvider($abstract);
869
        }
870
    }
871
 
872
    /**
873
     * Determine if the given abstract type has been bound.
874
     *
875
     * @param  string  $abstract
876
     * @return bool
877
     */
878
    public function bound($abstract)
879
    {
880
        return $this->isDeferredService($abstract) || parent::bound($abstract);
881
    }
882
 
883
    /**
884
     * Determine if the application has booted.
885
     *
886
     * @return bool
887
     */
888
    public function isBooted()
889
    {
890
        return $this->booted;
891
    }
892
 
893
    /**
894
     * Boot the application's service providers.
895
     *
896
     * @return void
897
     */
898
    public function boot()
899
    {
900
        if ($this->isBooted()) {
901
            return;
902
        }
903
 
904
        // Once the application has booted we will also fire some "booted" callbacks
905
        // for any listeners that need to do work after this initial booting gets
906
        // finished. This is useful when ordering the boot-up processes we run.
907
        $this->fireAppCallbacks($this->bootingCallbacks);
908
 
909
        array_walk($this->serviceProviders, function ($p) {
910
            $this->bootProvider($p);
911
        });
912
 
913
        $this->booted = true;
914
 
915
        $this->fireAppCallbacks($this->bootedCallbacks);
916
    }
917
 
918
    /**
919
     * Boot the given service provider.
920
     *
921
     * @param  \Illuminate\Support\ServiceProvider  $provider
922
     * @return void
923
     */
924
    protected function bootProvider(ServiceProvider $provider)
925
    {
926
        $provider->callBootingCallbacks();
927
 
928
        if (method_exists($provider, 'boot')) {
929
            $this->call([$provider, 'boot']);
930
        }
931
 
932
        $provider->callBootedCallbacks();
933
    }
934
 
935
    /**
936
     * Register a new boot listener.
937
     *
938
     * @param  callable  $callback
939
     * @return void
940
     */
941
    public function booting($callback)
942
    {
943
        $this->bootingCallbacks[] = $callback;
944
    }
945
 
946
    /**
947
     * Register a new "booted" listener.
948
     *
949
     * @param  callable  $callback
950
     * @return void
951
     */
952
    public function booted($callback)
953
    {
954
        $this->bootedCallbacks[] = $callback;
955
 
956
        if ($this->isBooted()) {
957
            $callback($this);
958
        }
959
    }
960
 
961
    /**
962
     * Call the booting callbacks for the application.
963
     *
964
     * @param  callable[]  $callbacks
965
     * @return void
966
     */
967
    protected function fireAppCallbacks(array &$callbacks)
968
    {
969
        $index = 0;
970
 
971
        while ($index < count($callbacks)) {
972
            $callbacks[$index]($this);
973
 
974
            $index++;
975
        }
976
    }
977
 
978
    /**
979
     * {@inheritdoc}
980
     *
981
     * @return \Symfony\Component\HttpFoundation\Response
982
     */
983
    public function handle(SymfonyRequest $request, int $type = self::MAIN_REQUEST, bool $catch = true): SymfonyResponse
984
    {
985
        return $this[HttpKernelContract::class]->handle(Request::createFromBase($request));
986
    }
987
 
988
    /**
989
     * Determine if middleware has been disabled for the application.
990
     *
991
     * @return bool
992
     */
993
    public function shouldSkipMiddleware()
994
    {
995
        return $this->bound('middleware.disable') &&
996
               $this->make('middleware.disable') === true;
997
    }
998
 
999
    /**
1000
     * Get the path to the cached services.php file.
1001
     *
1002
     * @return string
1003
     */
1004
    public function getCachedServicesPath()
1005
    {
1006
        return $this->normalizeCachePath('APP_SERVICES_CACHE', 'cache/services.php');
1007
    }
1008
 
1009
    /**
1010
     * Get the path to the cached packages.php file.
1011
     *
1012
     * @return string
1013
     */
1014
    public function getCachedPackagesPath()
1015
    {
1016
        return $this->normalizeCachePath('APP_PACKAGES_CACHE', 'cache/packages.php');
1017
    }
1018
 
1019
    /**
1020
     * Determine if the application configuration is cached.
1021
     *
1022
     * @return bool
1023
     */
1024
    public function configurationIsCached()
1025
    {
1026
        return is_file($this->getCachedConfigPath());
1027
    }
1028
 
1029
    /**
1030
     * Get the path to the configuration cache file.
1031
     *
1032
     * @return string
1033
     */
1034
    public function getCachedConfigPath()
1035
    {
1036
        return $this->normalizeCachePath('APP_CONFIG_CACHE', 'cache/config.php');
1037
    }
1038
 
1039
    /**
1040
     * Determine if the application routes are cached.
1041
     *
1042
     * @return bool
1043
     */
1044
    public function routesAreCached()
1045
    {
1046
        return $this['files']->exists($this->getCachedRoutesPath());
1047
    }
1048
 
1049
    /**
1050
     * Get the path to the routes cache file.
1051
     *
1052
     * @return string
1053
     */
1054
    public function getCachedRoutesPath()
1055
    {
1056
        return $this->normalizeCachePath('APP_ROUTES_CACHE', 'cache/routes-v7.php');
1057
    }
1058
 
1059
    /**
1060
     * Determine if the application events are cached.
1061
     *
1062
     * @return bool
1063
     */
1064
    public function eventsAreCached()
1065
    {
1066
        return $this['files']->exists($this->getCachedEventsPath());
1067
    }
1068
 
1069
    /**
1070
     * Get the path to the events cache file.
1071
     *
1072
     * @return string
1073
     */
1074
    public function getCachedEventsPath()
1075
    {
1076
        return $this->normalizeCachePath('APP_EVENTS_CACHE', 'cache/events.php');
1077
    }
1078
 
1079
    /**
1080
     * Normalize a relative or absolute path to a cache file.
1081
     *
1082
     * @param  string  $key
1083
     * @param  string  $default
1084
     * @return string
1085
     */
1086
    protected function normalizeCachePath($key, $default)
1087
    {
1088
        if (is_null($env = Env::get($key))) {
1089
            return $this->bootstrapPath($default);
1090
        }
1091
 
1092
        return Str::startsWith($env, $this->absoluteCachePathPrefixes)
1093
                ? $env
1094
                : $this->basePath($env);
1095
    }
1096
 
1097
    /**
1098
     * Add new prefix to list of absolute path prefixes.
1099
     *
1100
     * @param  string  $prefix
1101
     * @return $this
1102
     */
1103
    public function addAbsoluteCachePathPrefix($prefix)
1104
    {
1105
        $this->absoluteCachePathPrefixes[] = $prefix;
1106
 
1107
        return $this;
1108
    }
1109
 
1110
    /**
1111
     * Get an instance of the maintenance mode manager implementation.
1112
     *
1113
     * @return \Illuminate\Contracts\Foundation\MaintenanceMode
1114
     */
1115
    public function maintenanceMode()
1116
    {
1117
        return $this->make(MaintenanceModeContract::class);
1118
    }
1119
 
1120
    /**
1121
     * Determine if the application is currently down for maintenance.
1122
     *
1123
     * @return bool
1124
     */
1125
    public function isDownForMaintenance()
1126
    {
1127
        return $this->maintenanceMode()->active();
1128
    }
1129
 
1130
    /**
1131
     * Throw an HttpException with the given data.
1132
     *
1133
     * @param  int  $code
1134
     * @param  string  $message
1135
     * @param  array  $headers
1136
     * @return never
1137
     *
1138
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
1139
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
1140
     */
1141
    public function abort($code, $message = '', array $headers = [])
1142
    {
1143
        if ($code == 404) {
1144
            throw new NotFoundHttpException($message);
1145
        }
1146
 
1147
        throw new HttpException($code, $message, null, $headers);
1148
    }
1149
 
1150
    /**
1151
     * Register a terminating callback with the application.
1152
     *
1153
     * @param  callable|string  $callback
1154
     * @return $this
1155
     */
1156
    public function terminating($callback)
1157
    {
1158
        $this->terminatingCallbacks[] = $callback;
1159
 
1160
        return $this;
1161
    }
1162
 
1163
    /**
1164
     * Terminate the application.
1165
     *
1166
     * @return void
1167
     */
1168
    public function terminate()
1169
    {
1170
        $index = 0;
1171
 
1172
        while ($index < count($this->terminatingCallbacks)) {
1173
            $this->call($this->terminatingCallbacks[$index]);
1174
 
1175
            $index++;
1176
        }
1177
    }
1178
 
1179
    /**
1180
     * Get the service providers that have been loaded.
1181
     *
1182
     * @return array
1183
     */
1184
    public function getLoadedProviders()
1185
    {
1186
        return $this->loadedProviders;
1187
    }
1188
 
1189
    /**
1190
     * Determine if the given service provider is loaded.
1191
     *
1192
     * @param  string  $provider
1193
     * @return bool
1194
     */
1195
    public function providerIsLoaded(string $provider)
1196
    {
1197
        return isset($this->loadedProviders[$provider]);
1198
    }
1199
 
1200
    /**
1201
     * Get the application's deferred services.
1202
     *
1203
     * @return array
1204
     */
1205
    public function getDeferredServices()
1206
    {
1207
        return $this->deferredServices;
1208
    }
1209
 
1210
    /**
1211
     * Set the application's deferred services.
1212
     *
1213
     * @param  array  $services
1214
     * @return void
1215
     */
1216
    public function setDeferredServices(array $services)
1217
    {
1218
        $this->deferredServices = $services;
1219
    }
1220
 
1221
    /**
1222
     * Add an array of services to the application's deferred services.
1223
     *
1224
     * @param  array  $services
1225
     * @return void
1226
     */
1227
    public function addDeferredServices(array $services)
1228
    {
1229
        $this->deferredServices = array_merge($this->deferredServices, $services);
1230
    }
1231
 
1232
    /**
1233
     * Determine if the given service is a deferred service.
1234
     *
1235
     * @param  string  $service
1236
     * @return bool
1237
     */
1238
    public function isDeferredService($service)
1239
    {
1240
        return isset($this->deferredServices[$service]);
1241
    }
1242
 
1243
    /**
1244
     * Configure the real-time facade namespace.
1245
     *
1246
     * @param  string  $namespace
1247
     * @return void
1248
     */
1249
    public function provideFacades($namespace)
1250
    {
1251
        AliasLoader::setFacadeNamespace($namespace);
1252
    }
1253
 
1254
    /**
1255
     * Get the current application locale.
1256
     *
1257
     * @return string
1258
     */
1259
    public function getLocale()
1260
    {
1261
        return $this['config']->get('app.locale');
1262
    }
1263
 
1264
    /**
1265
     * Get the current application locale.
1266
     *
1267
     * @return string
1268
     */
1269
    public function currentLocale()
1270
    {
1271
        return $this->getLocale();
1272
    }
1273
 
1274
    /**
1275
     * Get the current application fallback locale.
1276
     *
1277
     * @return string
1278
     */
1279
    public function getFallbackLocale()
1280
    {
1281
        return $this['config']->get('app.fallback_locale');
1282
    }
1283
 
1284
    /**
1285
     * Set the current application locale.
1286
     *
1287
     * @param  string  $locale
1288
     * @return void
1289
     */
1290
    public function setLocale($locale)
1291
    {
1292
        $this['config']->set('app.locale', $locale);
1293
 
1294
        $this['translator']->setLocale($locale);
1295
 
1296
        $this['events']->dispatch(new LocaleUpdated($locale));
1297
    }
1298
 
1299
    /**
1300
     * Set the current application fallback locale.
1301
     *
1302
     * @param  string  $fallbackLocale
1303
     * @return void
1304
     */
1305
    public function setFallbackLocale($fallbackLocale)
1306
    {
1307
        $this['config']->set('app.fallback_locale', $fallbackLocale);
1308
 
1309
        $this['translator']->setFallback($fallbackLocale);
1310
    }
1311
 
1312
    /**
1313
     * Determine if the application locale is the given locale.
1314
     *
1315
     * @param  string  $locale
1316
     * @return bool
1317
     */
1318
    public function isLocale($locale)
1319
    {
1320
        return $this->getLocale() == $locale;
1321
    }
1322
 
1323
    /**
1324
     * Register the core class aliases in the container.
1325
     *
1326
     * @return void
1327
     */
1328
    public function registerCoreContainerAliases()
1329
    {
1330
        foreach ([
1331
            'app' => [self::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
1332
            'auth' => [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class],
1333
            'auth.driver' => [\Illuminate\Contracts\Auth\Guard::class],
1334
            'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
1335
            'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
1336
            'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class, \Psr\SimpleCache\CacheInterface::class],
1337
            'cache.psr6' => [\Symfony\Component\Cache\Adapter\Psr16Adapter::class, \Symfony\Component\Cache\Adapter\AdapterInterface::class, \Psr\Cache\CacheItemPoolInterface::class],
1338
            'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
1339
            'cookie' => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class],
1340
            'db' => [\Illuminate\Database\DatabaseManager::class, \Illuminate\Database\ConnectionResolverInterface::class],
1341
            'db.connection' => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
1342
            'db.schema' => [\Illuminate\Database\Schema\Builder::class],
1343
            'encrypter' => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\StringEncrypter::class],
1344
            'events' => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
1345
            'files' => [\Illuminate\Filesystem\Filesystem::class],
1346
            'filesystem' => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class],
1347
            'filesystem.disk' => [\Illuminate\Contracts\Filesystem\Filesystem::class],
1348
            'filesystem.cloud' => [\Illuminate\Contracts\Filesystem\Cloud::class],
1349
            'hash' => [\Illuminate\Hashing\HashManager::class],
1350
            'hash.driver' => [\Illuminate\Contracts\Hashing\Hasher::class],
1351
            'translator' => [\Illuminate\Translation\Translator::class, \Illuminate\Contracts\Translation\Translator::class],
1352
            'log' => [\Illuminate\Log\LogManager::class, \Psr\Log\LoggerInterface::class],
1353
            'mail.manager' => [\Illuminate\Mail\MailManager::class, \Illuminate\Contracts\Mail\Factory::class],
1354
            'mailer' => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class],
1355
            'auth.password' => [\Illuminate\Auth\Passwords\PasswordBrokerManager::class, \Illuminate\Contracts\Auth\PasswordBrokerFactory::class],
1356
            'auth.password.broker' => [\Illuminate\Auth\Passwords\PasswordBroker::class, \Illuminate\Contracts\Auth\PasswordBroker::class],
1357
            'queue' => [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class],
1358
            'queue.connection' => [\Illuminate\Contracts\Queue\Queue::class],
1359
            'queue.failer' => [\Illuminate\Queue\Failed\FailedJobProviderInterface::class],
1360
            'redirect' => [\Illuminate\Routing\Redirector::class],
1361
            'redis' => [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class],
1362
            'redis.connection' => [\Illuminate\Redis\Connections\Connection::class, \Illuminate\Contracts\Redis\Connection::class],
1363
            'request' => [\Illuminate\Http\Request::class, \Symfony\Component\HttpFoundation\Request::class],
1364
            'router' => [\Illuminate\Routing\Router::class, \Illuminate\Contracts\Routing\Registrar::class, \Illuminate\Contracts\Routing\BindingRegistrar::class],
1365
            'session' => [\Illuminate\Session\SessionManager::class],
1366
            'session.store' => [\Illuminate\Session\Store::class, \Illuminate\Contracts\Session\Session::class],
1367
            'url' => [\Illuminate\Routing\UrlGenerator::class, \Illuminate\Contracts\Routing\UrlGenerator::class],
1368
            'validator' => [\Illuminate\Validation\Factory::class, \Illuminate\Contracts\Validation\Factory::class],
1369
            'view' => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::class],
1370
        ] as $key => $aliases) {
1371
            foreach ($aliases as $alias) {
1372
                $this->alias($key, $alias);
1373
            }
1374
        }
1375
    }
1376
 
1377
    /**
1378
     * Flush the container of all bindings and resolved instances.
1379
     *
1380
     * @return void
1381
     */
1382
    public function flush()
1383
    {
1384
        parent::flush();
1385
 
1386
        $this->buildStack = [];
1387
        $this->loadedProviders = [];
1388
        $this->bootedCallbacks = [];
1389
        $this->bootingCallbacks = [];
1390
        $this->deferredServices = [];
1391
        $this->reboundCallbacks = [];
1392
        $this->serviceProviders = [];
1393
        $this->resolvingCallbacks = [];
1394
        $this->terminatingCallbacks = [];
1395
        $this->beforeResolvingCallbacks = [];
1396
        $this->afterResolvingCallbacks = [];
1397
        $this->globalBeforeResolvingCallbacks = [];
1398
        $this->globalResolvingCallbacks = [];
1399
        $this->globalAfterResolvingCallbacks = [];
1400
    }
1401
 
1402
    /**
1403
     * Get the application namespace.
1404
     *
1405
     * @return string
1406
     *
1407
     * @throws \RuntimeException
1408
     */
1409
    public function getNamespace()
1410
    {
1411
        if (! is_null($this->namespace)) {
1412
            return $this->namespace;
1413
        }
1414
 
1415
        $composer = json_decode(file_get_contents($this->basePath('composer.json')), true);
1416
 
1417
        foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path) {
1418
            foreach ((array) $path as $pathChoice) {
1419
                if (realpath($this->path()) === realpath($this->basePath($pathChoice))) {
1420
                    return $this->namespace = $namespace;
1421
                }
1422
            }
1423
        }
1424
 
1425
        throw new RuntimeException('Unable to detect application namespace.');
1426
    }
1427
}