44
55use Fleetbase \Http \Resources \Json \FleetbasePaginatedResourceResponse ;
66use 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+ */
823class 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