-
-
Notifications
You must be signed in to change notification settings - Fork 859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.0] Support for Eloquent API Resources #1702
Changes from 14 commits
c9e7a7b
dc861bf
84ebcaa
f70ad7c
3cdd6ec
0b8c468
f1cc54a
993ffee
e5f6cd3
a8d1bd1
90ac5b4
a049840
2a6a988
bb4ca3e
3e5e552
0713387
778f10e
800d58b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
|
||
namespace Yajra\DataTables; | ||
|
||
use Illuminate\Support\Collection; | ||
use Illuminate\Pagination\LengthAwarePaginator; | ||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection; | ||
|
||
class ApiResourceDataTable extends CollectionDataTable | ||
{ | ||
/** | ||
* Collection object. | ||
* | ||
* @var Illuminate\Http\Resources\Json\AnonymousResourceCollection | ||
*/ | ||
public $collection; | ||
|
||
/** | ||
* Collection object. | ||
* | ||
* @var Illuminate\Http\Resources\Json\AnonymousResourceCollection | ||
*/ | ||
public $original; | ||
|
||
/** | ||
* Can the DataTable engine be created with these parameters. | ||
* | ||
* @param mixed $source | ||
* @return bool | ||
*/ | ||
public static function canCreate($source) | ||
{ | ||
return is_array($source) || $source instanceof AnonymousResourceCollection; | ||
} | ||
|
||
/** | ||
* Factory method, create and return an instance for the DataTable engine. | ||
* | ||
* @param array|Illuminate\Http\Resources\Json\AnonymousResourceCollection $source | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @param should be |
||
* @return ApiResourceDataTable|DataTableAbstract | ||
*/ | ||
public static function create($source) | ||
{ | ||
if (is_array($source)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can remove the is_array part and let dt collection do the job. /**
* Factory method, create and return an instance for the DataTable engine.
*
* @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection $source
* @return ApiResourceDataTable|DataTableAbstract
*/
public static function create($source)
{
return new ApiResourceDataTable($source);
} |
||
$source = new AnonymousResourceCollection($source); | ||
} | ||
|
||
return parent::create($source); | ||
} | ||
|
||
/** | ||
* CollectionEngine constructor. | ||
* | ||
* @param Illuminate\Http\Resources\Json\AnonymousResourceCollection $collection | ||
*/ | ||
public function __construct(AnonymousResourceCollection $collection) | ||
{ | ||
$this->request = app('datatables.request'); | ||
$this->config = app('datatables.config'); | ||
$this->collection = collect($collection->toArray($this->request)); | ||
$this->original = $collection; | ||
$this->columns = array_keys($this->serialize(collect($collection->toArray($this->request))->first())); | ||
if ($collection->resource instanceof LengthAwarePaginator) { | ||
$this->isFilterApplied = true; | ||
} | ||
} | ||
|
||
/** | ||
* Count total items. | ||
* | ||
* @return int | ||
*/ | ||
public function totalCount() | ||
{ | ||
if ($this->original->resource instanceof LengthAwarePaginator) { | ||
return $this->totalRecords ? $this->totalRecords : $this->original->resource->total(); | ||
} else { | ||
return $this->totalRecords ? $this->totalRecords : $this->collection->count(); | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this class can inherit from CollectionDataTable to avoid duplicate codes? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Yajra\DataTables\Tests\Http\Resources; | ||
|
||
use Illuminate\Http\Resources\Json\ResourceCollection; | ||
|
||
class UserCollection extends ResourceCollection | ||
{ | ||
/** | ||
* Transform the resource collection into an array. | ||
* | ||
* @param \Illuminate\Http\Request $request | ||
* @return array | ||
*/ | ||
public function toArray($request) | ||
{ | ||
// return parent::toArray($request); | ||
return $this->collection; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace Yajra\DataTables\Tests\Http\Resources; | ||
|
||
use Illuminate\Http\Resources\Json\Resource; | ||
|
||
class UserResource extends Resource | ||
{ | ||
/** | ||
* Transform the resource into an array. | ||
* | ||
* @param \Illuminate\Http\Request $request | ||
* @return array | ||
*/ | ||
public function toArray($request) | ||
{ | ||
// return parent::toArray($request); | ||
return [ | ||
// 'id' => $this->id, | ||
'email' => $this->email, | ||
'name' => $this->name, | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
|
||
namespace Yajra\DataTables\Tests\Integration; | ||
|
||
use Yajra\DataTables\DataTables; | ||
use Illuminate\Http\JsonResponse; | ||
use Yajra\DataTables\Tests\TestCase; | ||
use Yajra\DataTables\Tests\Models\User; | ||
use Yajra\DataTables\ApiResourceDataTable; | ||
use Illuminate\Foundation\Testing\DatabaseTransactions; | ||
use Yajra\DataTables\Tests\Http\Resources\UserResource; | ||
use Yajra\DataTables\Facades\DataTables as DatatablesFacade; | ||
|
||
class ApiResourceEngineTest extends TestCase | ||
{ | ||
use DatabaseTransactions; | ||
|
||
/** @test */ | ||
public function it_returns_all_records_when_no_parameters_is_passed() | ||
{ | ||
$crawler = $this->call('GET', '/resource/users'); | ||
$crawler->assertJson([ | ||
'draw' => 0, | ||
'recordsTotal' => 20, | ||
'recordsFiltered' => 20, | ||
]); | ||
} | ||
|
||
/** @test */ | ||
public function it_only_returns_records_in_structure_defined_in_resource() | ||
{ | ||
$crawler = $this->call('GET', '/resource/users'); | ||
$crawler->assertJsonStructure([ | ||
'draw', | ||
'recordsTotal', | ||
'recordsFiltered', | ||
'data' => [ | ||
[ | ||
'email', | ||
'name', | ||
], | ||
], | ||
]); | ||
} | ||
|
||
/** @test */ | ||
public function it_can_perform_global_search() | ||
{ | ||
$crawler = $this->call('GET', '/resource/users', [ | ||
'columns' => [ | ||
['data' => 'name', 'name' => 'name', 'searchable' => 'true', 'orderable' => 'true'], | ||
['data' => 'email', 'name' => 'email', 'searchable' => 'true', 'orderable' => 'true'], | ||
], | ||
'search' => ['value' => 'Record 19'], | ||
]); | ||
|
||
$crawler->assertJson([ | ||
'draw' => 0, | ||
'recordsTotal' => 20, | ||
'recordsFiltered' => 1, | ||
]); | ||
} | ||
|
||
/** @test */ | ||
public function it_accepts_a_resource_using_of_factory() | ||
{ | ||
$dataTable = DataTables::of(UserResource::collection(User::all())); | ||
$response = $dataTable->make(true); | ||
$this->assertInstanceOf(ApiResourceDataTable::class, $dataTable); | ||
$this->assertInstanceOf(JsonResponse::class, $response); | ||
} | ||
|
||
/** @test */ | ||
public function it_accepts_a_resource_using_facade() | ||
{ | ||
$dataTable = DatatablesFacade::of(UserResource::collection(User::all())); | ||
$response = $dataTable->make(true); | ||
$this->assertInstanceOf(ApiResourceDataTable::class, $dataTable); | ||
$this->assertInstanceOf(JsonResponse::class, $response); | ||
} | ||
|
||
/** @test */ | ||
public function it_accepts_a_pagination_resource() | ||
{ | ||
$dataTable = DataTables::of(UserResource::collection(User::paginate(10))); | ||
$response = $dataTable->make(true); | ||
$this->assertInstanceOf(ApiResourceDataTable::class, $dataTable); | ||
$this->assertInstanceOf(JsonResponse::class, $response); | ||
} | ||
|
||
/** @test */ | ||
public function it_returns_only_paginated_records() | ||
{ | ||
$crawler = $this->call('GET', '/resource/users_p'); | ||
$crawler->assertJson([ | ||
'draw' => 0, | ||
'recordsTotal' => 20, | ||
'recordsFiltered' => 10, | ||
]); | ||
} | ||
|
||
protected function setUp() | ||
{ | ||
parent::setUp(); | ||
|
||
$this->app['router']->get('/resource/users', function (DataTables $datatables) { | ||
return $datatables->resource(UserResource::collection(User::all()))->make('true'); | ||
}); | ||
|
||
$this->app['router']->get('/resource/users_p', function (DataTables $datatables) { | ||
return $datatables->resource(UserResource::collection(User::paginate(10)))->make('true'); | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove is_array here since it's handled by CollectionDataTable.