Skip to content

Commit

Permalink
Merge pull request #6652 from kenjis/feat-disable-filters
Browse files Browse the repository at this point in the history
feat: add method to disable controller filters
  • Loading branch information
kenjis authored Oct 14, 2022
2 parents 16e2b14 + badbd22 commit cca6295
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 35 deletions.
91 changes: 56 additions & 35 deletions system/CodeIgniter.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ class CodeIgniter
*/
protected ?string $context = null;

/**
* Whether to enable Control Filters.
*/
protected bool $enableFilters = true;

/**
* Constructor.
*/
Expand Down Expand Up @@ -401,6 +406,14 @@ private function isWeb(): bool
return $this->context === 'web';
}

/**
* Disables Controller Filters.
*/
public function disableFilters(): void
{
$this->enableFilters = false;
}

/**
* Handles the main request logic and fires the controller.
*
Expand All @@ -415,35 +428,37 @@ protected function handleRequest(?RouteCollectionInterface $routes, Cache $cache

$uri = $this->determinePath();

// Start up the filters
$filters = Services::filters();

// If any filters were specified within the routes file,
// we need to ensure it's active for the current request
if ($routeFilter !== null) {
$multipleFiltersEnabled = config('Feature')->multipleFilters ?? false;
if ($multipleFiltersEnabled) {
$filters->enableFilters($routeFilter, 'before');
$filters->enableFilters($routeFilter, 'after');
} else {
// for backward compatibility
$filters->enableFilter($routeFilter, 'before');
$filters->enableFilter($routeFilter, 'after');
if ($this->enableFilters) {
// Start up the filters
$filters = Services::filters();

// If any filters were specified within the routes file,
// we need to ensure it's active for the current request
if ($routeFilter !== null) {
$multipleFiltersEnabled = config('Feature')->multipleFilters ?? false;
if ($multipleFiltersEnabled) {
$filters->enableFilters($routeFilter, 'before');
$filters->enableFilters($routeFilter, 'after');
} else {
// for backward compatibility
$filters->enableFilter($routeFilter, 'before');
$filters->enableFilter($routeFilter, 'after');
}
}
}

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

// If a ResponseInterface instance is returned then send it back to the client and stop
if ($possibleResponse instanceof ResponseInterface) {
return $returnResponse ? $possibleResponse : $possibleResponse->send();
}
// If a ResponseInterface instance is returned then send it back to the client and stop
if ($possibleResponse instanceof ResponseInterface) {
return $returnResponse ? $possibleResponse : $possibleResponse->send();
}

if ($possibleResponse instanceof Request) {
$this->request = $possibleResponse;
if ($possibleResponse instanceof Request) {
$this->request = $possibleResponse;
}
}

$returned = $this->startController();
Expand All @@ -470,22 +485,28 @@ protected function handleRequest(?RouteCollectionInterface $routes, Cache $cache
// so it can be used with the output.
$this->gatherOutput($cacheConfig, $returned);

$filters->setResponse($this->response);
if ($this->enableFilters) {
$filters = Services::filters();
$filters->setResponse($this->response);

// After filter debug toolbar requires 'total_execution'.
$this->totalTime = $this->benchmark->getElapsedTime('total_execution');
// After filter debug toolbar requires 'total_execution'.
$this->totalTime = $this->benchmark->getElapsedTime('total_execution');

// Run "after" filters
$this->benchmark->start('after_filters');
$response = $filters->run($uri, 'after');
$this->benchmark->stop('after_filters');
// Run "after" filters
$this->benchmark->start('after_filters');
$response = $filters->run($uri, 'after');
$this->benchmark->stop('after_filters');

if ($response instanceof ResponseInterface) {
$this->response = $response;
if ($response instanceof ResponseInterface) {
$this->response = $response;
}
}

// Skip unnecessary processing for special Responses.
if (! $response instanceof DownloadResponse && ! $response instanceof RedirectResponse) {
if (
! $this->response instanceof DownloadResponse
&& ! $this->response instanceof RedirectResponse
) {
// Cache it without the performance metrics replaced
// so that we can have live speed updates along the way.
// Must be run after filters to preserve the Response headers.
Expand Down
27 changes: 27 additions & 0 deletions tests/system/CodeIgniterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,33 @@ public function testControllersRunFilterByClassName()
$this->resetServices();
}

public function testDisableControllerFilters()
{
$_SERVER['argv'] = ['index.php', 'pages/about'];
$_SERVER['argc'] = 2;

$_SERVER['REQUEST_URI'] = '/pages/about';

// Inject mock router.
$routes = Services::routes();
$routes->add(
'pages/about',
static fn () => Services::incomingrequest()->getBody(),
['filter' => Customfilter::class]
);
$router = Services::router($routes, Services::incomingrequest());
Services::injectMock('router', $router);

ob_start();
$this->codeigniter->disableFilters();
$this->codeigniter->run();
$output = ob_get_clean();

$this->assertStringContainsString('', $output);

$this->resetServices();
}

public function testResponseConfigEmpty()
{
$_SERVER['argv'] = ['index.php', '/'];
Expand Down

0 comments on commit cca6295

Please sign in to comment.