diff --git a/Export/Aggregator/ActivityUserAggregator.php b/Export/Aggregator/ActivityUserAggregator.php new file mode 100644 index 000000000..ca01e0ae5 --- /dev/null +++ b/Export/Aggregator/ActivityUserAggregator.php @@ -0,0 +1,99 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +namespace Chill\ActivityBundle\Export\Aggregator; + +use Symfony\Component\Form\FormBuilderInterface; +use Doctrine\ORM\QueryBuilder; +use Chill\MainBundle\Export\AggregatorInterface; +use Symfony\Component\Security\Core\Role\Role; +use Doctrine\ORM\Query\Expr\Join; +use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; +use Doctrine\ORM\EntityManagerInterface; +use Chill\MainBundle\Entity\User; + +/** + * + * + * @author Julien Fastré + */ +class ActivityUserAggregator implements AggregatorInterface +{ + /** + * + * @var EntityManagerInterface + */ + protected $em; + + const KEY = 'activity_user_id'; + + function __construct(EntityManagerInterface $em) + { + $this->em = $em; + } + + public function addRole() + { + return new Role(ActivityStatsVoter::STATS); + } + + public function alterQuery(QueryBuilder $qb, $data) + { + // add select element + $qb->addSelect(sprintf('IDENTITY(activity.user) AS %s', self::KEY)); + + // add the "group by" part + $qb->addGroupBy(self::KEY); + } + + public function applyOn(): string + { + return 'activity'; + } + + public function buildForm(FormBuilderInterface $builder) + { + // nothing to add + } + + public function getLabels($key, $values, $data): \Closure + { + // preload users at once + $this->em->getRepository(User::class) + ->findBy(['id' => $values]); + + return function($value) { + switch ($value) { + case '_header': + return 'activity user'; + default: + return $this->em->getRepository(User::class)->find($value) + ->getUsername(); + } + }; + } + + public function getQueryKeys($data) + { + return [ self::KEY ]; + } + + public function getTitle(): string + { + return "Aggregate by activity user"; + } +} diff --git a/Resources/config/services/export.yml b/Resources/config/services/export.yml index cb6ff5f52..8fdb98bbf 100644 --- a/Resources/config/services/export.yml +++ b/Resources/config/services/export.yml @@ -65,3 +65,10 @@ services: - "@chill.main.helper.translatable_string" tags: - { name: chill.export_aggregator, alias: activity_type_aggregator } + + chill.activity.export.user_aggregator: + class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator + arguments: + $em: "@doctrine.orm.entity_manager" + tags: + - { name: chill.export_aggregator, alias: activity_user_aggregator } diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 63620fb49..b4bc1ad05 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -138,4 +138,8 @@ By reason: Par sujet By category of reason: Par catégorie de sujet Reason's level: Niveau du sujet Aggregate by activity type: Aggréger par date d'activité - +Aggregate by activity type: Aggréger par type d'activité +Activity type: Type d'activité +Group by reasons: Sujet d'activité +Activity user: Utilisateur lié à l'activity +Aggregate by activity user: Aggréger par utilisateur lié à l'activité diff --git a/Tests/Export/Aggregator/ActivityUserAggregatorTest.php b/Tests/Export/Aggregator/ActivityUserAggregatorTest.php new file mode 100644 index 000000000..45f974a56 --- /dev/null +++ b/Tests/Export/Aggregator/ActivityUserAggregatorTest.php @@ -0,0 +1,91 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace Chill\ActivityBundle\Tests\Aggregator; + +use Chill\MainBundle\Test\Export\AbstractAggregatorTest; + +/** + * Add tests for ActivityUsernAggregator + * + */ +class ActivityUserAggregatorTest extends AbstractAggregatorTest +{ + /** + * + * @var \Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator + */ + private $aggregator; + + public function setUp() + { + static::bootKernel(); + + $container = static::$kernel->getContainer(); + + $this->aggregator = $container->get('chill.activity.export.user_aggregator'); + + // add a fake request with a default locale (used in translatable string) + $prophet = new \Prophecy\Prophet; + $request = $prophet->prophesize(); + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $container->get('request_stack') + ->push($request->reveal()); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData() + { + return array( + array() + ); + } + + public function getQueryBuilders() + { + if (static::$kernel === null) { + static::bootKernel(); + } + + $em = static::$kernel->getContainer() + ->get('doctrine.orm.entity_manager'); + + return array( + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from('ChillActivityBundle:Activity', 'activity'), + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from('ChillActivityBundle:Activity', 'activity') + ->join('activity.reasons', 'reasons'), + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from('ChillActivityBundle:Activity', 'activity') + ->join('activity.reasons', 'reasons') + ->join('reasons.category', 'category') + ); + } + +}