mirror of
https://github.com/shlinkio/shlink.git
synced 2026-03-06 15:23:12 +08:00
Applied API role specs to tag visits
This commit is contained in:
@@ -5,9 +5,13 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\Core\Repository;
|
||||
|
||||
use Happyr\DoctrineSpecification\EntitySpecificationRepository;
|
||||
use Happyr\DoctrineSpecification\Spec;
|
||||
use Happyr\DoctrineSpecification\Specification\Specification;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Tag\Model\TagInfo;
|
||||
use Shlinkio\Shlink\Core\Tag\Spec\CountTagsWithName;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Spec\WithApiKeySpecsEnsuringJoin;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
use function Functional\map;
|
||||
|
||||
@@ -47,4 +51,14 @@ class TagRepository extends EntitySpecificationRepository implements TagReposito
|
||||
fn (array $row) => new TagInfo($row['tag'], (int) $row['shortUrlsCount'], (int) $row['visitsCount']),
|
||||
);
|
||||
}
|
||||
|
||||
public function tagExists(string $tag, ?ApiKey $apiKey = null): bool
|
||||
{
|
||||
$result = (int) $this->matchSingleScalarResult(Spec::andX(
|
||||
new CountTagsWithName($tag),
|
||||
new WithApiKeySpecsEnsuringJoin($apiKey),
|
||||
));
|
||||
|
||||
return $result > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use Doctrine\Persistence\ObjectRepository;
|
||||
use Happyr\DoctrineSpecification\EntitySpecificationRepositoryInterface;
|
||||
use Happyr\DoctrineSpecification\Specification\Specification;
|
||||
use Shlinkio\Shlink\Core\Tag\Model\TagInfo;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
interface TagRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface
|
||||
{
|
||||
@@ -17,4 +18,6 @@ interface TagRepositoryInterface extends ObjectRepository, EntitySpecificationRe
|
||||
* @return TagInfo[]
|
||||
*/
|
||||
public function findTagsWithInfo(?Specification $spec = null): array;
|
||||
|
||||
public function tagExists(string $tag, ?ApiKey $apiKey = null): bool;
|
||||
}
|
||||
|
||||
@@ -131,32 +131,36 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo
|
||||
string $tag,
|
||||
?DateRange $dateRange = null,
|
||||
?int $limit = null,
|
||||
?int $offset = null
|
||||
?int $offset = null,
|
||||
?Specification $spec = null
|
||||
): array {
|
||||
$qb = $this->createVisitsByTagQueryBuilder($tag, $dateRange);
|
||||
$qb = $this->createVisitsByTagQueryBuilder($tag, $dateRange, $spec);
|
||||
return $this->resolveVisitsWithNativeQuery($qb, $limit, $offset);
|
||||
}
|
||||
|
||||
public function countVisitsByTag(string $tag, ?DateRange $dateRange = null): int
|
||||
public function countVisitsByTag(string $tag, ?DateRange $dateRange = null, ?Specification $spec = null): int
|
||||
{
|
||||
$qb = $this->createVisitsByTagQueryBuilder($tag, $dateRange);
|
||||
$qb = $this->createVisitsByTagQueryBuilder($tag, $dateRange, $spec);
|
||||
$qb->select('COUNT(v.id)');
|
||||
|
||||
return (int) $qb->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
private function createVisitsByTagQueryBuilder(string $tag, ?DateRange $dateRange = null): QueryBuilder
|
||||
{
|
||||
// Parameters in this query need to be part of the query itself, as we need to use it a sub-query later
|
||||
private function createVisitsByTagQueryBuilder(
|
||||
string $tag,
|
||||
?DateRange $dateRange,
|
||||
?Specification $spec
|
||||
): QueryBuilder {
|
||||
// Parameters in this query need to be inlined, not bound, as we need to use it as sub-query later
|
||||
// Since they are not strictly provided by the caller, it's reasonably safe
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->from(Visit::class, 'v')
|
||||
->join('v.shortUrl', 's')
|
||||
->join('s.tags', 't')
|
||||
->where($qb->expr()->eq('t.name', '\'' . $tag . '\''));
|
||||
->where($qb->expr()->eq('t.name', '\'' . $tag . '\'')); // This needs to be concatenated, not bound
|
||||
|
||||
// Apply date range filtering
|
||||
$this->applyDatesInline($qb, $dateRange);
|
||||
$this->applySpecification($qb, $spec, 'v');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
@@ -55,8 +55,9 @@ interface VisitRepositoryInterface extends ObjectRepository, EntitySpecification
|
||||
string $tag,
|
||||
?DateRange $dateRange = null,
|
||||
?int $limit = null,
|
||||
?int $offset = null
|
||||
?int $offset = null,
|
||||
?Specification $spec = null
|
||||
): array;
|
||||
|
||||
public function countVisitsByTag(string $tag, ?DateRange $dateRange = null): int;
|
||||
public function countVisitsByTag(string $tag, ?DateRange $dateRange = null, ?Specification $spec = null): int;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user