Skip to content
This repository was archived by the owner on Feb 14, 2023. It is now read-only.

Commit 02c68e9

Browse files
committed
New way of authorization for JsonApiCollection and pagination fixes
1 parent 8ec50f4 commit 02c68e9

File tree

4 files changed

+111
-8
lines changed

4 files changed

+111
-8
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
namespace SkoreLabs\JsonApi\Http\Resources;
4+
5+
use Illuminate\Http\Resources\MissingValue;
6+
use Illuminate\Support\Str;
7+
use Illuminate\Pagination\AbstractPaginator;
8+
use Illuminate\Pagination\LengthAwarePaginator;
9+
use Illuminate\Support\Facades\Auth;
10+
11+
trait CollectsResources
12+
{
13+
/**
14+
* Map the given collection resource into its individual resources.
15+
*
16+
* @param mixed $resource
17+
* @return mixed
18+
*/
19+
protected function collectResource($resource)
20+
{
21+
if ($resource instanceof MissingValue) {
22+
return $resource;
23+
}
24+
25+
$collects = $this->collects();
26+
27+
$this->collection = $collects && ! $resource->first() instanceof $collects
28+
? $this->getFiltered($resource, $collects)
29+
: $resource->toBase();
30+
31+
return $resource instanceof AbstractPaginator
32+
? $this->refreshPaginator($resource)
33+
: $this->collection;
34+
}
35+
36+
/**
37+
* Undocumented function
38+
*
39+
* @param \Illuminate\Pagination\AbstractPaginator $resource
40+
* @return void
41+
*/
42+
protected function refreshPaginator(AbstractPaginator $resource)
43+
{
44+
return (new LengthAwarePaginator(
45+
$this->collection,
46+
$this->collection->count(),
47+
$resource->perPage(),
48+
$resource->currentPage(),
49+
$resource->getOptions()
50+
))->setPageName($resource->getPageName());
51+
}
52+
53+
/**
54+
* Get resource collection filtered by authorization.
55+
*
56+
* @param mixed $resource
57+
* @param mixed $collects
58+
* @return \Illuminate\Support\Collection
59+
*/
60+
protected function getFiltered($resource, $collects)
61+
{
62+
/** @var \Illuminate\Support\Collection $collection */
63+
$collection = $resource->map(function ($item) use ($collects) {
64+
$authorize = $this->authorize;
65+
66+
if (gettype($this->authorize) !== 'boolean') {
67+
$authorize = Auth::user()->can('viewAny', class_basename($item));
68+
}
69+
70+
return new $collects($item, $authorize);
71+
});
72+
73+
return $collection->filter(function (JsonApiResource $item) {
74+
return ! $item->resource instanceof MissingValue;
75+
});
76+
}
77+
78+
/**
79+
* Get the resource that this resource collects.
80+
*
81+
* @return string|null
82+
*/
83+
protected function collects()
84+
{
85+
if ($this->collects) {
86+
return $this->collects;
87+
}
88+
89+
if (Str::endsWith(class_basename($this), 'Collection') &&
90+
class_exists($class = Str::replaceLast('Collection', '', get_class($this)))) {
91+
return $class;
92+
}
93+
}
94+
95+
/**
96+
* Get an iterator for the resource collection.
97+
*
98+
* @return \ArrayIterator
99+
*/
100+
public function getIterator()
101+
{
102+
return $this->collection->getIterator();
103+
}
104+
}

src/Http/Resources/Json/ResourceCollection.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
use Countable;
66
use IteratorAggregate;
77
use Illuminate\Pagination\AbstractPaginator;
8-
use Illuminate\Http\Resources\CollectsResources;
9-
use Illuminate\Support\Facades\Auth;
108
use SkoreLabs\JsonApi\Http\Resources\JsonApiResource;
119
use Illuminate\Http\Resources\Json\PaginatedResourceResponse;
10+
use SkoreLabs\JsonApi\Http\Resources\CollectsResources;
1211

1312
class ResourceCollection extends JsonApiResource implements Countable, IteratorAggregate
1413
{
@@ -36,8 +35,6 @@ class ResourceCollection extends JsonApiResource implements Countable, IteratorA
3635
*/
3736
public function __construct($resource)
3837
{
39-
parent::__construct($resource, Auth::user()->can('viewAny', get_class($resource)));
40-
4138
$this->resource = $this->collectResource($resource);
4239
}
4340

@@ -71,7 +68,7 @@ public function toArray($request)
7168
public function toResponse($request)
7269
{
7370
return $this->resource instanceof AbstractPaginator
74-
? (new PaginatedResourceResponse($this))->toResponse($request)
75-
: parent::toResponse($request);
71+
? (new PaginatedResourceResponse($this))->toResponse($request)
72+
: parent::toResponse($request);
7673
}
7774
}

src/Http/Resources/JsonApiCollection.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ class JsonApiCollection extends ResourceCollection
1212
* Create a new resource instance.
1313
*
1414
* @param mixed $resource
15+
* @param bool|null $authorize
1516
* @return void
1617
*/
17-
public function __construct($resource)
18+
public function __construct($resource, $authorize = null)
1819
{
1920
$this->collects = JsonApiResource::class;
21+
$this->authorize = $authorize;
2022

2123
parent::__construct($resource);
2224

src/Http/Resources/JsonApiResource.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class JsonApiResource extends JsonResource
2121
* Create a new resource instance.
2222
*
2323
* @param mixed $resource
24-
* @param bool $authorize
24+
* @param bool|null $authorize
2525
* @return void
2626
*/
2727
public function __construct($resource, $authorize = null)

0 commit comments

Comments
 (0)