cs: Fix code style (safe rules only).

This commit is contained in:
Pol Dellaiera
2021-11-23 14:06:38 +01:00
parent 149d7ce991
commit 8f96a1121d
1223 changed files with 65199 additions and 64625 deletions

View File

@@ -1,59 +1,44 @@
<?php
/*
* Copyright (C) 2019 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use function in_array;
/**
*
*
*/
class AbstractAccompanyingPeriodExportElement
{
/**
* Add the accompanying period alias to the query.
*
* @throws LogicException if the "person" alias is not present and attaching accompanying period is not possible
*/
protected function addJoinAccompanyingPeriod(QueryBuilder $query): void
{
if (false === $this->havingAccompanyingPeriodInJoin($query)) {
if (false === in_array('person', $query->getAllAliases())) {
throw new LogicException("the alias 'person' does not exists in "
. 'query builder');
}
$query->join('person.accompanyingPeriods', 'accompanying_period');
}
}
/**
* Return true if "accompanying_period" alias is present in the query alises.
*
* @param QueryBuilder $query
* @return bool
*/
protected function havingAccompanyingPeriodInJoin(QueryBuilder $query): bool
{
$joins = $query->getDQLPart('join') ?? [];
return (\in_array('accompanying_period', $query->getAllAliases()));
}
/**
* Add the accompanying period alias to the query
*
* @param QueryBuilder $query
* @return void
* @throws \LogicException if the "person" alias is not present and attaching accompanying period is not possible
*/
protected function addJoinAccompanyingPeriod(QueryBuilder $query): void
{
if (FALSE === $this->havingAccompanyingPeriodInJoin($query)) {
if (FALSE === \in_array('person', $query->getAllAliases())) {
throw new \LogicException("the alias 'person' does not exists in "
. "query builder");
}
$query->join('person.accompanyingPeriods', 'accompanying_period');
}
return in_array('accompanying_period', $query->getAllAliases());
}
}

View File

@@ -1,28 +1,19 @@
<?php
/*
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Aggregator;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use DateTime;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -54,48 +45,47 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder)
{
$builder->add('date_age_calculation', DateType::class, array(
'label' => "Calculate age in relation to this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
'format' => 'dd-MM-yyyy'
));
}
public function validateForm($data, ExecutionContextInterface $context)
{
if ($data['date_age_calculation'] === null) {
$context->buildViolation("The date should not be empty")
->addViolation();
}
$builder->add('date_age_calculation', DateType::class, [
'label' => 'Calculate age in relation to this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
]);
}
public function getLabels($key, array $values, $data)
{
return function($value) {
if ($value === '_header') {
return "Age";
return function ($value) {
if ('_header' === $value) {
return 'Age';
}
if ($value === NULL) {
return $this->translator->trans("without data");
if (null === $value) {
return $this->translator->trans('without data');
}
return $value;
};
}
public function getQueryKeys($data)
{
return array(
'person_age'
);
return [
'person_age',
];
}
public function getTitle()
{
return "Aggregate by age";
return 'Aggregate by age';
}
public function validateForm($data, ExecutionContextInterface $context)
{
if (null === $data['date_age_calculation']) {
$context->buildViolation('The date should not be empty')
->addViolation();
}
}
}

View File

@@ -1,37 +1,25 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
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 Chill\MainBundle\Repository\CountryRepository;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Util\CountriesInfo;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
final class CountryOfBirthAggregator implements AggregatorInterface, ExportElementValidatedInterface
{
@@ -51,38 +39,17 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
$this->translator = $translator;
}
public function applyOn()
public function addRole()
{
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();
}
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
// add a clause in select part
if ($data['group_by_level'] === 'country') {
if ('country' === $data['group_by_level']) {
$qb->addSelect('countryOfBirth.countryCode as country_of_birth_aggregator');
} elseif ($data['group_by_level'] === 'continent') {
} 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\' '
@@ -95,24 +62,24 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
. 'END as country_of_birth_aggregator ';
$qb->addSelect($clause);
$params =
array(
[
'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')
);
'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.");
throw new LogicException("The group_by_level '" . $data['group_by_level']
. ' is not known.');
}
$qb->leftJoin('person.countryOfBirth', 'countryOfBirth');
// add group by
@@ -123,36 +90,37 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
} else {
$qb->groupBy('country_of_birth_aggregator');
}
}
public function getTitle()
public function applyOn()
{
return "Group people by country of birth";
return 'person';
}
public function getQueryKeys($data)
public function buildForm(FormBuilderInterface $builder)
{
return array('country_of_birth_aggregator');
}
public function addRole()
{
return NULL;
$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 ($data['group_by_level'] === 'country') {
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);
->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 = [
@@ -160,13 +128,13 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
'_header' => $this->translator->trans('Country of birth'),
];
foreach($countries as $row) {
foreach ($countries as $row) {
$labels[$row['c_countryCode']] = $this->translatableStringHelper->localize($row['c_name']);
}
}
if ($data['group_by_level'] === 'continent') {
$labels = array(
if ('continent' === $data['group_by_level']) {
$labels = [
'EU' => $this->translator->trans('Europe'),
'AS' => $this->translator->trans('Asia'),
'AN' => $this->translator->trans('Antartica'),
@@ -175,13 +143,30 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
'NA' => $this->translator->trans('North America'),
'OC' => $this->translator->trans('Oceania'),
'' => $this->translator->trans('without data'),
'_header' => $this->translator->trans('Continent of birth')
);
'_header' => $this->translator->trans('Continent of birth'),
];
}
return function(string $value) use ($labels): string {
return 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();
}
}
}

View File

@@ -1,30 +1,21 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Aggregator;
use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\TranslatorInterface;
final class GenderAggregator implements AggregatorInterface
{
@@ -35,6 +26,18 @@ final class GenderAggregator implements AggregatorInterface
$this->translator = $translator;
}
public function addRole()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->addSelect('person.gender as gender');
$qb->addGroupBy('gender');
}
public function applyOn()
{
return Declarations::PERSON_TYPE;
@@ -42,51 +45,40 @@ final class GenderAggregator implements AggregatorInterface
public function buildForm(FormBuilderInterface $builder)
{
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->addSelect('person.gender as gender');
$qb->addGroupBy('gender');
}
public function getTitle()
{
return "Group people by gender";
}
public function getQueryKeys($data)
{
return array('gender');
}
public function getLabels($key, array $values, $data)
{
return function($value) {
{
return function ($value) {
switch ($value) {
case Person::FEMALE_GENDER :
case Person::FEMALE_GENDER:
return $this->translator->trans('woman');
case Person::MALE_GENDER :
case Person::MALE_GENDER:
return $this->translator->trans('man');
case Person::BOTH_GENDER:
return $this->translator->trans('both');
case null:
return $this->translator->trans('Not given');
case '_header' :
case '_header':
return $this->translator->trans('Gender');
default:
throw new \LogicException(sprintf("The value %s is not valid", $value));
throw new LogicException(sprintf('The value %s is not valid', $value));
}
};
}
public function addRole()
public function getQueryKeys($data)
{
return NULL;
return ['gender'];
}
public function getTitle()
{
return 'Group people by gender';
}
}

View File

@@ -1,37 +1,25 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
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 Chill\MainBundle\Repository\CountryRepository;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Util\CountriesInfo;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
final class NationalityAggregator implements AggregatorInterface, ExportElementValidatedInterface
{
@@ -51,39 +39,17 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
$this->translator = $translator;
}
public function applyOn()
public function addRole()
{
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();
}
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
// add a clause in select part
if ($data['group_by_level'] === 'country') {
if ('country' === $data['group_by_level']) {
$qb->addSelect('nationality.countryCode as nationality_aggregator');
} elseif ($data['group_by_level'] === 'continent') {
} elseif ('continent' === $data['group_by_level']) {
$clause = 'CASE '
. 'WHEN nationality.countryCode IN(:africa_codes) THEN \'AF\' '
. 'WHEN nationality.countryCode IN(:asia_codes) THEN \'AS\' '
@@ -96,24 +62,24 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
. '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')
);
'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.");
throw new LogicException("The group_by_level '" . $data['group_by_level']
. ' is not known.');
}
$qb->leftJoin('person.nationality', 'nationality');
// add group by
@@ -124,36 +90,37 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
} else {
$qb->groupBy('nationality_aggregator');
}
}
public function getTitle()
public function applyOn()
{
return "Group people by nationality";
return 'person';
}
public function getQueryKeys($data)
public function buildForm(FormBuilderInterface $builder)
{
return array('nationality_aggregator');
}
public function addRole()
{
return NULL;
$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 ($data['group_by_level'] === 'country') {
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);
->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 = [
@@ -161,13 +128,13 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
'_header' => $this->translator->trans('Nationality'),
];
foreach($countries as $row) {
foreach ($countries as $row) {
$labels[$row['c_countryCode']] = $this->translatableStringHelper->localize($row['c_name']);
}
}
if ($data['group_by_level'] === 'continent') {
$labels = array(
if ('continent' === $data['group_by_level']) {
$labels = [
'EU' => $this->translator->trans('Europe'),
'AS' => $this->translator->trans('Asia'),
'AN' => $this->translator->trans('Antartica'),
@@ -175,14 +142,31 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
'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')
);
'' => $this->translator->trans('without data'),
'_header' => $this->translator->trans('Continent'),
];
}
return function(string $value) use ($labels): string {
return function (string $value) use ($labels): string {
return $labels[$value];
};
}
public function getQueryKeys($data)
{
return ['nationality_aggregator'];
}
public function getTitle()
{
return 'Group people by nationality';
}
public function validateForm($data, ExecutionContextInterface $context)
{
if (null === $data['group_by_level']) {
$context->buildViolation('You should select an option')
->addViolation();
}
}
}

View File

@@ -1,32 +1,20 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export;
/**
* This class declare constants used for the export framework.
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
abstract class Declarations
{
CONST PERSON_TYPE = 'person';
CONST PERSON_IMPLIED_IN = 'person_implied_in';
public const PERSON_IMPLIED_IN = 'person_implied_in';
public const PERSON_TYPE = 'person';
}

View File

@@ -1,136 +1,113 @@
<?php
/*
* Copyright (C) 2015 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Export;
use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\Query;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Export\Declarations;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class CountPerson implements ExportInterface
{
/**
*
* @var EntityManagerInterface
*/
protected $entityManager;
public function __construct(
EntityManagerInterface $em
)
{
EntityManagerInterface $em
) {
$this->entityManager = $em;
}
/**
*
*/
public function getType()
public function buildForm(FormBuilderInterface $builder)
{
return Declarations::PERSON_TYPE;
}
public function getAllowedFormattersTypes()
{
return [FormatterInterface::TYPE_TABULAR];
}
public function getDescription()
{
return "Count peoples by various parameters.";
return 'Count peoples by various parameters.';
}
public function getTitle()
public function getLabels($key, array $values, $data)
{
return "Count peoples";
if ('export_result' !== $key) {
throw new LogicException("the key {$key} is not used by this export");
}
$labels = array_combine($values, $values);
$labels['_header'] = $this->getTitle();
return function ($value) use ($labels) {
return $labels[$value];
};
}
public function requiredRole()
public function getQueryKeys($data)
{
return new Role(PersonVoter::STATS);
return ['export_result'];
}
/**
* Initiate the query
*
* @param QueryBuilder $qb
* @return QueryBuilder
*/
public function initiateQuery(array $requiredModifiers, array $acl, array $data = array())
{
$centers = array_map(function($el) { return $el['center']; }, $acl);
$qb = $this->entityManager->createQueryBuilder();
$qb->select('COUNT(person.id) AS export_result')
->from('ChillPersonBundle:Person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
;
return $qb;
}
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getQueryKeys($data)
{
return array('export_result');
}
public function getLabels($key, array $values, $data)
{
if ($key !== 'export_result') {
throw new \LogicException("the key $key is not used by this export");
}
$labels = array_combine($values, $values);
$labels['_header'] = $this->getTitle();
return function($value) use ($labels) {
return $labels[$value];
};
}
public function getAllowedFormattersTypes()
{
return array(FormatterInterface::TYPE_TABULAR);
}
public function buildForm(FormBuilderInterface $builder) {
public function getTitle()
{
return 'Count peoples';
}
public function getType()
{
return Declarations::PERSON_TYPE;
}
/**
* Initiate the query.
*
* @return QueryBuilder
*/
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$centers = array_map(function ($el) { return $el['center']; }, $acl);
$qb = $this->entityManager->createQueryBuilder();
$qb->select('COUNT(person.id) AS export_result')
->from('ChillPersonBundle:Person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
return $qb;
}
public function requiredRole()
{
return new Role(PersonVoter::STATS);
}
public function supportsModifiers()
{
return array(Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN);
return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN];
}
}

View File

@@ -1,59 +1,73 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Export\Export;
use Chill\MainBundle\Export\ListInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\Query;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Export\Declarations;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
use Chill\CustomFieldsBundle\Entity\CustomField;
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\ListInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Exception;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\CustomFieldsBundle\Entity\CustomField;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
use function addcslashes;
use function array_key_exists;
use function array_keys;
use function array_merge;
use function strtolower;
use function uniqid;
/**
* Render a list of people.
*/
class ListPerson implements ListInterface, ExportElementValidatedInterface
{
protected EntityManagerInterface $entityManager;
protected TranslatorInterface $translator;
protected TranslatableStringHelper $translatableStringHelper;
protected CustomFieldProvider $customFieldProvider;
protected EntityManagerInterface $entityManager;
protected array $fields = [
'id', 'firstName', 'lastName', 'birthdate',
'placeOfBirth', 'gender', 'memo', 'email', 'phonenumber',
'mobilenumber', 'contactInfo', 'countryOfBirth', 'nationality',
'address_street_address_1', 'address_street_address_2',
'address_valid_from', 'address_postcode_label', 'address_postcode_code',
'address_country_name', 'address_country_code', 'address_isnoaddress'
'address_country_name', 'address_country_code', 'address_isnoaddress',
];
protected TranslatableStringHelper $translatableStringHelper;
protected TranslatorInterface $translator;
private $slugs = [];
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper,
CustomFieldProvider $customFieldProvider
EntityManagerInterface $em,
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper,
CustomFieldProvider $customFieldProvider
) {
$this->entityManager = $em;
$this->translator = $translator;
@@ -66,19 +80,18 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
$choices = array_combine($this->fields, $this->fields);
foreach ($this->getCustomFields() as $cf) {
$choices
[$this->translatableStringHelper->localize($cf->getName())]
$choices[$this->translatableStringHelper->localize($cf->getName())]
=
$cf->getSlug();
}
// Add a checkbox to select fields
$builder->add('fields', ChoiceType::class, array(
$builder->add('fields', ChoiceType::class, [
'multiple' => true,
'expanded' => true,
'choices' => $choices,
'label' => 'Fields to include in export',
'choice_attr' => static function(string $val): array {
'label' => 'Fields to include in export',
'choice_attr' => static function (string $val): array {
// add a 'data-display-target' for address fields
if (substr($val, 0, 8) === 'address_') {
return ['data-display-target' => 'address_date'];
@@ -86,76 +99,37 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
return [];
},
'constraints' => [new Callback(array(
'callback' => function($selected, ExecutionContextInterface $context) {
'constraints' => [new Callback([
'callback' => function ($selected, ExecutionContextInterface $context) {
if (count($selected) === 0) {
$context->buildViolation('You must select at least one element')
->atPath('fields')
->addViolation();
}
}
))]
));
},
])],
]);
// add a date field for addresses
$builder->add('address_date', DateType::class, array(
'label' => "Address valid at this date",
'data' => new \DateTime(),
'attr' => array( 'class' => 'datepicker'),
'widget'=> 'single_text',
$builder->add('address_date', DateType::class, [
'label' => 'Address valid at this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
'required' => false,
'block_name' => 'list_export_form_address_date'
));
}
public function validateForm($data, ExecutionContextInterface $context)
{
// get the field starting with address_
$addressFields = array_filter(
$this->fields,
static fn(string $el): bool => substr($el, 0, 8) === 'address_'
);
// check if there is one field starting with address in data
if (count(array_intersect($data['fields'], $addressFields)) > 0) {
// if a field address is checked, the date must not be empty
if (empty($data['address_date'])) {
$context
->buildViolation("You must set this date if an address is checked")
->atPath('address_date')
->addViolation();
}
}
}
/**
* Get custom fields associated with person
*
* @return CustomField[]
*/
private function getCustomFields()
{
return $this->entityManager
->createQuery("SELECT cf "
. "FROM ChillCustomFieldsBundle:CustomField cf "
. "JOIN cf.customFieldGroup g "
. "WHERE cf.type != :title AND g.entity LIKE :entity")
->setParameters(array(
'title' => 'title',
'entity' => \addcslashes(Person::class, "\\")
))
->getResult();
'block_name' => 'list_export_form_address_date',
]);
}
public function getAllowedFormattersTypes()
{
return array(FormatterInterface::TYPE_LIST);
return [FormatterInterface::TYPE_LIST];
}
public function getDescription()
{
return "Create a list of people according to various filters.";
return 'Create a list of people according to various filters.';
}
public function getLabels($key, array $values, $data)
@@ -164,63 +138,75 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
case 'birthdate':
// for birthdate, we have to transform the string into a date
// to format the date correctly.
return static function($value) {
if ($value === '_header') { return 'birthdate'; }
if (empty($value))
{
return "";
return static function ($value) {
if ('_header' === $value) {
return 'birthdate';
}
$date = \DateTime::createFromFormat('Y-m-d', $value);
if (empty($value)) {
return '';
}
$date = DateTime::createFromFormat('Y-m-d', $value);
// check that the creation could occurs.
if ($date === false) {
throw new \Exception(sprintf("The value %s could "
. "not be converted to %s", $value, \DateTime::class));
if (false === $date) {
throw new Exception(sprintf('The value %s could '
. 'not be converted to %s', $value, DateTime::class));
}
return $date->format('d-m-Y');
};
case 'gender' :
case 'gender':
// for gender, we have to translate men/women statement
return function($value) {
if ($value === '_header') { return 'gender'; }
return function ($value) {
if ('_header' === $value) {
return 'gender';
}
return $this->translator->trans($value);
};
case 'countryOfBirth':
case 'nationality':
$countryRepository = $this->entityManager
->getRepository('ChillMainBundle:Country');
// load all countries in a single query
$countryRepository->findBy(array('countryCode' => $values));
$countryRepository->findBy(['countryCode' => $values]);
return function($value) use ($key, $countryRepository) {
if ($value === '_header') { return \strtolower($key); }
return function ($value) use ($key, $countryRepository) {
if ('_header' === $value) {
return strtolower($key);
}
if ($value === NULL) {
if (null === $value) {
return $this->translator->trans('no data');
}
$country = $countryRepository->find($value);
return $this->translatableStringHelper->localize(
$country->getName());
$country->getName()
);
};
case 'address_country_name':
return function($value) use ($key) {
if ($value === '_header') { return \strtolower($key); }
if ($value === NULL) {
case 'address_country_name':
return function ($value) use ($key) {
if ('_header' === $value) {
return strtolower($key);
}
if (null === $value) {
return '';
}
return $this->translatableStringHelper->localize(json_decode($value, true));
};
case 'address_isnoaddress':
return static function(?string $value): string {
if ($value === '_header') {
return static function (?string $value): string {
if ('_header' === $value) {
return 'address.address_homeless';
}
@@ -230,68 +216,26 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
return '';
};
default:
// for fields which are associated with person
if (in_array($key, $this->fields)) {
return static function($value) use ($key) {
if ($value === '_header') { return \strtolower($key); }
return static function ($value) use ($key) {
if ('_header' === $value) {
return strtolower($key);
}
return $value;
};
};
}
return $this->getLabelForCustomField($key, $values, $data);
}
}
private function getLabelForCustomField($key, array $values, $data)
{
// for fields which are custom fields
/* @var $cf CustomField */
$cf = $this->entityManager
->getRepository(CustomField::class)
->findOneBy(array('slug' => $this->DQLToSlug($key)));
$cfType = $this->customFieldProvider->getCustomFieldByType($cf->getType());
$defaultFunction = function($value) use ($cf) {
if ($value === '_header') {
return $this->translatableStringHelper->localize($cf->getName());
}
return $this->customFieldProvider
->getCustomFieldByType($cf->getType())
->render(json_decode($value, true), $cf, 'csv');
};
if ($cfType instanceof CustomFieldChoice and $cfType->isMultiple($cf)) {
return function($value) use ($cf, $cfType, $key) {
$slugChoice = $this->extractInfosFromSlug($key)['additionnalInfos']['choiceSlug'];
$decoded = \json_decode($value, true);
if ($value === '_header') {
$label = $cfType->getChoices($cf)[$slugChoice];
return $this->translatableStringHelper->localize($cf->getName())
.' | '.$label;
}
if ($slugChoice === '_other' and $cfType->isChecked($cf, $choiceSlug, $decoded)) {
return $cfType->extractOtherValue($cf, $decoded);
}
return $cfType->isChecked($cf, $slugChoice, $decoded);
};
}
return $defaultFunction;
}
public function getQueryKeys($data)
{
$fields = array();
$fields = [];
foreach ($data['fields'] as $key) {
if (in_array($key, $this->fields)) {
@@ -300,36 +244,7 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
}
// add the key from slugs and return
return \array_merge($fields, \array_keys($this->slugs));
}
/**
* Clean a slug to be usable by DQL.
*/
private function slugToDQL(string $slug, string $type = "default", array $additionalInfos = []): string
{
$uid = 'slug_' . \uniqid('', true);
$this->slugs[$uid] = [
'slug' => $slug,
'type' => $type,
'additionnalInfos' => $additionalInfos
];
return $uid;
}
private function DQLToSlug($cleanedSlug)
{
return $this->slugs[$cleanedSlug]['slug'];
}
/**
* @return array An array with keys = 'slug', 'type', 'additionnalInfo'
*/
private function extractInfosFromSlug($slug): array
{
return $this->slugs[$slug];
return array_merge($fields, array_keys($this->slugs));
}
public function getResult($query, $data)
@@ -339,7 +254,7 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
public function getTitle()
{
return "List peoples";
return 'List peoples';
}
public function getType()
@@ -347,14 +262,14 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
return Declarations::PERSON_TYPE;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = array())
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$centers = array_map(function($el) { return $el['center']; }, $acl);
$centers = array_map(function ($el) { return $el['center']; }, $acl);
// throw an error if any fields are present
if (!\array_key_exists('fields', $data)) {
throw new \Doctrine\DBAL\Exception\InvalidArgumentException("any fields "
. "have been checked");
if (!array_key_exists('fields', $data)) {
throw new \Doctrine\DBAL\Exception\InvalidArgumentException('any fields '
. 'have been checked');
}
$qb = $this->entityManager->createQueryBuilder();
@@ -365,7 +280,9 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
case 'countryOfBirth':
case 'nationality':
$qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f));
break;
case 'address_street_address_1':
case 'address_street_address_2':
case 'address_valid_from':
@@ -374,14 +291,16 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
case 'address_country_name':
case 'address_country_code':
case 'address_isnoaddress':
$qb->addSelect(sprintf(
'GET_PERSON_ADDRESS_%s(person.id, :address_date) AS %s',
// get the part after address_
strtoupper(substr($f, 8)),
$f));
$f
));
$qb->setParameter('address_date', $data['address_date']);
break;
default:
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
}
@@ -390,30 +309,37 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
foreach ($this->getCustomFields() as $cf) {
$cfType = $this->customFieldProvider->getCustomFieldByType($cf->getType());
if ($cfType instanceof CustomFieldChoice and $cfType->isMultiple($cf)) {
foreach($cfType->getChoices($cf) as $choiceSlug => $label) {
$slug = $this->slugToDQL($cf->getSlug(), 'choice', [ 'choiceSlug' => $choiceSlug ]);
foreach ($cfType->getChoices($cf) as $choiceSlug => $label) {
$slug = $this->slugToDQL($cf->getSlug(), 'choice', ['choiceSlug' => $choiceSlug]);
$qb->addSelect(
sprintf('GET_JSON_FIELD_BY_KEY(person.cFData, :slug%s) AS %s',
$slug, $slug));
sprintf(
'GET_JSON_FIELD_BY_KEY(person.cFData, :slug%s) AS %s',
$slug,
$slug
)
);
$qb->setParameter(sprintf('slug%s', $slug), $cf->getSlug());
}
} else {
$slug = $this->slugToDQL($cf->getSlug());
$qb->addSelect(
sprintf('GET_JSON_FIELD_BY_KEY(person.cFData, :slug%s) AS %s',
$slug, $slug));
sprintf(
'GET_JSON_FIELD_BY_KEY(person.cFData, :slug%s) AS %s',
$slug,
$slug
)
);
$qb->setParameter(sprintf('slug%s', $slug), $cf->getSlug());
}
}
$qb
->from('ChillPersonBundle:Person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
;
->from('ChillPersonBundle:Person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
return $qb;
}
@@ -425,6 +351,117 @@ class ListPerson implements ListInterface, ExportElementValidatedInterface
public function supportsModifiers()
{
return array(Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN);
return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN];
}
public function validateForm($data, ExecutionContextInterface $context)
{
// get the field starting with address_
$addressFields = array_filter(
$this->fields,
static fn (string $el): bool => substr($el, 0, 8) === 'address_'
);
// check if there is one field starting with address in data
if (count(array_intersect($data['fields'], $addressFields)) > 0) {
// if a field address is checked, the date must not be empty
if (empty($data['address_date'])) {
$context
->buildViolation('You must set this date if an address is checked')
->atPath('address_date')
->addViolation();
}
}
}
private function DQLToSlug($cleanedSlug)
{
return $this->slugs[$cleanedSlug]['slug'];
}
/**
* @param mixed $slug
*
* @return array An array with keys = 'slug', 'type', 'additionnalInfo'
*/
private function extractInfosFromSlug($slug): array
{
return $this->slugs[$slug];
}
/**
* Get custom fields associated with person.
*
* @return CustomField[]
*/
private function getCustomFields()
{
return $this->entityManager
->createQuery('SELECT cf '
. 'FROM ChillCustomFieldsBundle:CustomField cf '
. 'JOIN cf.customFieldGroup g '
. 'WHERE cf.type != :title AND g.entity LIKE :entity')
->setParameters([
'title' => 'title',
'entity' => addcslashes(Person::class, '\\'),
])
->getResult();
}
private function getLabelForCustomField($key, array $values, $data)
{
// for fields which are custom fields
/* @var $cf CustomField */
$cf = $this->entityManager
->getRepository(CustomField::class)
->findOneBy(['slug' => $this->DQLToSlug($key)]);
$cfType = $this->customFieldProvider->getCustomFieldByType($cf->getType());
$defaultFunction = function ($value) use ($cf) {
if ('_header' === $value) {
return $this->translatableStringHelper->localize($cf->getName());
}
return $this->customFieldProvider
->getCustomFieldByType($cf->getType())
->render(json_decode($value, true), $cf, 'csv');
};
if ($cfType instanceof CustomFieldChoice and $cfType->isMultiple($cf)) {
return function ($value) use ($cf, $cfType, $key) {
$slugChoice = $this->extractInfosFromSlug($key)['additionnalInfos']['choiceSlug'];
$decoded = \json_decode($value, true);
if ('_header' === $value) {
$label = $cfType->getChoices($cf)[$slugChoice];
return $this->translatableStringHelper->localize($cf->getName())
. ' | ' . $label;
}
if ('_other' === $slugChoice and $cfType->isChecked($cf, $choiceSlug, $decoded)) {
return $cfType->extractOtherValue($cf, $decoded);
}
return $cfType->isChecked($cf, $slugChoice, $decoded);
};
}
return $defaultFunction;
}
/**
* Clean a slug to be usable by DQL.
*/
private function slugToDQL(string $slug, string $type = 'default', array $additionalInfos = []): string
{
$uid = 'slug_' . uniqid('', true);
$this->slugs[$uid] = [
'slug' => $slug,
'type' => $type,
'additionnalInfos' => $additionalInfos,
];
return $uid;
}
}

View File

@@ -1,11 +1,16 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Export;
use Chill\MainBundle\Export\DirectExportInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Doctrine\ORM\EntityManagerInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
@@ -21,25 +26,14 @@ use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Render a list of duplicate peoples
* Render a list of duplicate peoples.
*/
class ListPersonDuplicate implements DirectExportInterface, ExportElementValidatedInterface
{
/**
*
* @var EntityManagerInterface
* @var float
*/
protected $entityManager;
/**
* @var \Symfony\Component\Translation\TranslatorInterface
*/
private $translator;
/**
* @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface
*/
private $router;
private const PRECISION_DEFAULT_VALUE = 0.7;
/**
* @var string
@@ -47,48 +41,33 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
protected $baseUrl;
/**
* @var float
* @var EntityManagerInterface
*/
private const PRECISION_DEFAULT_VALUE = 0.7;
protected $entityManager;
/**
* @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface
*/
private $router;
/**
* @var \Symfony\Component\Translation\TranslatorInterface
*/
private $translator;
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
UrlGeneratorInterface $router,
$routeParameters
EntityManagerInterface $em,
TranslatorInterface $translator,
UrlGeneratorInterface $router,
$routeParameters
) {
$this->entityManager = $em;
$this->translator = $translator;
$this->router = $router;
$this->baseUrl = $routeParameters['scheme'].
'://'.$routeParameters['host'];
$this->baseUrl = $routeParameters['scheme'] .
'://' . $routeParameters['host'];
}
/**
* {@inheritDoc}
*
* @return string
*/
public function getTitle()
{
return "List duplicates";
}
/**
* {@inheritDoc}
*
* @return string
*/
public function getDescription()
{
return "Create a list of duplicate people.";
}
/**
* {@inheritDoc}
*
* @param FormBuilderInterface $builder
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('precision', NumberType::class, [
@@ -97,27 +76,23 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
]);
}
public function validateForm($data, ExecutionContextInterface $context)
{
}
public function generate(array $acl, array $data = []): Response
{
$values = [];
$values[] = $this->getHeaders();
$result = $this->getResult($data);
foreach ($result as $row) {
$values[] = [
$row['id1'],
$row['firstname1'],
$row['lastname1'],
$this->baseUrl.$this->router->generate('chill_person_view', ['person_id' => $row['id1']]),
$this->baseUrl . $this->router->generate('chill_person_view', ['person_id' => $row['id1']]),
$row['id2'],
$row['firstname2'],
$row['lastname2'],
$this->baseUrl.$this->router->generate('chill_person_view', ['person_id' => $row['id2']]),
$this->baseUrl . $this->router->generate('chill_person_view', ['person_id' => $row['id2']]),
];
}
@@ -125,15 +100,15 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
$spreadsheet->getActiveSheet()->fromArray($values);
// Make links clickable
for ($i = 1; $i <= $spreadsheet->getActiveSheet()->getHighestDataRow(); $i++) {
$spreadsheet->getActiveSheet()->getCell('D'.$i)->getHyperlink()
->setUrl($spreadsheet->getActiveSheet()->getCell('D'.$i)->getValue());
$spreadsheet->getActiveSheet()->getCell('H'.$i)->getHyperlink()
->setUrl($spreadsheet->getActiveSheet()->getCell('H'.$i)->getValue());
for ($i = 1; $spreadsheet->getActiveSheet()->getHighestDataRow() >= $i; ++$i) {
$spreadsheet->getActiveSheet()->getCell('D' . $i)->getHyperlink()
->setUrl($spreadsheet->getActiveSheet()->getCell('D' . $i)->getValue());
$spreadsheet->getActiveSheet()->getCell('H' . $i)->getHyperlink()
->setUrl($spreadsheet->getActiveSheet()->getCell('H' . $i)->getValue());
}
$writer = new Xlsx($spreadsheet);
$temp_file = sys_get_temp_dir().'/'.uniqid('export_').'.xlsx';
$temp_file = sys_get_temp_dir() . '/' . uniqid('export_') . '.xlsx';
$writer->save($temp_file);
$response = new BinaryFileResponse($temp_file);
@@ -143,6 +118,45 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
return $response;
}
/**
* @return string
*/
public function getDescription()
{
return 'Create a list of duplicate people.';
}
/**
* @return string
*/
public function getTitle()
{
return 'List duplicates';
}
public function requiredRole(): Role
{
return new Role(PersonVoter::DUPLICATE);
}
public function validateForm($data, ExecutionContextInterface $context)
{
}
protected function getHeaders(): array
{
return [
$this->translator->trans('Departure folder number'),
$this->translator->trans('Last name'),
$this->translator->trans('First name'),
$this->translator->trans('Link'),
$this->translator->trans('Arrival folder number'),
$this->translator->trans('Last name'),
$this->translator->trans('First name'),
$this->translator->trans('Link'),
];
}
protected function getResult($data = [])
{
$precision = $data['precision'] ?? self::PRECISION_DEFAULT_VALUE;
@@ -180,23 +194,4 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
return $statement->fetchAll();
}
protected function getHeaders(): array
{
return [
$this->translator->trans('Departure folder number'),
$this->translator->trans('Last name'),
$this->translator->trans('First name'),
$this->translator->trans('Link'),
$this->translator->trans('Arrival folder number'),
$this->translator->trans('Last name'),
$this->translator->trans('First name'),
$this->translator->trans('Link'),
];
}
public function requiredRole(): Role
{
return new Role(PersonVoter::DUPLICATE);
}
}

View File

@@ -1,33 +1,22 @@
<?php
/*
* Copyright (C) 2019 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Form\Type\ChillDateType;
use Doctrine\DBAL\Types\Types;
use Chill\PersonBundle\Export\AbstractAccompanyingPeriodExportElement;
use DateTime;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
/**
*
*
*/
class AccompanyingPeriodClosingFilter extends AbstractAccompanyingPeriodExportElement implements FilterInterface
{
public function addRole()
@@ -41,7 +30,8 @@ class AccompanyingPeriodClosingFilter extends AbstractAccompanyingPeriodExportEl
$clause = $qb->expr()->andX(
$qb->expr()->lte('accompanying_period.closingDate', ':date_to'),
$qb->expr()->gte('accompanying_period.closingDate', ':date_from'));
$qb->expr()->gte('accompanying_period.closingDate', ':date_from')
);
$qb->andWhere($clause);
$qb->setParameter('date_from', $data['date_from'], Types::DATE_MUTABLE);
@@ -55,31 +45,31 @@ class AccompanyingPeriodClosingFilter extends AbstractAccompanyingPeriodExportEl
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('date_from', ChillDateType::class, array(
'label' => "Having an accompanying period closed after this date",
'data' => new \DateTime("-1 month"),
));
$builder->add('date_from', ChillDateType::class, [
'label' => 'Having an accompanying period closed after this date',
'data' => new DateTime('-1 month'),
]);
$builder->add('date_to', ChillDateType::class, array(
'label' => "Having an accompanying period closed before this date",
'data' => new \DateTime(),
));
$builder->add('date_to', ChillDateType::class, [
'label' => 'Having an accompanying period closed before this date',
'data' => new DateTime(),
]);
}
public function describeAction($data, $format = 'string')
{
return [
"Filtered by accompanying period: persons having an accompanying period"
. " closed between the %date_from% and %date_to%",
'Filtered by accompanying period: persons having an accompanying period'
. ' closed between the %date_from% and %date_to%',
[
'%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y')
]
'%date_to%' => $data['date_to']->format('d-m-Y'),
],
];
}
public function getTitle(): string
{
return "Filter by accompanying period: closed between two dates";
return 'Filter by accompanying period: closed between two dates';
}
}

View File

@@ -1,33 +1,22 @@
<?php
/*
* Copyright (C) 2019 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Form\Type\ChillDateType;
use Doctrine\DBAL\Types\Types;
use Chill\PersonBundle\Export\AbstractAccompanyingPeriodExportElement;
use DateTime;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
/**
*
*
*/
class AccompanyingPeriodFilter extends AbstractAccompanyingPeriodExportElement implements FilterInterface
{
public function addRole()
@@ -43,13 +32,13 @@ class AccompanyingPeriodFilter extends AbstractAccompanyingPeriodExportElement i
$clause->add(
$qb->expr()->lte('accompanying_period.openingDate', ':date_to')
);
);
$clause->add(
$qb->expr()->orX(
$qb->expr()->gte('accompanying_period.closingDate', ':date_from'),
$qb->expr()->isNull('accompanying_period.closingDate')
)
);
)
);
$qb->andWhere($clause);
$qb->setParameter('date_from', $data['date_from'], Types::DATE_MUTABLE);
@@ -63,33 +52,33 @@ class AccompanyingPeriodFilter extends AbstractAccompanyingPeriodExportElement i
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('date_from', ChillDateType::class, array(
'label' => "Having an accompanying period opened after this date",
'data' => new \DateTime("-1 month"),
));
$builder->add('date_from', ChillDateType::class, [
'label' => 'Having an accompanying period opened after this date',
'data' => new DateTime('-1 month'),
]);
$builder->add('date_to', ChillDateType::class, array(
'label' => "Having an accompanying period ending before this date, or "
. "still opened at this date",
'data' => new \DateTime(),
));
$builder->add('date_to', ChillDateType::class, [
'label' => 'Having an accompanying period ending before this date, or '
. 'still opened at this date',
'data' => new DateTime(),
]);
}
public function describeAction($data, $format = 'string')
{
return [
"Filtered by accompanying period: persons having an accompanying period"
. " opened after the %date_from% and closed before the %date_to% (or still opened "
. "at the %date_to%)",
'Filtered by accompanying period: persons having an accompanying period'
. ' opened after the %date_from% and closed before the %date_to% (or still opened '
. 'at the %date_to%)',
[
'%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y')
]
'%date_to%' => $data['date_to']->format('d-m-Y'),
],
];
}
public function getTitle(): string
{
return "Filter by accompanying period: active period";
return 'Filter by accompanying period: active period';
}
}

View File

@@ -1,33 +1,22 @@
<?php
/*
* Copyright (C) 2019 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Form\Type\ChillDateType;
use Doctrine\DBAL\Types\Types;
use Chill\PersonBundle\Export\AbstractAccompanyingPeriodExportElement;
use DateTime;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
/**
*
*
*/
class AccompanyingPeriodOpeningFilter extends AbstractAccompanyingPeriodExportElement implements FilterInterface
{
public function addRole()
@@ -41,7 +30,8 @@ class AccompanyingPeriodOpeningFilter extends AbstractAccompanyingPeriodExportEl
$clause = $qb->expr()->andX(
$qb->expr()->lte('accompanying_period.openingDate', ':date_to'),
$qb->expr()->gte('accompanying_period.openingDate', ':date_from'));
$qb->expr()->gte('accompanying_period.openingDate', ':date_from')
);
$qb->andWhere($clause);
$qb->setParameter('date_from', $data['date_from'], Types::DATE_MUTABLE);
@@ -55,31 +45,31 @@ class AccompanyingPeriodOpeningFilter extends AbstractAccompanyingPeriodExportEl
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('date_from', ChillDateType::class, array(
'label' => "Having an accompanying period opened after this date",
'data' => new \DateTime("-1 month"),
));
$builder->add('date_from', ChillDateType::class, [
'label' => 'Having an accompanying period opened after this date',
'data' => new DateTime('-1 month'),
]);
$builder->add('date_to', ChillDateType::class, array(
'label' => "Having an accompanying period opened before this date",
'data' => new \DateTime(),
));
$builder->add('date_to', ChillDateType::class, [
'label' => 'Having an accompanying period opened before this date',
'data' => new DateTime(),
]);
}
public function describeAction($data, $format = 'string')
{
return [
"Filtered by accompanying period: persons having an accompanying period"
. " opened between the %date_from% and %date_to%",
'Filtered by accompanying period: persons having an accompanying period'
. ' opened between the %date_from% and %date_to%',
[
'%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y')
]
'%date_to%' => $data['date_to']->format('d-m-Y'),
],
];
}
public function getTitle(): string
{
return "Filter by accompanying period: starting between two dates";
return 'Filter by accompanying period: starting between two dates';
}
}

View File

@@ -1,43 +1,23 @@
<?php
/*
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use DateTime;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Doctrine\ORM\Query\Expr;
use Chill\MainBundle\Form\Type\Export\FilterType;
use Symfony\Component\Form\FormError;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class BirthdateFilter implements FilterInterface, ExportElementValidatedInterface
{
public function addRole()
{
return null;
@@ -46,15 +26,18 @@ class BirthdateFilter implements FilterInterface, ExportElementValidatedInterfac
public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->between('person.birthdate', ':date_from',
':date_to');
$clause = $qb->expr()->between(
'person.birthdate',
':date_from',
':date_to'
);
if ($where instanceof Expr\Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('date_from', $data['date_from']);
$qb->setParameter('date_to', $data['date_to']);
@@ -67,59 +50,30 @@ class BirthdateFilter implements FilterInterface, ExportElementValidatedInterfac
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder)
{
$builder->add('date_from', DateType::class, array(
'label' => "Born after this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
$builder->add('date_from', DateType::class, [
'label' => 'Born after this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
));
$builder->add('date_to', DateType::class, array(
'label' => "Born before this date",
'data' => new \DateTime(),
'attr' => array('class' => 'datepicker'),
'widget'=> 'single_text',
]);
$builder->add('date_to', DateType::class, [
'label' => 'Born before this date',
'data' => new DateTime(),
'attr' => ['class' => 'datepicker'],
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
));
}
public function validateForm($data, ExecutionContextInterface $context)
{
$date_from = $data['date_from'];
$date_to = $data['date_to'];
if ($date_from === null) {
$context->buildViolation('The "date from" should not be empty')
//->atPath('date_from')
->addViolation();
}
if ($date_to === null) {
$context->buildViolation('The "date to" should not be empty')
//->atPath('date_to')
->addViolation();
}
if (
($date_from !== null && $date_to !== null)
&&
$date_from >= $date_to
) {
$context->buildViolation('The date "date to" should be after the '
. 'date given in "date from" field')
->addViolation();
}
]);
}
public function describeAction($data, $format = 'string')
{
return array('Filtered by person\'s birtdate: '
. 'between %date_from% and %date_to%', array(
return ['Filtered by person\'s birtdate: '
. 'between %date_from% and %date_to%', [
'%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y')
));
'%date_to%' => $data['date_to']->format('d-m-Y'),
], ];
}
public function getTitle()
@@ -127,4 +81,30 @@ class BirthdateFilter implements FilterInterface, ExportElementValidatedInterfac
return 'Filter by person\'s birthdate';
}
public function validateForm($data, ExecutionContextInterface $context)
{
$date_from = $data['date_from'];
$date_to = $data['date_to'];
if (null === $date_from) {
$context->buildViolation('The "date from" should not be empty')
//->atPath('date_from')
->addViolation();
}
if (null === $date_to) {
$context->buildViolation('The "date to" should not be empty')
//->atPath('date_to')
->addViolation();
}
if (
(null !== $date_from && null !== $date_to)
&& $date_from >= $date_to
) {
$context->buildViolation('The date "date to" should be after the '
. 'date given in "date from" field')
->addViolation();
}
}
}

View File

@@ -1,90 +1,52 @@
<?php
/*
* Copyright (C) 2015 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Role\Role;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use function array_filter;
use function implode;
use function in_array;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class GenderFilter implements FilterInterface,
class GenderFilter implements
FilterInterface,
ExportElementValidatedInterface
{
/**
*
* @var TranslatorInterface
*/
protected $translator;
function __construct(TranslatorInterface $translator)
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function applyOn()
public function addRole()
{
return 'person';
}
/**
*
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_genders', ChoiceType::class, array(
'choices' => array(
'Woman' => Person::FEMALE_GENDER,
'Man' => Person::MALE_GENDER,
'Both' => Person::BOTH_GENDER,
'Not given' => 'null'
),
'multiple' => true,
'expanded' => true
));
}
public function validateForm($data, ExecutionContextInterface $context)
{
if (!is_array($data['accepted_genders']) || count($data['accepted_genders']) === 0 ) {
$context->buildViolation("You should select an option")
->addViolation();
}
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$isIn = $qb->expr()->in('person.gender', ':person_gender');
if (!\in_array('null', $data['accepted_genders'])) {
if (!in_array('null', $data['accepted_genders'])) {
$clause = $isIn;
} else {
$clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender'));
@@ -97,15 +59,53 @@ class GenderFilter implements FilterInterface,
}
$qb->add('where', $where);
$qb->setParameter('person_gender', \array_filter(
$qb->setParameter('person_gender', array_filter(
$data['accepted_genders'],
function($el) {
return $el !== 'null';
}));
function ($el) {
return 'null' !== $el;
}
));
}
public function applyOn()
{
return 'person';
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_genders', ChoiceType::class, [
'choices' => [
'Woman' => Person::FEMALE_GENDER,
'Man' => Person::MALE_GENDER,
'Both' => Person::BOTH_GENDER,
'Not given' => 'null',
],
'multiple' => true,
'expanded' => true,
]);
}
public function describeAction($data, $format = 'string')
{
$genders = [];
foreach ($data['accepted_genders'] as $g) {
if ('null' === $g) {
$genders[] = $this->translator->trans('Not given');
} else {
$genders[] = $this->translator->trans($g);
}
}
return [
'Filtering by genders: only %genders%',
['%genders%' => implode(', ', $genders)],
];
}
/**
* A title which will be used in the label for the form
* A title which will be used in the label for the form.
*
* @return string
*/
@@ -114,26 +114,11 @@ class GenderFilter implements FilterInterface,
return 'Filter by person gender';
}
public function addRole()
public function validateForm($data, ExecutionContextInterface $context)
{
return NULL;
}
public function describeAction($data, $format = 'string')
{
$genders = [];
foreach ($data['accepted_genders'] as $g) {
if ('null' === $g) {
$genders[] = $this->translator->trans('Not given');
} else {
$genders[] = $this->translator->trans($g);
}
if (!is_array($data['accepted_genders']) || count($data['accepted_genders']) === 0) {
$context->buildViolation('You should select an option')
->addViolation();
}
return [
"Filtering by genders: only %genders%",
[ "%genders%" => \implode(", ", $genders)]
];
}
}

View File

@@ -1,45 +1,29 @@
<?php
/*
* Copyright (C) 2015 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Filter;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\FilterInterface;
use Doctrine\ORM\Query\Expr;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\Select2CountryType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class NationalityFilter implements FilterInterface,
class NationalityFilter implements
FilterInterface,
ExportElementValidatedInterface
{
/**
*
* @var TranslatableStringHelper
*/
private $translatableStringHelper;
@@ -49,25 +33,9 @@ class NationalityFilter implements FilterInterface,
$this->translatableStringHelper = $helper;
}
public function applyOn()
public function addRole()
{
return 'person';
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('nationalities', Select2CountryType::class, array(
'placeholder' => 'Choose countries'
));
}
public function validateForm($data, ExecutionContextInterface $context)
{
if ($data['nationalities'] === null) {
$context->buildViolation("A nationality must be selected")
->addViolation();
}
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
@@ -82,7 +50,33 @@ class NationalityFilter implements FilterInterface,
}
$qb->add('where', $where);
$qb->setParameter('person_nationality', array($data['nationalities']));
$qb->setParameter('person_nationality', [$data['nationalities']]);
}
public function applyOn()
{
return 'person';
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('nationalities', Select2CountryType::class, [
'placeholder' => 'Choose countries',
]);
}
public function describeAction($data, $format = 'string')
{
$countries = $data['nationalities'];
$names = array_map(function (Country $c) {
return $this->translatableStringHelper->localize($c->getName());
}, [$countries]);
return [
'Filtered by nationality : %nationalities%',
['%nationalities%' => implode(', ', $names)],
];
}
public function getTitle()
@@ -90,22 +84,11 @@ class NationalityFilter implements FilterInterface,
return "Filter by person's nationality";
}
public function addRole()
public function validateForm($data, ExecutionContextInterface $context)
{
return NULL;
}
public function describeAction($data, $format = 'string')
{
$countries = $data['nationalities'];
$names = array_map(function(Country $c) {
return $this->translatableStringHelper->localize($c->getName());
}, array($countries));
return array(
"Filtered by nationality : %nationalities%",
array('%nationalities%' => implode(", ", $names))
);
if (null === $data['nationalities']) {
$context->buildViolation('A nationality must be selected')
->addViolation();
}
}
}