1
1
<?php
2
- declare (strict_types = 1 );
2
+ declare (strict_types= 1 );
3
3
4
4
namespace Nano ;
5
5
@@ -12,6 +12,7 @@ final class Framework
12
12
private $ projectNamespace = '\Project ' ;
13
13
private $ controllerPackage = '\Controller ' ;
14
14
private $ controllerActionSuffix = 'Action ' ;
15
+ private $ withParameterMatching = false ;
15
16
16
17
/**
17
18
* Dispatch the request
@@ -21,27 +22,62 @@ final class Framework
21
22
public function dispatch ()
22
23
{
23
24
list ($ controllerName , $ action ) = $ this ->getControllerAndAction ();
24
- $ controller = $ this ->projectNamespace . $ this ->controllerPackage . '\\' . ucfirst ($ controllerName );
25
- if (!class_exists ($ controller )) {
26
- throw new \Exception ('controller ' . $ controllerName . ' not found ' );
27
- };
28
- $ controller = new $ controller ;
25
+ $ controller = $ this ->getControllerFromName ($ controllerName );
29
26
$ finalAction = $ this ->getVerbFromRequest () . ucfirst ($ action ) . $ this ->controllerActionSuffix ;
30
27
if (is_callable (array ($ controller , $ finalAction ))) {
31
- return $ controller ->$ finalAction ();
28
+ return call_user_func_array (
29
+ [$ controller , $ finalAction ],
30
+ $ this ->getParametersForMatching ($ controller , $ finalAction )
31
+ );
32
32
}
33
33
$ finalAction = $ action . $ this ->controllerActionSuffix ;
34
34
if (!is_callable (array ($ controller , $ finalAction ))) {
35
35
throw new \Exception ('action ' . $ finalAction . ' not found in controller ' . $ controllerName );
36
36
}
37
- return $ controller ->$ finalAction ();
37
+ return call_user_func_array (
38
+ [$ controller , $ finalAction ],
39
+ $ this ->getParametersForMatching ($ controller , $ finalAction )
40
+ );
41
+ }
42
+
43
+ /**
44
+ * Returns parameters from request matching specified controller and action
45
+ * @param object $controller
46
+ * @param string $action
47
+ * @return array
48
+ */
49
+ private function getParametersForMatching ($ controller , string $ action ): array
50
+ {
51
+ $ parameters = [];
52
+ $ reflection = new \ReflectionMethod ($ controller , $ action );
53
+ foreach ($ reflection ->getParameters () as $ param ) {
54
+ if (isset ($ _REQUEST [$ param ->name ])) {
55
+ $ parameters [$ param ->name ] = $ _REQUEST [$ param ->name ];
56
+ }
57
+ }
58
+ return $ parameters ;
59
+ }
60
+
61
+ /**
62
+ * Return Controller instance from a controller name
63
+ * @param string $controllerName
64
+ * @return object
65
+ * @throws \Exception
66
+ */
67
+ private function getControllerFromName (string $ controllerName )
68
+ {
69
+ $ controller = $ this ->projectNamespace . $ this ->controllerPackage . '\\' . ucfirst ($ controllerName );
70
+ if (!class_exists ($ controller )) {
71
+ throw new \Exception ('controller ' . $ controllerName . ' not found ' );
72
+ }
73
+ return new $ controller ;
38
74
}
39
75
40
76
/**
41
77
* Return HTTP Method for request
42
78
* @return string
43
79
*/
44
- private function getVerbFromRequest ()
80
+ private function getVerbFromRequest (): string
45
81
{
46
82
return isset ($ _SERVER ['REQUEST_METHOD ' ]) ? strtolower ($ _SERVER ['REQUEST_METHOD ' ]) : 'get ' ;
47
83
}
@@ -50,7 +86,7 @@ private function getVerbFromRequest()
50
86
* Returns Request uri without query string
51
87
* @return string
52
88
*/
53
- private function getQuery () : string
89
+ private function getQuery (): string
54
90
{
55
91
$ requestUri = $ _SERVER ['REQUEST_URI ' ];
56
92
$ appendUri = strpos ($ requestUri , '? ' );
@@ -61,7 +97,7 @@ private function getQuery() : string
61
97
* Determine controller and action from Request Uri
62
98
* @return array
63
99
*/
64
- private function getControllerAndAction () : array
100
+ private function getControllerAndAction (): array
65
101
{
66
102
$ parts = explode ('/ ' , preg_replace ('~^ ' . Basepath::get () . '~ ' , '' , $ this ->getQuery ()));
67
103
$ action = count ($ parts ) >= 2 ? array_pop ($ parts ) : 'index ' ;
@@ -74,7 +110,7 @@ private function getControllerAndAction() : array
74
110
* @param string $namespace
75
111
* @return Framework
76
112
*/
77
- public function setNamespace(string $ namespace = '\Project ' ) : Framework
113
+ public function setNamespace(string $ namespace = '\Project ' ): Framework
78
114
{
79
115
$ this ->projectNamespace = strlen ($ namespace ) && $ namespace {0 } != '\\' ? '\\' . $ namespace : $ namespace ;
80
116
return $ this ;
@@ -85,7 +121,7 @@ public function setNamespace(string $namespace = '\Project') : Framework
85
121
* @param string $controllerPackage
86
122
* @return Framework
87
123
*/
88
- public function setControllerPackage (string $ controllerPackage = '\Controller ' ) : Framework
124
+ public function setControllerPackage (string $ controllerPackage = '\Controller ' ): Framework
89
125
{
90
126
$ this ->controllerPackage = strlen ($ controllerPackage ) && $ controllerPackage {0 } != '\\'
91
127
? '\\' . $ controllerPackage
@@ -98,9 +134,20 @@ public function setControllerPackage(string $controllerPackage = '\Controller')
98
134
* @param string $suffix
99
135
* @return Framework
100
136
*/
101
- public function setControllerActionSuffix (string $ suffix = 'Action ' ) : Framework
137
+ public function setControllerActionSuffix (string $ suffix = 'Action ' ): Framework
102
138
{
103
139
$ this ->controllerActionSuffix = (string )$ suffix ;
104
140
return $ this ;
105
141
}
142
+
143
+ /**
144
+ * Tells if we should use parameter matching for controllers
145
+ * @param bool $active
146
+ * @return Framework
147
+ */
148
+ public function setParameterMatching ($ active = true ): Framework
149
+ {
150
+ $ this ->withParameterMatching = (bool )$ active ;
151
+ return $ this ;
152
+ }
106
153
}
0 commit comments