Add logic to match redirect conditions based on query params or language

This commit is contained in:
Alejandro Celaya 2024-02-24 23:33:16 +01:00
parent 09e81b00c5
commit 7f83d37b3c
3 changed files with 39 additions and 3 deletions

View file

@ -26,7 +26,9 @@ use function print_r;
use function Shlinkio\Shlink\Common\buildDateRange;
use function sprintf;
use function str_repeat;
use function str_replace;
use function strtolower;
use function trim;
use function ucfirst;
function generateRandomShortCode(int $length, ShortUrlMode $mode = ShortUrlMode::STRICT): string
@ -74,6 +76,11 @@ function normalizeDate(string|DateTimeInterface|Chronos $date): Chronos
return normalizeOptionalDate($date);
}
function normalizeLocale(string $locale): string
{
return trim(strtolower(str_replace('_', '-', $locale)));
}
function getOptionalIntFromInputFilter(InputFilter $inputFilter, string $fieldName): ?int
{
$value = $inputFilter->getValue($fieldName);

View file

@ -2,9 +2,14 @@
namespace Shlinkio\Shlink\Core\RedirectRule\Entity;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Core\RedirectRule\Model\RedirectConditionType;
use function explode;
use function Shlinkio\Shlink\Core\ArrayUtils\some;
use function Shlinkio\Shlink\Core\normalizeLocale;
class RedirectCondition extends AbstractEntity
{
public function __construct(
@ -14,4 +19,28 @@ class RedirectCondition extends AbstractEntity
public readonly ?string $matchKey = null,
) {
}
/**
* Tells if this condition matches provided request
*/
public function matchesRequest(ServerRequestInterface $request): bool
{
if ($this->type === RedirectConditionType::QUERY_PARAM && $this->matchKey !== null) {
$query = $request->getQueryParams();
$queryValue = $query[$this->matchKey] ?? null;
return $queryValue === $this->matchValue;
}
if ($this->type === RedirectConditionType::LANGUAGE && $request->hasHeader('Accept-Language')) {
$acceptedLanguages = explode(',', $request->getHeaderLine('Accept-Language'));
$normalizedLanguage = normalizeLocale($this->matchValue);
return some(
$acceptedLanguages,
static fn (string $lang) => normalizeLocale($lang) === $normalizedLanguage,
);
}
return false;
}
}

View file

@ -4,7 +4,7 @@ namespace Shlinkio\Shlink\Core\RedirectRule\Model;
enum RedirectConditionType: string
{
case DEVICE = 'device';
// case LANGUAGE = 'language';
// case QUERY_PARAM = 'query';
// case DEVICE = 'device';
case LANGUAGE = 'language';
case QUERY_PARAM = 'query';
}