Completed
Push — aria-required-and-aria-invalid... ( 0b9feb...e1b0cb )
by Alexander
12:52 queued 09:30
created

Application::setContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
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\Cache $cache The cache application component. Null if the component is not enabled.
23
 * This property is read-only.
24
 * @property \yii\db\Connection $db The database connection. This property is read-only.
25
 * @property \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application
26
 * component. This property is read-only.
27
 * @property \yii\i18n\Formatter $formatter The formatter application component. This property is read-only.
28
 * @property \yii\i18n\I18N $i18n The internationalization application component. This property is read-only.
29
 * @property \yii\log\Dispatcher $log The log dispatcher application component. This property is read-only.
30
 * @property \yii\mail\MailerInterface $mailer The mailer application component. This property is read-only.
31
 * @property \yii\web\Request|\yii\console\Request $request The request component. This property is read-only.
32
 * @property \yii\web\Response|\yii\console\Response $response The response component. This property is
33
 * read-only.
34
 * @property string $runtimePath The directory that stores runtime files. Defaults to the "runtime"
35
 * subdirectory under [[basePath]].
36
 * @property \yii\base\Security $security The security application component. This property is read-only.
37
 * @property string $timeZone The time zone used by this application.
38
 * @property string $uniqueId The unique ID of the module. This property is read-only.
39
 * @property \yii\web\UrlManager $urlManager The URL manager for this application. This property is read-only.
40
 * @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under
41
 * [[basePath]].
42
 * @property View|\yii\web\View $view The view application component that is used to render various view
43
 * files. This property is read-only.
44
 *
45
 * @author Qiang Xue <[email protected]>
46
 * @since 2.0
47
 */
48
abstract class Application extends Module
49
{
50
    /**
51
     * @event Event an event raised before the application starts to handle a request.
52
     */
53
    const EVENT_BEFORE_REQUEST = 'beforeRequest';
54
    /**
55
     * @event Event an event raised after the application successfully handles a request (before the response is sent out).
56
     */
57
    const EVENT_AFTER_REQUEST = 'afterRequest';
58
    /**
59
     * Application state used by [[state]]: application just started.
60
     */
61
    const STATE_BEGIN = 0;
62
    /**
63
     * Application state used by [[state]]: application is initializing.
64
     */
65
    const STATE_INIT = 1;
66
    /**
67
     * Application state used by [[state]]: application is triggering [[EVENT_BEFORE_REQUEST]].
68
     */
69
    const STATE_BEFORE_REQUEST = 2;
70
    /**
71
     * Application state used by [[state]]: application is handling the request.
72
     */
73
    const STATE_HANDLING_REQUEST = 3;
74
    /**
75
     * Application state used by [[state]]: application is triggering [[EVENT_AFTER_REQUEST]]..
76
     */
77
    const STATE_AFTER_REQUEST = 4;
78
    /**
79
     * Application state used by [[state]]: application is about to send response.
80
     */
81
    const STATE_SENDING_RESPONSE = 5;
82
    /**
83
     * Application state used by [[state]]: application has ended.
84
     */
85
    const STATE_END = 6;
86
87
    /**
88
     * @var string the namespace that controller classes are located in.
89
     * This namespace will be used to load controller classes by prepending it to the controller class name.
90
     * The default namespace is `app\controllers`.
91
     *
92
     * Please refer to the [guide about class autoloading](guide:concept-autoloading.md) for more details.
93
     */
94
    public $controllerNamespace = 'app\\controllers';
95
    /**
96
     * @var string the application name.
97
     */
98
    public $name = 'My Application';
99
    /**
100
     * @var string the charset currently used for the application.
101
     */
102
    public $charset = 'UTF-8';
103
    /**
104
     * @var string the language that is meant to be used for end users. It is recommended that you
105
     * use [IETF language tags](http://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands
106
     * for English, while `en-US` stands for English (United States).
107
     * @see sourceLanguage
108
     */
109
    public $language = 'en-US';
110
    /**
111
     * @var string the language that the application is written in. This mainly refers to
112
     * the language that the messages and view files are written in.
113
     * @see language
114
     */
115
    public $sourceLanguage = 'en-US';
116
    /**
117
     * @var Controller the currently active controller instance
118
     */
119
    public $controller;
120
    /**
121
     * @var string|bool the layout that should be applied for views in this application. Defaults to 'main'.
122
     * If this is false, layout will be disabled.
123
     */
124
    public $layout = 'main';
125
    /**
126
     * @var string the requested route
127
     */
128
    public $requestedRoute;
129
    /**
130
     * @var Action the requested Action. If null, it means the request cannot be resolved into an action.
131
     */
132
    public $requestedAction;
133
    /**
134
     * @var array the parameters supplied to the requested action.
135
     */
136
    public $requestedParams;
137
    /**
138
     * @var array list of installed Yii extensions. Each array element represents a single extension
139
     * with the following structure:
140
     *
141
     * ```php
142
     * [
143
     *     'name' => 'extension name',
144
     *     'version' => 'version number',
145
     *     'bootstrap' => 'BootstrapClassName',  // optional, may also be a configuration array
146
     *     'alias' => [
147
     *         '@alias1' => 'to/path1',
148
     *         '@alias2' => 'to/path2',
149
     *     ],
150
     * ]
151
     * ```
152
     *
153
     * The "bootstrap" class listed above will be instantiated during the application
154
     * [[bootstrap()|bootstrapping process]]. If the class implements [[BootstrapInterface]],
155
     * its [[BootstrapInterface::bootstrap()|bootstrap()]] method will be also be called.
156
     *
157
     * If not set explicitly in the application config, this property will be populated with the contents of
158
     * `@vendor/yiisoft/extensions.php`.
159
     */
160
    public $extensions;
161
    /**
162
     * @var array list of components that should be run during the application [[bootstrap()|bootstrapping process]].
163
     *
164
     * Each component may be specified in one of the following formats:
165
     *
166
     * - an application component ID as specified via [[components]].
167
     * - a module ID as specified via [[modules]].
168
     * - a class name.
169
     * - a configuration array.
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 2194
    public function __construct($config = [])
194
    {
195 2194
        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...
196 2194
        static::setInstance($this);
197
198 2194
        $this->state = self::STATE_BEGIN;
199
200 2194
        $this->preInit($config);
201
202 2194
        $this->registerErrorHandler($config);
203
204 2194
        Component::__construct($config);
205 2194
    }
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 2194
    public function preInit(&$config)
216
    {
217 2194
        if (!isset($config['id'])) {
218
            throw new InvalidConfigException('The "id" configuration for the Application is required.');
219
        }
220 2194
        if (isset($config['basePath'])) {
221 2194
            $this->setBasePath($config['basePath']);
222 2194
            unset($config['basePath']);
223 2194
        } else {
224
            throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
225
        }
226
227 2194
        if (isset($config['vendorPath'])) {
228 2194
            $this->setVendorPath($config['vendorPath']);
229 2194
            unset($config['vendorPath']);
230 2194
        } else {
231
            // set "@vendor"
232
            $this->getVendorPath();
233
        }
234 2194
        if (isset($config['runtimePath'])) {
235
            $this->setRuntimePath($config['runtimePath']);
236
            unset($config['runtimePath']);
237
        } else {
238
            // set "@runtime"
239 2194
            $this->getRuntimePath();
240
        }
241
242 2194
        if (isset($config['timeZone'])) {
243 363
            $this->setTimeZone($config['timeZone']);
244 363
            unset($config['timeZone']);
245 2194
        } elseif (!ini_get('date.timezone')) {
246
            $this->setTimeZone('UTC');
247
        }
248
249 2194
        if (isset($config['container'])) {
250 1
            $this->setContainer($config['container']);
251
252 1
            unset($config['container']);
253 1
        }
254
255
        // merge core components with custom components
256 2194
        foreach ($this->coreComponents() as $id => $component) {
257 2194
            if (!isset($config['components'][$id])) {
258 2194
                $config['components'][$id] = $component;
259 2194
            } elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) {
260 145
                $config['components'][$id]['class'] = $component['class'];
261 145
            }
262 2194
        }
263 2194
    }
264
265
    /**
266
     * @inheritdoc
267
     */
268 2194
    public function init()
269
    {
270 2194
        $this->state = self::STATE_INIT;
271 2194
        $this->bootstrap();
272 2194
    }
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 2194
    protected function bootstrap()
280
    {
281 2194
        if ($this->extensions === null) {
282 2194
            $file = Yii::getAlias('@vendor/yiisoft/extensions.php');
283 2194
            $this->extensions = is_file($file) ? include($file) : [];
284 2194
        }
285 2194
        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::trace('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
295
                    $component->bootstrap($this);
296
                } else {
297
                    Yii::trace('Bootstrap with ' . get_class($component), __METHOD__);
298
                }
299
            }
300 2194
        }
301
302 2194
        foreach ($this->bootstrap as $class) {
303 1
            $component = null;
304 1
            if (is_string($class)) {
305 1
                if ($this->has($class)) {
306 1
                    $component = $this->get($class);
307 1
                } elseif ($this->hasModule($class)) {
308
                    $component = $this->getModule($class);
309
                } elseif (strpos($class, '\\') === false) {
310
                    throw new InvalidConfigException("Unknown bootstrapping component ID: $class");
311
                }
312 1
            }
313 1
            if (!isset($component)) {
314
                $component = Yii::createObject($class);
315
            }
316
317 1
            if ($component instanceof BootstrapInterface) {
318
                Yii::trace('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
319
                $component->bootstrap($this);
320
            } else {
321 1
                Yii::trace('Bootstrap with ' . get_class($component), __METHOD__);
322
            }
323 2194
        }
324 2194
    }
325
326
    /**
327
     * Registers the errorHandler component as a PHP error handler.
328
     * @param array $config application config
329
     */
330 2194
    protected function registerErrorHandler(&$config)
331
    {
332 2194
        if (YII_ENABLE_ERROR_HANDLER) {
333
            if (!isset($config['components']['errorHandler']['class'])) {
334
                echo "Error: no errorHandler component is configured.\n";
335
                exit(1);
336
            }
337
            $this->set('errorHandler', $config['components']['errorHandler']);
338
            unset($config['components']['errorHandler']);
339
            $this->getErrorHandler()->register();
340
        }
341 2194
    }
342
343
    /**
344
     * Returns an ID that uniquely identifies this module among all modules within the current application.
345
     * Since this is an application instance, it will always return an empty string.
346
     * @return string the unique ID of the module.
347
     */
348
    public function getUniqueId()
349
    {
350
        return '';
351
    }
352
353
    /**
354
     * Sets the root directory of the application and the @app alias.
355
     * This method can only be invoked at the beginning of the constructor.
356
     * @param string $path the root directory of the application.
357
     * @property string the root directory of the application.
358
     * @throws InvalidParamException if the directory does not exist.
359
     */
360 2194
    public function setBasePath($path)
361
    {
362 2194
        parent::setBasePath($path);
363 2194
        Yii::setAlias('@app', $this->getBasePath());
364 2194
    }
365
366
    /**
367
     * Runs the application.
368
     * This is the main entrance of an application.
369
     * @return int the exit status (0 means normal, non-zero values mean abnormal)
370
     */
371
    public function run()
372
    {
373
        try {
374
375
            $this->state = self::STATE_BEFORE_REQUEST;
376
            $this->trigger(self::EVENT_BEFORE_REQUEST);
377
378
            $this->state = self::STATE_HANDLING_REQUEST;
379
            $response = $this->handleRequest($this->getRequest());
0 ignored issues
show
Documentation introduced by
$this->getRequest() is of type object|null, but the function expects a object<yii\base\Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
380
381
            $this->state = self::STATE_AFTER_REQUEST;
382
            $this->trigger(self::EVENT_AFTER_REQUEST);
383
384
            $this->state = self::STATE_SENDING_RESPONSE;
385
            $response->send();
386
387
            $this->state = self::STATE_END;
388
389
            return $response->exitStatus;
390
391
        } catch (ExitException $e) {
392
393
            $this->end($e->statusCode, isset($response) ? $response : null);
394
            return $e->statusCode;
395
396
        }
397
    }
398
399
    /**
400
     * Handles the specified request.
401
     *
402
     * This method should return an instance of [[Response]] or its child class
403
     * which represents the handling result of the request.
404
     *
405
     * @param Request $request the request to be handled
406
     * @return Response the resulting response
407
     */
408
    abstract public function handleRequest($request);
409
410
    private $_runtimePath;
411
412
    /**
413
     * Returns the directory that stores runtime files.
414
     * @return string the directory that stores runtime files.
415
     * Defaults to the "runtime" subdirectory under [[basePath]].
416
     */
417 2194
    public function getRuntimePath()
418
    {
419 2194
        if ($this->_runtimePath === null) {
420 2194
            $this->setRuntimePath($this->getBasePath() . DIRECTORY_SEPARATOR . 'runtime');
421 2194
        }
422
423 2194
        return $this->_runtimePath;
424
    }
425
426
    /**
427
     * Sets the directory that stores runtime files.
428
     * @param string $path the directory that stores runtime files.
429
     */
430 2194
    public function setRuntimePath($path)
431
    {
432 2194
        $this->_runtimePath = Yii::getAlias($path);
433 2194
        Yii::setAlias('@runtime', $this->_runtimePath);
434 2194
    }
435
436
    private $_vendorPath;
437
438
    /**
439
     * Returns the directory that stores vendor files.
440
     * @return string the directory that stores vendor files.
441
     * Defaults to "vendor" directory under [[basePath]].
442
     */
443
    public function getVendorPath()
444
    {
445
        if ($this->_vendorPath === null) {
446
            $this->setVendorPath($this->getBasePath() . DIRECTORY_SEPARATOR . 'vendor');
447
        }
448
449
        return $this->_vendorPath;
450
    }
451
452
    /**
453
     * Sets the directory that stores vendor files.
454
     * @param string $path the directory that stores vendor files.
455
     */
456 2194
    public function setVendorPath($path)
457
    {
458 2194
        $this->_vendorPath = Yii::getAlias($path);
459 2194
        Yii::setAlias('@vendor', $this->_vendorPath);
460 2194
        Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower');
461 2194
        Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm');
462 2194
    }
463
464
    /**
465
     * Returns the time zone used by this application.
466
     * This is a simple wrapper of PHP function date_default_timezone_get().
467
     * If time zone is not configured in php.ini or application config,
468
     * it will be set to UTC by default.
469
     * @return string the time zone used by this application.
470
     * @see http://php.net/manual/en/function.date-default-timezone-get.php
471
     */
472 258
    public function getTimeZone()
473
    {
474 258
        return date_default_timezone_get();
475
    }
476
477
    /**
478
     * Sets the time zone used by this application.
479
     * This is a simple wrapper of PHP function date_default_timezone_set().
480
     * Refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available timezones.
481
     * @param string $value the time zone used by this application.
482
     * @see http://php.net/manual/en/function.date-default-timezone-set.php
483
     */
484 363
    public function setTimeZone($value)
485
    {
486 363
        date_default_timezone_set($value);
487 363
    }
488
489
    /**
490
     * Returns the database connection component.
491
     * @return \yii\db\Connection the database connection.
492
     */
493 34
    public function getDb()
494
    {
495 34
        return $this->get('db');
496
    }
497
498
    /**
499
     * Returns the log dispatcher component.
500
     * @return \yii\log\Dispatcher the log dispatcher application component.
501
     */
502
    public function getLog()
503
    {
504
        return $this->get('log');
505
    }
506
507
    /**
508
     * Returns the error handler component.
509
     * @return \yii\web\ErrorHandler|\yii\console\ErrorHandler the error handler application component.
510
     */
511
    public function getErrorHandler()
512
    {
513
        return $this->get('errorHandler');
514
    }
515
516
    /**
517
     * Returns the cache component.
518
     * @return \yii\caching\Cache the cache application component. Null if the component is not enabled.
519
     */
520 1
    public function getCache()
521 1
    {
522
        return $this->get('cache', false);
523
    }
524
525
    /**
526
     * Returns the formatter component.
527
     * @return \yii\i18n\Formatter the formatter application component.
528
     */
529 14
    public function getFormatter()
530
    {
531 14
        return $this->get('formatter');
532
    }
533
534
    /**
535
     * Returns the request component.
536
     * @return \yii\web\Request|\yii\console\Request the request component.
537
     */
538
    public function getRequest()
539
    {
540
        return $this->get('request');
541
    }
542
543
    /**
544
     * Returns the response component.
545
     * @return \yii\web\Response|\yii\console\Response the response component.
546
     */
547
    public function getResponse()
548
    {
549
        return $this->get('response');
550
    }
551
552
    /**
553
     * Returns the view object.
554
     * @return View|\yii\web\View the view application component that is used to render various view files.
555
     */
556 23
    public function getView()
557
    {
558 23
        return $this->get('view');
559
    }
560
561
    /**
562
     * Returns the URL manager for this application.
563
     * @return \yii\web\UrlManager the URL manager for this application.
564
     */
565 27
    public function getUrlManager()
566
    {
567 27
        return $this->get('urlManager');
568
    }
569
570
    /**
571
     * Returns the internationalization (i18n) component
572
     * @return \yii\i18n\I18N the internationalization application component.
573
     */
574 572
    public function getI18n()
575
    {
576 572
        return $this->get('i18n');
577
    }
578
579
    /**
580
     * Returns the mailer component.
581
     * @return \yii\mail\MailerInterface the mailer application component.
582
     */
583
    public function getMailer()
584
    {
585
        return $this->get('mailer');
586
    }
587
588
    /**
589
     * Returns the auth manager for this application.
590
     * @return \yii\rbac\ManagerInterface the auth manager application component.
591
     * Null is returned if auth manager is not configured.
592
     */
593
    public function getAuthManager()
594
    {
595
        return $this->get('authManager', false);
596
    }
597
598
    /**
599
     * Returns the asset manager.
600
     * @return \yii\web\AssetManager the asset manager application component.
601
     */
602 2
    public function getAssetManager()
603
    {
604 2
        return $this->get('assetManager');
605
    }
606
607
    /**
608
     * Returns the security component.
609
     * @return \yii\base\Security the security application component.
610
     */
611 28
    public function getSecurity()
612
    {
613 28
        return $this->get('security');
614
    }
615
616
    /**
617
     * Returns the configuration of core application components.
618
     * @see set()
619
     */
620 2194
    public function coreComponents()
621
    {
622
        return [
623 2194
            'log' => ['class' => 'yii\log\Dispatcher'],
624 2194
            'view' => ['class' => 'yii\web\View'],
625 2194
            'formatter' => ['class' => 'yii\i18n\Formatter'],
626 2194
            'i18n' => ['class' => 'yii\i18n\I18N'],
627 2194
            'mailer' => ['class' => 'yii\swiftmailer\Mailer'],
628 2194
            'urlManager' => ['class' => 'yii\web\UrlManager'],
629 2194
            'assetManager' => ['class' => 'yii\web\AssetManager'],
630 2194
            'security' => ['class' => 'yii\base\Security'],
631 2194
        ];
632
    }
633
634
    /**
635
     * Terminates the application.
636
     * This method replaces the `exit()` function by ensuring the application life cycle is completed
637
     * before terminating the application.
638
     * @param int $status the exit status (value 0 means normal exit while other values mean abnormal exit).
639
     * @param Response $response the response to be sent. If not set, the default application [[response]] component will be used.
640
     * @throws ExitException if the application is in testing mode
641
     */
642 3
    public function end($status = 0, $response = null)
643
    {
644 3
        if ($this->state === self::STATE_BEFORE_REQUEST || $this->state === self::STATE_HANDLING_REQUEST) {
645
            $this->state = self::STATE_AFTER_REQUEST;
646
            $this->trigger(self::EVENT_AFTER_REQUEST);
647
        }
648
649 3
        if ($this->state !== self::STATE_SENDING_RESPONSE && $this->state !== self::STATE_END) {
650 3
            $this->state = self::STATE_END;
651 3
            $response = $response ? : $this->getResponse();
652 3
            $response->send();
653 3
        }
654
655 3
        if (YII_ENV_TEST) {
656 3
            throw new ExitException($status);
657
        } else {
658
            exit($status);
659
        }
660
    }
661
662
    /**
663
     * Configures [[Yii::$container]] with the $config
664
     *
665
     * @param array $config values given in terms of name-value pairs
666
     * @since 2.0.11
667
     */
668 1
    public function setContainer($config)
669
    {
670 1
        Yii::configure(Yii::$container, $config);
671 1
    }
672
}
673