Skip to content

Commit

Permalink
Merge pull request codeigniter4#8058 from kenjis/fix-filters-var-type
Browse files Browse the repository at this point in the history
fix: FilterTestTrait::getFilterCaller() does not support Filter classes as array
  • Loading branch information
kenjis committed Oct 21, 2023
2 parents 9e5cdd0 + 66b572a commit 4c09ca3
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 9 deletions.
5 changes: 3 additions & 2 deletions app/Config/Filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ class Filters extends BaseConfig
* Configures aliases for Filter classes to
* make reading things nicer and simpler.
*
* @var array<string, string>
* @phpstan-var array<string, class-string>
* @var array<string, array<int, string>|string> [filter_name => classname]
* or [filter_name => [classname1, classname2, ...]]
* @phpstan-var array<string, class-string|list<class-string>>
*/
public array $aliases = [
'csrf' => CSRF::class,
Expand Down
56 changes: 49 additions & 7 deletions system/Test/FilterTestTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,26 +132,68 @@ protected function getFilterCaller($filter, string $position): Closure
throw new RuntimeException("No filter found with alias '{$filter}'");
}

$filter = $this->filtersConfig->aliases[$filter];
$filterClasses = $this->filtersConfig->aliases[$filter];
}

// Get an instance
$filter = new $filter();
$filterClasses = (array) $filterClasses;
}

if (! $filter instanceof FilterInterface) {
throw FilterException::forIncorrectInterface(get_class($filter));
foreach ($filterClasses as $class) {
// Get an instance
$filter = new $class();

if (! $filter instanceof FilterInterface) {
throw FilterException::forIncorrectInterface(get_class($filter));
}
}

$request = clone $this->request;

if ($position === 'before') {
return static fn (?array $params = null) => $filter->before($request, $params);
return static function (?array $params = null) use ($filterClasses, $request) {
foreach ($filterClasses as $class) {
$filter = new $class();

$result = $filter->before($request, $params);

// @TODO The following logic is in Filters class.
// Should use Filters class.
if ($result instanceof RequestInterface) {
$request = $result;

continue;
}
if ($result instanceof ResponseInterface) {
return $result;
}
if (empty($result)) {
continue;
}
}

return $result;
};
}

$response = clone $this->response;

return static fn (?array $params = null) => $filter->after($request, $response, $params);
return static function (?array $params = null) use ($filterClasses, $request, $response) {
foreach ($filterClasses as $class) {
$filter = new $class();

$result = $filter->after($request, $response, $params);

// @TODO The following logic is in Filters class.
// Should use Filters class.
if ($result instanceof ResponseInterface) {
$response = $result;

continue;
}
}

return $result;
};
}

/**
Expand Down
12 changes: 12 additions & 0 deletions tests/system/Test/FilterTestTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace CodeIgniter\Test;

use CodeIgniter\HTTP\RequestInterface;
use Config\Services;
use Tests\Support\Filters\Customfilter;

/**
Expand Down Expand Up @@ -62,12 +63,23 @@ public function testGetCallerInvalidPosition(): void
$this->getFilterCaller('test-customfilter', 'banana');
}

public function testCallerSupportArray(): void
{
$this->filtersConfig->aliases['test-customfilter'] = [Customfilter::class];

$caller = $this->getFilterCaller('test-customfilter', 'before');
$result = $caller();

$this->assertSame('http://hellowworld.com', $result->getBody());
}

public function testCallerUsesClonedInstance(): void
{
$caller = $this->getFilterCaller('test-customfilter', 'before');
$result = $caller();

$this->assertSame('http://hellowworld.com', $result->getBody());
$this->assertNull(Services::response()->getBody());

$this->resetServices();
}
Expand Down

0 comments on commit 4c09ca3

Please sign in to comment.