1
+ <?php
2
+
3
+ namespace Orion \Concerns ;
4
+
5
+ use Exception ;
6
+ use Illuminate \Database \Eloquent \Model ;
7
+ use Illuminate \Database \Eloquent \Relations \BelongsTo ;
8
+ use Illuminate \Database \Eloquent \Relations \BelongsToMany ;
9
+ use Illuminate \Database \Eloquent \Relations \MorphToMany ;
10
+ use Illuminate \Support \Arr ;
11
+ use Illuminate \Support \Collection ;
12
+ use Orion \Http \Requests \Request ;
13
+ use Orion \Http \Resources \CollectionResource ;
14
+
15
+ trait HandlesRelationStandardBatchOperations
16
+ {
17
+ /**
18
+ * Create a batch of new relation resources.
19
+ *
20
+ * @param Request $request
21
+ * @param int|string $parentKey
22
+ * @return CollectionResource
23
+ */
24
+ public function batchStore (Request $ request , $ parentKey )
25
+ {
26
+ $ beforeHookResult = $ this ->beforeBatchStore ($ request );
27
+ if ($ this ->hookResponds ($ beforeHookResult )) {
28
+ return $ beforeHookResult ;
29
+ }
30
+
31
+ $ resourceModelClass = $ this ->resolveResourceModelClass ();
32
+
33
+ if ($ this ->authorizationRequired ()) {
34
+ $ this ->authorize ('create ' , $ resourceModelClass );
35
+ }
36
+
37
+ /**
38
+ * @var Model $entity
39
+ */
40
+ $ parentEntity = $ this ->queryBuilder ->buildQuery ($ this ->newModelQuery (), $ request )
41
+ ->findOrFail ($ parentKey );
42
+
43
+ $ resources = $ request ->get ('resources ' , []);
44
+ $ entities = collect ([]);
45
+
46
+ foreach ($ resources as $ resource ) {
47
+ $ entity = new $ resourceModelClass ;
48
+ $ entity ->fill (Arr::only ($ resource , $ entity ->getFillable ()));
49
+
50
+ $ this ->beforeStore ($ request , $ entity );
51
+ $ this ->beforeSave ($ request , $ entity );
52
+
53
+ if (!$ parentEntity ->{$ this ->getRelation ()}() instanceof BelongsTo) {
54
+ $ parentEntity ->{$ this ->getRelation ()}()->save ($ entity , $ this ->preparePivotFields (Arr::get ($ resource , 'pivot ' , [])));
55
+ } else {
56
+ $ entity ->save ();
57
+ $ parentEntity ->{$ this ->getRelation ()}()->associate ($ entity );
58
+ }
59
+
60
+ $ entity = $ entity ->fresh ($ this ->relationsResolver ->requestedRelations ($ request ));
61
+ $ entity ->wasRecentlyCreated = true ;
62
+
63
+ $ entity = $ this ->cleanupEntity ($ entity );
64
+
65
+ if (count ($ this ->getPivotJson ())) {
66
+ $ entity = $ this ->castPivotJsonFields ($ entity );
67
+ }
68
+
69
+ $ this ->afterSave ($ request , $ entity );
70
+ $ this ->afterStore ($ request , $ entity );
71
+
72
+ $ entities ->push ($ entity );
73
+ }
74
+
75
+ $ afterHookResult = $ this ->afterBatchStore ($ request , $ entities );
76
+ if ($ this ->hookResponds ($ afterHookResult )) {
77
+ return $ afterHookResult ;
78
+ }
79
+
80
+ return $ this ->collectionResponse ($ entities );
81
+ }
82
+
83
+ /**
84
+ * Updates a batch of relation resources.
85
+ *
86
+ * @param Request $request
87
+ * @param int|string $parentKey
88
+ * @return CollectionResource
89
+ */
90
+ public function batchUpdate (Request $ request , $ parentKey )
91
+ {
92
+ $ beforeHookResult = $ this ->beforeBatchUpdate ($ request );
93
+ if ($ this ->hookResponds ($ beforeHookResult )) {
94
+ return $ beforeHookResult ;
95
+ }
96
+
97
+ $ parentEntity = $ this ->queryBuilder ->buildQuery ($ this ->newModelQuery (), $ request )
98
+ ->findOrFail ($ parentKey );
99
+
100
+ $ resourceModelClass = $ this ->resolveResourceModelClass ();
101
+ $ resourceKeyName = (new $ resourceModelClass )->getKeyName ();
102
+
103
+ $ entities = $ this ->relationQueryBuilder ->buildQuery ($ this ->newRelationQuery ($ parentEntity ), $ request )
104
+ ->with ($ this ->relationsResolver ->requestedRelations ($ request ))
105
+ ->whereIn ($ resourceKeyName , array_keys ($ request ->get ('resources ' , [])))
106
+ ->get ();
107
+
108
+ foreach ($ entities as $ entity ) {
109
+ /**
110
+ * @var Model $entity
111
+ */
112
+ if ($ this ->authorizationRequired ()) {
113
+ $ this ->authorize ('update ' , $ entity );
114
+ }
115
+
116
+ $ resource = $ request ->input ("resources. {$ entity ->getKey ()}" );
117
+
118
+ $ entity ->fill (Arr::only ($ resource , $ entity ->getFillable ()));
119
+
120
+ $ this ->beforeUpdate ($ request , $ entity );
121
+ $ this ->beforeSave ($ request , $ entity );
122
+
123
+ $ entity ->save ();
124
+
125
+ $ relation = $ parentEntity ->{$ this ->getRelation ()}();
126
+ if ($ relation instanceof BelongsToMany || $ relation instanceof MorphToMany) {
127
+ $ relation ->updateExistingPivot ($ entity ->getKey (), $ this ->preparePivotFields (Arr::get ($ resource , 'pivot ' , [])));
128
+
129
+ $ entity = $ entity ->fresh ($ this ->relationsResolver ->requestedRelations ($ request ));
130
+ }
131
+
132
+ $ entity = $ this ->cleanupEntity ($ entity );
133
+
134
+ if (count ($ this ->getPivotJson ())) {
135
+ $ entity = $ this ->castPivotJsonFields ($ entity );
136
+ }
137
+
138
+ $ this ->afterSave ($ request , $ entity );
139
+ $ this ->afterUpdate ($ request , $ entity );
140
+ }
141
+
142
+ $ afterHookResult = $ this ->afterBatchUpdate ($ request , $ entities );
143
+ if ($ this ->hookResponds ($ afterHookResult )) {
144
+ return $ afterHookResult ;
145
+ }
146
+
147
+ return $ this ->collectionResponse ($ entities );
148
+ }
149
+
150
+ /**
151
+ * Deletes a batch of relation resources.
152
+ *
153
+ * @param Request $request
154
+ * @param int|string $parentKey
155
+ * @return CollectionResource
156
+ * @throws Exception
157
+ */
158
+ public function batchDestroy (Request $ request , $ parentKey )
159
+ {
160
+ $ beforeHookResult = $ this ->beforeBatchDestroy ($ request );
161
+ if ($ this ->hookResponds ($ beforeHookResult )) {
162
+ return $ beforeHookResult ;
163
+ }
164
+
165
+ $ parentEntity = $ this ->queryBuilder ->buildQuery ($ this ->newModelQuery (), $ request )
166
+ ->findOrFail ($ parentKey );
167
+
168
+ $ resourceModelClass = $ this ->resolveResourceModelClass ();
169
+ $ resourceKeyName = (new $ resourceModelClass )->getKeyName ();
170
+
171
+ $ softDeletes = $ this ->softDeletes ($ this ->resolveResourceModelClass ());
172
+
173
+ $ entities = $ this ->relationQueryBuilder ->buildQuery ($ this ->newRelationQuery ($ parentEntity ), $ request )
174
+ ->with ($ this ->relationsResolver ->requestedRelations ($ request ))
175
+ ->when ($ softDeletes , function ($ query ) {
176
+ $ query ->withTrashed ();
177
+ })
178
+ ->whereIn ($ resourceKeyName , $ request ->get ('resources ' , []))
179
+ ->get ();
180
+
181
+ foreach ($ entities as $ entity ) {
182
+ /**
183
+ * @var Model $entity
184
+ */
185
+ $ forceDeletes = $ softDeletes && $ request ->get ('force ' );
186
+
187
+ if ($ this ->authorizationRequired ()) {
188
+ $ this ->authorize ($ forceDeletes ? 'forceDelete ' : 'delete ' , $ entity );
189
+ }
190
+
191
+ $ this ->beforeDestroy ($ request , $ entity );
192
+
193
+ if (!$ forceDeletes ) {
194
+ $ entity ->delete ();
195
+ } else {
196
+ $ entity ->forceDelete ();
197
+ }
198
+
199
+ $ entity = $ this ->cleanupEntity ($ entity );
200
+
201
+ if (count ($ this ->getPivotJson ())) {
202
+ $ entity = $ this ->castPivotJsonFields ($ entity );
203
+ }
204
+
205
+ $ this ->afterDestroy ($ request , $ entity );
206
+ }
207
+
208
+ $ afterHookResult = $ this ->afterBatchDestroy ($ request , $ entities );
209
+ if ($ this ->hookResponds ($ afterHookResult )) {
210
+ return $ afterHookResult ;
211
+ }
212
+
213
+ return $ this ->collectionResponse ($ entities );
214
+ }
215
+
216
+ /**
217
+ * Restores a batch of relation resources.
218
+ *
219
+ * @param Request $request
220
+ * @param int|string $parentKey
221
+ * @return CollectionResource
222
+ * @throws Exception
223
+ */
224
+ public function batchRestore (Request $ request , $ parentKey )
225
+ {
226
+ $ beforeHookResult = $ this ->beforeBatchRestore ($ request );
227
+ if ($ this ->hookResponds ($ beforeHookResult )) {
228
+ return $ beforeHookResult ;
229
+ }
230
+
231
+ $ parentEntity = $ this ->queryBuilder ->buildQuery ($ this ->newModelQuery (), $ request )
232
+ ->findOrFail ($ parentKey );
233
+
234
+ $ resourceModelClass = $ this ->resolveResourceModelClass ();
235
+ $ resourceKeyName = (new $ resourceModelClass )->getKeyName ();
236
+
237
+ $ entities = $ this ->relationQueryBuilder ->buildQuery ($ this ->newRelationQuery ($ parentEntity ), $ request )
238
+ ->with ($ this ->relationsResolver ->requestedRelations ($ request ))
239
+ ->whereIn ($ resourceKeyName , $ request ->get ('resources ' , []))
240
+ ->withTrashed ()
241
+ ->get ();
242
+
243
+ foreach ($ entities as $ entity ) {
244
+ /**
245
+ * @var Model $entity
246
+ */
247
+ if ($ this ->authorizationRequired ()) {
248
+ $ this ->authorize ('restore ' , $ entity );
249
+ }
250
+
251
+ $ this ->beforeRestore ($ request , $ entity );
252
+
253
+ $ entity ->restore ();
254
+
255
+ $ entity = $ this ->cleanupEntity ($ entity );
256
+
257
+ if (count ($ this ->getPivotJson ())) {
258
+ $ entity = $ this ->castPivotJsonFields ($ entity );
259
+ }
260
+
261
+ $ this ->afterRestore ($ request , $ entity );
262
+ }
263
+
264
+ $ afterHookResult = $ this ->afterBatchRestore ($ request , $ entities );
265
+ if ($ this ->hookResponds ($ afterHookResult )) {
266
+ return $ afterHookResult ;
267
+ }
268
+
269
+ return $ this ->collectionResponse ($ entities );
270
+ }
271
+
272
+ /**
273
+ * The hook is executed before creating a batch of new resources.
274
+ *
275
+ * @param Request $request
276
+ * @return mixed
277
+ */
278
+ protected function beforeBatchStore (Request $ request )
279
+ {
280
+ return null ;
281
+ }
282
+
283
+ /**
284
+ * The hook is executed after creating a batch of new resources.
285
+ *
286
+ * @param Request $request
287
+ * @param Collection $entities
288
+ * @return mixed
289
+ */
290
+ protected function afterBatchStore (Request $ request , Collection $ entities )
291
+ {
292
+ return null ;
293
+ }
294
+
295
+ /**
296
+ * The hook is executed before updating a batch of resources.
297
+ *
298
+ * @param Request $request
299
+ * @return mixed
300
+ */
301
+ protected function beforeBatchUpdate (Request $ request )
302
+ {
303
+ return null ;
304
+ }
305
+
306
+ /**
307
+ * The hook is executed after updating a batch of resources.
308
+ *
309
+ * @param Request $request
310
+ * @param Collection $entities
311
+ * @return mixed
312
+ */
313
+ protected function afterBatchUpdate (Request $ request , Collection $ entities )
314
+ {
315
+ return null ;
316
+ }
317
+
318
+ /**
319
+ * The hook is executed before deleting a batch of resources.
320
+ *
321
+ * @param Request $request
322
+ * @return mixed
323
+ */
324
+ protected function beforeBatchDestroy (Request $ request )
325
+ {
326
+ return null ;
327
+ }
328
+
329
+ /**
330
+ * The hook is executed after deleting a batch of resources.
331
+ *
332
+ * @param Request $request
333
+ * @param Collection $entities
334
+ * @return mixed
335
+ */
336
+ protected function afterBatchDestroy (Request $ request , Collection $ entities )
337
+ {
338
+ return null ;
339
+ }
340
+
341
+ /**
342
+ * The hook is executed before restoring a batch of resources.
343
+ *
344
+ * @param Request $request
345
+ * @return mixed
346
+ */
347
+ protected function beforeBatchRestore (Request $ request )
348
+ {
349
+ return null ;
350
+ }
351
+
352
+ /**
353
+ * The hook is executed after restoring a batch of resources.
354
+ *
355
+ * @param Request $request
356
+ * @param Collection $entities
357
+ * @return mixed
358
+ */
359
+ protected function afterBatchRestore (Request $ request , Collection $ entities )
360
+ {
361
+ return null ;
362
+ }
363
+ }
0 commit comments