Completed
Push — master ( 01c760...023fa6 )
by Gjero
03:19
created

Application   D

Complexity

Total Complexity 33

Size/Duplication

Total Lines 273
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 24

Importance

Changes 0
Metric Value
dl 0
loc 273
rs 4.9238
c 0
b 0
f 0
wmc 33
lcom 1
cbo 24

10 Methods

Rating   Name   Duplication   Size   Complexity  
B bootstrap() 0 29 3
D run() 0 36 9
B setupErrorHandling() 0 41 3
B setupUtils() 0 36 2
A loadPdoDriver() 0 6 3
A loadRoutes() 0 13 4
A loadListeners() 0 6 2
A reportIf() 0 10 4
A __clone() 0 3 1
A finish() 0 6 2
1
<?php
2
/**
3
 * Pimf
4
 *
5
 * @copyright Copyright (c) Gjero Krsteski (http://krsteski.de)
6
 * @license   http://opensource.org/licenses/MIT MIT License
7
 */
8
9
namespace Pimf;
10
11
use Pimf\Util\Character as Str, Pimf\Util\Header, Pimf\Util\Header\ResponseStatus, Pimf\Util\Uuid;
12
13
/**
14
 * Provides a facility for applications which provides reusable resources,
15
 * common-based bootstrapping and dependency checking.
16
 *
17
 * @package Pimf
18
 * @author  Gjero Krsteski <[email protected]>
19
 *
20
 */
21
final class Application
22
{
23
    const VERSION = '1.9.0';
24
25
    /**
26
     * @var Environment
27
     */
28
    protected static $env;
29
30
    /**
31
     * @var Logger
32
     */
33
    protected static $logger;
34
35
    /**
36
     * @var EntityManager
37
     */
38
    protected static $em;
39
40
    /**
41
     * @var Router
42
     */
43
    protected static $router;
44
45
    /**
46
     * Mechanism used to do initial setup and edging before a application runs.
47
     *
48
     * @param array $conf The array of configuration options.
49
     * @param array $server Array of information such as headers, paths, and script locations.
50
     *
51
     * @return boolean|null
52
     */
53
    public static function bootstrap(array $conf, array $server = array())
54
    {
55
        $problems = array();
56
57
        try {
58
59
            Config::load($conf);
60
61
            $environment = Config::get('environment');
62
63
            date_default_timezone_set(Config::get('timezone'));
64
65
            self::setupUtils($server, Config::get('bootstrap.local_temp_directory'), Config::get('logging.storage', 'file'));
66
            self::loadListeners(BASE_PATH . 'app/' . Config::get('app.name') . '/events.php');
67
            self::setupErrorHandling($environment);
68
            self::loadPdoDriver($environment, Config::get($environment . '.db'), Config::get('app.name'));
69
            self::loadRoutes(
70
                Config::get('app.routeable'),
71
                BASE_PATH . 'app/' . Config::get('app.name') . '/routes.php'
72
            );
73
74
        } catch (\Throwable $throwable) {
0 ignored issues
show
Bug introduced by Gjero Krsteski
The class Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
75
            $problems[] = $throwable->getMessage();
76
        } catch (\Exception $exception) {
77
            $problems[] = $exception->getMessage();
78
        }
79
80
        self::reportIf($problems, PHP_VERSION);
81
    }
82
83
    /**
84
     * Please bootstrap first, than run the application!
85
     * Run a application, let application accept a request, route the request,
86
     * dispatch to controller/action, render response and return response to client finally.
87
     *
88
     * @param array $get Array of variables passed to the current script via the URL parameters.
89
     * @param array $post Array of variables passed to the current script via the HTTP POST method.
90
     * @param array $cookie Array of variables passed to the current script via HTTP Cookies.
91
     * @param array $files An associative array FILES of items uploaded to the current script via the HTTP POST method.
92
     *
93
     * @return void
94
     */
95
    public static function run(array $get, array $post, array $cookie, array $files)
96
    {
97
        $cli = array();
98
        if (Sapi::isCli()) {
99
            $cli = Cli::parse((array)self::$env->argv);
100
            if (count($cli) < 1 || isset($cli['list'])) {
101
                Cli::absorb();
102
                exit(0);
103
            }
104
        }
105
106
        $prefix = Str::ensureTrailing('\\', Config::get('app.name'));
107
        $repository = BASE_PATH . 'app/' . Config::get('app.name') . '/Controller';
108
109
        if (isset($cli['controller']) && $cli['controller'] == 'core') {
110
            $prefix = 'Pimf\\';
111
            $repository = BASE_PATH . 'pimf-framework/core/Pimf/Controller';
112
        }
113
114
        $request = new Request($get, $post, $cookie, $cli, $files, self::$env);
115
        $resolver = new Resolver($request, $repository, $prefix, self::$router);
116
        $sessionized = (Sapi::isWeb() && Config::get('session.storage') !== '');
117
118
        if ($sessionized) {
119
            Session::load();
120
        }
121
122
        $pimf = $resolver->process(self::$env, self::$em, self::$logger);
123
124
        if ($sessionized) {
125
            Session::save();
126
            Cookie::send();
127
        }
128
129
        $pimf->render();
130
    }
131
132
    /**
133
     * @param string $environment
134
     */
135
    private static function setupErrorHandling($environment)
136
    {
137
        if ($environment == 'testing') {
138
            error_reporting(E_ALL | E_STRICT);
139
        } else {
140
141
            $logger = self::$logger;
142
143
            set_exception_handler(
144
                function ($exception) use ($logger) {
145
                    Error::exception($exception, $logger);
146
                }
147
            );
148
149
            set_error_handler(
150
                function ($code, $error, $file, $line) use ($logger) {
151
                    Error::native($code, $error, $file, $line, $logger, error_reporting());
152
                }
153
            );
154
155
            register_shutdown_function(
156
                function () use ($logger) {
157
                    Error::shutdown($logger, error_get_last());
158
                }
159
            );
160
161
            error_reporting(-1);
162
        }
163
164
        if (function_exists('pcntl_signal')) {
165
            pcntl_signal(SIGTERM, function ($signal) {
166
                Event::fire('on.sigterm', array($signal));
167
            });
168
            pcntl_signal(SIGINT, function ($signal) {
169
                Event::fire('on.sigint', array($signal));
170
            });
171
            pcntl_signal(SIGKILL, function ($signal) {
172
                Event::fire('on.sigkill', array($signal));
173
            });
174
        }
175
    }
176
177
    /**
178
     * @param array $server
179
     * @param $tmpPath
180
     * @param string $logging
181
     */
182
    private static function setupUtils(array $server, $tmpPath, $logging = 'file')
183
    {
184
        self::$env = new Environment($server);
185
        $envData = self::$env->data();
186
187
        Logger::setup(
188
            self::$env->getIp(),
189
            $envData->get('PHP_SELF', $envData->get('SCRIPT_NAME'))
190
        );
191
192
        ResponseStatus::setup($envData->get('SERVER_PROTOCOL', 'HTTP/1.0'));
193
194
        Header::setup(
195
            self::$env->getUserAgent()
196
        );
197
198
        Url::setup(self::$env->getUrl(), self::$env->isHttps());
199
        Uri::setup(self::$env->PATH_INFO, self::$env->REQUEST_URI);
200
        Uuid::setup(self::$env->getIp(), self::$env->getHost());
201
202
        if ($logging === 'file') {
203
            self::$logger = new Logger(
204
                new Adapter\File($tmpPath, "pimf-logs.txt"),
205
                new Adapter\File($tmpPath, "pimf-warnings.txt"),
206
                new Adapter\File($tmpPath, "pimf-errors.txt")
207
            );
208
        } else {
209
            self::$logger = new Logger(
210
                new Adapter\Std(Adapter\Std::OUT),
211
                new Adapter\Std(Adapter\Std::OUT),
212
                new Adapter\Std(Adapter\Std::ERR)
213
            );
214
        }
215
216
        self::$logger->init();
217
    }
218
219
    /**
220
     * @param string $environment
221
     * @param array $dbConf
222
     * @param string $appName
223
     */
224
    private static function loadPdoDriver($environment, $dbConf, $appName)
225
    {
226
        if (is_array($dbConf) && $environment != 'testing') {
227
            self::$em = new EntityManager(Pdo\Factory::get($dbConf), $appName);
228
        }
229
    }
230
231
    /**
232
     * @param boolean $routeable
233
     * @param string $routes Path to routes definition file.
234
     */
235
    private static function loadRoutes($routeable, $routes)
236
    {
237
        if ($routeable === true && file_exists($routes)) {
238
239
            self::$router = new Router();
240
241
            foreach ((array)(include $routes) as $route) {
242
243
                self::$router->map($route);
244
245
            }
246
        }
247
    }
248
249
    /**
250
     * @param string $events Path to event listeners
251
     */
252
    private static function loadListeners($events)
253
    {
254
        if (file_exists($events)) {
255
            include_once $events;
256
        }
257
    }
258
259
    /**
260
     * @param array $problems
261
     * @param float $version
262
     * @param bool $die
263
     *
264
     * @return array|void
265
     */
266
    private static function reportIf(array $problems, $version, $die = true)
267
    {
268
        if (version_compare($version, 5.3) == -1) {
269
            $problems[] = 'You have PHP ' . $version . ' and you need 5.3 or higher!';
270
        }
271
272
        if (!empty($problems)) {
273
            return ($die === true) ? die(implode(PHP_EOL . PHP_EOL, $problems)) : $problems;
274
        }
275
    }
276
277
    /**
278
     * PIMF Application can not be cloned.
279
     */
280
    private function __clone()
281
    {
282
    }
283
284
    /**
285
     * Stopping the PHP process for PHP-FastCGI users to speed up some PHP queries.
286
     */
287
    public static function finish()
288
    {
289
        if (function_exists('fastcgi_finish_request')) {
290
            fastcgi_finish_request();
291
        }
292
    }
293
}
294