Allow short URLs list to be filtered by domain authority

This commit is contained in:
Alejandro Celaya
2024-10-28 09:27:33 +01:00
parent 525a306ec6
commit bb270396b6
9 changed files with 83 additions and 25 deletions

View File

@@ -19,17 +19,18 @@ final class ShortUrlsParams
private function __construct(
public readonly int $page,
public readonly int $itemsPerPage,
public readonly ?string $searchTerm,
public readonly string|null $searchTerm,
public readonly array $tags,
public readonly Ordering $orderBy,
public readonly ?DateRange $dateRange,
public readonly bool $excludeMaxVisitsReached,
public readonly bool $excludePastValidUntil,
public readonly TagsMode $tagsMode = TagsMode::ANY,
public readonly string|null $domain = null,
) {
}
public static function emptyInstance(): self
public static function empty(): self
{
return self::fromRawData([]);
}
@@ -59,6 +60,7 @@ final class ShortUrlsParams
excludeMaxVisitsReached: $inputFilter->getValue(ShortUrlsParamsInputFilter::EXCLUDE_MAX_VISITS_REACHED),
excludePastValidUntil: $inputFilter->getValue(ShortUrlsParamsInputFilter::EXCLUDE_PAST_VALID_UNTIL),
tagsMode: self::resolveTagsMode($inputFilter->getValue(ShortUrlsParamsInputFilter::TAGS_MODE)),
domain: $inputFilter->getValue(ShortUrlsParamsInputFilter::DOMAIN),
);
}

View File

@@ -26,6 +26,7 @@ class ShortUrlsParamsInputFilter extends InputFilter
public const ORDER_BY = 'orderBy';
public const EXCLUDE_MAX_VISITS_REACHED = 'excludeMaxVisitsReached';
public const EXCLUDE_PAST_VALID_UNTIL = 'excludePastValidUntil';
public const DOMAIN = 'domain';
public function __construct(array $data)
{
@@ -56,5 +57,7 @@ class ShortUrlsParamsInputFilter extends InputFilter
$this->add(InputFactory::boolean(self::EXCLUDE_MAX_VISITS_REACHED));
$this->add(InputFactory::boolean(self::EXCLUDE_PAST_VALID_UNTIL));
$this->add(InputFactory::basic(self::DOMAIN));
}
}

View File

@@ -44,6 +44,7 @@ class ShortUrlsCountFiltering
$params->excludePastValidUntil,
$apiKey,
$defaultDomain,
$params->domain,
);
}
}

View File

@@ -23,7 +23,9 @@ class ShortUrlsListFiltering extends ShortUrlsCountFiltering
bool $excludeMaxVisitsReached = false,
bool $excludePastValidUntil = false,
?ApiKey $apiKey = null,
// Used only to determine if search term includes default domain
?string $defaultDomain = null,
?string $domain = null,
) {
parent::__construct(
$searchTerm,
@@ -34,6 +36,7 @@ class ShortUrlsListFiltering extends ShortUrlsCountFiltering
$excludePastValidUntil,
$apiKey,
$defaultDomain,
$domain,
);
}
@@ -56,6 +59,7 @@ class ShortUrlsListFiltering extends ShortUrlsCountFiltering
$params->excludePastValidUntil,
$apiKey,
$defaultDomain,
$params->domain,
);
}
}

View File

@@ -9,6 +9,7 @@ use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Model\OrderableField;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary;
@@ -118,8 +119,8 @@ class ShortUrlListRepository extends EntitySpecificationRepository implements Sh
$qb->expr()->like('d.authority', ':searchPattern'),
];
// Include default domain in search if provided
if ($filtering->searchIncludesDefaultDomain) {
// Include default domain in search if included, and a domain was not explicitly provided
if ($filtering->searchIncludesDefaultDomain && $filtering->domain === null) {
$conditions[] = $qb->expr()->isNull('s.domain');
}
@@ -142,6 +143,12 @@ class ShortUrlListRepository extends EntitySpecificationRepository implements Sh
}
if ($filtering->domain !== null) {
if ($filtering->domain === Domain::DEFAULT_AUTHORITY) {
$qb->andWhere($qb->expr()->isNull('s.domain'));
} else {
$qb->andWhere($qb->expr()->eq('d.authority', ':domain'))
->setParameter('domain', $filtering->domain);
}
}
if ($filtering->excludeMaxVisitsReached) {