| 574 | } |
| 575 | |
| 576 | private function aggregateRows(array $data): array { |
| 577 | if (!isset($data['data']) || !is_array($data['data']) || empty($data['data'])) { |
| 578 | return $data; |
| 579 | } |
| 580 | |
| 581 | $aggregatedData = []; |
| 582 | |
| 583 | foreach ($data['data'] as $row) { |
| 584 | if (!is_array($row) || empty($row)) { |
| 585 | continue; |
| 586 | } |
| 587 | |
| 588 | $row = array_values($row); |
| 589 | $value = array_pop($row); |
| 590 | $key = empty($row) ? 'xxsingle_valuexx' : implode("|", $row); |
| 591 | |
| 592 | if (!isset($aggregatedData[$key])) { |
| 593 | $aggregatedData[$key] = 0; |
| 594 | } |
| 595 | |
| 596 | if (is_numeric($value)) { |
| 597 | $aggregatedData[$key] += $value; |
| 598 | } elseif ($value !== null && $value !== '') { |
| 599 | $aggregatedData[$key] = $value; |
| 600 | } |
| 601 | } |
| 602 | |
| 603 | if (empty($aggregatedData)) { |
| 604 | $data['data'] = []; |
| 605 | return $data; |
| 606 | } |
| 607 | |
| 608 | $result = []; |
| 609 | foreach ($aggregatedData as $aKey => $aValue) { |
| 610 | if ($aKey === 'xxsingle_valuexx') { |
| 611 | if (!isset($data['header']) || !is_array($data['header'])) { |
| 612 | $data['header'] = ['']; |
| 613 | } else { |
| 614 | array_unshift($data['header'], ''); |
| 615 | } |
| 616 | $result[] = [$this->l10n->t('Total'), $aValue]; |
| 617 | } else { |
| 618 | $components = explode('|', $aKey); |
| 619 | $result[] = array_merge($components, [$aValue]); |
| 620 | } |
| 621 | } |
| 622 | $data['data'] = $result; |
| 623 | return $data; |
| 624 | } |
| 625 | |
| 626 | private function encodeFilterOptions(array $options): string { |
| 627 | if (empty($options)) { |