* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace Chill\PersonBundle\Export\Aggregator; use Chill\MainBundle\Export\AggregatorInterface; use Symfony\Component\Form\FormBuilderInterface; use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\EntityRepository; use Chill\MainBundle\Templating\TranslatableStringHelper; use Symfony\Component\Translation\TranslatorInterface; use Chill\MainBundle\Util\CountriesInfo; use Symfony\Component\Security\Core\Role\Role; use Chill\PersonBundle\Security\Authorization\PersonVoter; use Chill\MainBundle\Export\ExportElementValidatedInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; /** * * * @author Julien Fastré */ class NationalityAggregator implements AggregatorInterface, ExportElementValidatedInterface { /** * * @var EntityRepository */ protected $countriesRepository; /** * * @var TranslatableStringHelper */ protected $translatableStringHelper; /** * * @var TranslatorInterface */ protected $translator; public function __construct(EntityRepository $countriesRepository, TranslatableStringHelper $translatableStringHelper, TranslatorInterface $translator) { $this->countriesRepository = $countriesRepository; $this->translatableStringHelper = $translatableStringHelper; $this->translator = $translator; } public function applyOn() { return 'person'; } public function buildForm(FormBuilderInterface $builder) { $builder->add('group_by_level', ChoiceType::class, array( 'choices' => array( 'Group by continents' => 'continent', 'Group by country' => 'country' ), 'expanded' => true, 'multiple' => false )); } public function validateForm($data, ExecutionContextInterface $context) { if ($data['group_by_level'] === null) { $context->buildViolation("You should select an option") ->addViolation(); } } public function alterQuery(QueryBuilder $qb, $data) { // add a clause in select part if ($data['group_by_level'] === 'country') { $qb->addSelect('nationality.countryCode as nationality_aggregator'); } elseif ($data['group_by_level'] === 'continent') { $clause = 'CASE ' . 'WHEN nationality.countryCode IN(:africa_codes) THEN \'AF\' ' . 'WHEN nationality.countryCode IN(:asia_codes) THEN \'AS\' ' . 'WHEN nationality.countryCode IN(:europe_codes) THEN \'EU\' ' . 'WHEN nationality.countryCode IN(:north_america_codes) THEN \'NA\' ' . 'WHEN nationality.countryCode IN(:south_america_codes) THEN \'SA\' ' . 'WHEN nationality.countryCode IN(:oceania_codes) THEN \'OC\' ' . 'WHEN nationality.countryCode IN(:antartica_codes) THEN \'AN\' ' . 'ELSE \'\' ' . 'END as nationality_aggregator '; $qb->addSelect($clause); $params = array( 'africa_codes' => CountriesInfo::getCountriesCodeByContinent('AF'), 'asia_codes' => CountriesInfo::getCountriesCodeByContinent('AS'), 'europe_codes' => CountriesInfo::getCountriesCodeByContinent('EU'), 'north_america_codes' => CountriesInfo::getCountriesCodeByContinent('NA'), 'south_america_codes' => CountriesInfo::getCountriesCodeByContinent('SA'), 'oceania_codes' => CountriesInfo::getCountriesCodeByContinent('OC'), '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.nationality', 'nationality'); // add group by $groupBy = $qb->getDQLPart('groupBy'); if (!empty($groupBy)) { $qb->addGroupBy('nationality_aggregator'); } else { $qb->groupBy('nationality_aggregator'); } } public function getTitle() { return "Group people by nationality"; } public function getQueryKeys($data) { return array('nationality_aggregator'); } public function addRole() { return NULL; } public function getLabels($key, array $values, $data) { if ($data['group_by_level'] === 'country') { $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'); $labels['_header'] = $this->translator->trans('Nationality'); foreach($countries as $row) { $labels[$row['c_countryCode']] = $this->translatableStringHelper->localize($row['c_name']); } } elseif ($data['group_by_level'] === 'continent') { $labels = array( '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') ); } return function($value) use ($labels) { return $labels[$value]; }; } }