171 lines
5.1 KiB
PHP

<?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\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class ActivityReasonAggregator implements AggregatorInterface, ExportElementValidatedInterface
{
public function __construct(
protected ActivityReasonCategoryRepository $activityReasonCategoryRepository,
protected ActivityReasonRepository $activityReasonRepository,
protected TranslatableStringHelper $translatableStringHelper,
) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
// add select element
if ('reasons' === $data['level']) {
$elem = 'actreasons.id';
$alias = 'activity_reasons_id';
} elseif ('categories' === $data['level']) {
$elem = 'actreasoncat.id';
$alias = 'activity_categories_id';
} else {
throw new \RuntimeException('The data provided are not recognized.');
}
$qb->addSelect($elem.' as '.$alias);
// make a jointure only if needed
if (!\in_array('actreasons', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.reasons', 'actreasons');
}
// join category if necessary
if ('activity_categories_id' === $alias) {
// add join only if needed
if (!\in_array('actreasoncat', $qb->getAllAliases(), true)) {
$qb->join('actreasons.category', 'actreasoncat');
}
}
$qb->addGroupBy($alias);
}
public function applyOn(): string
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add(
'level',
ChoiceType::class,
[
'choices' => [
'By reason' => 'reasons',
'By category of reason' => 'categories',
],
'multiple' => false,
'expanded' => true,
'label' => "Reason's level",
]
);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['level' => $formData['level']];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['level' => $formData['level']];
}
public function getFormDefaultData(): array
{
return [
'level' => 'reasons',
];
}
public function getLabels($key, array $values, $data): callable
{
return function ($value) use ($data) {
if ('_header' === $value) {
return 'reasons' === $data['level'] ? 'Group by reasons' : 'Group by categories of reason';
}
if (null === $value || '' === $value) {
return '';
}
switch ($data['level']) {
case 'reasons':
$r = $this->activityReasonRepository->find($value);
return sprintf(
'%s > %s',
$this->translatableStringHelper->localize($r->getCategory()->getName()),
$this->translatableStringHelper->localize($r->getName())
);
case 'categories':
$c = $this->activityReasonCategoryRepository->find($value);
return $this->translatableStringHelper->localize($c->getName());
}
};
}
public function getQueryKeys($data): array
{
// add select element
if ('reasons' === $data['level']) {
return ['activity_reasons_id'];
}
if ('categories' === $data['level']) {
return ['activity_categories_id'];
}
throw new \RuntimeException('The data provided are not recognised.');
}
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Aggregate by activity reason';
}
public function validateForm($data, ExecutionContextInterface $context): void
{
if (null === $data['level']) {
$context
->buildViolation("The reasons's level should not be empty.")
->addViolation();
}
}
}