8000 Handle case of static controller method and controllers using magic _… · symfony/symfony@e477a2e · GitHub
[go: up one dir, main page]

Skip to content

Commit e477a2e

Browse files
DerManoMannfabpot
DerManoMann
authored andcommitted
Handle case of static controller method and controllers using magic __call() method
1 parent 5aa6788 commit e477a2e

File tree

2 files changed

+147
-7
lines changed

2 files changed

+147
-7
lines changed

src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,25 @@ public function collect(Request $request, Response $response, \Exception $except
9898
if (isset($this->controllers[$request])) {
9999
$controller = $this->controllers[$request];
100100
if (is_array($controller)) {
101-
$r = new \ReflectionMethod($controller[0], $controller[1]);
102-
$this->data['controller'] = array(
103-
'class' => get_class($controller[0]),
104-
'method' => $controller[1],
105-
'file' => $r->getFilename(),
106-
'line' => $r->getStartLine(),
107-
);
101+
try {
102+
$r = new \ReflectionMethod($controller[0], $controller[1]);
103+
$this->data['controller'] = array(
104+
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
105+
'method' => $controller[1],
106+
'file' => $r->getFilename(),
107+
'line' => $r->getStartLine(),
108+
);
109+
} catch (\ReflectionException $re) {
110+
if (is_callable($controller)) {
111+
// using __call or __callStatic
112+
$this->data['controller'] = array(
113+
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
114+
'method' => $controller[1],
115+
'file' => 'n/a',
116+
'line' => 'n/a',
117+
);
118+
}
119+
}
108120
} elseif ($controller instanceof \Closure) {
109121
$this->data['controller'] = 'Closure';
110122
} else {

src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@
1111

1212
namespace Symfony\Component\HttpKernel\Tests\DataCollector;
1313

14+
use Symfony\Component\HttpKernel\HttpKernel;
15+
use Symfony\Component\HttpKernel\HttpKernelInterface;
1416
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
17+
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
1518
use Symfony\Component\HttpFoundation\Request;
1619
use Symfony\Component\HttpFoundation\Response;
1720
use Symfony\Component\HttpFoundation\Cookie;
21+
use Symfony\Component\EventDispatcher\EventDispatcher;
1822

1923
class RequestDataCollectorTest extends \PHPUnit_Framework_TestCase
2024
{
@@ -50,6 +54,95 @@ public function testCollect(Request $request, Response $response)
5054
$this->assertEquals('application/json',$c->getContentType());
5155
}
5256

57+
/**
58+
* Test various types of controller callables.
59+
*
60+
* @dataProvider provider
61+
*/
62+
public function testControllerInspection(Request $request, Response $response)
63+
{
64+
// make sure we always match the line number
65+
$r1 = new \ReflectionMethod($this, 'testControllerInspection');
66+
$r2 = new \ReflectionMethod($this, 'staticControllerMethod');
67+
// test name, callable, expected
68+
$controllerTests = array(
69+
array(
70+
'"Regular" callable',
71+
array($this, 'testControllerInspection'),
72+
array(
73+
'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
74+
'method' => 'testControllerInspection',
75+
'file' => __FILE__,
76+
'line' => $r1->getStartLine()
77+
),
78+
),
79+
80+
array(
81+
'Closure',
82+
function() { return 'foo'; },
83+
'Closure',
84+
),
85+
86+
array(
87+
'Static callback as string',
88+
'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest::staticControllerMethod',
89+
'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest::staticControllerMethod',
90+
),
91+
92+
array(
93+
'Static callable with instance',
94+
array($this, 'staticControllerMethod'),
95+
array(
96+
'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
97+
'method' => 'staticControllerMethod',
98+
'file' => __FILE__,
99+
'line' => $r2->getStartLine()
100+
),
101+
),
102+
103+
array(
104+
'Static callable with class name',
105+
array('Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest', 'staticControllerMethod'),
106+
array(
107+
'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
108+
'method' => 'staticControllerMethod',
109+
'file' => __FILE__,
110+
'line' => $r2->getStartLine()
111+
),
112+
),
113+
114+
array(
115+
'Callable with instance depending on __call()',
116+
array($this, 'magicMethod'),
117+
array(
118+
'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
119+
'method' => 'magicMethod',
120+
'file' => 'n/a',
121+
'line' => 'n/a'
122+
),
123+
),
124+
125+
array(
126+
'Callable with class name depending on __callStatic()',
127+
array('Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest', 'magicMethod'),
128+
array(
129+
'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
130+
'method' => 'magicMethod',
131+
'file' => 'n/a',
132+
'line' => 'n/a'
133+
),
134+
),
135+
);
136+
137+
$c = new RequestDataCollector();
138+
139+
foreach ($controllerTests as $controllerTest) {
140+
$this->injectController($c, $controllerTest[1], $request);
141+
$c->collect($request, $response);
142+
$this->assertEquals($controllerTest[2], $c->getController(), sprintf('Testing: %s', $controllerTest[0]));
143+
}
144+
}
145+
53146
public function provider()
54147
{
55148
if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
@@ -71,4 +164,39 @@ public function provider()
71164
);
72165
}
73166

167+
/**
168+
* Inject the given controller callable into the data collector.
169+
*/
170+
protected function injectController($collector, $controller, $request)
171+
{
172+
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
173+
$httpKernel = new HttpKernel(new EventDispatcher(), $resolver);
174+
$event = new FilterControllerEvent($httpKernel, $controller, $request, HttpKernelInterface::MASTER_REQUEST);
175+
$collector->onKernelController($event);
176+
}
177+
178+
/**
179+
* Dummy method used as controller callable
180+
*/
181+
public static function staticControllerMethod()
182+
{
183+
throw new \LogicException('Unexpected method call');
184+
}
185+
186+
/**
187+
* Magic method to allow non existing methods to be called and delegated.
188+
*/
189+
public function __call($method, $args)
190+
{
191+
throw new \LogicException('Unexpected method call');
192+
}
193+
194+
/**
195+
* Magic method to allow non existing methods to be called and delegated.
196+
*/
197+
public static function __callStatic($method, $args)
198+
{
199+
throw new \LogicException('Unexpected method call');
200+
}
201+
74202
}

0 commit comments

Comments
 (0)
0