Skip to content

Commit 3ddc3c3

Browse files
authored
Merge pull request #5703 from kenjis/fix-404Override
fix: 404 override controller does not output Response object body
2 parents fa6494f + ba7f5df commit 3ddc3c3

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

system/CodeIgniter.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,8 @@ public function setPath(string $path)
777777
* Now that everything has been setup, this method attempts to run the
778778
* controller method and make the script go. If it's not able to, will
779779
* show the appropriate Page Not Found error.
780+
*
781+
* @return ResponseInterface|string|void
780782
*/
781783
protected function startController()
782784
{
@@ -804,7 +806,7 @@ protected function startController()
804806
/**
805807
* Instantiates the controller class.
806808
*
807-
* @return mixed
809+
* @return Controller
808810
*/
809811
protected function createController()
810812
{
@@ -821,7 +823,7 @@ protected function createController()
821823
*
822824
* @param mixed $class
823825
*
824-
* @return mixed
826+
* @return false|ResponseInterface|string|void
825827
*/
826828
protected function runController($class)
827829
{
@@ -847,6 +849,8 @@ protected function display404errors(PageNotFoundException $e)
847849
{
848850
// Is there a 404 Override available?
849851
if ($override = $this->router->get404Override()) {
852+
$returned = null;
853+
850854
if ($override instanceof Closure) {
851855
echo $override($e->getMessage());
852856
} elseif (is_array($override)) {
@@ -857,13 +861,13 @@ protected function display404errors(PageNotFoundException $e)
857861
$this->method = $override[1];
858862

859863
$controller = $this->createController();
860-
$this->runController($controller);
864+
$returned = $this->runController($controller);
861865
}
862866

863867
unset($override);
864868

865869
$cacheConfig = new Cache();
866-
$this->gatherOutput($cacheConfig);
870+
$this->gatherOutput($cacheConfig, $returned);
867871
$this->sendResponse();
868872

869873
return;
@@ -891,7 +895,7 @@ protected function display404errors(PageNotFoundException $e)
891895
* Gathers the script output from the buffer, replaces some execution
892896
* time tag in the output and displays the debug toolbar, if required.
893897
*
894-
* @param mixed|null $returned
898+
* @param ResponseInterface|string|null $returned
895899
*/
896900
protected function gatherOutput(?Cache $cacheConfig = null, $returned = null)
897901
{

tests/_support/Controllers/Popcorn.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function index()
3030

3131
public function pop()
3232
{
33-
$this->respond('Oops', 567, 'Surprise');
33+
return $this->respond('Oops', 567, 'Surprise');
3434
}
3535

3636
public function popper()
@@ -40,12 +40,12 @@ public function popper()
4040

4141
public function weasel()
4242
{
43-
$this->respond('', 200);
43+
return $this->respond('', 200);
4444
}
4545

4646
public function oops()
4747
{
48-
$this->failUnauthorized();
48+
return $this->failUnauthorized();
4949
}
5050

5151
public function goaway()
@@ -72,12 +72,12 @@ public function cat()
7272

7373
public function json()
7474
{
75-
$this->respond(['answer' => 42]);
75+
return $this->respond(['answer' => 42]);
7676
}
7777

7878
public function xml()
7979
{
80-
$this->respond('<my><pet>cat</pet></my>');
80+
return $this->respond('<my><pet>cat</pet></my>');
8181
}
8282

8383
public function toindex()

tests/system/CodeIgniterTest.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,34 @@ public function testRun404Override()
9494
// Inject mock router.
9595
$routes = Services::routes();
9696
$routes->setAutoRoute(false);
97-
$routes->set404Override('Home::index');
97+
$routes->set404Override('Tests\Support\Controllers\Hello::index');
9898
$router = Services::router($routes, Services::request());
9999
Services::injectMock('router', $router);
100100

101101
ob_start();
102-
$this->codeigniter->useSafeOutput(true)->run();
102+
$this->codeigniter->useSafeOutput(true)->run($routes);
103103
$output = ob_get_clean();
104104

105-
$this->assertStringContainsString('Welcome to CodeIgniter', $output);
105+
$this->assertStringContainsString('Hello', $output);
106+
}
107+
108+
public function testRun404OverrideControllerReturnsResponse()
109+
{
110+
$_SERVER['argv'] = ['index.php', '/'];
111+
$_SERVER['argc'] = 2;
112+
113+
// Inject mock router.
114+
$routes = Services::routes();
115+
$routes->setAutoRoute(false);
116+
$routes->set404Override('Tests\Support\Controllers\Popcorn::pop');
117+
$router = Services::router($routes, Services::request());
118+
Services::injectMock('router', $router);
119+
120+
ob_start();
121+
$this->codeigniter->useSafeOutput(true)->run($routes);
122+
$output = ob_get_clean();
123+
124+
$this->assertStringContainsString('Oops', $output);
106125
}
107126

108127
public function testRun404OverrideByClosure()

0 commit comments

Comments
 (0)