Passed
Pull Request — master (#346)
by Wilmer
04:17
created

WebApplicationRunner::run()   A

Complexity

Conditions 3
Paths 32

Size

Total Lines 60
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 3.0261

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 31
c 1
b 0
f 0
nc 32
nop 0
dl 0
loc 60
ccs 24
cts 28
cp 0.8571
crap 3.0261
rs 9.424

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Runner;
6
7
use App\Handler\ThrowableHandler;
0 ignored issues
show
Bug introduced by
The type App\Handler\ThrowableHandler was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use ErrorException;
9
use Psr\Container\ContainerInterface;
10
use Psr\Http\Message\RequestInterface;
11
use Psr\Http\Message\ResponseInterface;
12
use Psr\Http\Message\ServerRequestInterface;
13
use Throwable;
14
use Yiisoft\Config\Config;
15
use Yiisoft\Di\Container;
16
use Yiisoft\ErrorHandler\ErrorHandler;
17
use Yiisoft\ErrorHandler\Middleware\ErrorCatcher;
18
use Yiisoft\ErrorHandler\Renderer\HtmlRenderer;
19
use Yiisoft\Factory\Exception\CircularReferenceException;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Factory\Exceptio...cularReferenceException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Yiisoft\Factory\Exception\InvalidConfigException;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Factory\Exception\InvalidConfigException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use Yiisoft\Factory\Exception\NotFoundException;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Factory\Exception\NotFoundException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Yiisoft\Factory\Exception\NotInstantiableException;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Factory\Exception\NotInstantiableException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Yiisoft\Http\Method;
24
use Yiisoft\Log\Logger;
25
use Yiisoft\Log\Target\File\FileTarget;
26
use Yiisoft\Yii\Event\ListenerConfigurationChecker;
27
use Yiisoft\Yii\Web\Application;
28
use Yiisoft\Yii\Web\Exception\HeadersHaveBeenSentException;
29
use Yiisoft\Yii\Web\SapiEmitter;
30
use Yiisoft\Yii\Web\ServerRequestFactory;
31
32
use function dirname;
33
use function microtime;
34
35
final class WebApplicationRunner
36
{
37
    private bool $debug = false;
38
39 10
    public function debug(bool $enable = true): void
40
    {
41 10
        $this->debug = $enable;
42 10
    }
43
44
    /**
45
     * @throws CircularReferenceException|ErrorException|HeadersHaveBeenSentException|InvalidConfigException
46
     * @throws NotFoundException|NotInstantiableException|
47
     */
48 10
    public function run(): void
49
    {
50 10
        $startTime = microtime(true);
51
52
        // Register temporary error handler to catch error while container is building.
53 10
        $errorHandler = $this->createTemporaryErrorHandler();
54 10
        $this->registerErrorHandler($errorHandler);
55
56 10
        $config = new Config(
57 10
            dirname(__DIR__, 2),
58 10
            '/config/packages', // Configs path.
59 10
            null,
60
            [
61 10
                'params',
62
                'events',
63
                'events-web',
64
                'events-console',
65
            ],
66
        );
67
68 10
        $container = new Container($config->get('web'), $config->get('providers-web'));
69
70
        // Register error handler with real container-configured dependencies.
71 10
        $this->registerErrorHandler($container->get(ErrorHandler::class), $errorHandler);
72
73
        // Run bootstrap
74 10
        $this->runBootstrap($container, $config->get('bootstrap-web'));
75
76 10
        $container = $container->get(ContainerInterface::class);
77
78 10
        if ($this->debug) {
79
            /** @psalm-suppress MixedMethodCall */
80 10
            $container->get(ListenerConfigurationChecker::class)->check($config->get('events-web'));
81
        }
82
83
        /** @var Application */
84 10
        $application = $container->get(Application::class);
85
86
        /**
87
         * @var ServerRequestInterface
88
         * @psalm-suppress MixedMethodCall
89
         */
90 10
        $serverRequest = $container->get(ServerRequestFactory::class)->createFromGlobals();
91 10
        $request = $serverRequest->withAttribute('applicationStartTime', $startTime);
92
93
        try {
94 10
            $application->start();
95 10
            $response = $application->handle($request);
96 10
            $this->emit($request, $response);
97
        } catch (Throwable $throwable) {
98
            $handler = new ThrowableHandler($throwable);
99
            /**
100
             * @var ResponseInterface
101
             * @psalm-suppress MixedMethodCall
102
             */
103
            $response = $container->get(ErrorCatcher::class)->process($request, $handler);
104
            $this->emit($request, $response);
105 10
        } finally {
106 10
            $application->afterEmit($response ?? null);
107 10
            $application->shutdown();
108
        }
109 10
    }
110
111 10
    private function createTemporaryErrorHandler(): ErrorHandler
112
    {
113 10
        $logger = new Logger([new FileTarget(dirname(__DIR__) . '/runtime/logs/app.log')]);
114 10
        return new ErrorHandler($logger, new HtmlRenderer());
115
    }
116
117
    /**
118
     * @throws HeadersHaveBeenSentException
119
     */
120 10
    private function emit(RequestInterface $request, ResponseInterface $response): void
121
    {
122 10
        (new SapiEmitter())->emit($response, $request->getMethod() === Method::HEAD);
123 10
    }
124
125
    /**
126
     * @throws ErrorException
127
     */
128 10
    private function registerErrorHandler(ErrorHandler $registered, ErrorHandler $unregistered = null): void
129
    {
130 10
        if ($unregistered !== null) {
131 10
            $unregistered->unregister();
132
        }
133
134 10
        if ($this->debug) {
135 10
            $registered->debug();
136
        }
137
138 10
        $registered->register();
139 10
    }
140
141 10
    private function runBootstrap(Container $container, array $bootstrapList): void
142
    {
143 10
        (new BootstrapRunner($container, $bootstrapList))->run();
144 10
    }
145
}
146