fix: Let Symfony inject dependencies automatically.

This commit is contained in:
Pol Dellaiera 2021-11-18 10:28:22 +01:00
parent 7dcf0f8dcf
commit d9b862925f
No known key found for this signature in database
GPG Key ID: D476DFE9C67467CA
9 changed files with 282 additions and 526 deletions

View File

@ -1,70 +1,39 @@
<?php <?php
/* declare(strict_types=1);
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* 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/>.
*/
namespace Chill\ActivityBundle\Export\Aggregator; namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
/** class ActivityReasonAggregator implements AggregatorInterface, ExportElementValidatedInterface
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityReasonAggregator implements AggregatorInterface,
ExportElementValidatedInterface
{ {
/** protected ActivityReasonCategoryRepository $activityReasonCategoryRepository;
*
* @var EntityRepository
*/
protected $categoryRepository;
/** protected ActivityReasonRepository $activityReasonRepository;
*
* @var EntityRepository
*/
protected $reasonRepository;
/** protected TranslatableStringHelperInterface $translatableStringHelper;
*
* @var TranslatableStringHelper
*/
protected $stringHelper;
public function __construct( public function __construct(
EntityRepository $categoryRepository, ActivityReasonCategoryRepository $activityReasonCategoryRepository,
EntityRepository $reasonRepository, ActivityReasonRepository $activityReasonRepository,
TranslatableStringHelper $stringHelper TranslatableStringHelper $translatableStringHelper
) { ) {
$this->categoryRepository = $categoryRepository; $this->activityReasonCategoryRepository = $activityReasonCategoryRepository;
$this->reasonRepository = $reasonRepository; $this->activityReasonRepository = $activityReasonRepository;
$this->stringHelper = $stringHelper; $this->translatableStringHelper = $translatableStringHelper;
} }
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
@ -77,7 +46,7 @@ class ActivityReasonAggregator implements AggregatorInterface,
$elem = 'category.id'; $elem = 'category.id';
$alias = 'activity_categories_id'; $alias = 'activity_categories_id';
} else { } else {
throw new \RuntimeException('the data provided are not recognized'); throw new \RuntimeException('The data provided are not recognized.');
} }
$qb->addSelect($elem.' as '.$alias); $qb->addSelect($elem.' as '.$alias);
@ -94,10 +63,11 @@ class ActivityReasonAggregator implements AggregatorInterface,
) { ) {
$qb->add( $qb->add(
'join', 'join',
array('activity' => [
new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons') 'activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')
), ],
true); true
);
} }
// join category if necessary // join category if necessary
@ -143,28 +113,33 @@ class ActivityReasonAggregator implements AggregatorInterface,
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$builder->add('level', ChoiceType::class, array( $builder->add(
'choices' => array( 'level',
ChoiceType::class,
[
'choices' => [
'By reason' => 'reasons', 'By reason' => 'reasons',
'By category of reason' => 'categories' 'By category of reason' => 'categories'
), ],
'multiple' => false, 'multiple' => false,
'expanded' => true, 'expanded' => true,
'label' => 'Reason\'s level' 'label' => "Reason's level"
)); ]
);
} }
public function validateForm($data, ExecutionContextInterface $context) public function validateForm($data, ExecutionContextInterface $context)
{ {
if ($data['level'] === null) { if ($data['level'] === null) {
$context->buildViolation("The reasons's level should not be empty") $context
->buildViolation("The reasons's level should not be empty.")
->addViolation(); ->addViolation();
} }
} }
public function getTitle() public function getTitle()
{ {
return "Aggregate by activity reason"; return 'Aggregate by activity reason';
} }
public function addRole() public function addRole()
@ -177,41 +152,33 @@ class ActivityReasonAggregator implements AggregatorInterface,
// for performance reason, we load data from db only once // for performance reason, we load data from db only once
switch ($data['level']) { switch ($data['level']) {
case 'reasons': case 'reasons':
$this->reasonRepository->findBy(array('id' => $values)); $this->activityReasonRepository->findBy(['id' => $values]);
break; break;
case 'categories': case 'categories':
$this->categoryRepository->findBy(array('id' => $values)); $this->activityReasonCategoryRepository->findBy(['id' => $values]);
break; break;
default: default:
throw new \RuntimeException(sprintf("the level data '%s' is invalid", throw new \RuntimeException(sprintf("The level data '%s' is invalid.", $data['level']));
$data['level']));
} }
return function($value) use ($data) { return function($value) use ($data) {
if ($value === '_header') { if ($value === '_header') {
return $data['level'] === 'reasons' ? return $data['level'] === 'reasons' ? 'Group by reasons' : 'Group by categories of reason';
'Group by reasons'
:
'Group by categories of reason'
;
} }
switch ($data['level']) { switch ($data['level']) {
case 'reasons': case 'reasons':
/* @var $r \Chill\ActivityBundle\Entity\ActivityReason */ $r = $this->activityReasonRepository->find($value);
$r = $this->reasonRepository->find($value);
return $this->stringHelper->localize($r->getCategory()->getName()) return sprintf(
." > " "%s > %s",
. $this->stringHelper->localize($r->getName()); $this->translatableStringHelper->localize($r->getCategory()->getName()),
; $this->translatableStringHelper->localize($r->getName())
break; );
case 'categories': case 'categories':
$c = $this->categoryRepository->find($value); $c = $this->activityReasonCategoryRepository->find($value);
return $this->stringHelper->localize($c->getName()); return $this->translatableStringHelper->localize($c->getName());
break;
// no need for a default : the default was already set above
} }
}; };
@ -222,12 +189,14 @@ class ActivityReasonAggregator implements AggregatorInterface,
// add select element // add select element
if ($data['level'] === 'reasons') { if ($data['level'] === 'reasons') {
return array('activity_reasons_id'); return array('activity_reasons_id');
} elseif ($data['level'] === 'categories') { }
if ($data['level'] === 'categories') {
return array ('activity_categories_id'); return array ('activity_categories_id');
} else {
throw new \RuntimeException('the data provided are not recognised');
} }
throw new \RuntimeException('The data provided are not recognised.');
} }
} }

View File

@ -1,61 +1,32 @@
<?php <?php
/* declare(strict_types=1);
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* 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/>.
*/
namespace Chill\ActivityBundle\Export\Aggregator; namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityTypeAggregator implements AggregatorInterface class ActivityTypeAggregator implements AggregatorInterface
{ {
protected ActivityTypeRepository $activityTypeRepository;
/** protected TranslatableStringHelperInterface $translatableStringHelper;
*
* @var EntityRepository
*/
protected $typeRepository;
/** public const KEY = 'activity_type_aggregator';
*
* @var TranslatableStringHelper
*/
protected $stringHelper;
const KEY = 'activity_type_aggregator';
public function __construct( public function __construct(
EntityRepository $typeRepository, ActivityTypeRepository $activityTypeRepository,
TranslatableStringHelper $stringHelper TranslatableStringHelperInterface $translatableStringHelper
) { ) {
$this->typeRepository = $typeRepository; $this->activityTypeRepository = $activityTypeRepository;
$this->stringHelper = $stringHelper; $this->translatableStringHelper = $translatableStringHelper;
} }
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
@ -64,7 +35,7 @@ class ActivityTypeAggregator implements AggregatorInterface
$qb->addSelect(sprintf('IDENTITY(activity.type) AS %s', self::KEY)); $qb->addSelect(sprintf('IDENTITY(activity.type) AS %s', self::KEY));
// add the "group by" part // add the "group by" part
$groupBy = $qb->addGroupBy(self::KEY); $qb->addGroupBy(self::KEY);
} }
/** /**
@ -97,7 +68,7 @@ class ActivityTypeAggregator implements AggregatorInterface
public function getTitle() public function getTitle()
{ {
return "Aggregate by activity type"; return 'Aggregate by activity type';
} }
public function addRole() public function addRole()
@ -108,17 +79,16 @@ class ActivityTypeAggregator implements AggregatorInterface
public function getLabels($key, array $values, $data): \Closure public function getLabels($key, array $values, $data): \Closure
{ {
// for performance reason, we load data from db only once // for performance reason, we load data from db only once
$this->typeRepository->findBy(array('id' => $values)); $this->activityTypeRepository->findBy(['id' => $values]);
return function($value): string { return function($value): string {
if ($value === '_header') { if ($value === '_header') {
return 'Activity type'; return 'Activity type';
} }
/* @var $r \Chill\ActivityBundle\Entity\ActivityType */ $t = $this->activityTypeRepository->find($value);
$t = $this->typeRepository->find($value);
return $this->stringHelper->localize($t->getName()); return $this->translatableStringHelper->localize($t->getName());
}; };
} }

View File

@ -1,49 +1,24 @@
<?php <?php
/*
* Copyright (C) 2019 Champs Libres Cooperative <info@champs-libres.coop>
*
* 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/>.
*/
namespace Chill\ActivityBundle\Export\Aggregator; namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\MainBundle\Repository\UserRepository;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\AggregatorInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query\Expr\Join;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityManagerInterface;
use Chill\MainBundle\Entity\User;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityUserAggregator implements AggregatorInterface class ActivityUserAggregator implements AggregatorInterface
{ {
/** public const KEY = 'activity_user_id';
*
* @var EntityManagerInterface
*/
protected $em;
const KEY = 'activity_user_id'; private UserRepository $userRepository;
function __construct(EntityManagerInterface $em) public function __construct(
{ UserRepository $userRepository
$this->em = $em; ) {
$this->userRepository = $userRepository;
} }
public function addRole() public function addRole()
@ -73,17 +48,14 @@ class ActivityUserAggregator implements AggregatorInterface
public function getLabels($key, $values, $data): \Closure public function getLabels($key, $values, $data): \Closure
{ {
// preload users at once // preload users at once
$this->em->getRepository(User::class) $this->userRepository->findBy(['id' => $values]);
->findBy(['id' => $values]);
return function($value) { return function($value) {
switch ($value) { if ($value === '_header') {
case '_header':
return 'activity user'; return 'activity user';
default:
return $this->em->getRepository(User::class)->find($value)
->getUsername();
} }
return $this->userRepository->find($value)->getUsername();
}; };
} }
@ -94,6 +66,6 @@ class ActivityUserAggregator implements AggregatorInterface
public function getTitle(): string public function getTitle(): string
{ {
return "Aggregate by activity user"; return 'Aggregate by activity user';
} }
} }

View File

@ -1,64 +1,40 @@
<?php <?php
/* declare(strict_types=1);
* Copyright (C) 2015 Champs-Libres <info@champs-libres.coop>
*
* 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/>.
*/
namespace Chill\ActivityBundle\Export\Export; namespace Chill\ActivityBundle\Export\Export;
use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\QueryBuilder; use Chill\MainBundle\Export\FormatterInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityManagerInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class CountActivity implements ExportInterface class CountActivity implements ExportInterface
{ {
/** protected ActivityRepository $activityRepository;
*
* @var EntityManagerInterface
*/
protected $entityManager;
public function __construct( public function __construct(
EntityManagerInterface $em ActivityRepository $activityRepository
) ) {
{ $this->activityRepository = $activityRepository;
$this->entityManager = $em;
} }
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
} }
public function getDescription() public function getDescription()
{ {
return "Count activities by various parameters."; return 'Count activities by various parameters.';
} }
public function getTitle() public function getTitle()
{ {
return "Count activities"; return 'Count activities';
} }
public function getType() public function getType()
@ -68,24 +44,24 @@ class CountActivity implements ExportInterface
public function initiateQuery(array $requiredModifiers, array $acl, array $data = array()) public function initiateQuery(array $requiredModifiers, array $acl, array $data = array())
{ {
$qb = $this->entityManager->createQueryBuilder(); $centers = array_map(static fn($el) => $el['center'], $acl);
$centers = array_map(function($el) { return $el['center']; }, $acl);
$qb->select('COUNT(activity.id) as export_count_activity') $qb = $this
->from('ChillActivityBundle:Activity', 'activity') ->activityRepository
->join('activity.person', 'person') ->createQueryBuilder('activity')
; ->select('COUNT(activity.id) as export_count_activity')
->join('activity.person', 'person');
$qb->where($qb->expr()->in('person.center', ':centers')) $qb
->setParameter('centers', $centers) ->where($qb->expr()->in('person.center', ':centers'))
; ->setParameter('centers', $centers);
return $qb; return $qb;
} }
public function supportsModifiers() public function supportsModifiers()
{ {
return array('person', 'activity'); return ['person', 'activity'];
} }
public function requiredRole() public function requiredRole()
@ -95,7 +71,7 @@ class CountActivity implements ExportInterface
public function getAllowedFormattersTypes() public function getAllowedFormattersTypes()
{ {
return array(\Chill\MainBundle\Export\FormatterInterface::TYPE_TABULAR); return [FormatterInterface::TYPE_TABULAR];
} }
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)
@ -104,18 +80,12 @@ class CountActivity implements ExportInterface
throw new \LogicException("the key $key is not used by this export"); throw new \LogicException("the key $key is not used by this export");
} }
return function($value) { return static fn($value) => $value === '_header' ? 'Number of activities' : $value;
return $value === '_header' ?
'Number of activities'
:
$value
;
};
} }
public function getQueryKeys($data) public function getQueryKeys($data)
{ {
return array('export_count_activity'); return ['export_count_activity'];
} }
public function getResult($qb, $data) public function getResult($qb, $data)

View File

@ -1,31 +1,14 @@
<?php <?php
/* declare(strict_types=1);
* Copyright (C) 2017 Champs-Libres <info@champs-libres.coop>
*
* 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/>.
*/
namespace Chill\ActivityBundle\Export\Export; namespace Chill\ActivityBundle\Export\Export;
use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\MainBundle\Export\ListInterface; use Chill\MainBundle\Export\ListInterface;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\MainBundle\Entity\Scope; use Doctrine\DBAL\Exception\InvalidArgumentException;
use Chill\ActivityBundle\Entity\ActivityType;
use Doctrine\ORM\Query\Expr;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
@ -37,33 +20,17 @@ use Chill\MainBundle\Export\FormatterInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Create a list for all activities
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ListActivity implements ListInterface class ListActivity implements ListInterface
{ {
private ActivityRepository $activityRepository;
/** protected EntityManagerInterface $entityManager;
*
* @var EntityManagerInterface
*/
protected $entityManager;
/** protected TranslatorInterface $translator;
*
* @var TranslatorInterface
*/
protected $translator;
/** protected TranslatableStringHelperInterface $translatableStringHelper;
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
protected $fields = array( protected array $fields = [
'id', 'id',
'date', 'date',
'durationTime', 'durationTime',
@ -75,32 +42,28 @@ class ListActivity implements ListInterface
'person_firstname', 'person_firstname',
'person_lastname', 'person_lastname',
'person_id' 'person_id'
); ];
public function __construct( public function __construct(
EntityManagerInterface $em, EntityManagerInterface $em,
TranslatorInterface $translator, TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper TranslatableStringHelperInterface $translatableStringHelper,
) ActivityRepository $activityRepository
{ ) {
$this->entityManager = $em; $this->entityManager = $em;
$this->translator = $translator; $this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper; $this->translatableStringHelper = $translatableStringHelper;
$this->activityRepository = $activityRepository;
} }
/**
* {@inheritDoc}
*
* @param FormBuilderInterface $builder
*/
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$builder->add('fields', ChoiceType::class, array( $builder->add('fields', ChoiceType::class, [
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
'choices' => array_combine($this->fields, $this->fields), 'choices' => array_combine($this->fields, $this->fields),
'label' => 'Fields to include in export', 'label' => 'Fields to include in export',
'constraints' => [new Callback(array( 'constraints' => [new Callback([
'callback' => function($selected, ExecutionContextInterface $context) { 'callback' => function($selected, ExecutionContextInterface $context) {
if (count($selected) === 0) { if (count($selected) === 0) {
$context->buildViolation('You must select at least one element') $context->buildViolation('You must select at least one element')
@ -108,19 +71,14 @@ class ListActivity implements ListInterface
->addViolation(); ->addViolation();
} }
} }
))] ])]
)); ]);
} }
/**
* {@inheritDoc}
*
* @return type
*/
public function getAllowedFormattersTypes() public function getAllowedFormattersTypes()
{ {
return array(FormatterInterface::TYPE_LIST); return [FormatterInterface::TYPE_LIST];
} }
public function getDescription() public function getDescription()
@ -133,29 +91,32 @@ class ListActivity implements ListInterface
switch ($key) switch ($key)
{ {
case 'date' : case 'date' :
return function($value) { return static function($value) {
if ($value === '_header') return 'date'; if ($value === '_header') {
return 'date';
}
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $value); $date = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
return $date->format('d-m-Y'); return $date->format('d-m-Y');
}; };
case 'attendee': case 'attendee':
return function($value) { return static function($value) {
if ($value === '_header') return 'attendee'; if ($value === '_header') {
return 'attendee';
}
return $value ? 1 : 0; return $value ? 1 : 0;
}; };
case 'list_reasons' : case 'list_reasons' :
/* @var $activityReasonsRepository EntityRepository */ $activityRepository = $this->activityRepository;
$activityRepository = $this->entityManager
->getRepository('ChillActivityBundle:Activity');
return function($value) use ($activityRepository) { return function($value) use ($activityRepository): string {
if ($value === '_header') return 'activity reasons'; if ($value === '_header') {
return 'activity reasons';
}
$activity = $activityRepository $activity = $activityRepository->find($value);
->find($value);
return implode(", ", array_map(function(ActivityReason $r) { return implode(", ", array_map(function(ActivityReason $r) {
@ -168,21 +129,25 @@ class ListActivity implements ListInterface
}; };
case 'circle_name' : case 'circle_name' :
return function($value) { return function($value) {
if ($value === '_header') return 'circle'; if ($value === '_header') {
return 'circle';
}
return $this->translatableStringHelper return $this->translatableStringHelper->localize(json_decode($value, true));
->localize(json_decode($value, true));
}; };
case 'type_name' : case 'type_name' :
return function($value) { return function($value) {
if ($value === '_header') return 'activity type'; if ($value === '_header') {
return 'activity type';
}
return $this->translatableStringHelper return $this->translatableStringHelper->localize(json_decode($value, true));
->localize(json_decode($value, true));
}; };
default: default:
return function($value) use ($key) { return static function($value) use ($key) {
if ($value === '_header') return $key; if ($value === '_header') {
return $key;
}
return $value; return $value;
}; };
@ -209,14 +174,13 @@ class ListActivity implements ListInterface
return 'activity'; return 'activity';
} }
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 // throw an error if any fields are present
if (!\array_key_exists('fields', $data)) { if (!\array_key_exists('fields', $data)) {
throw new \Doctrine\DBAL\Exception\InvalidArgumentException("any fields " throw new InvalidArgumentException('Any fields have been checked.');
. "have been checked");
} }
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
@ -227,7 +191,6 @@ class ListActivity implements ListInterface
->join('person.center', 'center') ->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)') ->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers); ->setParameter('authorized_centers', $centers);
;
foreach ($this->fields as $f) { foreach ($this->fields as $f) {
if (in_array($f, $data['fields'])) { if (in_array($f, $data['fields'])) {
@ -269,8 +232,6 @@ class ListActivity implements ListInterface
} }
} }
return $qb; return $qb;
} }
@ -281,7 +242,7 @@ class ListActivity implements ListInterface
public function supportsModifiers() public function supportsModifiers()
{ {
return array('activity', 'person'); return ['activity', 'person'];
} }
} }

View File

@ -4,12 +4,13 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Export; namespace Chill\ActivityBundle\Export\Export;
use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\ExportInterface;
use Doctrine\ORM\QueryBuilder; use Chill\MainBundle\Export\FormatterInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityManagerInterface;
/** /**
* This export allow to compute stats on activity duration. * This export allow to compute stats on activity duration.
@ -18,7 +19,7 @@ use Doctrine\ORM\EntityManagerInterface;
*/ */
class StatActivityDuration implements ExportInterface class StatActivityDuration implements ExportInterface
{ {
protected EntityManagerInterface $entityManager; private ActivityRepository $activityRepository;
public const SUM = 'sum'; public const SUM = 'sum';
@ -30,13 +31,15 @@ class StatActivityDuration implements ExportInterface
/** /**
* @param string $action the stat to perform * @param string $action the stat to perform
*/ */
public function __construct(EntityManagerInterface $em, string $action = 'sum') public function __construct(
{ ActivityRepository $activityRepository,
$this->entityManager = $em; string $action = 'sum'
) {
$this->action = $action; $this->action = $action;
$this->activityRepository = $activityRepository;
} }
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
} }
@ -68,7 +71,7 @@ class StatActivityDuration implements ExportInterface
$acl $acl
); );
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->activityRepository->createQueryBuilder('activity');
$select = null; $select = null;
@ -77,7 +80,6 @@ class StatActivityDuration implements ExportInterface
} }
return $qb->select($select) return $qb->select($select)
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person') ->join('activity.person', 'person')
->join('person.center', 'center') ->join('person.center', 'center')
->where($qb->expr()->in('center', ':centers')) ->where($qb->expr()->in('center', ':centers'))
@ -96,7 +98,7 @@ class StatActivityDuration implements ExportInterface
public function getAllowedFormattersTypes() public function getAllowedFormattersTypes()
{ {
return array(\Chill\MainBundle\Export\FormatterInterface::TYPE_TABULAR); return [FormatterInterface::TYPE_TABULAR];
} }
public function getLabels($key, array $values, $data) public function getLabels($key, array $values, $data)

View File

@ -1,25 +1,12 @@
<?php <?php
/* declare(strict_types=1);
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* 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/>.
*/
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
@ -28,41 +15,24 @@ use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface;
/** class ActivityReasonFilter implements FilterInterface, ExportElementValidatedInterface
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ActivityReasonFilter implements FilterInterface,
ExportElementValidatedInterface
{ {
/** protected TranslatableStringHelperInterface $translatableStringHelper;
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/** protected ActivityReasonRepository $activityReasonRepository;
* The repository for activity reasons
*
* @var EntityRepository
*/
protected $reasonRepository;
public function __construct( public function __construct(
TranslatableStringHelper $helper, TranslatableStringHelper $helper,
EntityRepository $reasonRepository ActivityReasonRepository $activityReasonRepository
) { ) {
$this->translatableStringHelper = $helper; $this->translatableStringHelper = $helper;
$this->reasonRepository = $reasonRepository; $this->activityReasonRepository = $activityReasonRepository;
} }
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
$where = $qb->getDQLPart('where'); $where = $qb->getDQLPart('where');
@ -75,7 +45,7 @@ class ActivityReasonFilter implements FilterInterface,
&& &&
!$this->checkJoinAlreadyDefined($join['activity'], 'reasons') !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
) )
OR ||
(! array_key_exists('activity', $join)) (! array_key_exists('activity', $join))
) { ) {
$qb->add( $qb->add(
@ -101,7 +71,7 @@ class ActivityReasonFilter implements FilterInterface,
* @param Join[] $joins * @param Join[] $joins
* @return boolean * @return boolean
*/ */
private function checkJoinAlreadyDefined(array $joins, $alias) private function checkJoinAlreadyDefined(array $joins, $alias): bool
{ {
foreach ($joins as $join) { foreach ($joins as $join) {
if ($join->getAlias() === $alias) { if ($join->getAlias() === $alias) {
@ -119,26 +89,20 @@ class ActivityReasonFilter implements FilterInterface,
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
//create a local copy of translatableStringHelper $builder->add('reasons', EntityType::class, [
$helper = $this->translatableStringHelper; 'class' => ActivityReason::class,
'choice_label' => static fn(ActivityReason $reason) => $this->translatableStringHelper->localize($reason->getName()),
$builder->add('reasons', EntityType::class, array( 'group_by' => static fn(ActivityReason $reason) => $this->translatableStringHelper->localize($reason->getCategory()->getName()),
'class' => 'ChillActivityBundle:ActivityReason',
'choice_label' => function (ActivityReason $reason) use ($helper) {
return $helper->localize($reason->getName());
},
'group_by' => function(ActivityReason $reason) use ($helper) {
return $helper->localize($reason->getCategory()->getName());
},
'multiple' => true, 'multiple' => true,
'expanded' => false 'expanded' => false
)); ]);
} }
public function validateForm($data, ExecutionContextInterface $context) public function validateForm($data, ExecutionContextInterface $context)
{ {
if ($data['reasons'] === null || count($data['reasons']) === 0) { if ($data['reasons'] === null || count($data['reasons']) === 0) {
$context->buildViolation("At least one reason must be choosen") $context
->buildViolation('At least one reason must be chosen')
->addViolation(); ->addViolation();
} }
} }
@ -157,13 +121,15 @@ class ActivityReasonFilter implements FilterInterface,
{ {
// collect all the reasons'name used in this filter in one array // collect all the reasons'name used in this filter in one array
$reasonsNames = array_map( $reasonsNames = array_map(
function(ActivityReason $r) { static fn(ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"',
return "\"".$this->translatableStringHelper->localize($r->getName())."\""; $this->activityReasonRepository->findBy(array('id' => $data['reasons']->toArray()))
},
$this->reasonRepository->findBy(array('id' => $data['reasons']->toArray()))
); );
return array("Filtered by reasons: only %list%", return [
["%list%" => implode(", ", $reasonsNames)]); 'Filtered by reasons: only %list%',
[
'%list%' => implode(", ", $reasonsNames),
]
];
} }
} }

View File

@ -1,67 +1,37 @@
<?php <?php
/* declare(strict_types=1);
* Copyright (C) 2018 Champs-Libres <info@champs-libres.coop>
*
* 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/>.
*/
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\Role;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\ActivityBundle\Entity\ActivityType; use Chill\ActivityBundle\Entity\ActivityType;
/** class ActivityTypeFilter implements FilterInterface, ExportElementValidatedInterface
*
*
*/
class ActivityTypeFilter implements FilterInterface,
ExportElementValidatedInterface
{ {
/** protected TranslatableStringHelperInterface $translatableStringHelper;
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
/** protected ActivityTypeRepository $activityTypeRepository;
* The repository for activity reasons
*
* @var EntityRepository
*/
protected $typeRepository;
public function __construct( public function __construct(
TranslatableStringHelper $helper, TranslatableStringHelperInterface $translatableStringHelper,
EntityRepository $typeRepository ActivityTypeRepository $activityTypeRepository
) { ) {
$this->translatableStringHelper = $helper; $this->translatableStringHelper = $translatableStringHelper;
$this->typeRepository = $typeRepository; $this->activityTypeRepository = $activityTypeRepository;
} }
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
$where = $qb->getDQLPart('where'); $where = $qb->getDQLPart('where');
@ -101,23 +71,23 @@ class ActivityTypeFilter implements FilterInterface,
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
//create a local copy of translatableStringHelper $builder->add(
$helper = $this->translatableStringHelper; 'types',
EntityType::class,
$builder->add('types', EntityType::class, array( [
'class' => ActivityType::class, 'class' => ActivityType::class,
'choice_label' => function (ActivityType $type) use ($helper) { 'choice_label' => static fn(ActivityType $type) => $this->translatableStringHelper->localize($type->getName()),
return $helper->localize($type->getName());
},
'multiple' => true, 'multiple' => true,
'expanded' => false 'expanded' => false
)); ]
);
} }
public function validateForm($data, ExecutionContextInterface $context) public function validateForm($data, ExecutionContextInterface $context)
{ {
if ($data['types'] === null || count($data['types']) === 0) { if ($data['types'] === null || count($data['types']) === 0) {
$context->buildViolation("At least one type must be choosen") $context
->buildViolation('At least one type must be chosen')
->addViolation(); ->addViolation();
} }
} }
@ -136,13 +106,15 @@ class ActivityTypeFilter implements FilterInterface,
{ {
// collect all the reasons'name used in this filter in one array // collect all the reasons'name used in this filter in one array
$reasonsNames = array_map( $reasonsNames = array_map(
function(ActivityType $t) { static fn(ActivityType $t): string => '"' . $this->translatableStringHelper->localize($t->getName()) . '"',
return "\"".$this->translatableStringHelper->localize($t->getName())."\""; $this->activityTypeRepository->findBy(['id' => $data['types']->toArray()])
},
$this->typeRepository->findBy(array('id' => $data['types']->toArray()))
); );
return array("Filtered by activity type: only %list%", return [
["%list%" => implode(", ", $reasonsNames)]); 'Filtered by activity type: only %list%',
[
'%list%' => implode(", ", $reasonsNames),
]
];
} }
} }

View File

@ -1,57 +1,40 @@
services: services:
_defaults:
autowire: true
autoconfigure: true
chill.activity.export.count_activity: chill.activity.export.count_activity:
class: Chill\ActivityBundle\Export\Export\CountActivity class: Chill\ActivityBundle\Export\Export\CountActivity
arguments:
- "@doctrine.orm.entity_manager"
tags: tags:
- { name: chill.export, alias: 'count_activity' } - { name: chill.export, alias: 'count_activity' }
chill.activity.export.sum_activity_duration: chill.activity.export.sum_activity_duration:
class: Chill\ActivityBundle\Export\Export\StatActivityDuration class: Chill\ActivityBundle\Export\Export\StatActivityDuration
arguments:
- "@doctrine.orm.entity_manager"
- "sum"
tags: tags:
- { name: chill.export, alias: 'sum_activity_duration' } - { name: chill.export, alias: 'sum_activity_duration' }
chill.activity.export.list_activity: chill.activity.export.list_activity:
class: Chill\ActivityBundle\Export\Export\ListActivity class: Chill\ActivityBundle\Export\Export\ListActivity
arguments:
- "@doctrine.orm.entity_manager"
- "@translator"
- "@chill.main.helper.translatable_string"
tags: tags:
- { name: chill.export, alias: 'list_activity' } - { name: chill.export, alias: 'list_activity' }
chill.activity.export.reason_filter: chill.activity.export.reason_filter:
class: Chill\ActivityBundle\Export\Filter\ActivityReasonFilter class: Chill\ActivityBundle\Export\Filter\ActivityReasonFilter
arguments:
- "@chill.main.helper.translatable_string"
- "@chill_activity.repository.reason"
tags: tags:
- { name: chill.export_filter, alias: 'activity_reason_filter' } - { name: chill.export_filter, alias: 'activity_reason_filter' }
chill.activity.export.type_filter: chill.activity.export.type_filter:
class: Chill\ActivityBundle\Export\Filter\ActivityTypeFilter class: Chill\ActivityBundle\Export\Filter\ActivityTypeFilter
arguments:
- "@chill.main.helper.translatable_string"
- "@chill_activity.repository.activity_type"
tags: tags:
- { name: chill.export_filter, alias: 'activity_type_filter' } - { name: chill.export_filter, alias: 'activity_type_filter' }
chill.activity.export.date_filter: chill.activity.export.date_filter:
class: Chill\ActivityBundle\Export\Filter\ActivityDateFilter class: Chill\ActivityBundle\Export\Filter\ActivityDateFilter
arguments:
- "@translator"
tags: tags:
- { name: chill.export_filter, alias: 'activity_date_filter' } - { name: chill.export_filter, alias: 'activity_date_filter' }
chill.activity.export.person_having_an_activity_between_date_filter: chill.activity.export.person_having_an_activity_between_date_filter:
class: Chill\ActivityBundle\Export\Filter\PersonHavingActivityBetweenDateFilter class: Chill\ActivityBundle\Export\Filter\PersonHavingActivityBetweenDateFilter
arguments:
- "@chill.main.helper.translatable_string"
- "@chill_activity.repository.reason"
- "@translator"
tags: tags:
- #0 register as a filter - #0 register as a filter
name: chill.export_filter name: chill.export_filter
@ -59,24 +42,15 @@ services:
chill.activity.export.reason_aggregator: chill.activity.export.reason_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator class: Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
arguments:
- "@chill_activity.repository.reason_category"
- "@chill_activity.repository.reason"
- "@chill.main.helper.translatable_string"
tags: tags:
- { name: chill.export_aggregator, alias: activity_reason_aggregator } - { name: chill.export_aggregator, alias: activity_reason_aggregator }
chill.activity.export.type_aggregator: chill.activity.export.type_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ActivityTypeAggregator class: Chill\ActivityBundle\Export\Aggregator\ActivityTypeAggregator
arguments:
- "@chill_activity.repository.activity_type"
- "@chill.main.helper.translatable_string"
tags: tags:
- { name: chill.export_aggregator, alias: activity_type_aggregator } - { name: chill.export_aggregator, alias: activity_type_aggregator }
chill.activity.export.user_aggregator: chill.activity.export.user_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator
arguments:
$em: "@doctrine.orm.entity_manager"
tags: tags:
- { name: chill.export_aggregator, alias: activity_user_aggregator } - { name: chill.export_aggregator, alias: activity_user_aggregator }