Passed
Pull Request — master (#38)
by Melech
05:50 queued 01:43
created

App::getConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Application\Entry;
15
16
use Valkyrja\Application\Config;
17
use Valkyrja\Application\Contract\Application;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Application\Contract\Application 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...
18
use Valkyrja\Application\Data;
19
use Valkyrja\Application\Env;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Application\Env 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 Valkyrja\Application\Exception\RuntimeException;
21
use Valkyrja\Application\Valkyrja;
22
use Valkyrja\Cli\Interaction\Factory\InputFactory;
23
use Valkyrja\Cli\Interaction\Input\Contract\Input;
24
use Valkyrja\Cli\Server\Contract\InputHandler;
25
use Valkyrja\Container\Contract\Container;
26
use Valkyrja\Exception\Contract\ErrorHandler as ErrorHandlerContract;
27
use Valkyrja\Exception\ErrorHandler;
28
use Valkyrja\Http\Message\Factory\RequestFactory;
29
use Valkyrja\Http\Message\Request\Contract\ServerRequest;
30
use Valkyrja\Http\Server\Contract\RequestHandler;
31
use Valkyrja\Support\Directory;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Support\Directory 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...
32
33
use function define;
34
35
/**
36
 * Abstract Class App.
37
 *
38
 * @author Melech Mizrachi
39
 */
40
abstract class App
41
{
42
    /**
43
     * Start the application.
44
     *
45
     * @param non-empty-string $dir The directory
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
46
     */
47
    public static function start(string $dir, Env $env): Application
48
    {
49
        static::defaultErrorHandler();
50
        static::appStart();
51
        static::directory(dir: $dir);
52
53
        return static::app(env: $env);
54
    }
55
56
    /**
57
     * Now that the application has been bootstrapped and setup correctly with all our requirements lets run it!
58
     *
59
     * @param non-empty-string $dir The directory
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
60
     */
61
    public static function http(string $dir, Env $env): void
62
    {
63
        $app = static::start(
64
            dir: $dir,
65
            env: $env,
66
        );
67
68
        $container = $app->getContainer();
69
70
        self::bootstrapErrorHandler($app, $container);
71
72
        $handler = $container->getSingleton(RequestHandler::class);
73
        $handler->run(static::getRequest());
74
    }
75
76
    /**
77
     * Now that the application has been bootstrapped and setup correctly with all our requirements lets run it!
78
     *
79
     * @param non-empty-string $dir The directory
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
80
     */
81
    public static function cli(string $dir, Env $env): void
82
    {
83
        $app = static::start(
84
            dir: $dir,
85
            env: $env,
86
        );
87
88
        $container = $app->getContainer();
89
90
        self::bootstrapErrorHandler($app, $container);
91
92
        $handler = $container->getSingleton(InputHandler::class);
93
        $handler->run(static::getInput());
94
    }
95
96
    /**
97
     * Set a global constant for when the application as a whole started.
98
     */
99
    public static function appStart(): void
100
    {
101
        define('APP_START', microtime(true));
102
    }
103
104
    /**
105
     * Let's set the base directory within the web server for our application
106
     * so that when we locate directories and files within the application
107
     * we have a standard location from which to do so.
108
     *
109
     * @param non-empty-string $dir The directory
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
110
     */
111
    public static function directory(string $dir): void
112
    {
113
        Directory::$BASE_PATH = $dir;
114
    }
115
116
    /**
117
     * Let's start up the application by creating a new instance of the
118
     * application class. This is going to bind all the various
119
     * components together into a singular hub. This will set the
120
     *  correct environment class file to use, and appropriate the config
121
     *  that should be loaded by the application. In dev you'll want to
122
     *  use the default config out of the root config directory, but
123
     *  when you're on a production environment definitely have
124
     *  your config cached and the flag set in your env class.
125
     */
126
    public static function app(Env $env): Application
127
    {
128
        /** @var non-empty-string $cacheFilePath */
129
        $cacheFilePath = $env::APP_CACHE_FILE_PATH;
130
131
        if (is_file($cacheFilePath)) {
132
            $cache = file_get_contents($cacheFilePath);
133
134
            if ($cache === false || $cache === '') {
135
                throw new RuntimeException('Error occurred when retrieving cache file contents');
136
            }
137
138
            // Allow all classes, and filter for only Config classes down below since allowed_classes cannot be
139
            // a class that others extend off of, and we don't want to limit what a cached config class could be
140
            $data = unserialize($cache, ['allowed_classes' => true]);
141
142
            if (! $data instanceof Data) {
143
                throw new RuntimeException('Invalid cache');
144
            }
145
146
            $configData = $data;
147
        } else {
148
            $configData = static::getConfig();
149
        }
150
151
        return new Valkyrja(env: $env, configData: $configData);
152
    }
153
154
    /**
155
     * Get the application config.
156
     */
157
    protected static function getConfig(): Config
158
    {
159
        return new Config();
160
    }
161
162
    /**
163
     * Set a default error handler until the one specified in config is set in the Container\AppProvider.
164
     */
165
    protected static function defaultErrorHandler(): void
166
    {
167
        ErrorHandler::enable(
168
            displayErrors: true
169
        );
170
    }
171
172
    /**
173
     * Bootstrap error handler.
174
     */
175
    protected static function bootstrapErrorHandler(Application $app, Container $container): void
176
    {
177
        $errorHandler = new ErrorHandler();
178
179
        // Set error handler in the service container
180
        $container->setSingleton(ErrorHandlerContract::class, $errorHandler);
181
182
        // If debug is on, enable debug handling
183
        if ($app->getDebugMode()) {
184
            // Enable error handling
185
            $errorHandler::enable(
186
                displayErrors: true
187
            );
188
        }
189
    }
190
191
    /**
192
     * Get the request.
193
     */
194
    protected static function getRequest(): ServerRequest
195
    {
196
        return RequestFactory::fromGlobals();
197
    }
198
199
    /**
200
     * Get the input.
201
     */
202
    protected static function getInput(): Input
203
    {
204
        return InputFactory::fromGlobals();
205
    }
206
}
207