Skip to content

Commit 6553e33

Browse files
themsaidtaylorotwell
authored andcommitted
[5.4] Bring back an old behaviour in resolving controller method dependencies (#18646)
* bring back the old behaviour while fixing the issue * fix style * fix test to make more sense * fix test to make more sense * cover the scenarios with tests * fix style * add test to cover model bindings * fix style * clean tests
1 parent acc5feb commit 6553e33

File tree

2 files changed

+123
-25
lines changed

2 files changed

+123
-25
lines changed

src/Illuminate/Routing/RouteDependencyResolverTrait.php

+20-7
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ protected function resolveClassMethodDependencies(array $parameters, $instance,
3737
*/
3838
public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
3939
{
40-
$results = [];
41-
4240
$instanceCount = 0;
4341

4442
$values = array_values($parameters);
@@ -51,14 +49,14 @@ public function resolveMethodDependencies(array $parameters, ReflectionFunctionA
5149
if (! is_null($instance)) {
5250
$instanceCount++;
5351

54-
$results[$parameter->getName()] = $instance;
55-
} else {
56-
$results[$parameter->getName()] = isset($values[$key - $instanceCount])
57-
? $values[$key - $instanceCount] : $parameter->getDefaultValue();
52+
$this->spliceIntoParameters($parameters, $key, $instance);
53+
} elseif (! isset($values[$key - $instanceCount]) &&
54+
$parameter->isDefaultValueAvailable()) {
55+
$this->spliceIntoParameters($parameters, $key, $parameter->getDefaultValue());
5856
}
5957
}
6058

61-
return $results;
59+
return $parameters;
6260
}
6361

6462
/**
@@ -93,4 +91,19 @@ protected function alreadyInParameters($class, array $parameters)
9391
return $value instanceof $class;
9492
}));
9593
}
94+
95+
/**
96+
* Splice the given value into the parameter list.
97+
*
98+
* @param array $parameters
99+
* @param string $offset
100+
* @param mixed $value
101+
* @return void
102+
*/
103+
protected function spliceIntoParameters(array &$parameters, $offset, $value)
104+
{
105+
array_splice(
106+
$parameters, $offset, 0, [$value]
107+
);
108+
}
96109
}

tests/Routing/RoutingRouteTest.php

+103-18
Original file line numberDiff line numberDiff line change
@@ -309,24 +309,6 @@ public function testClassesCanBeInjectedIntoRoutes()
309309
unset($_SERVER['__test.route_inject']);
310310
}
311311

312-
public function testClassesAndVariablesCanBeInjectedIntoRoutes()
313-
{
314-
unset($_SERVER['__test.route_inject']);
315-
$router = $this->getRouter();
316-
$router->get('foo/{var}/{bar?}/{baz?}', function (stdClass $foo, $var, $bar = 'test', stdClass $baz = null) {
317-
$_SERVER['__test.route_inject'] = func_get_args();
318-
319-
return 'hello';
320-
});
321-
$this->assertEquals('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());
322-
$this->assertInstanceOf('stdClass', $_SERVER['__test.route_inject'][0]);
323-
$this->assertEquals('bar', $_SERVER['__test.route_inject'][1]);
324-
$this->assertEquals('test', $_SERVER['__test.route_inject'][2]);
325-
$this->assertInstanceOf('stdClass', $_SERVER['__test.route_inject'][3]);
326-
$this->assertArrayHasKey(3, $_SERVER['__test.route_inject']);
327-
unset($_SERVER['__test.route_inject']);
328-
}
329-
330312
public function testOptionsResponsesAreGeneratedByDefault()
331313
{
332314
$router = $this->getRouter();
@@ -420,6 +402,56 @@ public function testRouteParametersDefaultValue()
420402
$this->assertEquals('foo', $router->dispatch(Request::create('foo', 'GET'))->getContent());
421403
}
422404

405+
public function testControllerCallActionMethodParameters()
406+
{
407+
$router = $this->getRouter();
408+
409+
// Has one argument but receives two
410+
unset($_SERVER['__test.controller_callAction_parameters']);
411+
$router->get(($str = str_random()).'/{one}/{two}', 'Illuminate\Tests\Routing\RouteTestAnotherControllerWithParameterStub@oneArgument');
412+
$router->dispatch(Request::create($str.'/one/two', 'GET'));
413+
$this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);
414+
415+
// Has two arguments and receives two
416+
unset($_SERVER['__test.controller_callAction_parameters']);
417+
$router->get(($str = str_random()).'/{one}/{two}', 'Illuminate\Tests\Routing\RouteTestAnotherControllerWithParameterStub@twoArguments');
418+
$router->dispatch(Request::create($str.'/one/two', 'GET'));
419+
$this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);
420+
421+
// Has two arguments but with different names from the ones passed from the route
422+
unset($_SERVER['__test.controller_callAction_parameters']);
423+
$router->get(($str = str_random()).'/{one}/{two}', 'Illuminate\Tests\Routing\RouteTestAnotherControllerWithParameterStub@differentArgumentNames');
424+
$router->dispatch(Request::create($str.'/one/two', 'GET'));
425+
$this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);
426+
427+
// Has two arguments with same name but argument order is reversed
428+
unset($_SERVER['__test.controller_callAction_parameters']);
429+
$router->get(($str = str_random()).'/{one}/{two}', 'Illuminate\Tests\Routing\RouteTestAnotherControllerWithParameterStub@reversedArguments');
430+
$router->dispatch(Request::create($str.'/one/two', 'GET'));
431+
$this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);
432+
433+
// No route parameters while method has parameters
434+
unset($_SERVER['__test.controller_callAction_parameters']);
435+
$router->get(($str = str_random()).'', 'Illuminate\Tests\Routing\RouteTestAnotherControllerWithParameterStub@oneArgument');
436+
$router->dispatch(Request::create($str, 'GET'));
437+
$this->assertEquals([], $_SERVER['__test.controller_callAction_parameters']);
438+
439+
// With model bindings
440+
unset($_SERVER['__test.controller_callAction_parameters']);
441+
$router->get(($str = str_random()).'/{user}/{defaultNull?}/{team?}', [
442+
'middleware' => SubstituteBindings::class,
443+
'uses' => 'Illuminate\Tests\Routing\RouteTestAnotherControllerWithParameterStub@withModels',
444+
]);
445+
$router->dispatch(Request::create($str.'/1', 'GET'));
446+
447+
$values = array_values($_SERVER['__test.controller_callAction_parameters']);
448+
449+
$this->assertInstanceOf('Illuminate\Http\Request', $values[0]);
450+
$this->assertEquals(1, $values[1]->value);
451+
$this->assertNull($values[2]);
452+
$this->assertInstanceOf('Illuminate\Tests\Routing\RoutingTestTeamModel', $values[3]);
453+
}
454+
423455
/**
424456
* @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
425457
*/
@@ -1293,6 +1325,34 @@ public function returnParameter($bar = '')
12931325
}
12941326
}
12951327

1328+
class RouteTestAnotherControllerWithParameterStub extends Controller
1329+
{
1330+
public function callAction($method, $parameters)
1331+
{
1332+
$_SERVER['__test.controller_callAction_parameters'] = $parameters;
1333+
}
1334+
1335+
public function oneArgument($one)
1336+
{
1337+
}
1338+
1339+
public function twoArguments($one, $two)
1340+
{
1341+
}
1342+
1343+
public function differentArgumentNames($bar, $baz)
1344+
{
1345+
}
1346+
1347+
public function reversedArguments($two, $one)
1348+
{
1349+
}
1350+
1351+
public function withModels(Request $request, RoutingTestUserModel $user, $defaultNull = null, RoutingTestTeamModel $team = null)
1352+
{
1353+
}
1354+
}
1355+
12961356
class RouteTestResourceControllerWithModelParameter extends Controller
12971357
{
12981358
public function show(RoutingTestUserModel $fooBar)
@@ -1471,6 +1531,31 @@ public function firstOrFail()
14711531
}
14721532
}
14731533

1534+
class RoutingTestTeamModel extends Model
1535+
{
1536+
public function getRouteKeyName()
1537+
{
1538+
return 'id';
1539+
}
1540+
1541+
public function where($key, $value)
1542+
{
1543+
$this->value = $value;
1544+
1545+
return $this;
1546+
}
1547+
1548+
public function first()
1549+
{
1550+
return $this;
1551+
}
1552+
1553+
public function firstOrFail()
1554+
{
1555+
return $this;
1556+
}
1557+
}
1558+
14741559
class RoutingTestExtendedUserModel extends RoutingTestUserModel
14751560
{
14761561
}

0 commit comments

Comments
 (0)