mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-03 18:58:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			217 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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\ActivityBundle\Export\Aggregator;
 | 
						|
 | 
						|
use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository;
 | 
						|
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
 | 
						|
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
 | 
						|
use Chill\MainBundle\Export\AggregatorInterface;
 | 
						|
use Chill\MainBundle\Export\ExportElementValidatedInterface;
 | 
						|
use Chill\MainBundle\Templating\TranslatableStringHelper;
 | 
						|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
						|
use Doctrine\ORM\Query\Expr\Join;
 | 
						|
use Doctrine\ORM\QueryBuilder;
 | 
						|
use RuntimeException;
 | 
						|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
						|
use Symfony\Component\Form\FormBuilderInterface;
 | 
						|
use Symfony\Component\Security\Core\Role\Role;
 | 
						|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
 | 
						|
 | 
						|
use function array_key_exists;
 | 
						|
use function count;
 | 
						|
 | 
						|
class ActivityReasonAggregator implements AggregatorInterface, ExportElementValidatedInterface
 | 
						|
{
 | 
						|
    protected ActivityReasonCategoryRepository $activityReasonCategoryRepository;
 | 
						|
 | 
						|
    protected ActivityReasonRepository $activityReasonRepository;
 | 
						|
 | 
						|
    protected TranslatableStringHelperInterface $translatableStringHelper;
 | 
						|
 | 
						|
    public function __construct(
 | 
						|
        ActivityReasonCategoryRepository $activityReasonCategoryRepository,
 | 
						|
        ActivityReasonRepository $activityReasonRepository,
 | 
						|
        TranslatableStringHelper $translatableStringHelper
 | 
						|
    ) {
 | 
						|
        $this->activityReasonCategoryRepository = $activityReasonCategoryRepository;
 | 
						|
        $this->activityReasonRepository = $activityReasonRepository;
 | 
						|
        $this->translatableStringHelper = $translatableStringHelper;
 | 
						|
    }
 | 
						|
 | 
						|
    public function addRole()
 | 
						|
    {
 | 
						|
        return new Role(ActivityStatsVoter::STATS);
 | 
						|
    }
 | 
						|
 | 
						|
    public function alterQuery(QueryBuilder $qb, $data)
 | 
						|
    {
 | 
						|
        // add select element
 | 
						|
        if ('reasons' === $data['level']) {
 | 
						|
            $elem = 'reasons.id';
 | 
						|
            $alias = 'activity_reasons_id';
 | 
						|
        } elseif ('categories' === $data['level']) {
 | 
						|
            $elem = 'category.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
 | 
						|
        $join = $qb->getDQLPart('join');
 | 
						|
 | 
						|
        if (
 | 
						|
            (
 | 
						|
                array_key_exists('activity', $join)
 | 
						|
            && !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
 | 
						|
            )
 | 
						|
            || (!array_key_exists('activity', $join))
 | 
						|
        ) {
 | 
						|
            $qb->add(
 | 
						|
                'join',
 | 
						|
                [
 | 
						|
                    'activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons'),
 | 
						|
                ],
 | 
						|
                true
 | 
						|
            );
 | 
						|
        }
 | 
						|
 | 
						|
        // join category if necessary
 | 
						|
        if ('activity_categories_id' === $alias) {
 | 
						|
            // add join only if needed
 | 
						|
            if (!$this->checkJoinAlreadyDefined($qb->getDQLPart('join')['activity'], 'category')) {
 | 
						|
                $qb->join('reasons.category', 'category');
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // add the "group by" part
 | 
						|
        $groupBy = $qb->getDQLPart('groupBy');
 | 
						|
 | 
						|
        if (count($groupBy) > 0) {
 | 
						|
            $qb->addGroupBy($alias);
 | 
						|
        } else {
 | 
						|
            $qb->groupBy($alias);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function applyOn()
 | 
						|
    {
 | 
						|
        return 'activity';
 | 
						|
    }
 | 
						|
 | 
						|
    public function buildForm(FormBuilderInterface $builder)
 | 
						|
    {
 | 
						|
        $builder->add(
 | 
						|
            'level',
 | 
						|
            ChoiceType::class,
 | 
						|
            [
 | 
						|
                'choices' => [
 | 
						|
                    'By reason' => 'reasons',
 | 
						|
                    'By category of reason' => 'categories',
 | 
						|
                ],
 | 
						|
                'multiple' => false,
 | 
						|
                'expanded' => true,
 | 
						|
                'label' => "Reason's level",
 | 
						|
            ]
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    public function getLabels($key, array $values, $data)
 | 
						|
    {
 | 
						|
        // for performance reason, we load data from db only once
 | 
						|
        switch ($data['level']) {
 | 
						|
            case 'reasons':
 | 
						|
                $this->activityReasonRepository->findBy(['id' => $values]);
 | 
						|
 | 
						|
                break;
 | 
						|
 | 
						|
            case 'categories':
 | 
						|
                $this->activityReasonCategoryRepository->findBy(['id' => $values]);
 | 
						|
 | 
						|
                break;
 | 
						|
 | 
						|
            default:
 | 
						|
                throw new RuntimeException(sprintf("The level data '%s' is invalid.", $data['level']));
 | 
						|
        }
 | 
						|
 | 
						|
        return function ($value) use ($data) {
 | 
						|
            if ('_header' === $value) {
 | 
						|
                return 'reasons' === $data['level'] ? 'Group by reasons' : 'Group by categories of reason';
 | 
						|
            }
 | 
						|
 | 
						|
            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)
 | 
						|
    {
 | 
						|
        // 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()
 | 
						|
    {
 | 
						|
        return 'Aggregate by activity reason';
 | 
						|
    }
 | 
						|
 | 
						|
    public function validateForm($data, ExecutionContextInterface $context)
 | 
						|
    {
 | 
						|
        if (null === $data['level']) {
 | 
						|
            $context
 | 
						|
                ->buildViolation("The reasons's level should not be empty.")
 | 
						|
                ->addViolation();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Check if a join between Activity and another alias.
 | 
						|
     *
 | 
						|
     * @param Join[] $joins
 | 
						|
     * @param string $alias the alias to search for
 | 
						|
     *
 | 
						|
     * @return bool
 | 
						|
     */
 | 
						|
    private function checkJoinAlreadyDefined(array $joins, $alias)
 | 
						|
    {
 | 
						|
        foreach ($joins as $join) {
 | 
						|
            if ($join->getAlias() === $alias) {
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
}
 |