Completed
Push — 2.1 ( 418fc4...115fa3 )
by Carsten
13:59
created

Application::setBasePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
199 3167
        static::setInstance($this);
200
201 3167
        $this->state = self::STATE_BEGIN;
202
203 3167
        $this->preInit($config);
204
205 3167
        $this->registerErrorHandler($config);
206
207 3167
        Component::__construct($config);
208 3167
    }
209
210
    /**
211
     * Pre-initializes the application.
212
     * This method is called at the beginning of the application constructor.
213
     * It initializes several important application properties.
214
     * If you override this method, please make sure you call the parent implementation.
215
     * @param array $config the application configuration
216
     * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
217
     */
218 3167
    public function preInit(&$config)
219
    {
220 3167
        if (!isset($config['id'])) {
221
            throw new InvalidConfigException('The "id" configuration for the Application is required.');
222
        }
223 3167
        if (isset($config['basePath'])) {
224 3167
            $this->setBasePath($config['basePath']);
225 3167
            unset($config['basePath']);
226
        } else {
227
            throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
228
        }
229
230 3167
        if (isset($config['vendorPath'])) {
231 3161
            $this->setVendorPath($config['vendorPath']);
232 3161
            unset($config['vendorPath']);
233
        } else {
234
            // set "@vendor"
235 10
            $this->getVendorPath();
236
        }
237 3167
        if (isset($config['runtimePath'])) {
238
            $this->setRuntimePath($config['runtimePath']);
239
            unset($config['runtimePath']);
240
        } else {
241
            // set "@runtime"
242 3167
            $this->getRuntimePath();
243
        }
244
245 3167
        if (isset($config['timeZone'])) {
246 376
            $this->setTimeZone($config['timeZone']);
247 376
            unset($config['timeZone']);
248
        }
249
250 3167
        if (isset($config['container'])) {
251 1
            $this->setContainer($config['container']);
252 1
            unset($config['container']);
253
        }
254
255 3167
        if (isset($config['logger'])) {
256 6
            $this->setLogger($config['logger']);
257 6
            unset($config['logger']);
258
        }
259
260 3167
        if (isset($config['profiler'])) {
261
            $this->setProfiler($config['profiler']);
262
            unset($config['profiler']);
263
        }
264
265
        // merge core components with custom components
266 3167
        foreach ($this->coreComponents() as $id => $component) {
267 3167
            if (!isset($config['components'][$id])) {
268 3167
                $config['components'][$id] = $component;
269 401
            } elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['__class'])) {
270 3167
                $config['components'][$id]['__class'] = $component['__class'];
271
            }
272
        }
273 3167
    }
274
275
    /**
276
     * {@inheritdoc}
277
     */
278 3167
    public function init()
279
    {
280 3167
        $this->state = self::STATE_INIT;
281 3167
        $this->bootstrap();
282 3167
    }
283
284
    /**
285
     * Initializes extensions and executes bootstrap components.
286
     * This method is called by [[init()]] after the application has been fully configured.
287
     * If you override this method, make sure you also call the parent implementation.
288
     */
289 3167
    protected function bootstrap()
290
    {
291 3167
        if ($this->extensions === null) {
292 3167
            $file = Yii::getAlias('@vendor/yiisoft/extensions.php');
293 3167
            $this->extensions = is_file($file) ? include $file : [];
294
        }
295 3167
        foreach ($this->extensions as $extension) {
296
            if (!empty($extension['alias'])) {
297
                foreach ($extension['alias'] as $name => $path) {
298
                    Yii::setAlias($name, $path);
299
                }
300
            }
301
            if (isset($extension['bootstrap'])) {
302
                $component = Yii::createObject($extension['bootstrap']);
303
                if ($component instanceof BootstrapInterface) {
304
                    Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
305
                    $component->bootstrap($this);
306
                } else {
307
                    Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
308
                }
309
            }
310
        }
311
312 3167
        foreach ($this->bootstrap as $mixed) {
313 2
            $component = null;
314 2
            if ($mixed instanceof \Closure) {
315 1
                Yii::debug('Bootstrap with Closure', __METHOD__);
316 1
                if (!$component = call_user_func($mixed, $this)) {
317 1
                    continue;
318
                }
319 2
            } elseif (is_string($mixed)) {
320 2
                if ($this->has($mixed)) {
321 2
                    $component = $this->get($mixed);
322 1
                } elseif ($this->hasModule($mixed)) {
323 1
                    $component = $this->getModule($mixed);
324
                } elseif (strpos($mixed, '\\') === false) {
325
                    throw new InvalidConfigException("Unknown bootstrapping component ID: $mixed");
326
                }
327
            }
328
329 2
            if (!isset($component)) {
330
                $component = Yii::createObject($mixed);
331
            }
332
333 2
            if ($component instanceof BootstrapInterface) {
334 1
                Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
335 1
                $component->bootstrap($this);
336
            } else {
337 2
                Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
338
            }
339
        }
340 3167
    }
341
342
    /**
343
     * Registers the errorHandler component as a PHP error handler.
344
     * @param array $config application config
345
     */
346 3167
    protected function registerErrorHandler(&$config)
347
    {
348 3167
        if (YII_ENABLE_ERROR_HANDLER) {
349
            if (!isset($config['components']['errorHandler']['__class'])) {
350
                echo "Error: no errorHandler component is configured.\n";
351
                exit(1);
352
            }
353
            $this->set('errorHandler', $config['components']['errorHandler']);
354
            unset($config['components']['errorHandler']);
355
            $this->getErrorHandler()->register();
356
        }
357 3167
    }
358
359
    /**
360
     * Returns an ID that uniquely identifies this module among all modules within the current application.
361
     * Since this is an application instance, it will always return an empty string.
362
     * @return string the unique ID of the module.
363
     */
364 1
    public function getUniqueId()
365
    {
366 1
        return '';
367
    }
368
369
    /**
370
     * Sets the root directory of the application and the @app alias.
371
     * This method can only be invoked at the beginning of the constructor.
372
     * @param string $path the root directory of the application.
373
     * @property string the root directory of the application.
374
     * @throws InvalidArgumentException if the directory does not exist.
375
     */
376 3167
    public function setBasePath($path)
377
    {
378 3167
        parent::setBasePath($path);
379 3167
        Yii::setAlias('@app', $this->getBasePath());
380 3167
    }
381
382
    /**
383
     * Runs the application.
384
     * This is the main entrance of an application.
385
     * @return int the exit status (0 means normal, non-zero values mean abnormal)
386
     */
387
    public function run()
388
    {
389
        try {
390
            $this->state = self::STATE_BEFORE_REQUEST;
391
            $this->trigger(self::EVENT_BEFORE_REQUEST);
392
393
            $this->state = self::STATE_HANDLING_REQUEST;
394
            $response = $this->handleRequest($this->getRequest());
395
396
            $this->state = self::STATE_AFTER_REQUEST;
397
            $this->trigger(self::EVENT_AFTER_REQUEST);
398
399
            $this->state = self::STATE_SENDING_RESPONSE;
400
            $response->send();
401
402
            $this->state = self::STATE_END;
403
404
            return $response->exitStatus;
405
        } catch (ExitException $e) {
406
            $this->end($e->statusCode, isset($response) ? $response : null);
407
            return $e->statusCode;
408
        }
409
    }
410
411
    /**
412
     * Handles the specified request.
413
     *
414
     * This method should return an instance of [[Response]] or its child class
415
     * which represents the handling result of the request.
416
     *
417
     * @param Request $request the request to be handled
418
     * @return Response the resulting response
419
     */
420
    abstract public function handleRequest($request);
421
422
    private $_runtimePath;
423
424
    /**
425
     * Returns the directory that stores runtime files.
426
     * @return string the directory that stores runtime files.
427
     * Defaults to the "runtime" subdirectory under [[basePath]].
428
     */
429 3167
    public function getRuntimePath()
430
    {
431 3167
        if ($this->_runtimePath === null) {
432 3167
            $this->setRuntimePath($this->getBasePath() . DIRECTORY_SEPARATOR . 'runtime');
433
        }
434
435 3167
        return $this->_runtimePath;
436
    }
437
438
    /**
439
     * Sets the directory that stores runtime files.
440
     * @param string $path the directory that stores runtime files.
441
     */
442 3167
    public function setRuntimePath($path)
443
    {
444 3167
        $this->_runtimePath = Yii::getAlias($path);
445 3167
        Yii::setAlias('@runtime', $this->_runtimePath);
446 3167
    }
447
448
    private $_vendorPath;
449
450
    /**
451
     * Returns the directory that stores vendor files.
452
     * @return string the directory that stores vendor files.
453
     * Defaults to "vendor" directory under [[basePath]].
454
     */
455 10
    public function getVendorPath()
456
    {
457 10
        if ($this->_vendorPath === null) {
458 10
            $this->setVendorPath($this->getBasePath() . DIRECTORY_SEPARATOR . 'vendor');
459
        }
460
461 10
        return $this->_vendorPath;
462
    }
463
464
    /**
465
     * Sets the directory that stores vendor files.
466
     * @param string $path the directory that stores vendor files.
467
     */
468 3167
    public function setVendorPath($path)
469
    {
470 3167
        $this->_vendorPath = Yii::getAlias($path);
471 3167
        Yii::setAlias('@vendor', $this->_vendorPath);
472 3167
        Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower');
473 3167
        Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm');
474 3167
    }
475
476
    /**
477
     * Returns the time zone used by this application.
478
     * This is a simple wrapper of PHP function date_default_timezone_get().
479
     * If time zone is not configured in php.ini or application config,
480
     * it will be set to UTC by default.
481
     * @return string the time zone used by this application.
482
     * @see http://php.net/manual/en/function.date-default-timezone-get.php
483
     */
484 309
    public function getTimeZone()
485
    {
486 309
        return date_default_timezone_get();
487
    }
488
489
    /**
490
     * Sets the time zone used by this application.
491
     * This is a simple wrapper of PHP function date_default_timezone_set().
492
     * Refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available timezones.
493
     * @param string $value the time zone used by this application.
494
     * @see http://php.net/manual/en/function.date-default-timezone-set.php
495
     */
496 376
    public function setTimeZone($value)
497
    {
498 376
        date_default_timezone_set($value);
499 376
    }
500
501
    /**
502
     * Returns the database connection component.
503
     * @return \yii\db\Connection the database connection.
504
     */
505 85
    public function getDb()
506
    {
507 85
        return $this->get('db');
508
    }
509
510
    /**
511
     * Sets up or configure the logger instance.
512
     * @param \psr\log\LoggerInterface|\Closure|array|null $logger the logger object or its DI compatible configuration.
513
     * @since 2.1.0
514
     */
515 6
    public function setLogger($logger)
516
    {
517 6
        Yii::setLogger($logger);
518 6
    }
519
520
    /**
521
     * Returns the logger instance.
522
     * @return \psr\log\LoggerInterface the logger instance.
523
     * @since 2.1.0
524
     */
525 5
    public function getLogger()
526
    {
527 5
        return Yii::getLogger();
528
    }
529
530
    /**
531
     * Sets up or configure the profiler instance.
532
     * @param \yii\profile\ProfilerInterface|\Closure|array|null $profiler the profiler object or its DI compatible configuration.
533
     * @since 2.1.0
534
     */
535
    public function setProfiler($profiler)
536
    {
537
        Yii::setProfiler($profiler);
538
    }
539
540
    /**
541
     * Returns the profiler instance.
542
     * @return \yii\profile\ProfilerInterface profiler instance.
543
     * @since 2.1.0
544
     */
545
    public function getProfiler()
546
    {
547
        return Yii::getProfiler();
548
    }
549
550
    /**
551
     * Returns the error handler component.
552
     * @return \yii\web\ErrorHandler|\yii\console\ErrorHandler the error handler application component.
553
     */
554
    public function getErrorHandler()
555
    {
556
        return $this->get('errorHandler');
557
    }
558
559
    /**
560
     * Returns the cache component.
561
     * @return \yii\caching\CacheInterface the cache application component. Null if the component is not enabled.
562
     */
563
    public function getCache()
564
    {
565
        return $this->get('cache', false);
566
    }
567
568
    /**
569
     * Returns the formatter component.
570
     * @return \yii\i18n\Formatter the formatter application component.
571
     */
572 30
    public function getFormatter()
573
    {
574 30
        return $this->get('formatter');
575
    }
576
577
    /**
578
     * Returns the request component.
579
     * @return \yii\web\Request|\yii\console\Request the request component.
580
     */
581
    public function getRequest()
582
    {
583
        return $this->get('request');
584
    }
585
586
    /**
587
     * Returns the response component.
588
     * @return \yii\web\Response|\yii\console\Response the response component.
589
     */
590
    public function getResponse()
591
    {
592
        return $this->get('response');
593
    }
594
595
    /**
596
     * Returns the view object.
597
     * @return View|\yii\web\View the view application component that is used to render various view files.
598
     */
599 39
    public function getView()
600
    {
601 39
        return $this->get('view');
602
    }
603
604
    /**
605
     * Returns the URL manager for this application.
606
     * @return \yii\web\UrlManager the URL manager for this application.
607
     */
608 28
    public function getUrlManager()
609
    {
610 28
        return $this->get('urlManager');
611
    }
612
613
    /**
614
     * Returns the internationalization (i18n) component.
615
     * @return \yii\i18n\I18N the internationalization application component.
616
     */
617 535
    public function getI18n()
618
    {
619 535
        return $this->get('i18n');
620
    }
621
622
    /**
623
     * Returns the mailer component.
624
     * @return \yii\mail\MailerInterface the mailer application component.
625
     */
626
    public function getMailer()
627
    {
628
        return $this->get('mailer');
629
    }
630
631
    /**
632
     * Returns the auth manager for this application.
633
     * @return \yii\rbac\ManagerInterface the auth manager application component.
634
     * Null is returned if auth manager is not configured.
635
     */
636
    public function getAuthManager()
637
    {
638
        return $this->get('authManager', false);
639
    }
640
641
    /**
642
     * Returns the asset manager.
643
     * @return \yii\web\AssetManager the asset manager application component.
644
     */
645
    public function getAssetManager()
646
    {
647
        return $this->get('assetManager');
648
    }
649
650
    /**
651
     * Returns the security component.
652
     * @return \yii\base\Security the security application component.
653
     */
654 52
    public function getSecurity()
655
    {
656 52
        return $this->get('security');
657
    }
658
659
    /**
660
     * Returns the configuration of core application components.
661
     * @see set()
662
     */
663 3167
    public function coreComponents()
664
    {
665
        return [
666 3167
            'security' => ['__class' => Security::class],
667
            'formatter' => ['__class' => \yii\i18n\Formatter::class],
668
            'i18n' => ['__class' => \yii\i18n\I18N::class],
669
            'mailer' => ['__class' => \yii\swiftmailer\Mailer::class],
670
            'assetManager' => ['__class' => \yii\web\AssetManager::class],
671
            'urlManager' => ['__class' => \yii\web\UrlManager::class],
672
            'view' => ['__class' => \yii\web\View::class],
673
        ];
674
    }
675
676
    /**
677
     * Terminates the application.
678
     * This method replaces the `exit()` function by ensuring the application life cycle is completed
679
     * before terminating the application.
680
     * @param int $status the exit status (value 0 means normal exit while other values mean abnormal exit).
681
     * @param Response $response the response to be sent. If not set, the default application [[response]] component will be used.
682
     * @throws ExitException if the application is in testing mode
683
     */
684 3
    public function end($status = 0, $response = null)
685
    {
686 3
        if ($this->state === self::STATE_BEFORE_REQUEST || $this->state === self::STATE_HANDLING_REQUEST) {
687
            $this->state = self::STATE_AFTER_REQUEST;
688
            $this->trigger(self::EVENT_AFTER_REQUEST);
689
        }
690
691 3
        if ($this->state !== self::STATE_SENDING_RESPONSE && $this->state !== self::STATE_END) {
692 3
            $this->state = self::STATE_END;
693 3
            $response = $response ?: $this->getResponse();
694 3
            $response->send();
695
        }
696
697 3
        if (YII_ENV_TEST) {
698 3
            throw new ExitException($status);
699
        }
700
701
        exit($status);
702
    }
703
704
    /**
705
     * Configures [[Yii::$container]] with the $config.
706
     *
707
     * @param array $config values given in terms of name-value pairs
708
     * @since 2.0.11
709
     */
710 1
    public function setContainer($config)
711
    {
712 1
        Yii::configure(Yii::$container, $config);
713 1
    }
714
}
715