|
35 | 35 | */ |
36 | 36 | class TasksModel extends ListModel |
37 | 37 | { |
| 38 | + protected $listForbiddenList = ['select', 'multi_ordering']; |
| 39 | + |
38 | 40 | /** |
39 | 41 | * Constructor. |
40 | 42 | * |
@@ -343,8 +345,19 @@ static function (TaskOption $taskOption): string { |
343 | 345 | } |
344 | 346 | } |
345 | 347 | } else { |
346 | | - // @todo Should add quoting here |
347 | | - $query->order($multiOrdering); |
| 348 | + $orderClauses = []; |
| 349 | + |
| 350 | + // Loop through provided clauses |
| 351 | + foreach ($multiOrdering as $ordering) { |
| 352 | + [$column, $direction] = explode(' ', $ordering); |
| 353 | + |
| 354 | + $orderClauses[] = $db->quoteName($column) . ' ' . $direction; |
| 355 | + } |
| 356 | + |
| 357 | + // At least one correct order clause |
| 358 | + if (\count($orderClauses) > 0) { |
| 359 | + $query->order($orderClauses); |
| 360 | + } |
348 | 361 | } |
349 | 362 |
|
350 | 363 | return $query; |
@@ -435,6 +448,44 @@ private function attachTaskOptions(array $items): void |
435 | 448 | */ |
436 | 449 | protected function populateState($ordering = 'a.next_execution', $direction = 'ASC'): void |
437 | 450 | { |
| 451 | + $app = Factory::getApplication(); |
| 452 | + |
| 453 | + // Clean the multiorder values |
| 454 | + if ($list = $app->getUserStateFromRequest($this->context . '.list', 'list', [], 'array')) { |
| 455 | + if (!empty($list['multi_ordering']) && \is_array($list['multi_ordering'])) { |
| 456 | + $orderClauses = []; |
| 457 | + |
| 458 | + // Loop through provided clauses |
| 459 | + foreach ($list['multi_ordering'] as $multiOrdering) { |
| 460 | + // Split the combined string into individual variables |
| 461 | + $multiOrderingParts = explode(' ', $multiOrdering, 2); |
| 462 | + |
| 463 | + // Check that at least the column is present |
| 464 | + if (\count($multiOrderingParts) < 1) { |
| 465 | + continue; |
| 466 | + } |
| 467 | + |
| 468 | + // Assign variables |
| 469 | + $multiOrderingColumn = $multiOrderingParts[0]; |
| 470 | + $multiOrderingDir = \count($multiOrderingParts) === 2 ? $multiOrderingParts[1] : 'asc'; |
| 471 | + |
| 472 | + // Validate provided column |
| 473 | + if (!\in_array($multiOrderingColumn, $this->filter_fields)) { |
| 474 | + continue; |
| 475 | + } |
| 476 | + |
| 477 | + // Validate order dir |
| 478 | + if (strtolower($multiOrderingDir) !== 'asc' && strtolower($multiOrderingDir) !== 'desc') { |
| 479 | + continue; |
| 480 | + } |
| 481 | + |
| 482 | + $orderClauses[] = $multiOrderingColumn . ' ' . $multiOrderingDir; |
| 483 | + } |
| 484 | + |
| 485 | + $this->setState('list.multi_ordering', $orderClauses); |
| 486 | + } |
| 487 | + } |
| 488 | + |
438 | 489 | // Call the parent method |
439 | 490 | parent::populateState($ordering, $direction); |
440 | 491 | } |
|
0 commit comments