diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index f497a8c4cdb4..5a84baa7fc4a 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -18,6 +18,10 @@ use CodeIgniter\Exceptions\LogicException; use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\Filters\Filters; +use CodeIgniter\HTTP\Attributes\ParamSource\BaseParamSourceAttribute; +use CodeIgniter\HTTP\Attributes\ParamSource\Cookie; +use CodeIgniter\HTTP\Attributes\ParamSource\Header; +use CodeIgniter\HTTP\Attributes\ParamSource\Query; use CodeIgniter\HTTP\CLIRequest; use CodeIgniter\HTTP\Exceptions\FormRequestException; use CodeIgniter\HTTP\Exceptions\RedirectException; @@ -728,7 +732,32 @@ private function resolveCallableParams(ReflectionFunctionAbstract $reflection, a $resolved = []; $routeIndex = 0; + $request = service('request'); + foreach ($reflection->getParameters() as $param) { + $attrs = $param->getAttributes(); + + if (count($attrs) > 0) { + foreach ($attrs as $attr) { + $instance = $attr->newInstance(); + + if (! $instance instanceof BaseParamSourceAttribute) { + continue; + } + + $key = $instance->getKey($param->getName()); + + $resolved[] = match (true) { + $instance instanceof Query => $request->getGet($key), + $instance instanceof Header => $request->getHeaderLine($key), + $instance instanceof Cookie => $request->getCookie($key), + default => throw new LogicException('Unsupported parameter attribute: ' . $instance::class), + }; + + continue 2; + } + } + [$kind, $formRequestClass] = CallableParamClassifier::classify($param); switch ($kind) { diff --git a/system/HTTP/Attributes/ParamSource/BaseParamSourceAttribute.php b/system/HTTP/Attributes/ParamSource/BaseParamSourceAttribute.php new file mode 100644 index 000000000000..e3e1afb6037b --- /dev/null +++ b/system/HTTP/Attributes/ParamSource/BaseParamSourceAttribute.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\HTTP\Attributes\ParamSource; + +abstract class BaseParamSourceAttribute +{ + public function __construct(private readonly ?string $key = null) + { + } + + public function getKey(string $paramName): string + { + return $this->key ?? $paramName; + } +} diff --git a/system/HTTP/Attributes/ParamSource/Cookie.php b/system/HTTP/Attributes/ParamSource/Cookie.php new file mode 100644 index 000000000000..ab440bd654a5 --- /dev/null +++ b/system/HTTP/Attributes/ParamSource/Cookie.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\HTTP\Attributes\ParamSource; + +use Attribute; + +#[Attribute(Attribute::TARGET_PARAMETER)] +class Cookie extends BaseParamSourceAttribute +{ +} diff --git a/system/HTTP/Attributes/ParamSource/Header.php b/system/HTTP/Attributes/ParamSource/Header.php new file mode 100644 index 000000000000..e249d0e94ae5 --- /dev/null +++ b/system/HTTP/Attributes/ParamSource/Header.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\HTTP\Attributes\ParamSource; + +use Attribute; + +#[Attribute(Attribute::TARGET_PARAMETER)] +class Header extends BaseParamSourceAttribute +{ +} diff --git a/system/HTTP/Attributes/ParamSource/Query.php b/system/HTTP/Attributes/ParamSource/Query.php new file mode 100644 index 000000000000..cf5f37308860 --- /dev/null +++ b/system/HTTP/Attributes/ParamSource/Query.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\HTTP\Attributes\ParamSource; + +use Attribute; + +#[Attribute(Attribute::TARGET_PARAMETER)] +class Query extends BaseParamSourceAttribute +{ +}