7
7
use Illuminate \Database \Eloquent \Builder ;
8
8
use Illuminate \Database \Eloquent \Collection ;
9
9
use Illuminate \Database \Eloquent \Model as EloquentModel ;
10
+ use Illuminate \Database \Eloquent \Relations \BelongsTo ;
11
+ use Illuminate \Database \Eloquent \Relations \HasOne ;
10
12
use Illuminate \Database \Eloquent \Relations \Relation ;
11
13
use Illuminate \Pagination \LengthAwarePaginator ;
12
14
use Illuminate \Support \Arr ;
@@ -222,7 +224,6 @@ protected function setSort()
222
224
$ type = request ('sort_order ' , null );
223
225
224
226
225
-
226
227
if ($ sort_field && in_array ($ type , ['asc ' , 'desc ' ])) {
227
228
$ this ->sort = [
228
229
'column ' => $ sort_field ,
@@ -246,9 +247,10 @@ protected function setSort()
246
247
}
247
248
248
249
if (Str::contains ($ this ->sort ['column ' ], '. ' )) {
249
- //$this->setRelationSort($this->sort['column']);
250
+ $ this ->setRelationSort ($ this ->sort ['column ' ]);
251
+
250
252
} else {
251
- // $this->resetOrderBy();
253
+ $ this ->resetOrderBy ();
252
254
253
255
// get column. if contains "cast", set set column as cast
254
256
if (!empty ($ this ->sort ['cast ' ])) {
@@ -269,10 +271,102 @@ protected function setSort()
269
271
}
270
272
}
271
273
274
+ /**
275
+ * @param $column
276
+ * @throws \Exception
277
+ */
278
+ protected function setRelationSort ($ column )
279
+ {
280
+ list ($ relationName , $ relationColumn ) = explode ('. ' , $ column );
281
+
282
+
283
+ if ($ this ->queries ->contains (function ($ query ) use ($ relationName ) {
284
+ return $ query ['method ' ] == 'with ' && in_array ($ relationName , $ query ['arguments ' ]);
285
+ })) {
286
+ $ relation = $ this ->model ->$ relationName ();
287
+
288
+
289
+ $ this ->queries ->push ([
290
+ 'method ' => 'select ' ,
291
+ 'arguments ' => [$ this ->model ->getTable () . '.* ' ],
292
+ ]);
293
+
294
+
295
+ $ this ->queries ->push ([
296
+ 'method ' => 'join ' ,
297
+ 'arguments ' => $ this ->joinParameters ($ relation ),
298
+ ]);
299
+
300
+ $ this ->resetOrderBy ();
301
+
302
+ $ this ->queries ->push ([
303
+ 'method ' => 'orderBy ' ,
304
+ 'arguments ' => [
305
+ $ relation ->getRelated ()->getTable () . '. ' . $ relationColumn ,
306
+ $ this ->sort ['type ' ],
307
+ ],
308
+ ]);
309
+ }
310
+ }
311
+
312
+ public function resetOrderBy ()
313
+ {
314
+ $ this ->queries = $ this ->queries ->reject (function ($ query ) {
315
+ return $ query ['method ' ] == 'orderBy ' || $ query ['method ' ] == 'orderByDesc ' ;
316
+ });
317
+ }
318
+
319
+ /**
320
+ * @param Relation $relation
321
+ * @return array
322
+ * @throws \Exception
323
+ */
324
+ protected function joinParameters (Relation $ relation )
325
+ {
326
+ $ relatedTable = $ relation ->getRelated ()->getTable ();
327
+
328
+ if ($ relation instanceof BelongsTo) {
329
+ $ foreignKeyMethod = version_compare (app ()->version (), '5.8.0 ' , '< ' ) ? 'getForeignKey ' : 'getForeignKeyName ' ;
330
+
331
+
332
+ return [
333
+ $ relatedTable ,
334
+ $ relation ->{$ foreignKeyMethod }(),
335
+ '= ' ,
336
+ $ relatedTable . '. ' . $ relation ->getRelated ()->getKeyName (),
337
+ ];
338
+ }
339
+
340
+ if ($ relation instanceof HasOne) {
341
+
342
+ return [
343
+ $ relatedTable , function ($ join ) use ($ relation ) {
344
+ $ join ->on ($ relation ->getQualifiedParentKeyName (), "= " , $ relation ->getQualifiedForeignKeyName ())
345
+ ->where (function (\Illuminate \Database \Query \Builder $ query ) use ($ relation ) {
346
+ collect ($ relation ->getBaseQuery ()->wheres )->filter (function ($ item ) {
347
+ return $ item ['value ' ] ?? false ;
348
+ })->each (function ($ item ) use ($ query ) {
349
+ $ query ->where ($ item ['column ' ], $ item ['value ' ]);
350
+ });
351
+ });
352
+ }
353
+ ];
354
+
355
+ /* return [
356
+ $relatedTable,
357
+ $relation->getQualifiedParentKeyName(),
358
+ '=',
359
+ $relation->getQualifiedForeignKeyName(),
360
+ ];*/
361
+ }
362
+
363
+ throw new \Exception ('Related sortable only support `HasOne` and `BelongsTo` relation. ' );
364
+ }
365
+
272
366
protected function handleInvalidPage (LengthAwarePaginator $ paginator )
273
367
{
274
368
if ($ paginator ->lastPage () && $ paginator ->currentPage () > $ paginator ->lastPage ()) {
275
- $ lastPageUrl = Request::fullUrlWithQuery ([
369
+ $ lastPageUrl = \ Request::fullUrlWithQuery ([
276
370
$ paginator ->getPageName () => $ paginator ->lastPage (),
277
371
]);
278
372
}
@@ -298,19 +392,36 @@ public function buildData($toArray = false)
298
392
protected function displayData ($ data )
299
393
{
300
394
$ columcs = $ this ->grid ->getColumns ();
395
+ $ items = [];
396
+ foreach ($ data as $ row ) {
397
+ $ item = collect ($ row )->toArray ();
398
+ foreach ($ columcs as $ column ) {
399
+ $ n_value = $ column ->customValueUsing ($ row , Arr::get ($ row , $ column ->getName ()));
400
+ Arr::set ($ item , $ column ->getName (), $ n_value );
401
+ }
402
+ $ items [] = $ item ;
403
+ }
404
+
405
+ return $ items ;
406
+
407
+
408
+ /*$data = collect($data)->map(function ($row) use ($columcs) {
301
409
302
- $ data = collect ($ data )->map (function ($ row ) use ($ columcs ) {
303
410
collect($columcs)->each(function (Column $column) use ($row) {
304
411
$keys = explode(".", $column->getName());
412
+
305
413
$keys = array_filter($keys);
306
414
$keys = array_unique($keys);
307
415
if (count($keys) > 0) {
308
416
$value = $row[$keys[0]];
309
- $ row [$ keys [0 ]] = $ column ->customValueUsing ($ row , $ value );
417
+ $n_value = $column->customValueUsing($row, $value);
418
+ Arr::set($row, $column->getName(), $n_value);
419
+
310
420
}
311
421
});
422
+
312
423
return $row;
313
- })->toArray ();
424
+ })->toArray();*/
314
425
315
426
316
427
return $ data ;
@@ -350,7 +461,6 @@ public function get()
350
461
$ this ->setSort ();
351
462
$ this ->setPaginate ();
352
463
353
- //dd($this->queries);
354
464
355
465
$ this ->queries ->unique ()->each (function ($ query ) {
356
466
$ this ->model = call_user_func_array ([$ this ->model , $ query ['method ' ]], $ query ['arguments ' ]);
@@ -360,7 +470,7 @@ public function get()
360
470
$ data = $ this ->model ;
361
471
362
472
if ($ this ->model instanceof Collection) {
363
- return $ data ;
473
+ return $ this -> displayData ( $ data) ;
364
474
}
365
475
366
476
if ($ this ->model instanceof LengthAwarePaginator) {
0 commit comments