Passed
Push — 9.0-dev ( bf3f06...4f14a6 )
by Radu
01:13
created

Application::execute()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 20
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 15
nc 6
nop 0
dl 0
loc 20
rs 8.8571
c 0
b 0
f 0
1
<?php
2
namespace WebServCo\Framework;
3
4
use WebServCo\Framework\Settings as S;
5
use WebServCo\Framework\Framework as Fw;
6
use WebServCo\Framework\Environment as Env;
7
use WebServCo\Framework\ErrorHandler as Err;
8
9
class Application extends \WebServCo\Framework\AbstractApplication
10
{
11
    public function __construct($publicPath, $projectPath)
12
    {
13
        $publicPath = rtrim($publicPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
14
        $projectPath = rtrim($projectPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
15
        
16
        if (!is_readable("{$publicPath}index.php") || !is_readable("{$projectPath}.env")) {
17
            throw new \ErrorException(
18
                'Invalid paths specified when initializing Application.'
19
            );
20
        }
21
        
22
        $this->config()->set(sprintf('app%1$spath%1$sweb', S::DIVIDER), $publicPath);
23
        $this->config()->set(sprintf('app%1$spath%1$sproject', S::DIVIDER), $projectPath);
24
    }
25
    
26
    /**
27
     * Sets the env value from the project .env file.
28
     */
29
    final public function setEnvironmentValue()
30
    {
31
        /**
32
         * Project path is set in the constructor.
33
         */
34
        $pathProject = $this->config()->get(sprintf('app%1$spath%1$sproject', S::DIVIDER));
35
        /**
36
         * Env file existence is verified in the controller.
37
         */
38
        $this->config()->setEnv(trim(file_get_contents("{$pathProject}.env")));
39
        
40
        return true;
41
    }
42
    
43
    /**
44
     * Starts the execution of the application.
45
     */
46
    final public function start()
47
    {
48
        Err::set();
49
        register_shutdown_function([$this, 'shutdown']);
50
        
51
        try {
52
            $this->setEnvironmentValue();
53
            
54
            /**
55
             * With no argument, timezone will be set from the configuration.
56
             */
57
            $this->date()->setTimezone();
58
            /**
59
             * @todo i18n, log, session (if not cli), users (if not cli)
60
             */
61
            
62
            return true;
63
        } catch (\Throwable $e) { // php7
64
            return $this->shutdown($e, true);
65
        } catch (\Exception $e) { // php5
66
            return $this->shutdown($e, true);
67
        }
68
    }
69
    
70
    /**
71
     * Runs the application.
72
     */
73
    final public function run()
74
    {
75
        try {
76
            $response = $this->execute();
77
            if ($response instanceof
78
                \WebServCo\Framework\Interfaces\ResponseInterface) {
79
                $statusCode = $response->send($this->request());
80
                return $this->shutdown(
81
                    null,
82
                    true,
83
                    Fw::isCLI() ? $statusCode : 0
84
                );
85
            }
86
        } catch (\Throwable $e) { // php7
87
            return $this->shutdown($e, true);
88
        } catch (\Exception $e) { // php5
89
            return $this->shutdown($e, true);
90
        }
91
    }
92
    
93
    /**
94
     * Finishes the execution of the Application.
95
     *
96
     * This method is also registered as a shutdown handler.
97
     */
98
    final public function shutdown($exception = null, $manual = false, $statusCode = 0)
99
    {
100
        $hasError = $this->handleErrors($exception);
101
        if ($hasError) {
102
            $statusCode = 1;
103
        }
104
        
105
        if (!$manual) { //if shutdown handler
106
            /**
107
             * Warning: this part will always be executed,
108
             * independent of the outcome of the script.
109
             */
110
            Err::restore();
111
        }
112
        exit($statusCode);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
113
    }
114
    
115
    final protected function execute()
116
    {
117
        $classType = Fw::isCLI() ? 'Command' : 'Controller';
118
        list($class, $method, $args) =
119
            $this->router()->getRoute(
120
                $this->request()->target,
121
                $this->router()->setting('routes'),
122
                $this->request()->args
123
            );
124
        $className = "\\Project\\Domain\\{$class}\\{$class}{$classType}";
125
        if (!class_exists($className)) {
126
            throw new \ErrorException("No matching {$classType} found", 404);
127
        }
128
        $object = new $className;
129
        $parent = get_parent_class($object);
130
        if (method_exists($parent, $method) ||
131
            !is_callable([$className, $method])) {
132
            throw new \ErrorException('No matching action found', 404);
133
        }
134
        return call_user_func_array([$object, $method], $args);
135
    }
136
}
137