Make RedirectCondition->matchValue nullable

This commit is contained in:
Alejandro Celaya
2025-07-22 08:20:21 +02:00
parent 56df880a93
commit 5b5d0aae49
10 changed files with 66 additions and 33 deletions

View File

@@ -26,7 +26,7 @@ class RedirectCondition extends AbstractEntity implements JsonSerializable
{
private function __construct(
public readonly RedirectConditionType $type,
private readonly string $matchValue,
private readonly string|null $matchValue = null,
private readonly string|null $matchKey = null,
) {
}
@@ -38,12 +38,12 @@ class RedirectCondition extends AbstractEntity implements JsonSerializable
public static function forAnyValueQueryParam(string $param): self
{
return new self(RedirectConditionType::ANY_VALUE_QUERY_PARAM, $param);
return new self(RedirectConditionType::ANY_VALUE_QUERY_PARAM, matchKey: $param);
}
public static function forValuelessQueryParam(string $param): self
{
return new self(RedirectConditionType::VALUELESS_QUERY_PARAM, $param);
return new self(RedirectConditionType::VALUELESS_QUERY_PARAM, matchKey: $param);
}
public static function forLanguage(string $language): self
@@ -131,19 +131,19 @@ class RedirectCondition extends AbstractEntity implements JsonSerializable
private function matchesValuelessQueryParam(ServerRequestInterface $request): bool
{
$query = $request->getQueryParams();
return array_key_exists($this->matchValue, $query) && empty($query[$this->matchValue]);
return $this->matchKey !== null && array_key_exists($this->matchKey, $query) && empty($query[$this->matchKey]);
}
private function matchesAnyValueQueryParam(ServerRequestInterface $request): bool
{
$query = $request->getQueryParams();
return array_key_exists($this->matchValue, $query);
return $this->matchKey !== null && array_key_exists($this->matchKey, $query);
}
private function matchesLanguage(ServerRequestInterface $request): bool
{
$acceptLanguage = trim($request->getHeaderLine('Accept-Language'));
if ($acceptLanguage === '' || $acceptLanguage === '*') {
if ($acceptLanguage === '' || $acceptLanguage === '*' || $this->matchValue === null) {
return false;
}
@@ -173,13 +173,17 @@ class RedirectCondition extends AbstractEntity implements JsonSerializable
private function matchesRemoteIpAddress(ServerRequestInterface $request): bool
{
$remoteAddress = ipAddressFromRequest($request);
return $remoteAddress !== null && IpAddressUtils::ipAddressMatchesGroups($remoteAddress, [$this->matchValue]);
return (
$this->matchValue !== null
&& $remoteAddress !== null
&& IpAddressUtils::ipAddressMatchesGroups($remoteAddress, [$this->matchValue])
);
}
private function matchesGeolocationCountryCode(ServerRequestInterface $request): bool
{
$geolocation = geolocationFromRequest($request);
if ($geolocation === null) {
if ($geolocation === null || $this->matchValue === null) {
return false;
}
@@ -189,7 +193,7 @@ class RedirectCondition extends AbstractEntity implements JsonSerializable
private function matchesGeolocationCityName(ServerRequestInterface $request): bool
{
$geolocation = geolocationFromRequest($request);
if ($geolocation === null) {
if ($geolocation === null || $this->matchValue === null) {
return false;
}

View File

@@ -31,11 +31,7 @@ enum RedirectConditionType: string
// RedirectConditionType::LANGUAGE => TODO Validate at least format,
RedirectConditionType::IP_ADDRESS => IpAddressUtils::isStaticIpCidrOrWildcard($value),
RedirectConditionType::GEOLOCATION_COUNTRY_CODE => contains($value, ISO_COUNTRY_CODES),
RedirectConditionType::QUERY_PARAM,
RedirectConditionType::ANY_VALUE_QUERY_PARAM,
RedirectConditionType::VALUELESS_QUERY_PARAM => $value !== '',
// FIXME We should at least validate the value is not empty
// default => $value !== '',
RedirectConditionType::QUERY_PARAM => $value !== '',
default => true,
};
}

View File

@@ -75,7 +75,7 @@ class RedirectRulesInputFilter extends InputFilter
]));
$redirectConditionInputFilter->add($type);
$value = InputFactory::basic(self::CONDITION_MATCH_VALUE, required: true);
$value = InputFactory::basic(self::CONDITION_MATCH_VALUE, required: true)->setAllowEmpty(true);
$value->getValidatorChain()->attach(new Callback(
function (string $value, array $context): bool {
$conditionType = RedirectConditionType::tryFrom($context[self::CONDITION_TYPE]);