mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Create export list of events
This commit is contained in:
parent
3f1e625dee
commit
d5599ac6cc
271
src/Bundle/ChillEventBundle/Export/Export/ListEvents.php
Normal file
271
src/Bundle/ChillEventBundle/Export/Export/ListEvents.php
Normal file
@ -0,0 +1,271 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\EventBundle\Export\Export;
|
||||
|
||||
use Chill\EventBundle\Entity\Event;
|
||||
use Chill\EventBundle\Export\Declarations;
|
||||
use Chill\EventBundle\Security\EventVoter;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\MainBundle\Export\ListInterface;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Query;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Validator\Constraints\Callback;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
* Render a list of events.
|
||||
*/
|
||||
class ListEvents implements ListInterface, GroupedExportInterface
|
||||
{
|
||||
protected array $fields = [
|
||||
'event_id',
|
||||
'event_name',
|
||||
'event_date',
|
||||
'event_type',
|
||||
'event_center',
|
||||
'event_moderator',
|
||||
'event_participants_count',
|
||||
'event_location',
|
||||
];
|
||||
|
||||
private readonly bool $filterStatsByCenters;
|
||||
|
||||
public function __construct(
|
||||
protected readonly EntityManagerInterface $entityManager,
|
||||
ParameterBagInterface $parameterBag,
|
||||
protected readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
) {
|
||||
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('fields', ChoiceType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'choices' => array_combine($this->fields, $this->fields),
|
||||
'label' => 'Fields to include in export',
|
||||
'constraints' => [new Callback([
|
||||
'callback' => static function ($selected, ExecutionContextInterface $context) {
|
||||
if (0 === \count($selected)) {
|
||||
$context->buildViolation('You must select at least one element')
|
||||
->atPath('fields')
|
||||
->addViolation();
|
||||
}
|
||||
},
|
||||
])],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return [
|
||||
'fields' => $this->fields,
|
||||
];
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes()
|
||||
{
|
||||
return [FormatterInterface::TYPE_LIST];
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return 'event.export.list.description.Create a list of events according to various filters.';
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of events';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
switch ($key) {
|
||||
case 'event_id':
|
||||
return fn ($value) => '_header' === $value ? 'ID' : $value;
|
||||
|
||||
case 'event_name':
|
||||
return fn ($value) => '_header' === $value ? 'Name' : $value;
|
||||
|
||||
case 'event_date':
|
||||
return function ($value) {
|
||||
if ('_header' === $value) {
|
||||
return 'Date';
|
||||
}
|
||||
|
||||
if ($value instanceof \DateTime) {
|
||||
return $value->format('Y-m-d');
|
||||
}
|
||||
|
||||
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||
|
||||
return $date ? $date->format('Y-m-d') : $value;
|
||||
};
|
||||
|
||||
case 'event_type':
|
||||
return function ($value) {
|
||||
if ('_header' === $value) {
|
||||
return 'event type';
|
||||
}
|
||||
|
||||
return $this->translatableStringHelper->localize(json_decode((string) $value, true, 512, JSON_THROW_ON_ERROR));
|
||||
};
|
||||
|
||||
case 'event_center':
|
||||
return fn ($value) => '_header' === $value ? 'Center' : $value;
|
||||
|
||||
case 'event_moderator':
|
||||
return fn ($value) => '_header' === $value ? 'Moderator' : $value;
|
||||
|
||||
case 'event_participants_count':
|
||||
return fn ($value) => '_header' === $value ? 'Participants Count' : $value;
|
||||
|
||||
case 'event_location':
|
||||
return fn ($value) => '_header' === $value ? 'Location' : $value;
|
||||
|
||||
default:
|
||||
return fn ($value) => '_header' === $value ? $key : $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
{
|
||||
return $data['fields'];
|
||||
}
|
||||
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'List events';
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return Declarations::EVENT;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
// Throw an error if no fields are present
|
||||
if (!\array_key_exists('fields', $data)) {
|
||||
throw new \InvalidArgumentException('No fields have been checked.');
|
||||
}
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder()
|
||||
->from(Event::class, 'event');
|
||||
|
||||
if ($this->filterStatsByCenters) {
|
||||
$qb
|
||||
->andWhere('event.center IN (:authorized_centers)')
|
||||
->setParameter('authorized_centers', $centers);
|
||||
}
|
||||
|
||||
// Add fields based on selection
|
||||
foreach ($this->fields as $field) {
|
||||
if (\in_array($field, $data['fields'], true)) {
|
||||
switch ($field) {
|
||||
case 'event_id':
|
||||
$qb->addSelect('event.id AS event_id');
|
||||
break;
|
||||
|
||||
case 'event_name':
|
||||
$qb->addSelect('event.name AS event_name');
|
||||
break;
|
||||
|
||||
case 'event_date':
|
||||
$qb->addSelect('event.date AS event_date');
|
||||
break;
|
||||
|
||||
case 'event_type':
|
||||
if (!$qb->getDQLPart('join') || !$this->hasJoin($qb, 'event.type')) {
|
||||
$qb->leftJoin('event.type', 'type');
|
||||
}
|
||||
$qb->addSelect('type.name AS event_type');
|
||||
break;
|
||||
|
||||
case 'event_center':
|
||||
if (!$qb->getDQLPart('join') || !$this->hasJoin($qb, 'event.center')) {
|
||||
$qb->leftJoin('event.center', 'center');
|
||||
}
|
||||
$qb->addSelect('center.name AS event_center');
|
||||
break;
|
||||
|
||||
case 'event_moderator':
|
||||
if (!$qb->getDQLPart('join') || !$this->hasJoin($qb, 'event.moderator')) {
|
||||
$qb->leftJoin('event.moderator', 'user');
|
||||
}
|
||||
$qb->addSelect('user.username AS event_moderator');
|
||||
break;
|
||||
|
||||
case 'event_participants_count':
|
||||
$qb->addSelect('(SELECT COUNT(p.id) FROM Chill\EventBundle\Entity\Participation p WHERE p.event = event.id) AS event_participants_count');
|
||||
break;
|
||||
|
||||
case 'event_location':
|
||||
if (!$qb->getDQLPart('join') || !$this->hasJoin($qb, 'event.location')) {
|
||||
$qb->leftJoin('event.location', 'location');
|
||||
}
|
||||
$qb->addSelect('location.name AS event_location');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): string
|
||||
{
|
||||
return EventVoter::STATS;
|
||||
}
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return [Declarations::EVENT];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check if a join already exists in the QueryBuilder.
|
||||
*/
|
||||
private function hasJoin($queryBuilder, $joinPath): bool
|
||||
{
|
||||
$joins = $queryBuilder->getDQLPart('join');
|
||||
if (!isset($joins['event'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($joins['event'] as $join) {
|
||||
if ($join->getJoin() === $joinPath) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -8,6 +8,9 @@ services:
|
||||
Chill\EventBundle\Export\Export\CountEvents:
|
||||
tags:
|
||||
- { name: chill.export, alias: 'count_events' }
|
||||
Chill\EventBundle\Export\Export\ListEvents:
|
||||
tags:
|
||||
- { name: chill.export, alias: 'list_events' }
|
||||
Chill\EventBundle\Export\Export\CountEventParticipations:
|
||||
tags:
|
||||
- { name: chill.export, alias: 'count_event_participants' }
|
||||
|
Loading…
x
Reference in New Issue
Block a user