countriesRepository = $countriesRepository; $this->translatableStringHelper = $translatableStringHelper; $this->translator = $translator; } public function addRole() { return null; } public function alterQuery(QueryBuilder $qb, $data) { // add a clause in select part if ('country' === $data['group_by_level']) { $qb->addSelect('countryOfBirth.countryCode as country_of_birth_aggregator'); } elseif ('continent' === $data['group_by_level']) { $clause = 'CASE ' . 'WHEN countryOfBirth.countryCode IN(:cob_africa_codes) THEN \'AF\' ' . 'WHEN countryOfBirth.countryCode IN(:cob_asia_codes) THEN \'AS\' ' . 'WHEN countryOfBirth.countryCode IN(:cob_europe_codes) THEN \'EU\' ' . 'WHEN countryOfBirth.countryCode IN(:cob_north_america_codes) THEN \'NA\' ' . 'WHEN countryOfBirth.countryCode IN(:cob_south_america_codes) THEN \'SA\' ' . 'WHEN countryOfBirth.countryCode IN(:cob_oceania_codes) THEN \'OC\' ' . 'WHEN countryOfBirth.countryCode IN(:cob_antartica_codes) THEN \'AN\' ' . 'ELSE \'\' ' . 'END as country_of_birth_aggregator '; $qb->addSelect($clause); $params = [ 'cob_africa_codes' => CountriesInfo::getCountriesCodeByContinent('AF'), 'cob_asia_codes' => CountriesInfo::getCountriesCodeByContinent('AS'), 'cob_europe_codes' => CountriesInfo::getCountriesCodeByContinent('EU'), 'cob_north_america_codes' => CountriesInfo::getCountriesCodeByContinent('NA'), 'cob_south_america_codes' => CountriesInfo::getCountriesCodeByContinent('SA'), 'cob_oceania_codes' => CountriesInfo::getCountriesCodeByContinent('OC'), 'cob_antartica_codes' => CountriesInfo::getCountriesCodeByContinent('AN'), ]; foreach ($params as $k => $v) { $qb->setParameter($k, $v); } } else { throw new LogicException("The group_by_level '" . $data['group_by_level'] . ' is not known.'); } $qb->leftJoin('person.countryOfBirth', 'countryOfBirth'); // add group by $groupBy = $qb->getDQLPart('groupBy'); if (!empty($groupBy)) { $qb->addGroupBy('country_of_birth_aggregator'); } else { $qb->groupBy('country_of_birth_aggregator'); } } public function applyOn() { return 'person'; } public function buildForm(FormBuilderInterface $builder) { $builder->add('group_by_level', ChoiceType::class, [ 'choices' => [ 'Group by continents' => 'continent', 'Group by country' => 'country', ], 'expanded' => true, 'multiple' => false, ]); } public function getLabels($key, array $values, $data) { $labels = []; if ('country' === $data['group_by_level']) { $qb = $this->countriesRepository->createQueryBuilder('c'); $countries = $qb ->andWhere($qb->expr()->in('c.countryCode', ':countries')) ->setParameter('countries', $values) ->getQuery() ->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR); // initialize array and add blank key for null values $labels = [ '' => $this->translator->trans('without data'), '_header' => $this->translator->trans('Country of birth'), ]; foreach ($countries as $row) { $labels[$row['c_countryCode']] = $this->translatableStringHelper->localize($row['c_name']); } } if ('continent' === $data['group_by_level']) { $labels = [ 'EU' => $this->translator->trans('Europe'), 'AS' => $this->translator->trans('Asia'), 'AN' => $this->translator->trans('Antartica'), 'AF' => $this->translator->trans('Africa'), 'SA' => $this->translator->trans('South America'), 'NA' => $this->translator->trans('North America'), 'OC' => $this->translator->trans('Oceania'), '' => $this->translator->trans('without data'), '_header' => $this->translator->trans('Continent of birth'), ]; } return static function (string $value) use ($labels): string { return $labels[$value]; }; } public function getQueryKeys($data) { return ['country_of_birth_aggregator']; } public function getTitle() { return 'Group people by country of birth'; } public function validateForm($data, ExecutionContextInterface $context) { if (null === $data['group_by_level']) { $context->buildViolation('You should select an option') ->addViolation(); } } }