Skip to content

Commit

Permalink
Add support for namespaced controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
acoulton committed Mar 6, 2018
1 parent affd3fa commit 6dbd68f
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ You're really going to want to read this.

## Unreleased

* Add support for loading controllers with namespaced classes per https://github.com/kohana/core/pull/578/files
thanks to @rjd22 for the original implementation.
* Removed default support for passing client params to Request_Client
* Add new Request::initInitial which should now be called from index.php when creating the
main request. Request::fromGlobals no longer modifies any global state.
Expand Down
6 changes: 6 additions & 0 deletions classes/Kohana/Request/Client/Internal.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ public function execute_request(Request $request, Response $response)
$prefix .= str_replace(array('\\', '/'), '_', trim($directory, '/')).'_';
}

// Use the FQCN to load the Controller
if (substr($controller, 0, 1) === '\\')
{
$prefix = '';
}

if (Kohana::$profiling)
{
// Set the benchmark name
Expand Down
8 changes: 8 additions & 0 deletions classes/Kohana/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,14 @@ public function defaults(array $defaults = NULL)
return $this->_defaults;
}

if (isset($defaults['controller']) AND substr($defaults['controller'], 0, 1) === '\\')
{
if (isset($defaults['directory']))
{
throw new Kohana_Exception('Route directory should not be set when the controller is a FQCN.');
}
}

$this->_defaults = $defaults;

return $this;
Expand Down
19 changes: 19 additions & 0 deletions tests/kohana/RouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,25 @@ public function test_defaults_are_not_used_if_param_is_identical()
$this->assertSame('welcome2', $route->uri(array('controller' => 'welcome2')));
}


/**
* When using a FQCN test if the directory is not set else throw an exception
*
* @test
* @covers Route::defaults
*/
public function test_defaults_throws_exception_when_setting_fqcn_and_directory()
{
$this->setExpectedException('Kohana_Exception', 'Route directory should not be set when the controller is a FQCN.');

$route = new Route('(<controller>(/<action>(/<id>)))');
$route->defaults(array(
'directory' => 'directory/path',
'controller' => '\FQCN\Class\Name',
'action' => 'index'
));
}

/**
* Provider for test_required_parameters_are_needed
*
Expand Down
61 changes: 61 additions & 0 deletions tests/kohana/request/client/InternalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,65 @@ public function test_response_failure_status($directory, $controller, $action, $

$this->assertSame($expected, $response->status());
}

public function provider_controller_class()
{
return [
[
['directory' => NULL, 'controller' => 'Test', 'action' => 'anything'],
'Controller_Test',
'Controller_Test::anything'
],
[
['directory' => 'Subdir', 'controller' => 'Test', 'action' => 'anything'],
'Controller_Subdir_Test',
'Controller_Subdir_Test::anything'
],
[
['directory' => NULL, 'controller' => '\My\Test\Test', 'action' => 'things'],
'\My\Test\Test',
'My\Test\Test::things'
],
[
['directory' => NULL, 'controller' => '\My\Test\TestController', 'action' => 'things'],
'\My\Test\TestController',
'My\Test\TestController::things'
],

];
}

/**
* @dataProvider provider_controller_class
*/
public function test_it_executes_expected_controller_class($params, $controller_class, $expect)
{
if ( ! class_exists($controller_class)) {
$this->defineExtensionClass($controller_class, ClassReturningController::class);
}
$client = new Request_Client_Internal;
$request = \Request::with($params);
$response = $client->execute($request);
$this->assertEquals($expect, $response->body());
}

protected function defineExtensionClass($fqcn, $base_class)
{
$parts = array_filter(explode('\\', $fqcn));
$class = array_pop($parts);
$ns = implode('\\', $parts);
if ($ns) {
$ns = 'namespace '.$ns.';';
}
eval("$ns class $class extends \\$base_class {}");
}
}

class ClassReturningController extends Controller {

public function execute()
{
$this->response->body(get_class($this).'::'.$this->request->action());
return $this->response;
}
}

0 comments on commit 6dbd68f

Please sign in to comment.