Skip to content

Commit 76b6aac

Browse files
committed
refactor: simplify handleRequest method in CodeIgniter
1 parent ad8526f commit 76b6aac

2 files changed

Lines changed: 124 additions & 49 deletions

File tree

system/CodeIgniter.php

Lines changed: 93 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -463,16 +463,66 @@ protected function handleRequest(?RouteCollectionInterface $routes, Cache $cache
463463

464464
$routeFilters = $this->tryToRouteIt($routes);
465465

466-
// $uri is URL-encoded.
466+
// Run "before" filters
467+
$possibleResponse = $this->applyFilters('before', $routeFilters);
468+
469+
// If a ResponseInterface instance is returned then send it back to the client and stop
470+
if ($possibleResponse instanceof ResponseInterface) {
471+
$this->outputBufferingEnd();
472+
473+
return $possibleResponse;
474+
}
475+
476+
$returned = $this->startController();
477+
478+
$this->serveResponse($cacheConfig, $returned);
479+
480+
// Run "after" filters
481+
$this->applyFilters('after');
482+
483+
// Execute controller attributes' after() methods AFTER framework filters
484+
if ((config('Routing')->useControllerAttributes ?? true) === true) { // @phpstan-ignore nullCoalesce.property
485+
$this->benchmark->start('route_attributes_after');
486+
$this->response = $this->router->executeAfterAttributes($this->request, $this->response);
487+
$this->benchmark->stop('route_attributes_after');
488+
}
489+
490+
// Skip unnecessary processing for special Responses.
491+
if (
492+
! $this->response instanceof DownloadResponse
493+
&& ! $this->response instanceof RedirectResponse
494+
) {
495+
// Save our current URI as the previous URI in the session
496+
// for safer, more accurate use with `previous_url()` helper function.
497+
$this->storePreviousURL(current_url(true));
498+
}
499+
500+
return $this->response;
501+
}
502+
503+
/**
504+
* Runs filters.
505+
*
506+
* @param string $position 'before' or 'after'
507+
* @param list<string>|string|null $routeFilters
508+
*/
509+
protected function applyFilters(string $position, $routeFilters = null): ?ResponseInterface
510+
{
511+
if (! $this->enableFilters) {
512+
return null;
513+
}
514+
467515
$uri = $this->request->getPath();
468516

469-
if ($this->enableFilters) {
470-
/** @var Filters $filters */
471-
$filters = service('filters');
517+
/** @var Filters $filters */
518+
$filters = service('filters');
472519

473-
// If any filters were specified within the routes file,
474-
// we need to ensure it's active for the current request
520+
if ($position === 'before') {
475521
if ($routeFilters !== null) {
522+
if (is_string($routeFilters)) {
523+
$routeFilters = [$routeFilters];
524+
}
525+
476526
$filters->enableFilters($routeFilters, 'before');
477527

478528
$oldFilterOrder = config(Feature::class)->oldFilterOrder ?? false; // @phpstan-ignore nullCoalesce.property
@@ -483,31 +533,51 @@ protected function handleRequest(?RouteCollectionInterface $routes, Cache $cache
483533
$filters->enableFilters($routeFilters, 'after');
484534
}
485535

486-
// Run "before" filters
487536
$this->benchmark->start('before_filters');
488537
$possibleResponse = $filters->run($uri, 'before');
489538
$this->benchmark->stop('before_filters');
490539

491-
// If a ResponseInterface instance is returned then send it back to the client and stop
492540
if ($possibleResponse instanceof ResponseInterface) {
493-
$this->outputBufferingEnd();
494-
495541
return $possibleResponse;
496542
}
497543

498544
if ($possibleResponse instanceof IncomingRequest || $possibleResponse instanceof CLIRequest) {
499545
$this->request = $possibleResponse;
500546
}
547+
548+
return null;
501549
}
502550

503-
$returned = $this->startController();
551+
// after position
552+
$filters->setResponse($this->response);
553+
554+
$this->benchmark->start('after_filters');
555+
$response = $filters->run($uri, 'after');
556+
$this->benchmark->stop('after_filters');
504557

558+
if ($response instanceof ResponseInterface) {
559+
$this->response = $response;
560+
}
561+
562+
return null;
563+
}
564+
565+
/**
566+
* Start the controller, run it, and gather output.
567+
*
568+
* @param mixed $returned
569+
*/
570+
protected function serveResponse(Cache $cacheConfig, $returned): void
571+
{
505572
// If startController returned a Response (from an attribute or Closure), use it
506573
if ($returned instanceof ResponseInterface) {
507-
$this->gatherOutput($cacheConfig, $returned);
574+
$this->handleCache($cacheConfig, $returned);
575+
576+
return;
508577
}
578+
509579
// Closure controller has run in startController().
510-
elseif (! is_callable($this->controller)) {
580+
if (! is_callable($this->controller)) {
511581
$controller = $this->createController();
512582

513583
if (! method_exists($controller, '_remap') && ! is_callable([$controller, $this->method], false)) {
@@ -526,43 +596,17 @@ protected function handleRequest(?RouteCollectionInterface $routes, Cache $cache
526596
// If $returned is a string, then the controller output something,
527597
// probably a view, instead of echoing it directly. Send it along
528598
// so it can be used with the output.
529-
$this->gatherOutput($cacheConfig, $returned);
530-
531-
if ($this->enableFilters) {
532-
/** @var Filters $filters */
533-
$filters = service('filters');
534-
$filters->setResponse($this->response);
535-
536-
// Run "after" filters
537-
$this->benchmark->start('after_filters');
538-
$response = $filters->run($uri, 'after');
539-
$this->benchmark->stop('after_filters');
540-
541-
if ($response instanceof ResponseInterface) {
542-
$this->response = $response;
543-
}
544-
}
545-
546-
// Execute controller attributes' after() methods AFTER framework filters
547-
if ((config('Routing')->useControllerAttributes ?? true) === true) { // @phpstan-ignore nullCoalesce.property
548-
$this->benchmark->start('route_attributes_after');
549-
$this->response = $this->router->executeAfterAttributes($this->request, $this->response);
550-
$this->benchmark->stop('route_attributes_after');
551-
}
552-
553-
// Skip unnecessary processing for special Responses.
554-
if (
555-
! $this->response instanceof DownloadResponse
556-
&& ! $this->response instanceof RedirectResponse
557-
) {
558-
// Save our current URI as the previous URI in the session
559-
// for safer, more accurate use with `previous_url()` helper function.
560-
$this->storePreviousURL(current_url(true));
561-
}
562-
563-
unset($uri);
599+
$this->handleCache($cacheConfig, $returned);
600+
}
564601

565-
return $this->response;
602+
/**
603+
* Gathers the script output and handles caching.
604+
*
605+
* @param mixed $returned
606+
*/
607+
protected function handleCache(Cache $cacheConfig, $returned): void
608+
{
609+
$this->gatherOutput($cacheConfig, $returned);
566610
}
567611

568612
/**

tests/system/CodeIgniterTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,4 +1309,35 @@ public function testResetForWorkerMode(): void
13091309
$this->assertSame($csp->getStyleNonce(), RichRenderer::$css_nonce);
13101310
$this->assertTrue(RichRenderer::$needs_pre_render);
13111311
}
1312+
1313+
public function testServeResponseCallsHandleCacheOnceForResponse(): void
1314+
{
1315+
$this->resetServices();
1316+
1317+
$superglobals = service('superglobals');
1318+
$superglobals->setServer('argv', ['index.php', 'pages/test']);
1319+
$superglobals->setServer('argc', 2);
1320+
$superglobals->setServer('REQUEST_URI', '/pages/test');
1321+
$superglobals->setServer('SCRIPT_NAME', '/index.php');
1322+
1323+
$routes = service('routes');
1324+
$routes->add('pages/test', static fn () => service('response')->setBody('Test Body'));
1325+
1326+
$config = new App();
1327+
$codeigniter = new class ($config) extends MockCodeIgniter {
1328+
public int $handleCacheCalls = 0;
1329+
1330+
protected function handleCache(Cache $cacheConfig, $returned): void
1331+
{
1332+
$this->handleCacheCalls++;
1333+
parent::handleCache($cacheConfig, $returned);
1334+
}
1335+
};
1336+
1337+
ob_start();
1338+
$codeigniter->run($routes);
1339+
ob_end_clean();
1340+
1341+
$this->assertSame(1, $codeigniter->handleCacheCalls);
1342+
}
13121343
}

0 commit comments

Comments
 (0)