Passed
Push — 0.7.0 ( 2c5a8e...dc9ed8 )
by Alexander
10:13 queued 11s
created

Application::getProviderHasBeenLoaded()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 7
rs 10
1
<?php 
2
3
/**
4
 * Lenevor Framework
5
 *
6
 * LICENSE
7
 *
8
 * This source file is subject to the new BSD license that is bundled
9
 * with this package in the file license.md.
10
 * It is also available through the world-wide-web at this URL:
11
 * https://lenevor.com/license
12
 * If you did not receive a copy of the license and are unable to
13
 * obtain it through the world-wide-web, please send an email
14
 * to [email protected] so we can send you a copy immediately.
15
 *
16
 * @package     Lenevor
17
 * @subpackage  Base
18
 * @link        https://lenevor.com
19
 * @copyright   Copyright (c) 2019 - 2021 Alexander Campo <[email protected]>
20
 * @license     https://opensource.org/licenses/BSD-3-Clause New BSD license or see https://lenevor.com/license or see /license.md
21
 */
22
23
namespace Syscodes\Core;
24
25
use Closure;
26
use Syscodes\Support\Str;
27
use Syscodes\Collections\Arr;
28
use Syscodes\Container\Container;
29
use Syscodes\Support\Environment;
30
use Syscodes\Filesystem\Filesystem;
31
use Syscodes\Support\ServiceProvider;
32
use Syscodes\Log\LoggerServiceProvider;
33
use Syscodes\Events\EventServiceProvider;
34
use Syscodes\Routing\RoutingServiceProvider;
35
use Syscodes\Core\Http\Exceptions\HttpException;
36
use Syscodes\Core\Http\Exceptions\NotFoundHttpException;
37
use Syscodes\Contracts\Core\Application as ApplicationContract;
38
39
/**
40
 * Allows the loading of service providers and functions to activate 
41
 * routes, environments and calls of main classes.
42
 * 
43
 * @author Alexander Campo <[email protected]>
44
 */
45
class Application extends Container implements ApplicationContract
46
{
47
    /**
48
     * The current globally available application.
49
     * 
50
     * @var string $instance
51
     */
52
    protected static $instance;
53
54
    /**
55
     * Php version.
56
     */
57
    protected static $phpVersion = '7.3.12';
58
    
59
    /**
60
     * The custom application path defined by the developer.
61
     *
62
     * @var string $appPath
63
     */
64
    protected $appPath;
65
66
    /**
67
     * The base path for the Lenevor installation.
68
     *
69
     * @var string $basePath
70
     */
71
    protected $basePath;
72
73
    /**
74
     * Indicates if the application has 'booted'.
75
     * 
76
     * @var bool $booted
77
     */
78
    protected $booted = false;
79
80
    /**
81
     * The array of booted callbacks.
82
     * 
83
     * @var callable[] $bootedCallbacks
84
     */
85
    protected $bootedCallbacks = [];
86
87
    /**
88
     * The array of booting callbacks.
89
     * 
90
     * @var callable[] $bootingCallbacks
91
     */
92
    protected $bootingCallbacks = [];
93
94
    /**
95
     * The deferred services and their providers.
96
     * 
97
     * @var array $deferredServices
98
     */
99
    protected $deferredServices = [];
100
101
    /**
102
     * Get the current application environment.
103
     * 
104
     * @var string
105
     */
106
    protected $env;
107
108
    /**
109
     * The custom environment path defined by the developer.
110
     *
111
     * @var string $environmentPath
112
     */
113
    protected $environmentPath;
114
115
    /**
116
     * The environment file to load during bootstrapping.
117
     *
118
     * @var string $environmentFile
119
     */
120
    protected $environmentFile = '.env';
121
122
    /** 
123
     * Indicates if the application has been bootstrapped before.
124
     * 
125
     * @var bool $hasBeenBootstrapped
126
     */
127
    protected $hasBeenBootstrapped = false;
128
129
    /**
130
     * Indicates if the application is running in the console.
131
     * 
132
     * @var bool|null $isRunningInConsole
133
     */
134
    protected $isRunningInConsole;
135
136
    /**
137
     * The names of the loaded service providers.
138
     * 
139
     * @var array $loadServiceProviders
140
     */
141
    protected $loadServiceProviders = [];
142
143
    /**
144
     * All of the registered services providers.
145
     * 
146
     * @var \Syscodes\Support\ServiceProvider[] $serviceProviders
147
     */
148
    protected $serviceProviders = [];
149
150
    /**
151
     * Constructor. Create a new Application instance.
152
     * 
153
     * @param  string|null  $path 
154
     * 
155
     * @return void
156
     */
157
    public function __construct($path = null)
158
    {
159
        if ($path)
160
        {
161
            $this->setBasePath($path);
162
        }
163
164
        $this->registerBaseBindings();
165
        $this->registerBaseServiceProviders();
166
        $this->registerCoreContainerAliases();
167
        $this->requerimentVersion(static::$phpVersion);
168
        $this->getExtensionLoaded(['mbstring']);
169
    }
170
171
    /**
172
     * Throw an HttpException with the given data.
173
     *
174
     * @param  int  $code
175
     * @param  string  $message
176
     * @param  array  $headers
177
     * 
178
     * @return void
179
     *
180
     * @throws \Syscodes\Core\Http\Exceptions\NotFoundHttpException
181
     * @throws \Syscodes\Core\Http\Exceptions\HttpException
182
     */
183
    public function abort($code, $message = '', array $headers = [])
184
    {
185
        // Convert the first letter in capital
186
        $message = ucfirst($message);
187
188
        if ($code == 404) {
189
            throw new NotFoundHttpException($message);
190
        }
191
192
        throw new HttpException($code, $message, null, $headers);
193
    } 
194
195
    /**
196
     * Set the base path for the application.
197
     *
198
     * @param  string  $path
199
     * 
200
     * @return $this
201
     */
202
    public function setBasePath(string $path)
203
    {
204
        $this->basePath = rtrim($path, '\/');
205
206
        $this->bindContainerPaths();
207
208
        return $this;
209
    }
210
    
211
    /**
212
     * Register all of the base service providers.
213
     * 
214
     * @return void
215
     */
216
    protected function registerBaseServiceProviders()
217
    {
218
        $this->register(new EventServiceProvider($this));
219
        $this->register(new LoggerServiceProvider($this));
220
        $this->register(new RoutingServiceProvider($this));
221
    }
222
223
    /**
224
     * Bind all of the application paths in the container.
225
     * 
226
     * @return void
227
     */
228
    protected function bindContainerPaths()
229
    {
230
        $this->instance('path', $this->path());
231
        $this->instance('path.base', $this->basePath());
232
        $this->instance('path.lang', $this->langPath());
233
        $this->instance('path.config', $this->configPath());
234
        $this->instance('path.public', $this->publicPath());
235
        $this->instance('path.storage', $this->storagePath());
236
        $this->instance('path.database', $this->databasePath());
237
        $this->instance('path.resources', $this->resourcePath());
238
        $this->instance('path.bootstrap', $this->bootstrapPath());
239
    }
240
241
    /**
242
     * Get the path to the application "app" directory.
243
     *
244
     * @param  string  $path
245
     * 
246
     * @return string
247
     */
248
    public function path($path = '')
249
    {
250
        $appPath = $this->basePath.DIRECTORY_SEPARATOR.'app';
251
        
252
        return $appPath.($path ? DIRECTORY_SEPARATOR.$path : $path);
253
    }
254
255
    /**
256
     * Get the base path of the Lenevor installation.
257
     *
258
     * @param  string  $path  Optionally, a path to append to the base path
259
     * 
260
     * @return string
261
     */
262
    public function basePath($path = '')
263
    {
264
        return $this->basePath.($path ? DIRECTORY_SEPARATOR.$path : $path);
265
    }
266
    
267
    /**
268
     * Get the path to the bootstrap directory.
269
     *
270
     * @param  string  $path  Optionally, a path to append to the bootstrap path
271
     * 
272
     * @return string
273
     */
274
    public function bootstrapPath($path = '')
275
    {
276
        return $this->basePath.DIRECTORY_SEPARATOR.'bootstrap'.($path ? DIRECTORY_SEPARATOR.$path : $path);
277
    }
278
279
    /**
280
     * Get the path to the application configuration files.
281
     *
282
     * @param  string  $path  Optionally, a path to append to the config path
283
     * 
284
     * @return string
285
     */
286
    public function configPath($path = '')
287
    {
288
        return $this->basePath.DIRECTORY_SEPARATOR.'config'.($path ? DIRECTORY_SEPARATOR.$path : $path);
289
    }
290
291
    /**
292
     * Get the path to the database directory.
293
     *
294
     * @param  string  $path  Optionally, a path to append to the database path
295
     * 
296
     * @return string
297
     */
298
    public function databasePath($path = '')
299
    {
300
        return $this->basePath.DIRECTORY_SEPARATOR.'database'.($path ? DIRECTORY_SEPARATOR.$path : $path);
301
    }
302
303
    /**
304
     * Get the path to the lang directory.
305
     * 
306
     * @return string
307
     */
308
    public function langPath()
309
    {
310
        return $this->resourcePath().DIRECTORY_SEPARATOR.'lang';
311
    }
312
313
    /**
314
     * Get the path to the public / web directory.
315
     * 
316
     * @return string
317
     */
318
    public function publicPath()
319
    {
320
        return $this->basePath.DIRECTORY_SEPARATOR.'public';
321
    }
322
323
    /**
324
     * Get the path to the resources directory.
325
     *
326
     * @param  string  $path $path  Optionally, a path to append to the resources path
327
     * 
328
     * @return string
329
     */
330
    public function resourcePath($path = '')
331
    {
332
        return $this->basePath.DIRECTORY_SEPARATOR.'resources'.($path ? DIRECTORY_SEPARATOR.$path : $path);
333
    }
334
335
    /**
336
     * Get the path to the storage directory.
337
     * 
338
     * @return string
339
     */
340
    public function storagePath()
341
    {
342
        return $this->basePath.DIRECTORY_SEPARATOR.'storage';
343
    }
344
345
    /**
346
     * Run the given array of bootstap classes.
347
     * 
348
     * @param  string[]  $bootstrappers
349
     * 
350
     * @return void
351
     */
352
    public function bootstrapWith(array $bootstrappers)
353
    {
354
        $this->hasBeenBootstrapped = true;
355
356
        foreach ($bootstrappers as $bootstrapper) {
357
            $this->make($bootstrapper)->bootstrap($this);
358
        }
359
    }
360
361
    /**
362
     * Determine if middleware has been disabled for the application.
363
     * 
364
     * @return bool
365
     */
366
    public function skipGoingMiddleware()
367
    {
368
        return $this->bound('middleware.disable') &&
369
               $this->make('middleware.disable') === true;
370
    }
371
372
    /**
373
     * Set the directory for the environment file.
374
     * 
375
     * @param  string  $path
376
     * 
377
     * @return $this
378
     */
379
    public function setEnvironmentPath($path)
380
    {
381
        $this->environmentPath = $path;
382
383
        return $this;
384
    }
385
386
    /**
387
     * Get the path to the environment file directory.
388
     * 
389
     * @return string
390
     */
391
    public function environmentPath()
392
    {
393
        return $this->environmentPath ?: $this->basePath;
394
    }
395
396
    /**
397
     * Set the environment file to be loaded during bootstrapping.
398
     * 
399
     * @param  string  $file
400
     * 
401
     * @return $this
402
     */
403
    public function setEnvironmentFile($file)
404
    {
405
        $this->environmentFile = $file;
406
407
        return $this;
408
    }
409
410
    /**
411
     * Get the environment file the application is using.
412
     * 
413
     * @return string
414
     */
415
    public function environmentFile()
416
    {
417
        return $this->environmentFile ?: '.env';
418
    }
419
    
420
    /**
421
     * Get the fully qualified path to the environment file.
422
     * 
423
     * @return string
424
     */
425
    public function environmentFilePath()
426
    {
427
        return $this->environmentPath().DIRECTORY_SEPARATOR.$this->environmentFile();
428
    }
429
430
    /**
431
     * Get or check the current application environment.
432
     * 
433
     * @param  string|array  ...$environments
434
     * 
435
     * @return string|bool
436
     */
437
    public function environment(...$environments)
438
    {
439
        if (count($environments) > 0) {
440
            $patterns = is_array($environments[0]) ? $environments[0] : $environments;
441
442
            return Str::is($patterns, $this->env);
0 ignored issues
show
Bug introduced by
$patterns of type array|array<integer,array|string> is incompatible with the type string expected by parameter $pattern of Syscodes\Support\Str::is(). ( Ignorable by Annotation )

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

442
            return Str::is(/** @scrutinizer ignore-type */ $patterns, $this->env);
Loading history...
443
        }
444
445
        return $this->env;
446
    }
447
448
    /**
449
     * Detect the application's current environment.
450
     * 
451
     * @param  \Closure  $callback
452
     *
453
     * @return string
454
     */
455
    public function detectEnvironment(Closure $callback)
456
    {
457
        return $this->env = (new EnvironmentDetector)->detect($callback);
458
    }
459
    
460
    /**
461
     * Determine if application is in local environment.
462
     * 
463
     * @return bool
464
     */
465
    public function isLocal()
466
    {
467
        return $this->env === 'local';
468
    }
469
    
470
    /**
471
     * Determine if application is in production environment.
472
     * 
473
     * @return bool
474
     */
475
    public function isProduction()
476
    {
477
        return $this->env === 'production';
478
    }
479
    
480
    /**
481
     * Determine if the application is unit tests.
482
     * 
483
     * @return bool
484
     */
485
    public function isUnitTests()
486
    {
487
        return $this->env === 'testing';
488
    }
489
490
    /**
491
     * Determine if the application is running in the console.
492
     * 
493
     * @return bool|null
494
     */
495
    public function runningInConsole()
496
    {
497
        if (null === $this->isRunningInConsole) {
498
            $this->isRunningInConsole = Environment::get('APP_RUNNING_CONSOLE') ?? isCli();
0 ignored issues
show
Documentation Bug introduced by
It seems like Syscodes\Support\Environ...NG_CONSOLE') ?? isCli() can also be of type string. However, the property $isRunningInConsole is declared as type boolean|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
499
        }
500
501
        return $this->isRunningInConsole;
502
    }
503
    
504
    /**
505
     * You can load different configurations depending on your
506
     * current environment. Setting the environment also influences
507
     * things like logging and error reporting.
508
     * 
509
     * This can be set to anything, but default usage is:
510
     *     local (development)
511
     *     testing
512
     *     production
513
     * 
514
     * @return string
515
     */
516
    public function bootEnvironment()
517
    {
518
        if (file_exists(SYS_PATH.'src'.DIRECTORY_SEPARATOR.'environment'.DIRECTORY_SEPARATOR.$this->environment().'.php')) {
519
            require_once SYS_PATH.'src'.DIRECTORY_SEPARATOR.'environment'.DIRECTORY_SEPARATOR.$this->environment().'.php';
520
        } else {
521
            header('HTTP/1.1 503 Service Unavailable.', true, 503);
522
            print('<style>
523
                    body {
524
                        align-items: center;
525
                        background: #FBFCFC;
526
                        display: flex;
527
                        font-family: verdana, sans-seif;
528
                        font-size: .9em;
529
                        font-weight: 600;
530
                        justify-content: center;
531
                    }
532
                    
533
                    p {
534
                        background: #F0F3F4;
535
                        border-radius: 5px;
536
                        box-shadow: 0 1px 4px #333333;
537
                        color: #34495E;
538
                        padding: 10px;
539
                        text-align: center;
540
                        text-shadow: 0 1px 0 #424949;
541
                        width: 25%;
542
                    }
543
                </style>
544
                <p>The application environment is not set correctly.</p>');
545
            die(); // EXIT_ERROR
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
546
        }
547
    }
548
549
    /**
550
     * Determine if the application has been bootstrapped before.
551
     * 
552
     * @return bool
553
     */
554
    public function hasBeenBootstrapped()
555
    {
556
        return $this->hasBeenBootstrapped;
557
    }
558
559
    /**
560
     * You can empty out this file, if you are certain that you match all requirements.
561
     * You can remove this if you are confident that your PHP version is sufficient.
562
     * 
563
     * @return string
564
     */
565
    protected function requerimentVersion($version)
566
    {
567
        if (version_compare(PHP_VERSION, $version) < 0) {
568
            if (PHP_SAPI == 'cli') {
569
                $string  = "\033[1;36m";
570
                $string .= "$version\033[0m";
571
                trigger_error("Your PHP version must be equal or higher than {$string} to use Lenevor Framework.".PHP_EOL, E_USER_ERROR);
572
            }
573
    
574
            die("Your PHP version must be equal or higher than <b>{$version}</b> to use Lenevor Framework.");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
575
        }
576
    }
577
578
    /**
579
     * You can remove this if you are confident you have mbstring installed.
580
     * 
581
     * @return string
582
     */
583
    protected function getExtensionLoaded(array $extensionLoaded)
584
    {
585
        foreach ($extensionLoaded as $value) {
586
            if ( ! extension_loaded($value)) {
587
                if (PHP_SAPI == 'cli') {
588
                    $string  = "\033[1;36m";
589
                    $string .= "$value\033[0m";
590
                    trigger_error("You must enable the {$string} extension to use Lenevor Framework.".PHP_EOL, E_USER_ERROR);
591
                }
592
593
                die("You must enable the <b>{$value}</b> extension to use Lenevor Framework.");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
594
            }
595
        }
596
    }
597
598
    /**
599
     * Resolve the given type from the container.
600
     *
601
     * (Overriding Container::make)
602
     * 
603
     * @param  string  $id
604
     * @param  array   $parameters
605
     * 
606
     * @return mixed
607
     */
608
    public function make($id, array $parameters = [])
609
    {
610
        $id = $this->getAlias($id);
611
       
612
        return parent::make($id, $parameters);
613
    }
614
615
    /**
616
     * Register all of the configured providers.
617
     * 
618
     * @return void
619
     */
620
    public function registerConfiguredProviders()
621
    {
622
        (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
623
                ->load($this['config']['services.providers']);
624
    }
625
    
626
    /**
627
     * Register a service provider.
628
     * 
629
     * @param  \Syscodes\Support\ServiceProvider|string  $provider
630
     * @param  bool  $force
631
     * 
632
     * @return \Syscodes\Support\ServiceProvider
633
     */
634
    public function register($provider, $force = false)
635
    {
636
        if (($registered = $this->getProviderHasBeenLoaded($provider)) && ! $force) {
637
            return $registered;
638
        }
639
640
        if (is_string($provider)) {
641
            $provider = $this->resolveProviderClass($provider);
642
        }
643
        
644
        $provider->register();
645
646
        $this->markAsRegistered($provider);
647
648
        return $provider;
649
    }
650
651
    /**
652
     * Get the registered service provider instance if it exists.
653
     * 
654
     * @param  \Syscodes\Support\ServiceProvider|string  $provider
655
     * 
656
     * @return \Syscodes\Support\ServiceProvider
657
     */
658
    protected function getProviderHasBeenLoaded($provider)
659
    {
660
        $name = is_string($provider) ? $provider : get_class($provider);
661
662
        if (array_key_exists($name, $this->loadServiceProviders)) {
663
            return Arr::first($this->serviceProviders, function($key, $value) use ($name) {
664
                return get_class($value) == $name;
665
            });
666
        }
667
    }
668
669
    /**
670
     * Resolve a service provider instance from the class name.
671
     * 
672
     * @param  string  $provider
673
     * 
674
     * @return \Syscodes\Support\ServiceProvider
675
     */
676
    public function resolveProviderClass($provider)
677
    {
678
        return new $provider($this);
679
    }
680
681
    /**
682
     * Mark the given provider as registered.
683
     * 
684
     * @param  \Syscodes\Support\ServiceProvider  $provider
685
     * 
686
     * @return void
687
     */
688
    protected function markAsRegistered($provider)
689
    {
690
        $this['events']->dispatch($class = getClass($provider, true), array($provider));
0 ignored issues
show
Bug introduced by
$provider of type Syscodes\Support\ServiceProvider is incompatible with the type string expected by parameter $classname of getClass(). ( Ignorable by Annotation )

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

690
        $this['events']->dispatch($class = getClass(/** @scrutinizer ignore-type */ $provider, true), array($provider));
Loading history...
691
692
        $this->serviceProviders[] = $provider;
693
        
694
        $this->loadServiceProviders[$class] = true;
695
    }
696
697
    /**
698
     * Load and boot all of the remaining deferred providers.
699
     * 
700
     * @return void
701
     */
702
    public function loadDeferredProviders()
703
    {
704
        foreach ($this->deferredServices as $service => $provider) {
705
            $this->loadDeferredProvider($service);
706
        }
707
708
        $this->deferredServices = [];
709
    }
710
711
    /**
712
     * Load the provider for a deferred service.
713
     * 
714
     * @param  string  $service
715
     * 
716
     * @return void
717
     */
718
    public function loadDeferredProvider($service)
719
    {
720
        if ( ! $this->isDeferredService($service)) {
721
            return;
722
        }
723
724
        $provider = $this->deferredServices[$service];
725
726
        if ( ! isset($this->loadDeferredProviders[$service])) {
0 ignored issues
show
Bug Best Practice introduced by
The property loadDeferredProviders does not exist on Syscodes\Core\Application. Since you implemented __get, consider adding a @property annotation.
Loading history...
727
            $this->registerDeferredProvider($provider, $service);
728
        }
729
    }
730
731
    /**
732
     * Register a deferred provider and service.
733
     * 
734
     * @param  string  $provider
735
     * @param  string  $service
736
     * 
737
     * @return void
738
     */
739
    public function registerDeferredProvider($provider, $service = null)
740
    {
741
        if ($service) {
742
            unset($this->deferredServices[$service]);
743
        }
744
745
        $this->register($instance = new $provider($this));
746
747
        if ( ! $this->isbooted()) {
748
            $this->booting(function () use ($instance) {
749
                $this->bootProviderClass($instance);
750
            });
751
        }
752
    }
753
    
754
    /**
755
     * Determine if the given id type has been bound.
756
     * 
757
     * @param  string  $id
758
     * 
759
     * @return bool
760
     */
761
    public function bound($id)
762
    {
763
        return $this->isDeferredService($id) || parent::bound($id);
764
    }
765
766
    /**
767
     * Determine if the application has booted.
768
     * 
769
     * @return bool
770
     */
771
    public function isBooted()
772
    {
773
        return $this->booted;
774
    }
775
776
    /**
777
     * Boot the application´s service providers.
778
     * 
779
     * @return void
780
     */
781
    public function boot()
782
    {
783
        if ($this->isbooted()) {
784
            return;
785
        }
786
787
        $this->bootAppCallbacks($this->bootingCallbacks);
788
789
        array_walk($this->serviceProviders, function ($provider) {
790
            $this->bootProviderClass($provider);
791
        });
792
793
        $this->booted = true;
794
795
        $this->bootAppCallbacks($this->bootedCallbacks);
796
    }
797
798
    /**
799
     * Call the booting callbacks for the application.
800
     * 
801
     * @param  callable[]  $callbacks
802
     * 
803
     * @return void
804
     */
805
    protected function bootAppCallbacks(array $callbacks)
806
    {
807
        foreach ($callbacks as $callback) {
808
            $callback($this);
809
        }
810
    }
811
812
    /**
813
     * Boot the given service provider.
814
     * 
815
     * @param  \Syscodes\Support\ServiceProvider  $provider
816
     * 
817
     * @return mixed
818
     */
819
    protected function bootProviderClass(ServiceProvider $provider)
820
    {
821
        if (method_exists($provider, 'boot'))
822
        {
823
            $provider->boot();
824
        }
825
    }
826
827
    /**
828
     * Register a new boot listener.
829
     * 
830
     * @param  callable  $callback
831
     * 
832
     * @return void
833
     */
834
    public function booting($callback)
835
    {
836
        $this->bootingCallbacks[] = $callback;
837
    }
838
839
    /**
840
     * Register a new 'booted' listener.
841
     * 
842
     * @param  callable  $callback
843
     * 
844
     * @return void
845
     */
846
    public function booted($callback)
847
    {
848
        $this->bootedCallbacks[] = $callback;
849
850
        if ($this->isBooted()) {
851
            $this->bootAppCallbacks([$callback]);
852
        }
853
    }
854
855
    /**
856
     * Get the path to the cached services.php file.
857
     * 
858
     * @return string
859
     */
860
    public function getCachedServicesPath()
861
    {
862
        return $this->normalizeCachePath('APP_SERVICES_CACHE', 'cache/services.php');
863
    }
864
865
    /**
866
     * Normalize a relative or absolute path to a cache file.
867
     * 
868
     * @param  string  $key
869
     * @param  string  $default
870
     * 
871
     * @return string
872
     */
873
    protected function normalizeCachePath($key, $default)
874
    {
875
        if (is_null($env = Environment::get($key))) {
876
            return $this->bootstrapPath($default);
877
        }
878
879
        return isset($env) 
0 ignored issues
show
Bug Best Practice introduced by
The expression return IssetNode ? $env : $this->basePath($env) also could return the type boolean which is incompatible with the documented return type string.
Loading history...
880
                ? $env
881
                : $this->basePath($env);
882
    }
883
884
    /**
885
     * Get the service providers.
886
     * 
887
     * @return array
888
     */
889
    public function getLoadedProviders()
890
    {
891
        return $this->loadServiceProviders;
892
    }
893
894
    /**
895
     * Determine if the given service provider is loaded.
896
     * 
897
     * @param  string  $provider
898
     * 
899
     * @return bool
900
     */
901
    public function providerIsLoaded(string $provider)
902
    {
903
        return isset($this->loadServiceProviders[$provider]);
904
    }
905
906
    /**
907
     * Get the application's deferred services.
908
     * 
909
     * @return array
910
     */
911
    public function getDeferredServices()
912
    {
913
        return $this->deferredServices;
914
    }
915
916
    /**
917
     * Set the application's deferred services.
918
     * 
919
     * @param  array  $services
920
     * 
921
     * @return void
922
     */
923
    public function setDeferredServices(array $services)
924
    {
925
        $this->deferredServices = $services;
926
    }
927
928
    /**
929
     * Determine if the given service is a deferred service.
930
     * 
931
     * @param  string  $service
932
     * 
933
     * @return bool
934
     */
935
    public function isDeferredService($service)
936
    {
937
        return isset($this->deferredServices[$service]);
938
    }
939
940
    /**
941
     * Add an array of services to the application's deferred services.
942
     * 
943
     * @param  array  $services
944
     * 
945
     * @return void
946
     */
947
    public function addDeferredServices(array $services)
948
    {
949
        $this->deferredServices = array_merge($this->deferredServices, $services);
950
    }
951
952
    /**
953
     * Get the current application locale.
954
     * 
955
     * @return string
956
     */
957
    public function getLocale()
958
    {
959
        return $this['config']->get('app.locale');
960
    }
961
962
    /**
963
     * Get the current application fallback locale.
964
     * 
965
     * @return string
966
     */
967
    public function getFallbackLocale()
968
    {
969
        return $this['config']->get('app.fallbackLocale');
970
    }
971
972
    /**
973
     * Determine if application locale is the given locale.
974
     * 
975
     * @param  string  $locale
976
     * 
977
     * @return bool
978
     */
979
    public function isLocale($locale)
980
    {
981
        return $this->getLocale() == $locale;
982
    }
983
984
    /**
985
     * Register the basic bindings into the container.
986
     *
987
     * @return void
988
     */
989
    public function registerBaseBindings() 
990
    {
991
        static::setInstance($this);
992
        
993
        $this->instance('app', $this);
994
        
995
        $this->instance('config', $this[\Syscodes\Config\Configure::class]);
996
    }
997
998
    /**
999
     * Register the core class aliases in the container.
1000
     * 
1001
     * @return void
1002
     */
1003
    public function registerCoreContainerAliases()
1004
    {
1005
        foreach ([
1006
            'app'              => [self::class, \Syscodes\Contracts\Container\Container::class, \Syscodes\Contracts\Core\Application::class, \Psr\Container\ContainerInterface::class],
1007
            'cache'            => [\Syscodes\Cache\CacheManager::class, \Syscodes\Contracts\Cache\Manager::class],
1008
            'cache.store'      => [\Syscodes\Cache\CacheRepository::class],
1009
            'config'           => [\Syscodes\Config\Configure::class, \Syscodes\Contracts\Config\Configure::class],
1010
            'db'               => [\Syscodes\Database\DatabaseManager::class, \Syscodes\Database\ConnectionResolverInterface::class],
1011
            'db.connection'    => [\Syscodes\Database\Connection::class, \Syscodes\Database\ConnectionInterface::class],
1012
            'encrypter'        => [\Syscodes\Encryption\Encrypter::class, \Syscodes\Contracts\Encryption\Encrypter::class],
1013
            'events'           => [\Syscodes\Events\Dispatcher::class, \Syscodes\Contracts\Events\Dispatcher::class],
1014
            'files'            => [\Syscodes\Filesystem\Filesystem::class],
1015
            'log'              => [\Syscodes\Log\LogManager::class, \Psr\Log\LoggerInterface::class],
1016
            'plaze.transpiler' => [\Syscodes\View\Transpilers\PlazeTranspiler::class],
1017
            'redirect'         => [\Syscodes\Routing\Redirector::class],
1018
            'redis'            => [\Syscodes\Redis\RedisManager::class],
1019
            'request'          => [\Syscodes\Http\Request::class],
1020
            'router'           => [\Syscodes\Routing\Router::class],
1021
            'session'          => [\Syscodes\Session\SessionManager::class],
1022
            'session.store'    => [\Syscodes\Session\Store::class, \Syscodes\Contracts\Session\Session::class],
1023
            'translator'       => [\Syscodes\Translation\Translator::class],
1024
            'url'              => [\Syscodes\Routing\UrlGenerator::class],
1025
            'view'             => [\Syscodes\View\Factory::class, \Syscodes\Contracts\View\Factory::class]
1026
        ] as $key => $aliases) {
1027
            foreach ((array) $aliases as $alias) {
1028
                $this->alias($key, $alias);
1029
            }
1030
        }
1031
    }
1032
}