Skip to content

Commit ae4064d

Browse files
committed
Implement paginate() function
1 parent ef713c8 commit ae4064d

File tree

3 files changed

+129
-33
lines changed

3 files changed

+129
-33
lines changed

src/Contracts/QueryBuilder.php

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,36 @@
22

33
namespace Rareloop\Lumberjack\Contracts;
44

5+
use Timber\PostQuery;
56
use Tightenco\Collect\Support\Collection;
67

78
interface QueryBuilder
89
{
9-
public function getParameters() : array;
10+
public function getParameters(): array;
1011

11-
public function wherePostType($postType) : QueryBuilder;
12+
public function wherePostType($postType): QueryBuilder;
1213

13-
public function limit($limit) : QueryBuilder;
14+
public function limit($limit): QueryBuilder;
1415

15-
public function offset($offset) : QueryBuilder;
16+
public function offset($offset): QueryBuilder;
1617

17-
public function orderBy($orderBy, string $order = QueryBuilder::ASC) : QueryBuilder;
18+
public function orderBy($orderBy, string $order = QueryBuilder::ASC): QueryBuilder;
1819

19-
public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string $type = null) : QueryBuilder;
20+
public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string $type = null): QueryBuilder;
2021

21-
public function whereIdIn(array $ids) : QueryBuilder;
22+
public function whereIdIn(array $ids): QueryBuilder;
2223

23-
public function whereIdNotIn(array $ids) : QueryBuilder;
24+
public function whereIdNotIn(array $ids): QueryBuilder;
2425

25-
public function whereStatus() : QueryBuilder;
26+
public function whereStatus(): QueryBuilder;
2627

27-
public function whereMeta($key, $value, $compare = '=', $type = null) : QueryBuilder;
28+
public function whereMeta($key, $value, $compare = '=', $type = null): QueryBuilder;
2829

29-
public function whereMetaRelationshipIs(string $relation) : QueryBuilder;
30+
public function whereMetaRelationshipIs(string $relation): QueryBuilder;
3031

31-
public function get() : Collection;
32+
public function get(): Collection;
3233

33-
public function clone() : QueryBuilder;
34+
public function paginate($perPage = 10, $page = 1): PostQuery;
35+
36+
public function clone(): QueryBuilder;
3437
}

src/QueryBuilder.php

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Rareloop\Lumberjack\Post;
88
use Spatie\Macroable\Macroable;
99
use Tightenco\Collect\Support\Collection;
10+
use Timber\PostQuery;
1011
use Timber\Timber;
1112

1213
class QueryBuilder implements QueryBuilderContract
@@ -28,33 +29,33 @@ class QueryBuilder implements QueryBuilderContract
2829
const OR = 'OR';
2930
const AND = 'AND';
3031

31-
public function getParameters() : array
32+
public function getParameters(): array
3233
{
3334
return $this->params;
3435
}
3536

36-
public function wherePostType($postType) : QueryBuilderContract
37+
public function wherePostType($postType): QueryBuilderContract
3738
{
3839
$this->params['post_type'] = $postType;
3940

4041
return $this;
4142
}
4243

43-
public function limit($limit) : QueryBuilderContract
44+
public function limit($limit): QueryBuilderContract
4445
{
4546
$this->params['posts_per_page'] = $limit;
4647

4748
return $this;
4849
}
4950

50-
public function offset($offset) : QueryBuilderContract
51+
public function offset($offset): QueryBuilderContract
5152
{
5253
$this->params['offset'] = $offset;
5354

5455
return $this;
5556
}
5657

57-
public function orderBy($orderBy, string $order = QueryBuilder::ASC) : QueryBuilderContract
58+
public function orderBy($orderBy, string $order = QueryBuilder::ASC): QueryBuilderContract
5859
{
5960
$order = strtoupper($order);
6061

@@ -64,7 +65,7 @@ public function orderBy($orderBy, string $order = QueryBuilder::ASC) : QueryBuil
6465
return $this;
6566
}
6667

67-
public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string $type = null) : QueryBuilderContract
68+
public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string $type = null): QueryBuilderContract
6869
{
6970
$order = strtoupper($order);
7071

@@ -75,21 +76,21 @@ public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string
7576
return $this;
7677
}
7778

78-
public function whereIdIn(array $ids) : QueryBuilderContract
79+
public function whereIdIn(array $ids): QueryBuilderContract
7980
{
8081
$this->params['post__in'] = $ids;
8182

8283
return $this;
8384
}
8485

85-
public function whereIdNotIn(array $ids) : QueryBuilderContract
86+
public function whereIdNotIn(array $ids): QueryBuilderContract
8687
{
8788
$this->params['post__not_in'] = $ids;
8889

8990
return $this;
9091
}
9192

92-
public function whereStatus() : QueryBuilderContract
93+
public function whereStatus(): QueryBuilderContract
9394
{
9495
$args = func_get_args();
9596

@@ -107,7 +108,7 @@ protected function initialiseMetaQuery()
107108
$this->params['meta_query'] = $this->params['meta_query'] ?? [];
108109
}
109110

110-
public function whereMeta($key, $value, $compare = '=', $type = null) : QueryBuilderContract
111+
public function whereMeta($key, $value, $compare = '=', $type = null): QueryBuilderContract
111112
{
112113
$meta = [
113114
'key' => $key,
@@ -125,7 +126,7 @@ public function whereMeta($key, $value, $compare = '=', $type = null) : QueryBui
125126
return $this;
126127
}
127128

128-
public function whereMetaRelationshipIs(string $relation) : QueryBuilderContract
129+
public function whereMetaRelationshipIs(string $relation): QueryBuilderContract
129130
{
130131
$relation = strtoupper($relation);
131132

@@ -141,14 +142,14 @@ public function whereMetaRelationshipIs(string $relation) : QueryBuilderContract
141142
return $this;
142143
}
143144

144-
public function as($postClass) : QueryBuilderContract
145+
public function as($postClass): QueryBuilderContract
145146
{
146147
$this->postClass = $postClass;
147148

148149
return $this;
149150
}
150151

151-
public function get() : Collection
152+
public function get(): Collection
152153
{
153154
$posts = Timber::get_posts($this->getParameters(), $this->postClass);
154155

@@ -159,12 +160,30 @@ public function get() : Collection
159160
return collect($posts);
160161
}
161162

163+
public function paginate($perPage = 10, $page = 1): PostQuery
164+
{
165+
global $paged;
166+
167+
if (isset($page)) {
168+
$paged = $page;
169+
}
170+
171+
if (!isset($paged) || !$paged) {
172+
$paged = 1;
173+
}
174+
175+
$this->limit($perPage);
176+
$this->params['paged'] = $paged;
177+
178+
return new PostQuery($this->getParameters(), $this->postClass);
179+
}
180+
162181
/**
163182
* Get the first Post that matches the current query. If no Post matches then return `null`.
164183
*
165184
* @return \Rareloop\Lumberjack\Post|null
166185
*/
167-
public function first() : ?Post
186+
public function first(): ?Post
168187
{
169188
$params = array_merge($this->getParameters(), [
170189
'limit' => 1,
@@ -179,7 +198,7 @@ public function first() : ?Post
179198
return collect($posts)->first();
180199
}
181200

182-
public function clone() : QueryBuilderContract
201+
public function clone(): QueryBuilderContract
183202
{
184203
$clone = clone $this;
185204

tests/Unit/QueryBuilderTest.php

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22

33
namespace Rareloop\Lumberjack\Test;
44

5-
use Illuminate\Support\Collection;
65
use Mockery;
7-
use PHPUnit\Framework\TestCase;
6+
use Timber\Timber;
7+
use Timber\PostQuery;
8+
use Timber\PostGetter;
9+
use Timber\PostCollection;
10+
use Brain\Monkey\Functions;
811
use Rareloop\Lumberjack\Post;
12+
use PHPUnit\Framework\TestCase;
13+
use Illuminate\Support\Collection;
914
use Rareloop\Lumberjack\QueryBuilder;
10-
use Timber\Timber;
15+
use Rareloop\Lumberjack\Test\Unit\BrainMonkeyPHPUnitIntegration;
1116

1217
class QueryBuilderTest extends TestCase
1318
{
14-
use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
19+
use BrainMonkeyPHPUnitIntegration;
1520

1621
/** @test */
1722
public function correct_post_type_is_set()
@@ -400,6 +405,75 @@ public function get_retrieves_empty_collection_when_timber_returns_null()
400405
$this->assertSame(0, $returnedPosts->count());
401406
}
402407

408+
/**
409+
* @test
410+
* @runInSeparateProcess
411+
* @preserveGlobalState disabled
412+
*/
413+
public function paginate_retrieves_PostQuery_object_with_correct_defaults()
414+
{
415+
$this->assertPostQueryParameters([
416+
'post_status' => 'publish',
417+
'posts_per_page' => 10,
418+
'paged' => 1,
419+
]);
420+
421+
$builder = new QueryBuilder();
422+
$returnedPostQuery = $builder->whereStatus('publish')->paginate();
423+
424+
$this->assertInstanceOf(PostQuery::class, $returnedPostQuery);
425+
}
426+
427+
/**
428+
* @test
429+
* @runInSeparateProcess
430+
* @preserveGlobalState disabled
431+
*/
432+
public function paginate_retrieves_PostQuery_object_with_provided_arguments()
433+
{
434+
$this->assertPostQueryParameters([
435+
'post_status' => 'publish',
436+
'posts_per_page' => 20,
437+
'paged' => 2,
438+
]);
439+
440+
$builder = new QueryBuilder();
441+
$returnedPostQuery = $builder->whereStatus('publish')->paginate(20, 2);
442+
443+
$this->assertInstanceOf(PostQuery::class, $returnedPostQuery);
444+
}
445+
446+
/**
447+
* We have to mock quite a bit more than is ideal for this but there is no other way to hook
448+
* into this bit of Timber that I've found. It does leave us a little open to failing tests
449+
* if Timber change their implementation but not much we can do about that.
450+
*
451+
* @param array $params The parameters to assert are passed in construction
452+
* @return void
453+
*/
454+
protected function assertPostQueryParameters(array $params)
455+
{
456+
Functions\expect('get_post_type')
457+
->andReturn('post');
458+
459+
$posts = [new Post(1, true), new Post(2, true)];
460+
461+
$postGetter = Mockery::mock('alias:' . PostGetter::class);
462+
463+
$postGetter
464+
->shouldReceive('get_post_class')
465+
->andReturn(Post::class);
466+
467+
$postGetter
468+
->shouldReceive('query_posts')
469+
->withArgs([
470+
Mockery::subset($params),
471+
Post::class,
472+
])
473+
->once()
474+
->andReturn(new PostCollection($posts, Post::class));
475+
}
476+
403477
/**
404478
* @test
405479
* @runInSeparateProcess
@@ -593,7 +667,7 @@ class QueryBuilderMixin
593667
{
594668
function testFunctionAddedByMixin()
595669
{
596-
return function() {
670+
return function () {
597671
$this->params['foo'] = 'bar';
598672

599673
return $this;

0 commit comments

Comments
 (0)