Skip to content

Commit da407df

Browse files
committed
Add verb feature for RESTFul API
1 parent 00e7601 commit da407df

File tree

3 files changed

+61
-11
lines changed

3 files changed

+61
-11
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ With that on, you can now access to your pages like this :
3737

3838
http://mysite.tld/ \<controller>/\<action>
3939

40-
And it will load the class \Project\Controller\\\<controller>::\<action>Action
40+
And it will load the class \Project\Controller\\\<controller>::\<method>\<action>Action
4141

4242
You can easily configure your namespace, controller package and action suffix!
43+
*\<method>* represents the HTTP method used (usually *get* but you can use post/update/delete etc...). This is optional.
4344

4445
Either \<controller> or \<action> are optional and considered as 'index' if not defined.
4546

src/Framework.php

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,53 @@ final class Framework
2020
*/
2121
public function dispatch()
2222
{
23-
$requestUri = $_SERVER['REQUEST_URI'];
24-
$appendUri = strpos($requestUri, '?');
25-
$query = substr($requestUri, 0, $appendUri === false ? strlen($requestUri) : $appendUri);
26-
$parts = explode('/', preg_replace('~^' . Basepath::get() . '~', '', $query));
27-
$action = count($parts) >= 2 ? array_pop($parts) : 'index';
28-
$controllerName = isset($parts[0]) && $parts[0] ? implode($parts, '\\') : 'index';
23+
list($controllerName, $action) = $this->getControllerAndAction();
2924
$controller = $this->projectNamespace . $this->controllerPackage . '\\' . ucfirst($controllerName);
3025
if (!class_exists($controller)) {
3126
throw new \Exception('controller ' . $controllerName . ' not found');
3227
};
3328
$controller = new $controller;
34-
$action = ($action ?: 'index') . $this->controllerActionSuffix;
35-
if (!is_callable(array($controller, $action))) {
36-
throw new \Exception('action ' . $action . ' not found in controller ' . $controllerName);
29+
$finalAction = $this->getVerbFromRequest() . ucfirst($action) . $this->controllerActionSuffix;
30+
if (is_callable(array($controller, $finalAction))) {
31+
return $controller->$finalAction();
32+
}
33+
$finalAction = $action . $this->controllerActionSuffix;
34+
if (!is_callable(array($controller, $finalAction))) {
35+
throw new \Exception('action ' . $finalAction . ' not found in controller ' . $controllerName);
3736
}
38-
return $controller->$action();
37+
return $controller->$finalAction();
38+
}
39+
40+
/**
41+
* Return HTTP Method for request
42+
* @return string
43+
*/
44+
private function getVerbFromRequest()
45+
{
46+
return isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'get';
47+
}
48+
49+
/**
50+
* Returns Request uri without query string
51+
* @return string
52+
*/
53+
private function getQuery() : string
54+
{
55+
$requestUri = $_SERVER['REQUEST_URI'];
56+
$appendUri = strpos($requestUri, '?');
57+
return substr($requestUri, 0, $appendUri === false ? strlen($requestUri) : $appendUri);
58+
}
59+
60+
/**
61+
* Determine controller and action from Request Uri
62+
* @return array
63+
*/
64+
private function getControllerAndAction() : array
65+
{
66+
$parts = explode('/', preg_replace('~^' . Basepath::get() . '~', '', $this->getQuery()));
67+
$action = count($parts) >= 2 ? array_pop($parts) : 'index';
68+
$controllerName = isset($parts[0]) && $parts[0] ? implode($parts, '\\') : 'index';
69+
return [$controllerName, $action ?: 'index'];
3970
}
4071

4172
/**

tests/FrameworkTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ public function actionWithNoSuffix()
4747
{
4848
echo "Working5";
4949
}
50+
51+
public function postActionWithNoSuffix()
52+
{
53+
echo "Working6";
54+
}
5055
}
5156
}
5257

@@ -144,5 +149,18 @@ public function testDispatchSuccessWhenOtherSubPackageAndNoSuffixAndRecursivePat
144149
->setControllerActionSuffix('')
145150
->dispatch();
146151
}
152+
153+
public function testDispatchSuccessWhenOtherSubPackageAndNoSuffixAndRecursivePathWithPost()
154+
{
155+
$_SERVER['REQUEST_URI'] = '/recursive/recursive/actionwithnosuffix';
156+
$_SERVER['SCRIPT_FILENAME'] = '/var/www/index.php';
157+
$_SERVER['REQUEST_METHOD'] = 'POST';
158+
$this->expectOutputString("Working6");
159+
$nano = new \Nano\Framework();
160+
$nano->setNamespace('\OtherNamespace')
161+
->setControllerPackage('')
162+
->setControllerActionSuffix('')
163+
->dispatch();
164+
}
147165
}
148166
}

0 commit comments

Comments
 (0)