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

[5.1] Added ability to reference actions via an array #11300

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
36 changes: 36 additions & 0 deletions src/Illuminate/Routing/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,12 @@ protected function addRoute($methods, $uri, $action)
*/
protected function createRoute($methods, $uri, $action)
{
// If the action is referenced as an array we will
// convert the array to a regular action string.
if ($this->actionIsReferencedAsArray($action)) {
$action = $this->convertToActionString($action);
}

// If the route is routing to a controller we will parse the route action into
// an acceptable array format before registering it and creating this route
// instance itself. We need to build the Closure that will call this out.
Expand Down Expand Up @@ -561,6 +567,36 @@ protected function mergeGroupAttributesIntoRoute($route)
$route->setAction($action);
}

/**
* Determine if action is referenced as an array.
*
* @param string|array $action
* @return bool
*/
private function actionIsReferencedAsArray($action)
{
if (! is_array($action)) {
return false;
}

list($class, $method) = each($action);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be replaced by $class = $action[0]; since $method is not used afterwards.


return class_exists($class);
}

/**
* Convert action array to action string.
*
* @param array $action
* @return string
*/
private function convertToActionString($action)
{
list($class, $method) = each($action);

return '\\'.$class.'@'.$method;
}

/**
* Determine if the action is routing to a controller.
*
Expand Down
11 changes: 8 additions & 3 deletions src/Illuminate/Routing/UrlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -568,15 +568,20 @@ protected function getRouteScheme($route)
/**
* Get the URL to a controller action.
*
* @param string $action
* @param mixed $parameters
* @param bool $absolute
* @param array|string $action
* @param mixed $parameters
* @param bool $absolute
* @return string
*
* @throws \InvalidArgumentException
*/
public function action($action, $parameters = [], $absolute = true)
{
if (is_array($action)) {
list($class, $method) = each($action);
$action = '\\'.$class.'@'.$method;
}

if ($this->rootNamespace && ! (strpos($action, '\\') === 0)) {
$action = $this->rootNamespace.'\\'.$action;
} else {
Expand Down
7 changes: 7 additions & 0 deletions tests/Routing/RoutingRedirectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ public function testAction()
$this->assertEquals('http://foo.com/bar', $response->getTargetUrl());
}

public function testActionAsArray()
{
$this->url->shouldReceive('action')->with([bar::class => 'index'], [])->andReturn('http://foo.com/bar');
$response = $this->redirect->action([bar::class => 'index']);
$this->assertEquals('http://foo.com/bar', $response->getTargetUrl());
}

public function testRoute()
{
$this->url->shouldReceive('route')->with('home')->andReturn('http://foo.com/bar');
Expand Down
7 changes: 7 additions & 0 deletions tests/Routing/RoutingRouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,13 @@ public function testControllerInspection()
$this->assertEquals('hello', $router->dispatch(Request::create('home/foo', 'GET'))->getContent());
}

public function testRouterActionReferencedAsArray()
{
$router = $this->getRouter();
$router->get('home/foo', [RouteTestInspectedControllerStub::class => 'getFoo']);
$this->assertEquals('hello', $router->dispatch(Request::create('home/foo', 'GET'))->getContent());
}

protected function getRouter()
{
return new Router(new Illuminate\Events\Dispatcher);
Expand Down