Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unique namespace within a mount #158

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
}
],
"require": {
"php": ">=5.3.0"
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "~4.8",
Expand Down
96 changes: 49 additions & 47 deletions src/Bramus/Router/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class Router
private $serverBasePath;

/**
* @var string Default Controllers Namespace
* @var array Default Controllers Namespace
*/
private $namespace = '';
private $namespace = [];

/**
* Store a before middleware route and a handling function to be executed when accessed using one of the specified methods.
Expand All @@ -63,6 +63,7 @@ public function before($methods, $pattern, $fn)
$this->beforeRoutes[$method][] = array(
'pattern' => $pattern,
'fn' => $fn,
'baseRoute' => $this->baseRoute
);
}
}
Expand All @@ -83,6 +84,7 @@ public function match($methods, $pattern, $fn)
$this->afterRoutes[$method][] = array(
'pattern' => $pattern,
'fn' => $fn,
'baseRoute' => $this->baseRoute
);
}
}
Expand Down Expand Up @@ -250,7 +252,7 @@ public function getRequestMethod()
public function setNamespace($namespace)
{
if (is_string($namespace)) {
$this->namespace = $namespace;
$this->namespace[$this->baseRoute] = $namespace;
}
}

Expand All @@ -261,7 +263,7 @@ public function setNamespace($namespace)
*/
public function getNamespace()
{
return $this->namespace;
return $this->namespace[$this->baseRoute];
}

/**
Expand Down Expand Up @@ -314,11 +316,11 @@ public function run($callback = null)
*/
public function set404($match_fn, $fn = null)
{
if (!is_null($fn)) {
$this->notFoundCallback[$match_fn] = $fn;
} else {
$this->notFoundCallback['/'] = $match_fn;
}
if (!is_null($fn)) {
$this->notFoundCallback[$match_fn] = $fn;
} else {
$this->notFoundCallback['/'] = $match_fn;
}
}

/**
Expand All @@ -337,62 +339,62 @@ public function trigger404($match = null){
// loop fallback-routes
foreach ($this->notFoundCallback as $route_pattern => $route_callable) {

// matches result
$matches = [];
// matches result
$matches = [];

// check if there is a match and get matches as $matches (pointer)
$is_match = $this->patternMatches($route_pattern, $this->getCurrentUri(), $matches, PREG_OFFSET_CAPTURE);
// check if there is a match and get matches as $matches (pointer)
$is_match = $this->patternMatches($route_pattern, $this->getCurrentUri(), $matches, PREG_OFFSET_CAPTURE);

// is fallback route match?
if ($is_match) {
// is fallback route match?
if ($is_match) {

// Rework matches to only contain the matches, not the orig string
$matches = array_slice($matches, 1);
// Rework matches to only contain the matches, not the orig string
$matches = array_slice($matches, 1);

// Extract the matched URL parameters (and only the parameters)
$params = array_map(function ($match, $index) use ($matches) {
// Extract the matched URL parameters (and only the parameters)
$params = array_map(function ($match, $index) use ($matches) {

// We have a following parameter: take the substring from the current param position until the next one's position (thank you PREG_OFFSET_CAPTURE)
if (isset($matches[$index + 1]) && isset($matches[$index + 1][0]) && is_array($matches[$index + 1][0])) {
if ($matches[$index + 1][0][1] > -1) {
return trim(substr($match[0][0], 0, $matches[$index + 1][0][1] - $match[0][1]), '/');
}
} // We have no following parameters: return the whole lot
// We have a following parameter: take the substring from the current param position until the next one's position (thank you PREG_OFFSET_CAPTURE)
if (isset($matches[$index + 1]) && isset($matches[$index + 1][0]) && is_array($matches[$index + 1][0])) {
if ($matches[$index + 1][0][1] > -1) {
return trim(substr($match[0][0], 0, $matches[$index + 1][0][1] - $match[0][1]), '/');
}
} // We have no following parameters: return the whole lot

return isset($match[0][0]) && $match[0][1] != -1 ? trim($match[0][0], '/') : null;
}, $matches, array_keys($matches));
return isset($match[0][0]) && $match[0][1] != -1 ? trim($match[0][0], '/') : null;
}, $matches, array_keys($matches));

$this->invoke($route_callable);
$this->invoke($route_callable);

++$numHandled;
}
++$numHandled;
}
}
if($numHandled == 0 and $this->notFoundCallback['/']) {
$this->invoke($this->notFoundCallback['/']);
$this->invoke($this->notFoundCallback['/']);
} elseif ($numHandled == 0) {
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
}
}
}

/**
* Replace all curly braces matches {} into word patterns (like Laravel)
* Checks if there is a routing match
*
* @param $pattern
* @param $uri
* @param $matches
* @param $flags
*
* @return bool -> is match yes/no
*/
* Replace all curly braces matches {} into word patterns (like Laravel)
* Checks if there is a routing match
*
* @param $pattern
* @param $uri
* @param $matches
* @param $flags
*
* @return bool -> is match yes/no
*/
private function patternMatches($pattern, $uri, &$matches, $flags)
{
// Replace all curly braces matches {} into word patterns (like Laravel)
$pattern = preg_replace('/\/{(.*?)}/', '/(.*?)', $pattern);
// Replace all curly braces matches {} into word patterns (like Laravel)
$pattern = preg_replace('/\/{(.*?)}/', '/(.*?)', $pattern);

// we may have a match!
return boolval(preg_match_all('#^' . $pattern . '$#', $uri, $matches, PREG_OFFSET_CAPTURE));
// we may have a match!
return boolval(preg_match_all('#^' . $pattern . '$#', $uri, $matches, PREG_OFFSET_CAPTURE));
}

/**
Expand Down Expand Up @@ -437,6 +439,7 @@ private function handle($routes, $quitAfterRun = false)
}, $matches, array_keys($matches));

// Call the handling function with the URL parameters if the desired input is callable
$this->baseRoute = $route['baseRoute'];
$this->invoke($route['fn'], $params);

++$numHandled;
Expand All @@ -462,7 +465,6 @@ private function invoke($fn, $params = array())
elseif (stripos($fn, '@') !== false) {
// Explode segments of given route
list($controller, $method) = explode('@', $fn);

// Adjust controller class if namespace has been set
if ($this->getNamespace() !== '') {
$controller = $this->getNamespace() . '\\' . $controller;
Expand Down
46 changes: 46 additions & 0 deletions tests/RouterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,42 @@ public function testSubrouteMouting()
ob_end_clean();
}

public function testNamespaceWithMouting()
{
$router = new \Bramus\Router\Router();

$router->mount('/show', function () use ($router) {
$router->setNamespace('\Hello');
$router->get('/without/(.*)', 'HelloRouterTestController@show');

$router->mount('/folder', function () use ($router) {
$router->setNamespace('\Hello\Folder');
$router->get('/(.*)', 'HelloFolderRouterTestController@show');

});
});

$router->get('/anything/(.*)', 'Hello\HelloRouterTestController@show');

ob_start();
$_SERVER['REQUEST_URI'] = '/show/without/foo';
$router->run();
$this->assertEquals('foo', ob_get_contents());

ob_clean();
$_SERVER['REQUEST_URI'] = '/show/folder/foo';
$router->run();
$this->assertEquals('foo', ob_get_contents());

ob_clean();
$_SERVER['REQUEST_URI'] = '/anything/foo';
$router->run();
$this->assertEquals('foo', ob_get_contents());

// cleanup
ob_end_clean();
}

public function testHttpMethodOverride()
{
// Fake the request method to being POST and override it
Expand Down Expand Up @@ -956,4 +992,14 @@ public function show($id)
}
}

namespace Hello\Folder {
class HelloFolderRouterTestController
{
public function show($id)
{
echo $id;
}
}
}

// EOF