Completed
Push — master ( 41e3dd...be84a1 )
by Enrico
02:43
created

Application   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Test Coverage

Coverage 61.67%

Importance

Changes 0
Metric Value
eloc 57
dl 0
loc 192
ccs 37
cts 60
cp 0.6167
rs 10
c 0
b 0
f 0
wmc 21

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A handleRequest() 0 29 4
A boot() 0 11 4
A stream() 0 3 1
A getRoutes() 0 3 1
A addRoute() 0 5 1
A exceptionToResponse() 0 14 3
A json() 0 3 1
A register() 0 7 1
A run() 0 19 4
1
<?php 
2
namespace uSILEX;
3
4
use uSILEX\Exception\HttpExceptionInterface;
5
use uSILEX\Exception\NotFoundHttpException;
6
use Symfony\Component\HttpFoundation\Request;
7
use Symfony\Component\HttpFoundation\Response;
8
use Symfony\Component\HttpFoundation\RedirectResponse;
9
use Symfony\Component\HttpFoundation\StreamedResponse;
10
use Symfony\Component\HttpFoundation\JsonResponse;
11
use Pimple\Container;
12
use Pimple\ServiceProviderInterface;
13
14
15
/*
16
 * Inspired from Silex application
17
 */
18
class Application extends Container
19
{    
20
    const VERSION = '1.0.0';
21
    
22
    protected $providers = [];
23
    protected $routes = [];
24
    protected $booted = false;
25
26
    /**
27
     * Instantiate a new Application.
28
     *
29
     * Objects and parameters can be passed as argument to the constructor.
30
     *
31
     */
32 5
    public function __construct()
33
    {
34 5
        parent::__construct();
35 5
        $this['debug'] = false;
36 5
        $this['version'] = static::VERSION;
37 5
        $this['error_msg.short_template'] = 'Error %s (%s)';
38 5
        $this['error_msg.full_template'] = "Error %s (%s) - %s \nTrace info:\n%s\n";
39
        $this['RouteMatcher'] = function($c) {
40 2
            return new RouteMatcher($c);
41
        };
42
        $this['ControllerResolver'] = function($c) {
43 2
            return new ControllerResolver($c);
44
        };
45 5
    }
46
    
47
    
48
    /**
49
     * Transform a PHP exception into an http error message.
50
     *
51
     * @param \Exception $e a trapped exception
52
     *
53
     */
54
    protected function exceptionToResponse(\Exception $e): Response
55
    {
56
        if ($e instanceof  HttpExceptionInterface) {
57
            $response = new Response($e->getMessage(), $e->getStatusCode());            
58
        } else {
59
            $response = new Response(
60
                $this['debug']
61
                    ?sprintf($this['error_msg.full_template'], $e->getCode(), $this['version'], $e->getMessage(), $e->getTraceAsString())
62
                    :sprintf($this['error_msg.short_template'], $e->getCode(), $this['version']),
63
                Response::HTTP_INTERNAL_SERVER_ERROR
64
            );
65
        }
66
        
67
        return $response;
68
    }
69
    
70
71 3
    public function addRoute(Route $route): Container
72
    {
73 3
        $this->routes[] = $route;
74
        
75 3
        return $this;
76
    }
77
    
78
    
79 4
    public function getRoutes(): array
80
    {
81 4
        return $this->routes;
82
    }
83
    
84
    
85 2
    public function handleRequest(): Response 
86
    {
87 2
        assert(isset($this['ControllerResolver']));
88 2
        assert(isset($this['request']));
89
        
90
        try {
91 2
            if (!$this->booted) {
92 2
                $this->boot();
93
            }
94
            
95
            
96
            // execute the controller action
97 2
            $controllerService = $this['ControllerResolver']->getController();
98
            
99 2
            assert(isset($this[$controllerService]));
100
            
101
            // call on_route_match hook
102 2
            if (isset($this['on_route_match'])) {
103 1
                $this['on_route_match.result'] = $this['on_route_match'];
104
            }
105
            
106 2
            $response = $this[$controllerService];
107
              
108
            
109
        } catch (Exception $e) {
110
            $response = $this->exceptionToResponse($e);
111
        }
112
        
113 2
        return $response;
114
    }
115
    
116
    
117
    /**
118
     * Registers a service provider.
119
     *
120
     * @param ServiceProviderInterface $provider A ServiceProviderInterface instance
121
     * @param array                    $values   An array of values that customizes the provider
122
     *
123
     * @return Application
124
     */
125
    public function register(ServiceProviderInterface $provider, array $values = [])
126
    {
127
        $this->providers[] = $provider;
128
        
129
        parent::register($provider, $values);
130
        
131
        return $this;
132
    }
133
    
134
    
135
    /**
136
     * Boots all service providers.
137
     *
138
     * This method is automatically called by handle(), but you can use it
139
     * to boot all service providers when not handling a request.
140
     */
141 2
    public function boot()
142
    {
143 2
        if ($this->booted) {
144
            return;
145
        }
146
        
147 2
        $this->booted = true;
148
        
149 2
        foreach ($this->providers as $provider) {
150
            if ($provider instanceof BootableProviderInterface) {
151
                $provider->boot($this);
152
            }
153
        }
154 2
    }
155
    
156
    
157
    /**
158
     * Creates a streaming response.
159
     *
160
     * @param mixed $callback A valid PHP callback
161
     * @param int   $status   The response status code
162
     * @param array $headers  An array of response headers
163
     *
164
     * @return StreamedResponse
165
     */
166
    public function stream($callback = null, $status = 200, array $headers = [])
167
    {
168
        return new StreamedResponse($callback, $status, $headers);
169
    }
170
    
171
    
172
    /**
173
     * Convert some data into a JSON response.
174
     *
175
     * @param mixed $data    The response data
176
     * @param int   $status  The response status code
177
     * @param array $headers An array of response headers
178
     *
179
     * @return JsonResponse
180
     */
181
    public function json($data = [], $status = 200, array $headers = [])
182
    {
183
        return new JsonResponse($data, $status, $headers);
184
    }
185
    
186
    
187
    /**
188
     * Handles the request and delivers the response.
189
     *
190
     */
191 1
    public function run()
192
    {
193
        // define $this['request'] just for testing purposes
194 1
        if (!isset($this['request'])) {
195 1
            $this['request'] = Request::createFromGlobals();
196
        }
197
        
198
        // define $this['response'] just for testing purposes
199 1
        if (!isset($this['response'])) {
200
            $this['response'] = $this->handleRequest();
201
        }
202
        
203
        // call on_response hook
204 1
        if (isset($this['on_response'])) {
205 1
            $this['response'] = $this['on_response'];
206
        }
207
        
208
        
209 1
        $this['response']->send();
210
        
211 1
    }
212
    
213
}