Skip to content

Commit e6bbffa

Browse files
authored
Merge pull request #160 from fleetbase/dev-v1.6.18
added `without` feature to resources
2 parents 83ac19f + eba3c2a commit e6bbffa

File tree

2 files changed

+150
-9
lines changed

2 files changed

+150
-9
lines changed

src/Http/Resources/FleetbaseResource.php

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@
44

55
use Fleetbase\Support\Http;
66
use Illuminate\Http\Resources\Json\JsonResource;
7+
use Illuminate\Support\Arr;
78
use Illuminate\Support\Str;
89

910
class FleetbaseResource extends JsonResource
1011
{
12+
/**
13+
* List of attributes to exclude from the final array.
14+
*
15+
* @var array
16+
*/
17+
protected array $excluded = [];
18+
1119
/**
1220
* Transform the resource into an array.
1321
*
@@ -17,9 +25,10 @@ class FleetbaseResource extends JsonResource
1725
*/
1826
public function toArray($request)
1927
{
20-
$resource = parent::toArray($request);
28+
$data = parent::toArray($request);
29+
$data = $this->filterExcluded($data);
2130

22-
return $resource;
31+
return $data;
2332
}
2433

2534
/**
@@ -65,4 +74,36 @@ public function getInternalIds(): array
6574

6675
return $internalIds;
6776
}
77+
78+
/**
79+
* Exclude one or more keys from serialization.
80+
*
81+
* @param array|string $keys
82+
* @return static
83+
*/
84+
public function without(array|string $keys): static
85+
{
86+
$clone = clone $this;
87+
$clone->excluded = array_merge($this->excluded, (array) $keys);
88+
89+
return $clone;
90+
}
91+
92+
/**
93+
* Remove excluded keys recursively.
94+
*/
95+
protected function filterExcluded(array $data): array
96+
{
97+
foreach ($this->excluded as $key) {
98+
Arr::forget($data, $key);
99+
}
100+
101+
foreach ($data as $k => $v) {
102+
if (is_array($v)) {
103+
$data[$k] = $this->filterExcluded($v);
104+
}
105+
}
106+
107+
return $data;
108+
}
68109
}

src/Http/Resources/FleetbaseResourceCollection.php

Lines changed: 107 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,135 @@
44

55
use Fleetbase\Http\Resources\Json\FleetbasePaginatedResourceResponse;
66
use Illuminate\Http\Resources\Json\ResourceCollection;
7+
use Illuminate\Support\Arr;
78

9+
/**
10+
* FleetbaseResourceCollection
11+
*
12+
* Usage:
13+
* return (new FleetbaseResourceCollection($paginator, Order::class))
14+
* ->without(['place', 'places', 'payload.places', 'owner.places']);
15+
*
16+
* Notes:
17+
* - Exclusions are instance-scoped (affect only this response).
18+
* - Dot-notation is supported (e.g., 'payload.places', 'customer.address.street').
19+
* - If items are plain models/arrays, they’ll be wrapped with $collects (resource class)
20+
* and exclusions applied to the resolved array.
21+
* - If items are already resources and implement ->without(), that will be used.
22+
*/
823
class FleetbaseResourceCollection extends ResourceCollection
924
{
1025
/**
1126
* The name of the resource being collected.
1227
*
13-
* @var string
28+
* @var class-string|null
1429
*/
1530
public $collects;
1631

1732
/**
18-
* Create a new anonymous resource collection.
33+
* Keys to exclude from each item's serialized array (dot-notation supported).
1934
*
20-
* @param string $collects
35+
* @var array<int, string>
36+
*/
37+
protected array $excluded = [];
38+
39+
/**
40+
* Create a new resource collection.
2141
*
42+
* @param mixed $resource A paginator, array, or collection
43+
* @param class-string|null $collects Fully-qualified resource class for items
2244
* @return void
2345
*/
24-
public function __construct($resource, $collects)
46+
public function __construct($resource, $collects = null)
2547
{
2648
$this->collects = $collects;
2749

2850
parent::__construct($resource);
2951
}
3052

3153
/**
32-
* Create a paginate-aware HTTP response.
54+
* Exclude one or more keys from every item in this collection.
55+
*
56+
* @param array<string>|string $keys
57+
* @return static
58+
*/
59+
public function without(array|string $keys): static
60+
{
61+
$clone = clone $this;
62+
$clone->excluded = array_values(array_unique(array_merge($this->excluded, (array) $keys)));
63+
64+
return $clone;
65+
}
66+
67+
/**
68+
* Convert the resource collection into an array.
69+
*
70+
* Applies the exclusion list to every item. If items are not already resources,
71+
* they are wrapped using the $collects class (if provided).
72+
*
73+
* @param \Illuminate\Http\Request $request
74+
* @return array<int, mixed>
75+
*/
76+
public function toArray($request): array
77+
{
78+
return $this->collection->map(function ($item) use ($request) {
79+
// If the item is already a resource and has ->without(), use it.
80+
if (is_object($item) && method_exists($item, 'toArray')) {
81+
if (method_exists($item, 'without')) {
82+
/** @var object $item */
83+
$array = $item->without($this->excluded)->toArray($request);
84+
return $this->applyArrayExclusions($array);
85+
}
86+
87+
// Otherwise, just resolve it to array and then filter.
88+
$array = $item->toArray($request);
89+
return $this->applyArrayExclusions($array);
90+
}
91+
92+
// If $collects is set, wrap the raw item in the resource class.
93+
if (is_string($this->collects) && class_exists($this->collects)) {
94+
$resource = new $this->collects($item);
95+
96+
if (method_exists($resource, 'without')) {
97+
$array = $resource->without($this->excluded)->toArray($request);
98+
} else {
99+
$array = $resource->toArray($request);
100+
$array = $this->applyArrayExclusions($array);
101+
}
102+
103+
return $array;
104+
}
105+
106+
// Fallback: treat as plain array/object and filter keys.
107+
$array = is_array($item) ? $item : (array) $item;
108+
109+
return $this->applyArrayExclusions($array);
110+
})->all();
111+
}
112+
113+
/**
114+
* Apply the exclusion list to an array using dot-notation.
33115
*
34-
* @param \Illuminate\Http\Request $request
116+
* @param array<string, mixed> $array
117+
* @return array<string, mixed>
118+
*/
119+
protected function applyArrayExclusions(array $array): array
120+
{
121+
if (empty($this->excluded)) {
122+
return $array;
123+
}
124+
125+
foreach ($this->excluded as $key) {
126+
Arr::forget($array, $key);
127+
}
128+
129+
return $array;
130+
}
131+
132+
/**
133+
* Create a paginate-aware HTTP response (unchanged from your original).
35134
*
135+
* @param \Illuminate\Http\Request $request
36136
* @return \Illuminate\Http\JsonResponse
37137
*/
38138
protected function preparePaginatedResponse($request)
@@ -45,4 +145,4 @@ protected function preparePaginatedResponse($request)
45145

46146
return (new FleetbasePaginatedResourceResponse($this))->toResponse($request);
47147
}
48-
}
148+
}

0 commit comments

Comments
 (0)