Skip to content
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

Laravel Resource Support #24

Merged
merged 7 commits into from
Nov 3, 2019
Merged
Show file tree
Hide file tree
Changes from 6 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
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,52 @@ And you'll get
}
```

## Resource Collection

Lampager supports Laravel's API Resources.

- [Eloquent: API Resources - Laravel - The PHP Framework For Web Artisans](https://laravel.com/docs/6.x/eloquent-resources)

Use helper traits on Resource and ResourceCollection.

```php
use Illuminate\Http\Resources\Json\JsonResource;
use Lampager\Laravel\LampagerResourceTrait;

class PostResource extends JsonResource
{
use LampagerResourceTrait;
}
```

```php
use Illuminate\Http\Resources\Json\ResourceCollection;
use Lampager\Laravel\LampagerResourceCollectionTrait;

class PostResourceCollection extends ResourceCollection
{
use LampagerResourceCollectionTrait;
}
```

```php
$posts = App\Post::lampager()
->orderByDesc('id')
->paginate();

return new PostResourceCollection($posts);
```

```json5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know this technique... quite nice!

{
"data": [/* ... */],
"has_previous": false,
"previous_cursor": null,
"has_next": true,
"next_cursor": {/* ... */}
}
```

## Classes

Note: See also [lampager/lampager](https://github.com/lampager/lampager).
Expand All @@ -155,6 +201,8 @@ Note: See also [lampager/lampager](https://github.com/lampager/lampager).
| Lampager\\Laravel\\`Processor` | Class | Lampager\\`AbstractProcessor` | Processor implementation for Laravel |
| Lampager\\Laravel\\`PaginationResult` | Class | Lampager\\`PaginationResult` | PaginationResult implementation for Laravel |
| Lampager\\Laravel\\`MacroServiceProvider` | Class | Illuminate\\Support\\`ServiceProvider` | Enable macros chainable from QueryBuilder, ElqouentBuilder and Relation |
| Lampager\\Laravel\\`LampagerResourceTrait` | Trait | | Support for Laravel JsonResource |
| Lampager\\Laravel\\`LampagerResourceCollectionTrait` | Trait | | Support for Laravel ResourceCollection |

`Paginator`, `Processor` and `PaginationResult` are macroable.

Expand Down
48 changes: 48 additions & 0 deletions src/Http/Resources/CollectsPaginationResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Lampager\Laravel\Http\Resources;

use Illuminate\Http\Resources\CollectsResources;
use Illuminate\Http\Resources\MissingValue;
use Illuminate\Pagination\AbstractPaginator;
use Lampager\Laravel\PaginationResult;

/**
* Trait CollectsPaginationResult
*
* @mixin \Illuminate\Http\Resources\Json\ResourceCollection
*/
trait CollectsPaginationResult
{
use CollectsResources;

/**
* Map the given collection resource into its individual resources.
*
* @param mixed $resource
* @return mixed
*/
protected function collectResource($resource)
{
if ($resource instanceof MissingValue) {
return $resource;
}

$collects = $this->collects();

$this->collection = $collects && !$resource->first() instanceof $collects
? $resource->mapInto($collects)
: $resource->toBase();

if ($resource instanceof AbstractPaginator) {
$resource->setCollection($this->collection);
return $resource;
}
if ($resource instanceof PaginationResult) {
$resource->records = $this->collection;
return $resource;
}

return $this->collection;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Lampager\Laravel\Http\Resources\Json;

use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Lampager\Laravel\Http\Resources\CollectsPaginationResult;

/**
* Class AnonymousPaginationResultAwareResourceCollection
*
* @mixin \Illuminate\Http\Resources\Json\JsonResource
*/
class AnonymousPaginationResultAwareResourceCollection extends AnonymousResourceCollection
{
use MakesAnonymousPaginationResultAwareResourceCollection,
CollectsPaginationResult,
RespondsWithPaginationResult;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Lampager\Laravel\Http\Resources\Json;

/**
* Trait MakesAnonymousPaginationResultAwareResourceCollection
*
* @mixin \Illuminate\Http\Resources\Json\JsonResource
*/
trait MakesAnonymousPaginationResultAwareResourceCollection
{
/**
* Create new anonymous resource collection.
mpyw marked this conversation as resolved.
Show resolved Hide resolved
*
* @param mixed $resource
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public static function collection($resource)
{
return tap(new AnonymousPaginationResultAwareResourceCollection($resource, static::class), function ($collection) {
if (property_exists(static::class, 'preserveKeys')) {
$collection->preserveKeys = (new static([]))->preserveKeys === true;
}
});
}
}
23 changes: 23 additions & 0 deletions src/Http/Resources/Json/PaginationResultResourceResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Lampager\Laravel\Http\Resources\Json;

use Illuminate\Http\Resources\Json\PaginatedResourceResponse;
use Illuminate\Support\Arr;

/**
* class PaginationResultResourceResponse
*/
class PaginationResultResourceResponse extends PaginatedResourceResponse
{
/**
* Add the pagination information to the response.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function paginationInformation($request)
{
return Arr::except($this->resource->resource->toArray(), 'records');
}
}
33 changes: 33 additions & 0 deletions src/Http/Resources/Json/RespondsWithPaginationResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Lampager\Laravel\Http\Resources\Json;

use Illuminate\Http\Resources\Json\PaginatedResourceResponse;
use Illuminate\Pagination\AbstractPaginator;
use Lampager\Laravel\PaginationResult;

/**
* Trait RespondsWithPaginationResult
*
* @mixin \Illuminate\Http\Resources\Json\ResourceCollection
*/
trait RespondsWithPaginationResult
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function toResponse($request)
{
if ($this->resource instanceof AbstractPaginator) {
return (new PaginatedResourceResponse($this))->toResponse($request);
}
if ($this->resource instanceof PaginationResult) {
return (new PaginationResultResourceResponse($this))->toResponse($request);
}

return parent::toResponse($request);
}
}
17 changes: 17 additions & 0 deletions src/LampagerResourceCollectionTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Lampager\Laravel;

use Lampager\Laravel\Http\Resources\CollectsPaginationResult;
use Lampager\Laravel\Http\Resources\Json\MakesAnonymousPaginationResultAwareResourceCollection;
use Lampager\Laravel\Http\Resources\Json\RespondsWithPaginationResult;

/**
* Trait LampagerResourceCollectionTrait
*/
trait LampagerResourceCollectionTrait
{
use MakesAnonymousPaginationResultAwareResourceCollection,
CollectsPaginationResult,
RespondsWithPaginationResult;
}
13 changes: 13 additions & 0 deletions src/LampagerResourceTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Lampager\Laravel;

use Lampager\Laravel\Http\Resources\Json\MakesAnonymousPaginationResultAwareResourceCollection;

/**
* Trait LampagerResourceTrait
*/
trait LampagerResourceTrait
{
use MakesAnonymousPaginationResultAwareResourceCollection;
}
27 changes: 27 additions & 0 deletions tests/PostResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Lampager\Laravel\Tests;

use Illuminate\Http\Resources\Json\JsonResource;
use Lampager\Laravel\LampagerResourceTrait;

/**
* Class PostResource
*/
class PostResource extends JsonResource
{
use LampagerResourceTrait;

public $preserveKeys = true;

/**
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return parent::toArray($request) + [
'post_resource' => true,
];
}
}
14 changes: 14 additions & 0 deletions tests/PostResourceCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Lampager\Laravel\Tests;

use Illuminate\Http\Resources\Json\ResourceCollection;
use Lampager\Laravel\LampagerResourceCollectionTrait;

/**
* Class PostResourceCollection
*/
class PostResourceCollection extends ResourceCollection
{
use LampagerResourceCollectionTrait;
}
Loading