Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
App
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
8 / 8
16
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 init
n/a
0 / 0
n/a
0 / 0
0
 process
n/a
0 / 0
n/a
0 / 0
0
 fullInit
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 fullProcess
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 addMiddleware
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 runMiddlewares
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 finish
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 loadConfigs
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 handleException
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace Dynart\Micro;
4
5/**
6 * Micro PHP Application
7 *
8 * @package Dynart\Micro
9 */
10abstract class App {
11
12    const CONFIG_BASE_URL = 'app.base_url';
13    const CONFIG_ROOT_PATH = 'app.root_path';
14    const CONFIG_ENVIRONMENT = 'app.environment';
15    const PRODUCTION_ENVIRONMENT = 'prod';
16
17    /**
18     * Stores the middleware class names in a list
19     * @var Middleware[]
20     */
21    protected $middlewares = [];
22
23    /** @var Config */
24    protected $config;
25
26    /** @var Logger */
27    protected $logger;
28
29    /** @var string[] */
30    protected $configPaths;
31
32    /** @var bool */
33    protected $exitOnFinish = true;
34
35    public function __construct(array $configPaths) {
36        $this->configPaths = $configPaths;
37        Micro::add(Config::class);
38        Micro::add(Logger::class);
39    }
40
41    /**
42     * Abstract function for initialize the application
43     * @return mixed
44     */
45    abstract public function init();
46
47    /**
48     * Abstract function for processing the application
49     * @return mixed
50     */
51    abstract public function process();
52
53    /**
54     * Fully initializes the application
55     *
56     * Creates the `Config`, loads the configs, creates the `Logger`, calls the `init()` method
57     * then runs all of the middlewares. If an exception happens, handles it with the `handleException()` method.
58     */
59    public function fullInit() {
60        try {
61            $this->config = Micro::get(Config::class);
62            $this->loadConfigs();
63            $this->logger = Micro::get(Logger::class);
64            $this->init();
65            $this->runMiddlewares();
66        } catch (\Exception $e) {
67            $this->handleException($e);
68        }
69    }
70
71    /**
72     * Calls the `process()` method within a try/catch, handles exception with the `handleException()` method
73     */
74    public function fullProcess() {
75        try {
76            $this->process();
77        } catch (\Exception $e) {
78            $this->handleException($e);
79        }
80    }
81
82    /**
83     * Adds a middleware
84     * @param string $interface
85     */
86    public function addMiddleware(string $interface) {
87        if (!in_array($interface, $this->middlewares)) {
88            Micro::add($interface);
89            $this->middlewares[] = $interface;
90        }
91    }
92
93    /**
94     * Runs all of the added middlewares
95     */
96    protected function runMiddlewares() {
97        foreach ($this->middlewares as $m) {
98            Micro::get($m)->run();
99        }
100    }
101
102    /**
103     * Finishes the application
104     * @param string|int $content Content for the output. If it's an int, it is the return code of the process.
105     * @return null
106     */
107    public function finish($content = 0) {
108        return $this->exitOnFinish ? exit($content) : print($content);
109    }
110
111    /**
112     * Loads all of the configs by the `$configPaths`
113     */
114    protected function loadConfigs() {
115        foreach ($this->configPaths as $path) {
116            $this->config->load($path);
117        }
118    }
119
120    /**
121     * Handles the exception
122     *
123     * Sends the type, the line, the exception message and the stacktrace to the standard error output.
124     * If the `Config` or the `Logger` wasn't initialised throws a `MicroException`.
125     *
126     * @param \Exception $e The exception
127     * @throws MicroException
128     */
129    protected function handleException(\Exception $e) {
130        if (!$this->config) {
131            throw new MicroException("Couldn't instantiate Config::class");
132        }
133        if (!$this->logger) {
134            throw new MicroException("Couldn't instantiate Logger::class");
135        }
136        $type = get_class($e);
137        $file = $e->getFile();
138        $line = $e->getLine();
139        $message = $e->getMessage();
140        $trace = $e->getTraceAsString();
141        $text = "`$type` in $file on line $line with message: $message\n$trace";
142        $this->logger->error($text);
143    }
144
145}