blob: 5303f8a0044146a248aa8826e8436805d3fb0d64 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
<?php
namespace Jasny\Controller;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Execute controller on given route
*/
trait RouteAction
{
/**
* Get request, set for controller
*
* @return ServerRequestInterface
*/
abstract protected function getRequest();
/**
* Get response. set for controller
*
* @return ResponseInterface
*/
abstract protected function getResponse();
/**
* Respond with a server error
*
* @param string $message
* @param int $code HTTP status code
*/
abstract public function notFound($message = '', $code = 404);
/**
* Check if response is 2xx succesful, or empty
*
* @return boolean
*/
abstract public function isSuccessful();
/**
* Called before executing the action.
* If the response is no longer a success statuc (>= 300), the action will not be executed.
*
* <code>
* protected function beforeAction()
* {
* $this->respondWith('json'); // Respond with JSON by default
*
* if ($this->auth->getUser()->getCredits() <= 0) {
* $this->paymentRequired();
* }
* }
* </code>
*/
protected function beforeAction()
{
}
/**
* Run the controller
*
* @return ResponseInterface
*/
public function run()
{
$route = $this->getRequest()->getAttribute('route');
$method = $this->getActionMethod(isset($route->action) ? $route->action : 'default');
if (!method_exists($this, $method)) {
return $this->notFound();
}
$args = isset($route->args)
? $route->args
: $this->getFunctionArgs($route, new \ReflectionMethod($this, $method));
$this->beforeAction();
if ($this->isSuccessful()) {
call_user_func_array([$this, $method], $args);
}
return $this->getResponse();
}
/**
* Get the method name of the action
*
* @param string $action
* @return string
*/
protected function getActionMethod($action)
{
return \Jasny\camelcase($action) . 'Action';
}
/**
* Get the arguments for a function from a route using reflection
*
* @param object $route
* @param \ReflectionFunctionAbstract $refl
* @return array
*/
protected function getFunctionArgs($route, \ReflectionFunctionAbstract $refl)
{
$args = [];
$params = $refl->getParameters();
foreach ($params as $param) {
$key = $param->name;
if (property_exists($route, $key)) {
$value = $route->{$key};
} else {
if (!$param->isOptional()) {
$fn = $refl instanceof \ReflectionMethod
? $refl->class . ':' . $refl->name
: $refl->name;
throw new \RuntimeException("Missing argument '$key' for $fn()");
}
$value = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
}
$args[$key] = $value;
}
return $args;
}
}
|