<?php
namespace App\Services;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\Filters as CoreFilters;
use Config\Modules;
class Filters extends CoreFilters
{
public function __construct($config, RequestInterface $request, ResponseInterface $response, ?Modules $modules = null) {
parent::__construct($config, $request, $response, $modules);
}
/**
* @param string|null $uri
*/
protected function processGlobals(?string $uri = null) {
if (!isset($this->config->globals) || !is_array($this->config->globals)) {
return;
}
$uri = strtolower(trim($uri ?? '', '/ '));
// Add any global filters, unless they are excluded for this URI
$sets = [
'before',
'after'
];
foreach ($sets as $set) {
if (isset($this->config->globals[$set])) {
// look at each alias in the group
foreach ($this->config->globals[$set] as $alias => $rules) {
$keep = true;
if (is_array($rules)) {
// see if it should be excluded
if (isset($rules['except'])) {
// grab the exclusion rules
$check = $rules['except'];
if ($this->pathApplies($uri, $check)) {
$keep = false;
}
}
} else {
$alias = $rules; // simple name of filter to apply
}
if ($keep) {
$this->filters[$set][] = $alias;
}
}
}
}
}
/**
* @param string|null $uri
*/
protected function processFilters(?string $uri = null) {
if (!isset($this->config->filters) || !$this->config->filters) {
return;
}
$uri = strtolower(trim($uri, '/ '));
// Add any filters that apply to this URI
foreach ($this->config->filters as $alias => $settings) {
// Look for inclusion rules
if (isset($settings['before'])) {
$path = $settings['before'];
if ($this->pathApplies($uri, $path)) {
$this->filters['before'][] = $alias;
}
}
if (isset($settings['after'])) {
$path = $settings['after'];
if ($this->pathApplies($uri, $path)) {
$this->filters['after'][] = $alias;
}
}
}
}
/**
* @param string $uri
* @param mixed $paths
* @return bool
*/
private function pathApplies(string $uri, $paths): bool {
// empty path matches all
if (empty($paths)) {
return true;
}
// make sure the paths are iterable
if (is_string($paths)) {
$paths = [$paths];
}
// treat each paths as pseudo-regex
foreach ($paths as $path) {
// Reset localeSegment
$localeSegment = null;
$path = trim($path, '/ ');
// Are we dealing with a locale?
if (strpos($path, '{locale}') !== false) {
$localeSegment = array_search('{locale}', preg_split('/[\/]*((^[a-zA-Z0-9])|\(([^()]*)\))*[\/]+/m', $path), true);
}
// need to escape path separators
$path = str_replace('/', '\/', $path);
// need to make pseudo wildcard real
$path = strtolower(str_replace('*', '.*', $path));
if (isset($localeSegment)) {
// Replace it with a regex so it
// will actually match.
$path = str_replace('{locale}', '[^\/]+', $path);
}
// Does this rule apply here?
if (preg_match('#^' . $path . '$#', $uri, $match) === 1) {
if (isset($localeSegment)) {
$temp = (explode('/', $uri));
$supportedLocales = config('App')->supportedLocales;
if (in_array($temp[$localeSegment], $supportedLocales)) {
return true;
}
} else {
return true;
}
}
}
return false;
}
}