Skip to content

Commit

Permalink
PHP 7.4 and defaults to simple pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
milroyfraser committed Mar 27, 2021
1 parent a09f349 commit 0235c34
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 96 deletions.
4 changes: 2 additions & 2 deletions composer.json
Expand Up @@ -17,8 +17,8 @@
}
],
"require": {
"php": "~7.2 || ^8.0",
"apichef/laravel-request-query-helper": "^0.5.0"
"php": "~7.4 || ^8.0",
"apichef/laravel-request-query-helper": "^1.0"
},
"require-dev": {
"laravel/legacy-factories": "^1.1",
Expand Down
116 changes: 44 additions & 72 deletions src/QueryBuilderAbstract.php
Expand Up @@ -11,8 +11,6 @@
use ApiChef\RequestQueryHelper\Sorts;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
Expand All @@ -21,39 +19,22 @@

abstract class QueryBuilderAbstract
{
/** @var Request */
private $request;

/** @var Fields */
protected $fields;

/** @var QueryParamBag */
protected $includes;

/** @var QueryParamBag */
protected $filters;

/** @var Sorts */
protected $sorts;

/** @var PaginationParams */
protected $paginationParams;

protected $defaultPageSize = null;
private Request $request;
protected Fields $fields;
protected QueryParamBag $includes;
protected QueryParamBag $filters;
protected Sorts $sorts;
protected PaginationParams $paginationParams;
protected ?int $defaultPageSize = null;
private array $allowedIncludes = [];
private ?array $allPossibleAvailableIncludes = null;
protected array $availableIncludes = [];
protected array $availableFilters = [];
protected array $availableSorts = [];

/** @var EloquentBuilder|QueryBuilder */
private $query;

private $allowedIncludes = [];

private $allPossibleAvailableIncludes = null;

protected $availableIncludes = [];

protected $availableFilters = [];

protected $availableSorts = [];

public function __construct(Request $request)
{
$this->request = $request;
Expand Down Expand Up @@ -95,7 +76,7 @@ public function parseAllowedIncludes(array $allowedIncludes): self
return $this;
}

private function getPossibleRelationshipCombinations(array $relations)
private function getPossibleRelationshipCombinations(array $relations): array
{
$combinations = [];

Expand All @@ -112,11 +93,6 @@ private function getPossibleRelationshipCombinations(array $relations)
return $combinations;
}

/**
* Build and get query.
*
* @return EloquentBuilder|QueryBuilder
*/
public function query()
{
if (! empty($this->allowedIncludes) && $this->includes->filled()) {
Expand All @@ -134,47 +110,43 @@ public function query()
return $this->query;
}

/**
* Execute the query.
*
* @param array $columns
* @return Collection|LengthAwarePaginator
*/
public function get($columns = ['*'])
public function get(array $columns = ['*'])
{
if ($this->paginationParams->filled()) {
return $this->query()->paginate(
$this->paginationParams->perPage(),
$columns,
$this->paginationParams->pageName(),
$this->paginationParams->page()
);
}

if ($this->defaultPageSize !== null) {
return $this->query()->paginate(
$this->defaultPageSize,
$columns,
$this->paginationParams->pageName(),
1
);
if ($this->shouldPaginate()) {
return $this->paginate($columns);
}

return $this->query()->get($columns);
}

/**
* Execute the query and get the first result.
*
* @param array $columns
* @return Model|object|null
*/
public function first($columns = ['*'])
public function paginateWithTotal(array $columns = ['*']): LengthAwarePaginator
{
return $this->paginate($columns, true);
}

private function paginate(array $columns, bool $withTotalCount = false)
{
$paginate = $withTotalCount ? 'paginate' : 'simplePaginate';

return $this->query()->{$paginate}(
$this->paginationParams->perPage($this->defaultPageSize),
$columns,
$this->paginationParams->pageName(),
$this->paginationParams->page(1)
);
}

private function shouldPaginate(): bool
{
return $this->defaultPageSize !== null || $this->paginationParams->filled();
}

public function first(array $columns = ['*'])
{
return $this->query()->first($columns);
}

private function loadIncludes(QueryParamBag $includes)
private function loadIncludes(QueryParamBag $includes): void
{
$includes->each(function ($params, $relation) {
if ($this->isAllowedToInclude($relation)) {
Expand Down Expand Up @@ -216,14 +188,14 @@ private function loadRelation($relation, $params): void
throw new RuntimeException("Trying to include non existing relationship {$relation}");
}

private function applyFilters(QueryParamBag $filters)
private function applyFilters(QueryParamBag $filters): void
{
$filters->each(function ($params, $scope) {
$this->applyFilter($scope, $params);
});
}

private function applyFilter($scope, $params)
private function applyFilter($scope, $params): void
{
if ($filterAlias = Arr::get($this->filtersMap(), $scope)) {
$this->query->{$filterAlias}($params);
Expand All @@ -248,14 +220,14 @@ private function applyFilter($scope, $params)
throw new RuntimeException("Trying to filter by non existing filter {$scope}");
}

private function applySorts(Sorts $sorts)
private function applySorts(Sorts $sorts): void
{
$sorts->each(function (SortField $sortField) {
$this->applySort($sortField->getField(), $sortField->getDirection(), $sortField->getParams());
});
}

private function applySort(string $field, string $direction, string $param = null)
private function applySort(string $field, string $direction, string $param = null): void
{
if ($sortAlias = Arr::get($this->sortsMap(), $field)) {
$this->query->orderBy($sortAlias, $direction);
Expand Down
6 changes: 3 additions & 3 deletions tests/Queries/PostListQuery.php
Expand Up @@ -19,7 +19,7 @@ protected function init(Request $request)

// includes

protected $availableIncludes = [
protected array $availableIncludes = [
'comments.user',
'author.posts.tags',
];
Expand All @@ -43,7 +43,7 @@ public function includeFeedbackWithSubmittedBy($query)

// filters

protected $availableFilters = [
protected array $availableFilters = [
'draft',
];

Expand All @@ -61,7 +61,7 @@ public function filterByPublishedBefore($query, $params)

// sorts

protected $availableSorts = [
protected array $availableSorts = [
'published_at',
];

Expand Down
2 changes: 1 addition & 1 deletion tests/Queries/PostListWithPageSizeQuery.php
Expand Up @@ -4,5 +4,5 @@

class PostListWithPageSizeQuery extends PostListQuery
{
protected $defaultPageSize = 10;
protected ?int $defaultPageSize = 10;
}
32 changes: 14 additions & 18 deletions tests/QueryBuilderPaginationTest.php
Expand Up @@ -5,35 +5,33 @@
use ApiChef\RequestToEloquent\Dummy\Post;
use ApiChef\RequestToEloquent\Queries\PostListQuery;
use ApiChef\RequestToEloquent\Queries\PostListWithPageSizeQuery;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class QueryBuilderPaginationTest extends TestCase
{
public function test_can_paginate()
{
factory(Post::class, 6)->create();

$request = Request::create('/posts?page[number]=1&page[size]=4');
factory(Post::class, 20)->create();
$request = Request::create('/posts?page[number]=2&page[size]=4');

/** @var Collection $post */
$result = (new PostListQuery($request))
->get();
/** @var Paginator $result */
$result = (new PostListQuery($request))->get();

$this->assertInstanceOf(LengthAwarePaginator::class, $result);
$this->assertInstanceOf(Paginator::class, $result);
$this->assertEquals(2, $result->currentPage());
$this->assertEquals(4, $result->perPage());
}

public function test_it_picks_up_number_and_size()
public function test_can_paginate_with_total_count()
{
factory(Post::class, 20)->create();

$request = Request::create('/posts?page[number]=2&page[size]=4');

/** @var LengthAwarePaginator $post */
$result = (new PostListQuery($request))
->get();
$result = (new PostListQuery($request))->paginateWithTotal();

$this->assertInstanceOf(LengthAwarePaginator::class, $result);
$this->assertEquals(2, $result->currentPage());
$this->assertEquals(5, $result->lastPage());
$this->assertEquals(4, $result->perPage());
Expand All @@ -42,12 +40,10 @@ public function test_it_picks_up_number_and_size()
public function test_it_uses_default_psge_size()
{
factory(Post::class, 20)->create();

$request = Request::create('/posts');

/** @var LengthAwarePaginator $post */
$result = (new PostListWithPageSizeQuery($request))
->get();
/** @var Paginator $result */
$result = (new PostListWithPageSizeQuery($request))->get();

$this->assertCount(10, $result->items());
}
Expand Down

0 comments on commit 0235c34

Please sign in to comment.