Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<testsuites>
<testsuite name="API Test Suite">
<directory suffix="Test.php">./test/tests</directory>
<exclude>./test/tests/TestCase.php</exclude>
</testsuite>
</testsuites>
<php>
Expand Down
26 changes: 26 additions & 0 deletions src/Enums/PaginationType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
namespace Specialtactics\L5Api\Enums;

/**
* This denotes the type of Laravel pagination to use, for example in controllers
*
* By default, and for compatibility reasons with previous versions of the boilerplate, we will use LengthAware pagination
*/
enum PaginationType: string
{
case SIMPLE = 'simple';
case LENGTH_AWARE = 'length-aware';
case CURSOR = 'cursor';

/**
* Attempt to get enum from string value, and set a default if we can't.
*/
public static function getFromValue(?string $value): self
{
if (! $value) {
return self::LENGTH_AWARE;
}

return self::tryFrom($value) ?? self::LENGTH_AWARE;
}
}
19 changes: 19 additions & 0 deletions src/Http/Controllers/Features/RestfulControllerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,30 @@
namespace Specialtactics\L5Api\Http\Controllers\Features;

use App\Transformers\BaseTransformer;
use Illuminate\Contracts\Pagination\CursorPaginator;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Specialtactics\L5Api\Enums\PaginationType;
use Specialtactics\L5Api\Helpers;

trait RestfulControllerTrait
{
public PaginationType $paginationType = PaginationType::LENGTH_AWARE;

/**
* Get the correct paginator instance based on the controller's paginator type param
*/
public function getPaginator(Builder $query, int $perPage): Paginator|LengthAwarePaginator|CursorPaginator
{
if ($this->paginationType === PaginationType::SIMPLE) {
return $query->simplePaginate($perPage);
} else {
return $query->paginate($perPage);
}
}

/**
* Figure out which transformer to use
*
Expand Down
7 changes: 4 additions & 3 deletions src/Http/Controllers/RestfulController.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ public function getAll()
$perPage = intval(request()->input('per_page'));
}

$paginator = $query->paginate($perPage);

return $this->response->paginator($paginator, $this->getTransformer());
return $this->response->paginator(
$this->getPaginator($query, $perPage),
$this->getTransformer()
);
} else {
$resources = $query->get();

Expand Down
3 changes: 3 additions & 0 deletions test/app/Http/Controllers/ForumController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Http\Request;
use App\Models\Forum;
use Specialtactics\L5Api\Enums\PaginationType;

class ForumController extends Controller
{
Expand All @@ -16,4 +17,6 @@ class ForumController extends Controller
* @var null|BaseTransformer The transformer this controller should use, if overriding the model & default
*/
public static $transformer = null;

public PaginationType $paginationType = PaginationType::LENGTH_AWARE;
}
1 change: 0 additions & 1 deletion test/routes/api-routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
* Test
*/
$api->group(['prefix' => 'posts'], function ($api) {
$api->get('/', 'App\Http\Controllers\PostController@getAll');
$api->post('/', 'App\Http\Controllers\PostController@post');
});

Expand Down
38 changes: 38 additions & 0 deletions test/tests/Unit/PaginationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Specialtactics\L5Api\Tests\Unit;

use App\Http\Controllers\ForumController;
use Specialtactics\L5Api\Enums\PaginationType;
use Specialtactics\L5Api\Tests\AppTestCase;

class PaginationTest extends AppTestCase
{
public function testLengthAwarePagination()
{
$jsonResponse = $this->actingAsAdmin()
->json('GET', '/forums');

$jsonResponse->assertStatus(200);
$response = $jsonResponse->decodeResponseJson();

$this->assertEquals(1, $response['meta']['pagination']['total']);
$this->assertEquals(1, $response['meta']['pagination']['totalPages']);
}

public function testSimplePagination()
{
$mockForumController = $this->partialMock(ForumController::class);
$mockForumController->paginationType = PaginationType::SIMPLE;

$jsonResponse = $this->actingAsAdmin()
->json('GET', '/forums');

$jsonResponse->assertStatus(200);
$response = $jsonResponse->decodeResponseJson();

// League's Serealiser contract needs to return something, so at the moment it's zero for simple pagination
$this->assertEquals(0, $response['meta']['pagination']['total']);
$this->assertEquals(0, $response['meta']['pagination']['totalPages']);
}
}