diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php index 853e135a5b53..c22a12257048 100644 --- a/system/Filters/Filters.php +++ b/system/Filters/Filters.php @@ -150,47 +150,59 @@ public function run(string $uri, string $position = 'before') throw FilterException::forNoAlias($alias); } - $class = new $this->config->aliases[$alias](); - - if (! $class instanceof FilterInterface) + if (is_array($this->config->aliases[$alias])) + { + $classNames = $this->config->aliases[$alias]; + } + else { - throw FilterException::forIncorrectInterface(get_class($class)); + $classNames = [$this->config->aliases[$alias]]; } - if ($position === 'before') + foreach ($classNames as $className) { - $result = $class->before($this->request, $this->arguments[$alias] ?? null); + $class = new $className(); - if ($result instanceof RequestInterface) + if (! $class instanceof FilterInterface) { - $this->request = $result; - continue; + throw FilterException::forIncorrectInterface(get_class($class)); } - // If the response object was sent back, - // then send it and quit. - if ($result instanceof ResponseInterface) + if ($position === 'before') { - // short circuit - bypass any other filters - return $result; - } + $result = $class->before($this->request, $this->arguments[$alias] ?? null); - // Ignore an empty result - if (empty($result)) - { - continue; - } + if ($result instanceof RequestInterface) + { + $this->request = $result; + continue; + } - return $result; - } - elseif ($position === 'after') - { - $result = $class->after($this->request, $this->response); + // If the response object was sent back, + // then send it and quit. + if ($result instanceof ResponseInterface) + { + // short circuit - bypass any other filters + return $result; + } + + // Ignore an empty result + if (empty($result)) + { + continue; + } - if ($result instanceof ResponseInterface) + return $result; + } + elseif ($position === 'after') { - $this->response = $result; - continue; + $result = $class->after($this->request, $this->response); + + if ($result instanceof ResponseInterface) + { + $this->response = $result; + continue; + } } } } diff --git a/tests/system/Filters/FiltersTest.php b/tests/system/Filters/FiltersTest.php index d8f16ffd246b..6601cc422646 100644 --- a/tests/system/Filters/FiltersTest.php +++ b/tests/system/Filters/FiltersTest.php @@ -11,6 +11,8 @@ require_once __DIR__ . '/fixtures/GoogleEmpty.php'; require_once __DIR__ . '/fixtures/GoogleCurious.php'; require_once __DIR__ . '/fixtures/InvalidClass.php'; +require_once __DIR__ . '/fixtures/Multiple1.php'; +require_once __DIR__ . '/fixtures/Multiple2.php'; /** * @backupGlobals enabled @@ -832,4 +834,30 @@ public function testSegmentedFilterMatching() $this->assertEquals($expected, $filters->initialize($uri)->getFilters()); } + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/2831 + */ + public function testFilterAlitasMultiple() + { + $config = [ + 'aliases' => [ + 'multipeTest' => [ + 'CodeIgniter\Filters\fixtures\Multiple1', + 'CodeIgniter\Filters\fixtures\Multiple2', + ], + ], + 'globals' => [ + 'before' => [ + 'multipeTest', + ], + ], + ]; + $filters = new Filters((object) $config, $this->request, $this->response); + $uri = 'admin/foo/bar'; + + $request = $filters->run($uri, 'before'); + $this->assertEquals('http://exampleMultipleURL.com', $request->url); + $this->assertEquals('http://exampleMultipleCSP.com', $request->csp); + } + } diff --git a/tests/system/Filters/fixtures/Multiple1.php b/tests/system/Filters/fixtures/Multiple1.php new file mode 100644 index 000000000000..d6788554cc43 --- /dev/null +++ b/tests/system/Filters/fixtures/Multiple1.php @@ -0,0 +1,20 @@ +csp = 'http://exampleMultipleCSP.com'; + return $request; + } + + public function after(RequestInterface $request, ResponseInterface $response) + { + } + +} diff --git a/tests/system/Filters/fixtures/Multiple2.php b/tests/system/Filters/fixtures/Multiple2.php new file mode 100644 index 000000000000..61ca1a3e7150 --- /dev/null +++ b/tests/system/Filters/fixtures/Multiple2.php @@ -0,0 +1,20 @@ +url = 'http://exampleMultipleURL.com'; + return $request; + } + + public function after(RequestInterface $request, ResponseInterface $response) + { + } + +}