Issues (836)

framework/base/Application.php (22 issues)

1
<?php
2
/**
3
 * @link https://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license https://www.yiiframework.com/license/
6
 */
7
8
namespace yii\base;
9
10
use Yii;
11
12
/**
13
 * Application is the base class for all application classes.
14
 *
15
 * For more details and usage information on Application, see the [guide article on applications](guide:structure-applications).
16
 *
17
 * @property-read \yii\web\AssetManager $assetManager The asset manager application component.
18
 * @property-read \yii\rbac\ManagerInterface|null $authManager The auth manager application component or null
19
 * if it's not configured.
20
 * @property string $basePath The root directory of the application.
21
 * @property-read \yii\caching\CacheInterface|null $cache The cache application component. Null if the
22
 * component is not enabled.
23
 * @property-write array $container Values given in terms of name-value pairs.
24
 * @property-read \yii\db\Connection $db The database connection.
25
 * @property-read \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application
26
 * component.
27
 * @property-read \yii\i18n\Formatter $formatter The formatter application component.
28
 * @property-read \yii\i18n\I18N $i18n The internationalization application component.
29
 * @property-read \yii\log\Dispatcher $log The log dispatcher application component.
30
 * @property-read \yii\mail\MailerInterface $mailer The mailer application component.
31
 * @property-read \yii\web\Request|\yii\console\Request $request The request component.
32
 * @property-read \yii\web\Response|\yii\console\Response $response The response component.
33
 * @property string $runtimePath The directory that stores runtime files. Defaults to the "runtime"
34
 * subdirectory under [[basePath]].
35
 * @property-read \yii\base\Security $security The security application component.
36
 * @property string $timeZone The time zone used by this application.
37
 * @property-read string $uniqueId The unique ID of the module.
38
 * @property-read \yii\web\UrlManager $urlManager The URL manager for this application.
39
 * @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under
40
 * [[basePath]].
41
 * @property-read View|\yii\web\View $view The view application component that is used to render various view
42
 * files.
43
 *
44
 * @author Qiang Xue <[email protected]>
45
 * @since 2.0
46
 */
47
abstract class Application extends Module
48
{
49
    /**
50
     * @event Event an event raised before the application starts to handle a request.
51
     */
52
    const EVENT_BEFORE_REQUEST = 'beforeRequest';
53
    /**
54
     * @event Event an event raised after the application successfully handles a request (before the response is sent out).
55
     */
56
    const EVENT_AFTER_REQUEST = 'afterRequest';
57
    /**
58
     * Application state used by [[state]]: application just started.
59
     */
60
    const STATE_BEGIN = 0;
61
    /**
62
     * Application state used by [[state]]: application is initializing.
63
     */
64
    const STATE_INIT = 1;
65
    /**
66
     * Application state used by [[state]]: application is triggering [[EVENT_BEFORE_REQUEST]].
67
     */
68
    const STATE_BEFORE_REQUEST = 2;
69
    /**
70
     * Application state used by [[state]]: application is handling the request.
71
     */
72
    const STATE_HANDLING_REQUEST = 3;
73
    /**
74
     * Application state used by [[state]]: application is triggering [[EVENT_AFTER_REQUEST]]..
75
     */
76
    const STATE_AFTER_REQUEST = 4;
77
    /**
78
     * Application state used by [[state]]: application is about to send response.
79
     */
80
    const STATE_SENDING_RESPONSE = 5;
81
    /**
82
     * Application state used by [[state]]: application has ended.
83
     */
84
    const STATE_END = 6;
85
86
    /**
87
     * @var string the namespace that controller classes are located in.
88
     * This namespace will be used to load controller classes by prepending it to the controller class name.
89
     * The default namespace is `app\controllers`.
90
     *
91
     * Please refer to the [guide about class autoloading](guide:concept-autoloading.md) for more details.
92
     */
93
    public $controllerNamespace = 'app\\controllers';
94
    /**
95
     * @var string the application name.
96
     */
97
    public $name = 'My Application';
98
    /**
99
     * @var string the charset currently used for the application.
100
     */
101
    public $charset = 'UTF-8';
102
    /**
103
     * @var string the language that is meant to be used for end users. It is recommended that you
104
     * use [IETF language tags](https://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands
105
     * for English, while `en-US` stands for English (United States).
106
     * @see sourceLanguage
107
     */
108
    public $language = 'en-US';
109
    /**
110
     * @var string the language that the application is written in. This mainly refers to
111
     * the language that the messages and view files are written in.
112
     * @see language
113
     */
114
    public $sourceLanguage = 'en-US';
115
    /**
116
     * @var Controller the currently active controller instance
117
     */
118
    public $controller;
119
    /**
120
     * @var string|bool the layout that should be applied for views in this application. Defaults to 'main'.
121
     * If this is false, layout will be disabled.
122
     */
123
    public $layout = 'main';
124
    /**
125
     * @var string the requested route
126
     */
127
    public $requestedRoute;
128
    /**
129
     * @var Action|null the requested Action. If null, it means the request cannot be resolved into an action.
130
     */
131
    public $requestedAction;
132
    /**
133
     * @var array the parameters supplied to the requested action.
134
     */
135
    public $requestedParams;
136
    /**
137
     * @var array|null list of installed Yii extensions. Each array element represents a single extension
138
     * with the following structure:
139
     *
140
     * ```php
141
     * [
142
     *     'name' => 'extension name',
143
     *     'version' => 'version number',
144
     *     'bootstrap' => 'BootstrapClassName',  // optional, may also be a configuration array
145
     *     'alias' => [
146
     *         '@alias1' => 'to/path1',
147
     *         '@alias2' => 'to/path2',
148
     *     ],
149
     * ]
150
     * ```
151
     *
152
     * The "bootstrap" class listed above will be instantiated during the application
153
     * [[bootstrap()|bootstrapping process]]. If the class implements [[BootstrapInterface]],
154
     * its [[BootstrapInterface::bootstrap()|bootstrap()]] method will be also be called.
155
     *
156
     * If not set explicitly in the application config, this property will be populated with the contents of
157
     * `@vendor/yiisoft/extensions.php`.
158
     */
159
    public $extensions;
160
    /**
161
     * @var array list of components that should be run during the application [[bootstrap()|bootstrapping process]].
162
     *
163
     * Each component may be specified in one of the following formats:
164
     *
165
     * - an application component ID as specified via [[components]].
166
     * - a module ID as specified via [[modules]].
167
     * - a class name.
168
     * - a configuration array.
169
     * - a Closure
170
     *
171
     * During the bootstrapping process, each component will be instantiated. If the component class
172
     * implements [[BootstrapInterface]], its [[BootstrapInterface::bootstrap()|bootstrap()]] method
173
     * will be also be called.
174
     */
175
    public $bootstrap = [];
176
    /**
177
     * @var int the current application state during a request handling life cycle.
178
     * This property is managed by the application. Do not modify this property.
179
     */
180
    public $state;
181
    /**
182
     * @var array list of loaded modules indexed by their class names.
183
     */
184
    public $loadedModules = [];
185
186
187
    /**
188
     * Constructor.
189
     * @param array $config name-value pairs that will be used to initialize the object properties.
190
     * Note that the configuration must contain both [[id]] and [[basePath]].
191
     * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
192
     */
193 2216
    public function __construct($config = [])
194
    {
195 2216
        Yii::$app = $this;
0 ignored issues
show
Documentation Bug introduced by
$this is of type yii\base\Application, but the property $app was declared to be of type yii\console\Application|yii\web\Application. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof 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 given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
196 2216
        static::setInstance($this);
197
198 2216
        $this->state = self::STATE_BEGIN;
199
200 2216
        $this->preInit($config);
201
202 2216
        $this->registerErrorHandler($config);
203
204 2216
        Component::__construct($config);
205
    }
206
207
    /**
208
     * Pre-initializes the application.
209
     * This method is called at the beginning of the application constructor.
210
     * It initializes several important application properties.
211
     * If you override this method, please make sure you call the parent implementation.
212
     * @param array $config the application configuration
213
     * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
214
     */
215 2216
    public function preInit(&$config)
216
    {
217 2216
        if (!isset($config['id'])) {
218
            throw new InvalidConfigException('The "id" configuration for the Application is required.');
219
        }
220 2216
        if (isset($config['basePath'])) {
221 2216
            $this->setBasePath($config['basePath']);
222 2216
            unset($config['basePath']);
223
        } else {
224
            throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
225
        }
226
227 2216
        if (isset($config['vendorPath'])) {
228 2215
            $this->setVendorPath($config['vendorPath']);
229 2215
            unset($config['vendorPath']);
230
        } else {
231
            // set "@vendor"
232 18
            $this->getVendorPath();
233
        }
234 2216
        if (isset($config['runtimePath'])) {
235
            $this->setRuntimePath($config['runtimePath']);
236
            unset($config['runtimePath']);
237
        } else {
238
            // set "@runtime"
239 2216
            $this->getRuntimePath();
240
        }
241
242 2216
        if (isset($config['timeZone'])) {
243 800
            $this->setTimeZone($config['timeZone']);
244 800
            unset($config['timeZone']);
245 1422
        } elseif (!ini_get('date.timezone')) {
246
            $this->setTimeZone('UTC');
247
        }
248
249 2216
        if (isset($config['container'])) {
250 3
            $this->setContainer($config['container']);
251
252 3
            unset($config['container']);
253
        }
254
255
        // merge core components with custom components
256 2216
        foreach ($this->coreComponents() as $id => $component) {
257 2216
            if (!isset($config['components'][$id])) {
258 2216
                $config['components'][$id] = $component;
259 661
            } elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) {
260 451
                $config['components'][$id]['class'] = $component['class'];
261
            }
262
        }
263
    }
264
265
    /**
266
     * {@inheritdoc}
267
     */
268 2216
    public function init()
269
    {
270 2216
        $this->state = self::STATE_INIT;
271 2216
        $this->bootstrap();
272
    }
273
274
    /**
275
     * Initializes extensions and executes bootstrap components.
276
     * This method is called by [[init()]] after the application has been fully configured.
277
     * If you override this method, make sure you also call the parent implementation.
278
     */
279 2216
    protected function bootstrap()
280
    {
281 2216
        if ($this->extensions === null) {
282 2216
            $file = Yii::getAlias('@vendor/yiisoft/extensions.php');
283 2216
            $this->extensions = is_file($file) ? include $file : [];
0 ignored issues
show
It seems like $file can also be of type false; however, parameter $filename of is_file() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

283
            $this->extensions = is_file(/** @scrutinizer ignore-type */ $file) ? include $file : [];
Loading history...
284
        }
285 2216
        foreach ($this->extensions as $extension) {
286
            if (!empty($extension['alias'])) {
287
                foreach ($extension['alias'] as $name => $path) {
288
                    Yii::setAlias($name, $path);
289
                }
290
            }
291
            if (isset($extension['bootstrap'])) {
292
                $component = Yii::createObject($extension['bootstrap']);
293
                if ($component instanceof BootstrapInterface) {
294
                    Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
295
                    $component->bootstrap($this);
296
                } else {
297
                    Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
298
                }
299
            }
300
        }
301
302 2216
        foreach ($this->bootstrap as $mixed) {
303 2
            $component = null;
304 2
            if ($mixed instanceof \Closure) {
305 1
                Yii::debug('Bootstrap with Closure', __METHOD__);
306 1
                if (!$component = call_user_func($mixed, $this)) {
307 1
                    continue;
308
                }
309 2
            } elseif (is_string($mixed)) {
310 2
                if ($this->has($mixed)) {
311 2
                    $component = $this->get($mixed);
312 1
                } elseif ($this->hasModule($mixed)) {
313 1
                    $component = $this->getModule($mixed);
314
                } elseif (strpos($mixed, '\\') === false) {
315
                    throw new InvalidConfigException("Unknown bootstrapping component ID: $mixed");
316
                }
317
            }
318
319 2
            if (!isset($component)) {
320
                $component = Yii::createObject($mixed);
321
            }
322
323 2
            if ($component instanceof BootstrapInterface) {
324 1
                Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
325 1
                $component->bootstrap($this);
0 ignored issues
show
The method bootstrap() does not exist on yii\base\Module. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

325
                $component->/** @scrutinizer ignore-call */ 
326
                            bootstrap($this);
Loading history...
326
            } else {
327 2
                Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
0 ignored issues
show
It seems like $component can also be of type mixed and null; however, parameter $object of get_class() does only seem to accept object, maybe add an additional type check? ( Ignorable by Annotation )

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

327
                Yii::debug('Bootstrap with ' . get_class(/** @scrutinizer ignore-type */ $component), __METHOD__);
Loading history...
328
            }
329
        }
330
    }
331
332
    /**
333
     * Registers the errorHandler component as a PHP error handler.
334
     * @param array $config application config
335
     */
336 2216
    protected function registerErrorHandler(&$config)
337
    {
338 2216
        if (YII_ENABLE_ERROR_HANDLER) {
339
            if (!isset($config['components']['errorHandler']['class'])) {
340
                echo "Error: no errorHandler component is configured.\n";
341
                exit(1);
0 ignored issues
show
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...
342
            }
343
            $this->set('errorHandler', $config['components']['errorHandler']);
344
            unset($config['components']['errorHandler']);
345
            $this->getErrorHandler()->register();
346
        }
347
    }
348
349
    /**
350
     * Returns an ID that uniquely identifies this module among all modules within the current application.
351
     * Since this is an application instance, it will always return an empty string.
352
     * @return string the unique ID of the module.
353
     */
354 2
    public function getUniqueId()
355
    {
356 2
        return '';
357
    }
358
359
    /**
360
     * Sets the root directory of the application and the @app alias.
361
     * This method can only be invoked at the beginning of the constructor.
362
     * @param string $path the root directory of the application.
363
     * @property string the root directory of the application.
364
     * @throws InvalidArgumentException if the directory does not exist.
365
     */
366 2216
    public function setBasePath($path)
367
    {
368 2216
        parent::setBasePath($path);
369 2216
        Yii::setAlias('@app', $this->getBasePath());
370
    }
371
372
    /**
373
     * Runs the application.
374
     * This is the main entrance of an application.
375
     * @return int the exit status (0 means normal, non-zero values mean abnormal)
376
     */
377
    public function run()
378
    {
379
        try {
380
            $this->state = self::STATE_BEFORE_REQUEST;
381
            $this->trigger(self::EVENT_BEFORE_REQUEST);
382
383
            $this->state = self::STATE_HANDLING_REQUEST;
384
            $response = $this->handleRequest($this->getRequest());
385
386
            $this->state = self::STATE_AFTER_REQUEST;
387
            $this->trigger(self::EVENT_AFTER_REQUEST);
388
389
            $this->state = self::STATE_SENDING_RESPONSE;
390
            $response->send();
391
392
            $this->state = self::STATE_END;
393
394
            return $response->exitStatus;
395
        } catch (ExitException $e) {
396
            $this->end($e->statusCode, isset($response) ? $response : null);
397
            return $e->statusCode;
398
        }
399
    }
400
401
    /**
402
     * Handles the specified request.
403
     *
404
     * This method should return an instance of [[Response]] or its child class
405
     * which represents the handling result of the request.
406
     *
407
     * @param Request $request the request to be handled
408
     * @return Response the resulting response
409
     */
410
    abstract public function handleRequest($request);
411
412
    private $_runtimePath;
413
414
    /**
415
     * Returns the directory that stores runtime files.
416
     * @return string the directory that stores runtime files.
417
     * Defaults to the "runtime" subdirectory under [[basePath]].
418
     */
419 2216
    public function getRuntimePath()
420
    {
421 2216
        if ($this->_runtimePath === null) {
422 2216
            $this->setRuntimePath($this->getBasePath() . DIRECTORY_SEPARATOR . 'runtime');
423
        }
424
425 2216
        return $this->_runtimePath;
426
    }
427
428
    /**
429
     * Sets the directory that stores runtime files.
430
     * @param string $path the directory that stores runtime files.
431
     */
432 2216
    public function setRuntimePath($path)
433
    {
434 2216
        $this->_runtimePath = Yii::getAlias($path);
435 2216
        Yii::setAlias('@runtime', $this->_runtimePath);
0 ignored issues
show
It seems like $this->_runtimePath can also be of type false; however, parameter $path of yii\BaseYii::setAlias() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

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

435
        Yii::setAlias('@runtime', /** @scrutinizer ignore-type */ $this->_runtimePath);
Loading history...
436
    }
437
438
    private $_vendorPath;
439
440
    /**
441
     * Returns the directory that stores vendor files.
442
     * @return string the directory that stores vendor files.
443
     * Defaults to "vendor" directory under [[basePath]].
444
     */
445 18
    public function getVendorPath()
446
    {
447 18
        if ($this->_vendorPath === null) {
448 18
            $this->setVendorPath($this->getBasePath() . DIRECTORY_SEPARATOR . 'vendor');
449
        }
450
451 18
        return $this->_vendorPath;
452
    }
453
454
    /**
455
     * Sets the directory that stores vendor files.
456
     * @param string $path the directory that stores vendor files.
457
     */
458 2216
    public function setVendorPath($path)
459
    {
460 2216
        $this->_vendorPath = Yii::getAlias($path);
461 2216
        Yii::setAlias('@vendor', $this->_vendorPath);
0 ignored issues
show
It seems like $this->_vendorPath can also be of type false; however, parameter $path of yii\BaseYii::setAlias() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

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

461
        Yii::setAlias('@vendor', /** @scrutinizer ignore-type */ $this->_vendorPath);
Loading history...
462 2216
        Yii::setAlias('@npm', $this->getBasePath() . DIRECTORY_SEPARATOR . 'node_modules');
463
    }
464
465
    /**
466
     * Returns the time zone used by this application.
467
     * This is a simple wrapper of PHP function date_default_timezone_get().
468
     * If time zone is not configured in php.ini or application config,
469
     * it will be set to UTC by default.
470
     * @return string the time zone used by this application.
471
     * @see https://www.php.net/manual/en/function.date-default-timezone-get.php
472
     */
473 413
    public function getTimeZone()
474
    {
475 413
        return date_default_timezone_get();
476
    }
477
478
    /**
479
     * Sets the time zone used by this application.
480
     * This is a simple wrapper of PHP function date_default_timezone_set().
481
     * Refer to the [php manual](https://www.php.net/manual/en/timezones.php) for available timezones.
482
     * @param string $value the time zone used by this application.
483
     * @see https://www.php.net/manual/en/function.date-default-timezone-set.php
484
     */
485 800
    public function setTimeZone($value)
486
    {
487 800
        date_default_timezone_set($value);
488
    }
489
490
    /**
491
     * Returns the database connection component.
492
     * @return \yii\db\Connection the database connection.
493
     */
494 67
    public function getDb()
495
    {
496 67
        return $this->get('db');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('db') also could return the type mixed which is incompatible with the documented return type yii\db\Connection.
Loading history...
497
    }
498
499
    /**
500
     * Returns the log dispatcher component.
501
     * @return \yii\log\Dispatcher the log dispatcher application component.
502
     */
503
    public function getLog()
504
    {
505
        return $this->get('log');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('log') also could return the type mixed which is incompatible with the documented return type yii\log\Dispatcher.
Loading history...
506
    }
507
508
    /**
509
     * Returns the error handler component.
510
     * @return \yii\web\ErrorHandler|\yii\console\ErrorHandler the error handler application component.
511
     */
512
    public function getErrorHandler()
513
    {
514
        return $this->get('errorHandler');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('errorHandler') also could return the type mixed which is incompatible with the documented return type yii\console\ErrorHandler|yii\web\ErrorHandler.
Loading history...
515
    }
516
517
    /**
518
     * Returns the cache component.
519
     * @return \yii\caching\CacheInterface|null the cache application component. Null if the component is not enabled.
520
     */
521
    public function getCache()
522
    {
523
        return $this->get('cache', false);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('cache', false) also could return the type mixed which is incompatible with the documented return type null|yii\caching\CacheInterface.
Loading history...
524
    }
525
526
    /**
527
     * Returns the formatter component.
528
     * @return \yii\i18n\Formatter the formatter application component.
529
     */
530 25
    public function getFormatter()
531
    {
532 25
        return $this->get('formatter');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('formatter') also could return the type mixed which is incompatible with the documented return type yii\i18n\Formatter.
Loading history...
533
    }
534
535
    /**
536
     * Returns the request component.
537
     * @return \yii\web\Request|\yii\console\Request the request component.
538
     */
539
    public function getRequest()
540
    {
541
        return $this->get('request');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('request') also could return the type mixed which is incompatible with the documented return type yii\console\Request|yii\web\Request.
Loading history...
542
    }
543
544
    /**
545
     * Returns the response component.
546
     * @return \yii\web\Response|\yii\console\Response the response component.
547
     */
548
    public function getResponse()
549
    {
550
        return $this->get('response');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('response') also could return the type mixed which is incompatible with the documented return type yii\console\Response|yii\web\Response.
Loading history...
551
    }
552
553
    /**
554
     * Returns the view object.
555
     * @return View|\yii\web\View the view application component that is used to render various view files.
556
     */
557 39
    public function getView()
558
    {
559 39
        return $this->get('view');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('view') also could return the type mixed which is incompatible with the documented return type yii\base\View|yii\web\View.
Loading history...
560
    }
561
562
    /**
563
     * Returns the URL manager for this application.
564
     * @return \yii\web\UrlManager the URL manager for this application.
565
     */
566 52
    public function getUrlManager()
567
    {
568 52
        return $this->get('urlManager');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('urlManager') also could return the type mixed which is incompatible with the documented return type yii\web\UrlManager.
Loading history...
569
    }
570
571
    /**
572
     * Returns the internationalization (i18n) component.
573
     * @return \yii\i18n\I18N the internationalization application component.
574
     */
575 761
    public function getI18n()
576
    {
577 761
        return $this->get('i18n');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('i18n') also could return the type mixed which is incompatible with the documented return type yii\i18n\I18N.
Loading history...
578
    }
579
580
    /**
581
     * Returns the mailer component.
582
     * @return \yii\mail\MailerInterface the mailer application component.
583
     * @throws InvalidConfigException If this component is not configured.
584
     */
585
    public function getMailer()
586
    {
587
        return $this->get('mailer');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('mailer') also could return the type mixed which is incompatible with the documented return type yii\mail\MailerInterface.
Loading history...
588
    }
589
590
    /**
591
     * Returns the auth manager for this application.
592
     * @return \yii\rbac\ManagerInterface|null the auth manager application component or null if it's not configured.
593
     */
594 2
    public function getAuthManager()
595
    {
596 2
        return $this->get('authManager', false);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('authManager', false) also could return the type mixed which is incompatible with the documented return type null|yii\rbac\ManagerInterface.
Loading history...
597
    }
598
599
    /**
600
     * Returns the asset manager.
601
     * @return \yii\web\AssetManager the asset manager application component.
602
     */
603 13
    public function getAssetManager()
604
    {
605 13
        return $this->get('assetManager');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('assetManager') also could return the type mixed which is incompatible with the documented return type yii\web\AssetManager.
Loading history...
606
    }
607
608
    /**
609
     * Returns the security component.
610
     * @return \yii\base\Security the security application component.
611
     */
612 94
    public function getSecurity()
613
    {
614 94
        return $this->get('security');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get('security') also could return the type mixed which is incompatible with the documented return type yii\base\Security.
Loading history...
615
    }
616
617
    /**
618
     * Returns the configuration of core application components.
619
     * @return array
620
     * @see set()
621
     */
622 2216
    public function coreComponents()
623
    {
624 2216
        $components = [
625 2216
            'log' => ['class' => 'yii\log\Dispatcher'],
626 2216
            'view' => ['class' => 'yii\web\View'],
627 2216
            'formatter' => ['class' => 'yii\i18n\Formatter'],
628 2216
            'i18n' => ['class' => 'yii\i18n\I18N'],
629 2216
            'urlManager' => ['class' => 'yii\web\UrlManager'],
630 2216
            'assetManager' => ['class' => 'yii\web\AssetManager'],
631 2216
            'security' => ['class' => 'yii\base\Security'],
632 2216
        ];
633 2216
        if (class_exists('yii\swiftmailer\Mailer')) {
634
            $components['mailer'] = ['class' => 'yii\swiftmailer\Mailer'];
635
        }
636
637 2216
        return $components;
638
    }
639
640
    /**
641
     * Terminates the application.
642
     * This method replaces the `exit()` function by ensuring the application life cycle is completed
643
     * before terminating the application.
644
     * @param int $status the exit status (value 0 means normal exit while other values mean abnormal exit).
645
     * @param Response|null $response the response to be sent. If not set, the default application [[response]] component will be used.
646
     * @throws ExitException if the application is in testing mode
647
     */
648 3
    public function end($status = 0, $response = null)
649
    {
650 3
        if ($this->state === self::STATE_BEFORE_REQUEST || $this->state === self::STATE_HANDLING_REQUEST) {
651
            $this->state = self::STATE_AFTER_REQUEST;
652
            $this->trigger(self::EVENT_AFTER_REQUEST);
653
        }
654
655 3
        if ($this->state !== self::STATE_SENDING_RESPONSE && $this->state !== self::STATE_END) {
656 3
            $this->state = self::STATE_END;
657 3
            $response = $response ?: $this->getResponse();
658 3
            $response->send();
659
        }
660
661 3
        if (YII_ENV_TEST) {
662 3
            throw new ExitException($status);
663
        }
664
665
        exit($status);
0 ignored issues
show
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...
666
    }
667
668
    /**
669
     * Configures [[Yii::$container]] with the $config.
670
     *
671
     * @param array $config values given in terms of name-value pairs
672
     * @since 2.0.11
673
     */
674 3
    public function setContainer($config)
675
    {
676 3
        Yii::configure(Yii::$container, $config);
677
    }
678
}
679