cancelReasonRepository = $cancelReasonRepository; $this->translatableStringHelper = $translatableStringHelper; } public function addRole(): ?string { return null; } public function alterQuery(QueryBuilder $qb, $data) { // TODO: still needs to take into account appointments without a cancel reason somehow if (!in_array('calcancel', $qb->getAllAliases(), true)) { $qb->join('cal.cancelReason', 'calcancel'); } $qb->addSelect('IDENTITY(cal.cancelReason) as cancel_reason_aggregator'); $groupBy = $qb->getDQLPart('groupBy'); if (!empty($groupBy)) { $qb->addGroupBy('cancel_reason_aggregator'); } else { $qb->groupBy('cancel_reason_aggregator'); } } public function applyOn(): string { return Declarations::CALENDAR_TYPE; } public function buildForm(FormBuilderInterface $builder) { // no form } public function getLabels($key, array $values, $data): Closure { return function ($value): string { if ('_header' === $value) { return 'Cancel reason'; } $j = $this->cancelReasonRepository->find($value); return $this->translatableStringHelper->localize( $j->getName() ); }; } public function getQueryKeys($data): array { return ['cancel_reason_aggregator']; } public function getTitle(): string { return 'Group appointments by cancel reason'; } }