Fixed filtered lists not being properly paginated

This commit is contained in:
Alejandro Celaya 2018-06-18 20:38:25 +02:00
parent 6e79b4ba7b
commit c7e49f223f
2 changed files with 14 additions and 15 deletions

View File

@ -8,7 +8,7 @@ use Zend\Paginator\Adapter\AdapterInterface;
class PaginableRepositoryAdapter implements AdapterInterface class PaginableRepositoryAdapter implements AdapterInterface
{ {
const ITEMS_PER_PAGE = 10; public const ITEMS_PER_PAGE = 10;
/** /**
* @var PaginableRepositoryInterface * @var PaginableRepositoryInterface
@ -34,7 +34,7 @@ class PaginableRepositoryAdapter implements AdapterInterface
$orderBy = null $orderBy = null
) { ) {
$this->paginableRepository = $paginableRepository; $this->paginableRepository = $paginableRepository;
$this->searchTerm = $searchTerm !== null ? trim(strip_tags($searchTerm)) : null; $this->searchTerm = $searchTerm !== null ? \trim(\strip_tags($searchTerm)) : null;
$this->orderBy = $orderBy; $this->orderBy = $orderBy;
$this->tags = $tags; $this->tags = $tags;
} }
@ -46,7 +46,7 @@ class PaginableRepositoryAdapter implements AdapterInterface
* @param int $itemCountPerPage Number of items per page * @param int $itemCountPerPage Number of items per page
* @return array * @return array
*/ */
public function getItems($offset, $itemCountPerPage) public function getItems($offset, $itemCountPerPage): array
{ {
return $this->paginableRepository->findList( return $this->paginableRepository->findList(
$itemCountPerPage, $itemCountPerPage,
@ -66,7 +66,7 @@ class PaginableRepositoryAdapter implements AdapterInterface
* The return value is cast to an integer. * The return value is cast to an integer.
* @since 5.1.0 * @since 5.1.0
*/ */
public function count() public function count(): int
{ {
return $this->paginableRepository->countList($this->searchTerm, $this->tags); return $this->paginableRepository->countList($this->searchTerm, $this->tags);
} }

View File

@ -25,7 +25,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
$orderBy = null $orderBy = null
): array { ): array {
$qb = $this->createListQueryBuilder($searchTerm, $tags); $qb = $this->createListQueryBuilder($searchTerm, $tags);
$qb->select('s'); $qb->select('DISTINCT s');
// Set limit and offset // Set limit and offset
if ($limit !== null) { if ($limit !== null) {
@ -47,17 +47,17 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
protected function processOrderByForList(QueryBuilder $qb, $orderBy) protected function processOrderByForList(QueryBuilder $qb, $orderBy)
{ {
$fieldName = is_array($orderBy) ? key($orderBy) : $orderBy; $fieldName = \is_array($orderBy) ? \key($orderBy) : $orderBy;
$order = is_array($orderBy) ? $orderBy[$fieldName] : 'ASC'; $order = \is_array($orderBy) ? $orderBy[$fieldName] : 'ASC';
if (in_array($fieldName, ['visits', 'visitsCount', 'visitCount'], true)) { if (\in_array($fieldName, ['visits', 'visitsCount', 'visitCount'], true)) {
$qb->addSelect('COUNT(v) AS totalVisits') $qb->addSelect('COUNT(v) AS totalVisits')
->leftJoin('s.visits', 'v') ->leftJoin('s.visits', 'v')
->groupBy('s') ->groupBy('s')
->orderBy('totalVisits', $order); ->orderBy('totalVisits', $order);
return array_column($qb->getQuery()->getResult(), 0); return \array_column($qb->getQuery()->getResult(), 0);
} elseif (in_array($fieldName, ['originalUrl', 'shortCode', 'dateCreated'], true)) { } elseif (\in_array($fieldName, ['originalUrl', 'shortCode', 'dateCreated'], true)) {
$qb->orderBy('s.' . $fieldName, $order); $qb->orderBy('s.' . $fieldName, $order);
} }
@ -74,7 +74,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
public function countList(string $searchTerm = null, array $tags = []): int public function countList(string $searchTerm = null, array $tags = []): int
{ {
$qb = $this->createListQueryBuilder($searchTerm, $tags); $qb = $this->createListQueryBuilder($searchTerm, $tags);
$qb->select('COUNT(s)'); $qb->select('COUNT(DISTINCT s)');
return (int) $qb->getQuery()->getSingleScalarResult(); return (int) $qb->getQuery()->getSingleScalarResult();
} }
@ -92,7 +92,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
// Apply search term to every searchable field if not empty // Apply search term to every searchable field if not empty
if (! empty($searchTerm)) { if (! empty($searchTerm)) {
$qb->join('s.tags', 't'); $qb->leftJoin('s.tags', 't');
$conditions = [ $conditions = [
$qb->expr()->like('s.originalUrl', ':searchPattern'), $qb->expr()->like('s.originalUrl', ':searchPattern'),
@ -102,8 +102,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
// Unpack and apply search conditions // Unpack and apply search conditions
$qb->andWhere($qb->expr()->orX(...$conditions)); $qb->andWhere($qb->expr()->orX(...$conditions));
$searchTerm = '%' . $searchTerm . '%'; $qb->setParameter('searchPattern', '%' . $searchTerm . '%');
$qb->setParameter('searchPattern', $searchTerm);
} }
// Filter by tags if provided // Filter by tags if provided
@ -119,7 +118,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
* @param string $shortCode * @param string $shortCode
* @return ShortUrl|null * @return ShortUrl|null
*/ */
public function findOneByShortCode(string $shortCode) public function findOneByShortCode(string $shortCode): ?ShortUrl
{ {
$now = new \DateTimeImmutable(); $now = new \DateTimeImmutable();