Completed
Push — master ( a40dae...3ec68e )
by Enrico
03:25 queued 28s
created

Application::getRoutes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 ( $exception instanceof  HttpExceptionInterface ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $exception seems to be never defined.
Loading history...
57
            $response =  new Response($e->getMessage(), $e->getStatusCode());            
0 ignored issues
show
Bug introduced by
The method getStatusCode() does not exist on Exception. It seems like you code against a sub-type of Exception such as uSILEX\Exception\HttpException. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

57
            $response =  new Response($e->getMessage(), $e->/** @scrutinizer ignore-call */ getStatusCode());            
Loading history...
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 = $response = $this[$controllerService];
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
107
              
108
            
109
        } catch (Exception $e) {
110
            $response = exceptionToResponse($e);
0 ignored issues
show
Bug introduced by
The function exceptionToResponse was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
            $response = /** @scrutinizer ignore-call */ exceptionToResponse($e);
Loading history...
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
        // define $this['uSILEX_IGNORE_SEND'] just for unit testing purposes
209 1
        if( !( isset($this['uSILEX_IGNORE_SEND']) &&  $this['uSILEX_IGNORE_SEND'])) {
210
            $this['response']->send();
211
        } 
212
        
213 1
    }
214
    
215
}