'month', 'by week' => 'week', 'by year' => 'year', ]; private const DEFAULT_CHOICE = 'year'; public function addRole(): ?string { return null; } public function alterQuery(QueryBuilder $qb, $data) { $order = null; switch ($data['frequency']) { case 'month': $fmt = 'YYYY-MM'; break; case 'week': $fmt = 'YYYY-IW'; break; case 'year': $fmt = 'YYYY'; $order = 'DESC'; break; // order DESC does not works ! default: throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency'])); } $qb->addSelect(sprintf("TO_CHAR(activity.date, '%s') AS date_aggregator", $fmt)); $qb->addGroupBy('date_aggregator'); $qb->addOrderBy('date_aggregator', $order); } public function applyOn(): string { return Declarations::ACTIVITY; } public function buildForm(FormBuilderInterface $builder) { $builder->add('frequency', ChoiceType::class, [ 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, 'empty_data' => self::DEFAULT_CHOICE, ]); } public function getFormDefaultData(): array { return ['frequency' => self::DEFAULT_CHOICE]; } public function getLabels($key, array $values, $data) { return static function ($value) use ($data): string { if ('_header' === $value) { return 'by ' . $data['frequency']; } if (null === $value) { return ''; } switch ($data['frequency']) { case 'month': case 'week': //return $this->translator->trans('for week') .' '. $value ; case 'year': //return $this->translator->trans('in year') .' '. $value ; default: return $value; } }; } public function getQueryKeys($data): array { return ['date_aggregator']; } public function getTitle(): string { return 'Group activity by date'; } }