fix: SA: Fix many critical rules.

SA stands for Static Analysis.
This commit is contained in:
Pol Dellaiera 2021-11-16 17:13:39 +01:00
parent db2010082a
commit 5432242376
No known key found for this signature in database
GPG Key ID: D476DFE9C67467CA
19 changed files with 345 additions and 655 deletions

View File

@ -90,51 +90,21 @@ parameters:
count: 1
path: src/Bundle/ChillTaskBundle/Controller/TaskController.php
-
message: "#^Undefined variable\\: \\$id$#"
count: 1
path: src/Bundle/ChillFamilyMembersBundle/Controller/FamilyMemberController.php
-
message: "#^Call to an undefined method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\AbstractCRUDController\\:\\:getRoleFor\\(\\)\\.$#"
count: 1
path: src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php
-
message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Command\\\\ChillImportUsersCommand\\:\\:tempOutput\\(\\)\\.$#"
count: 1
path: src/Bundle/ChillMainBundle/Command/ChillImportUsersCommand.php
-
message: "#^Access to an undefined property Chill\\\\MainBundle\\\\Controller\\\\AdminCountryCRUDController\\:\\:\\$paginatorFactory\\.$#"
count: 1
path: src/Bundle/ChillMainBundle/Controller/AdminCountryCRUDController.php
-
message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Controller\\\\UserController\\:\\:createEditForm\\(\\)\\.$#"
count: 1
path: src/Bundle/ChillMainBundle/Controller/UserController.php
-
message: "#^Access to an undefined property Chill\\\\MainBundle\\\\Entity\\\\RoleScope\\:\\:\\$new\\.$#"
count: 1
path: src/Bundle/ChillMainBundle/Entity/RoleScope.php
-
message: "#^Undefined variable\\: \\$current$#"
count: 1
path: src/Bundle/ChillMainBundle/Pagination/PageGenerator.php
-
message: "#^Access to an undefined property Chill\\\\MainBundle\\\\Routing\\\\MenuComposer\\:\\:\\$routeCollection\\.$#"
count: 1
path: src/Bundle/ChillMainBundle/Routing/MenuComposer.php
-
message: "#^Access to an undefined property Chill\\\\MainBundle\\\\Search\\\\SearchApiResult\\:\\:\\$relevance\\.$#"
count: 2
path: src/Bundle/ChillMainBundle/Search/SearchApiResult.php
-
message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AbstractChillVoter\\:\\:getSupportedAttributes\\(\\)\\.$#"
count: 1
@ -155,46 +125,6 @@ parameters:
count: 3
path: src/Bundle/ChillPersonBundle/Controller/PersonController.php
-
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Controller\\\\TimelinePersonController\\:\\:\\$authorizationHelper\\.$#"
count: 1
path: src/Bundle/ChillPersonBundle/Controller/TimelinePersonController.php
-
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\DataFixtures\\\\ORM\\\\LoadHousehold\\:\\:\\$personIds\\.$#"
count: 2
path: src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHousehold.php
-
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Form\\\\CreationPersonType\\:\\:\\$centerTransformer\\.$#"
count: 1
path: src/Bundle/ChillPersonBundle/Form/CreationPersonType.php
-
message: "#^Access to an undefined property Chill\\\\ReportBundle\\\\Timeline\\\\TimelineReportProvider\\:\\:\\$security\\.$#"
count: 4
path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php
-
message: "#^Access to an undefined property Chill\\\\AsideActivityBundle\\\\Entity\\\\AsideActivityCategory\\:\\:\\$oldParent\\.$#"
count: 2
path: src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php
-
message: "#^Access to an undefined property Chill\\\\AsideActivityBundle\\\\Form\\\\AsideActivityCategoryType\\:\\:\\$categoryRender\\.$#"
count: 2
path: src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php
-
message: "#^Access to an undefined property Chill\\\\AsideActivityBundle\\\\Form\\\\AsideActivityFormType\\:\\:\\$translatableStringHelper\\.$#"
count: 1
path: src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php
-
message: "#^Access to an undefined property Chill\\\\CalendarBundle\\\\DataFixtures\\\\ORM\\\\LoadCalendarRange\\:\\:\\$userRepository\\.$#"
count: 2
path: src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php
-
message: "#^Call to an undefined method Chill\\\\ThirdPartyBundle\\\\Form\\\\Type\\\\PickThirdPartyTypeCategoryType\\:\\:transform\\(\\)\\.$#"
count: 1

View File

@ -44,13 +44,15 @@ class AsideActivityCategory
* @ORM\ManyToOne(targetEntity=AsideActivityCategory::class, inversedBy="children")
* @ORM\JoinColumn(nullable=true)
*/
private $parent;
private AsideActivityCategory $parent;
/**
* @ORM\OneToMany(targetEntity=AsideActivityCategory::class, mappedBy="parent")
*/
private $children;
private AsideActivityCategory $oldParent;
public function __construct()
{
$this->children = new ArrayCollection();

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Chill\AsideActivityBundle\Form;
use Chill\AsideActivityBundle\Entity\AsideActivityCategory;
@ -14,12 +16,11 @@ use Symfony\Component\Form\FormBuilderInterface;
final class AsideActivityCategoryType extends AbstractType
{
private CategoryRender $categoryRender;
protected $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper, CategoryRender $categoryRender)
{
$this->translatableStringHelper = $translatableStringHelper;
public function __construct(
CategoryRender $categoryRender
) {
$this->categoryRender = $categoryRender;
}

View File

@ -25,18 +25,16 @@ use Symfony\Component\Templating\EngineInterface;
final class AsideActivityFormType extends AbstractType
{
protected array $timeChoices;
private array $timeChoices;
private TokenStorageInterface $storage;
private CategoryRender $categoryRender;
public function __construct (
TranslatableStringHelper $translatableStringHelper,
ParameterBagInterface $parameterBag,
TokenStorageInterface $storage,
CategoryRender $categoryRender
){
$this->timeChoices = $parameterBag->get('chill_aside_activity.form.time_duration');
$this->translatableStringHelper = $translatableStringHelper;
$this->storage = $storage;
$this->categoryRender = $categoryRender;
}

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Chill\CalendarBundle\DataFixtures\ORM;
use Chill\CalendarBundle\Entity\CalendarRange;
@ -15,6 +17,10 @@ use Doctrine\Persistence\ObjectManager;
class LoadCalendarRange extends Fixture implements FixtureGroupInterface, OrderedFixtureInterface
{
private UserRepository $userRepository;
public static array $references = [];
public function __construct(
UserRepository $userRepository
) {
@ -31,8 +37,6 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere
return ['calendar'];
}
public static $references = [];
public function load(ObjectManager $manager): void
{
$arr = range(-50, 50);

View File

@ -3,7 +3,6 @@
namespace Chill\AMLI\FamilyMembersBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
@ -13,27 +12,16 @@ use Chill\AMLI\FamilyMembersBundle\Form\FamilyMemberType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Translation\TranslatorInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Routing\Annotation\Route;
class FamilyMemberController extends Controller
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var LoggerInterface
*/
protected $chillMainLogger;
protected EntityManagerInterface $em;
protected TranslatorInterface $translator;
protected LoggerInterface $chillMainLogger;
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
@ -44,7 +32,7 @@ class FamilyMemberController extends Controller
$this->chillMainLogger = $chillMainLogger;
}
/**
* @Route(
* "{_locale}/family-members/family-members/by-person/{id}",
@ -54,11 +42,11 @@ class FamilyMemberController extends Controller
public function indexAction(Person $person)
{
$this->denyAccessUnlessGranted(FamilyMemberVoter::SHOW, $person);
$familyMembers = $this->em
->getRepository(FamilyMember::class)
->findByPerson($person);
return $this->render('ChillAMLIFamilyMembersBundle:FamilyMember:index.html.twig', array(
'person' => $person,
'familyMembers' => $familyMembers
@ -76,26 +64,26 @@ class FamilyMemberController extends Controller
$familyMember = (new FamilyMember())
->setPerson($person)
;
$this->denyAccessUnlessGranted(FamilyMemberVoter::CREATE, $familyMember);
$form = $this->createForm(FamilyMemberType::class, $familyMember);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($familyMember);
$em->flush();
$this->addFlash('success', $this->translator->trans('Family member created'));
return $this->redirectToRoute('chill_family_members_family_members_index', [
'id' => $person->getId()
]);
}
return $this->render('ChillAMLIFamilyMembersBundle:FamilyMember:new.html.twig', array(
'form' => $form->createView(),
'person' => $person
@ -111,37 +99,37 @@ class FamilyMemberController extends Controller
public function editAction(FamilyMember $familyMember, Request $request)
{
$this->denyAccessUnlessGranted(FamilyMemberVoter::UPDATE, $familyMember);
$form = $this->createForm(FamilyMemberType::class, $familyMember);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
$this->addFlash('success', $this->translator->trans('Family member updated'));
return $this->redirectToRoute('chill_family_members_family_members_index', [
'id' => $familyMember->getPerson()->getId()
]);
}
return $this->render('ChillAMLIFamilyMembersBundle:FamilyMember:edit.html.twig', array(
'familyMember' => $familyMember,
'form' => $form->createView(),
'person' => $familyMember->getPerson()
));
}
/**
*
*
* @Route(
* "{_locale}/family-members/family-members/{id}/delete",
* name="chill_family_members_family_members_delete"
* )
*
*
* @param FamilyMember $familyMember
* @param Request $request
* @return \Symfony\Component\BrowserKit\Response
@ -183,7 +171,7 @@ class FamilyMemberController extends Controller
'delete_form' => $form->createView()
));
}
/**
* @Route(
* "{_locale}/family-members/family-members/{id}/view",
@ -193,12 +181,12 @@ class FamilyMemberController extends Controller
public function viewAction(FamilyMember $familyMember)
{
$this->denyAccessUnlessGranted(FamilyMemberVoter::SHOW, $familyMember);
return $this->render('ChillAMLIFamilyMembersBundle:FamilyMember:view.html.twig', array(
'familyMember' => $familyMember
));
}
/**
* Creates a form to delete a help request entity by id.
*

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Chill\MainBundle\CRUD\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -14,31 +16,28 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Translation\TranslatorInterface;
class AbstractCRUDController extends AbstractController
abstract class AbstractCRUDController extends AbstractController
{
/**
* The crud configuration
* The crud configuration
*
* This configuration si defined by `chill_main['crud']` or `chill_main['apis']`
*
* @var array
*/
protected array $crudConfig = [];
/**
* get the instance of the entity with the given id
*
* @param string $id
* @return object
*
* @throw Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the object is not found
*/
protected function getEntity($action, $id, Request $request): object
protected function getEntity($action, string $id, Request $request): object
{
$e = $this->getDoctrine()
$e = $this
->getDoctrine()
->getRepository($this->getEntityClass())
->find($id);
if (NULL === $e) {
if (null === $e) {
throw $this->createNotFoundException(sprintf("The object %s for id %s is not found", $this->getEntityClass(), $id));
}
@ -47,61 +46,50 @@ class AbstractCRUDController extends AbstractController
/**
* Create an entity.
*
* @param string $action
* @param Request $request
*
* @return object
*/
protected function createEntity(string $action, Request $request): object
{
$type = $this->getEntityClass();
return new $type;
return $this->getEntityClass();
}
/**
* Count the number of entities
*
* By default, count all entities. You can customize the query by
* By default, count all entities. You can customize the query by
* using the method `customizeQuery`.
*
* @param string $action
* @param Request $request
* @return int
*/
protected function countEntities(string $action, Request $request, $_format): int
{
return $this->buildQueryEntities($action, $request)
->select('COUNT(e)')
->getQuery()
->getSingleScalarResult()
;
->getSingleScalarResult();
}
/**
* Query the entity.
*
*
* By default, get all entities. You can customize the query by using the
* method `customizeQuery`.
*
*
* The method `orderEntity` is called internally to order entities.
*
*
* It returns, by default, a query builder.
*
*/
protected function queryEntities(string $action, Request $request, string $_format, PaginatorInterface $paginator)
{
$query = $this->buildQueryEntities($action, $request)
->setFirstResult($paginator->getCurrentPage()->getFirstItemNumber())
->setMaxResults($paginator->getItemsPerPage());
// allow to order queries and return the new query
return $this->orderQuery($action, $query, $request, $paginator, $_format);
}
/**
* Add ordering fields in the query build by self::queryEntities
*
*/
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format)
{
@ -112,14 +100,12 @@ class AbstractCRUDController extends AbstractController
* Build the base query for listing all entities.
*
* This method is used internally by `countEntities` `queryEntities`
*
*
* This base query does not contains any `WHERE` or `SELECT` clauses. You
* can add some by using the method `customizeQuery`.
*
* The alias for the entity is "e".
*
* @param string $action
* @param Request $request
*
* @return QueryBuilder
*/
protected function buildQueryEntities(string $action, Request $request)
@ -127,8 +113,7 @@ class AbstractCRUDController extends AbstractController
$qb = $this->getDoctrine()->getManager()
->createQueryBuilder()
->select('e')
->from($this->getEntityClass(), 'e')
;
->from($this->getEntityClass(), 'e');
$this->customizeQuery($action, $request, $qb);
@ -138,55 +123,55 @@ class AbstractCRUDController extends AbstractController
protected function customizeQuery(string $action, Request $request, $query): void {}
/**
* Get the result of the query
* Get the result of the query.
*/
protected function getQueryResult(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query)
protected function getQueryResult(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query)
{
return $query->getQuery()->getResult();
}
protected function onPreIndex(string $action, Request $request, string $_format): ?Response
{
return null;
}
/**
* method used by indexAction
*/
protected function onPreIndexBuildQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator): ?Response
{
{
return null;
}
/**
* method used by indexAction
* Method used by indexAction.
*/
protected function onPreIndexBuildQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator): ?Response
{
return null;
}
/**
* Method used by indexAction.
*/
protected function onPostIndexBuildQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query): ?Response
{
return null;
}
/**
* method used by indexAction
* Method used by indexAction.
*/
protected function onPostIndexFetchQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $entities): ?Response
{
return null;
}
/**
* Get the complete FQDN of the class
*
* @return string the complete fqdn of the class
* Get the FQDN of the class.
*
* @return string The FQDN of the class
*/
protected function getEntityClass(): string
{
return $this->crudConfig['class'];
}
/**
* called on post fetch entity
* Called on post fetch entity.
*/
protected function onPostFetchEntity(string $action, Request $request, $entity, $_format): ?Response
{
@ -194,7 +179,7 @@ class AbstractCRUDController extends AbstractController
}
/**
* Called on post check ACL
* Called on post check ACL.
*/
protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response
{
@ -203,23 +188,23 @@ class AbstractCRUDController extends AbstractController
/**
* check the acl. Called by every action.
*
* By default, check the role given by `getRoleFor` for the value given in
*
* By default, check the role given by `getRoleFor` for the value given in
* $entity.
*
*
* Throw an \Symfony\Component\Security\Core\Exception\AccessDeniedHttpException
* if not accessible.
*
*
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedHttpException
*/
protected function checkACL(string $action, Request $request, string $_format, $entity = null)
{
// @TODO: Implements abstract getRoleFor method or do it in the interface.
$this->denyAccessUnlessGranted($this->getRoleFor($action, $request, $entity, $_format), $entity);
}
/**
*
* @return string the crud name
* @return string The crud name.
*/
protected function getCrudName(): string
{
@ -230,7 +215,7 @@ class AbstractCRUDController extends AbstractController
{
return $this->crudConfig['actions'][$action];
}
/**
* Set the crud configuration
*
@ -241,9 +226,6 @@ class AbstractCRUDController extends AbstractController
$this->crudConfig = $config;
}
/**
* @return PaginatorFactory
*/
protected function getPaginatorFactory(): PaginatorFactory
{
return $this->container->get('chill_main.paginator_factory');
@ -254,9 +236,6 @@ class AbstractCRUDController extends AbstractController
return $this->get('validator');
}
/**
* @return array
*/
public static function getSubscribedServices(): array
{
return \array_merge(

View File

@ -1,7 +1,10 @@
<?php
declare(strict_types=1);
namespace Chill\MainBundle\Command;
use Chill\MainBundle\Repository\UserRepository;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
@ -23,82 +26,35 @@ use League\Csv\Writer;
class ChillImportUsersCommand extends Command
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var ValidatorInterface
*/
protected $validator;
/**
*
* @var LoggerInterface
*/
protected $logger;
/**
*
* @var UserPasswordEncoderInterface
*/
protected $passwordEncoder;
/**
*
* @var \Chill\MainBundle\Repository\UserRepository
*/
protected $userRepository;
/**
*
* @var bool
*/
protected $doChanges = true;
/**
*
* @var OutputInterface
*/
protected $tempOutput;
/**
*
* @var InputInterface
*/
protected $tempInput;
protected EntityManagerInterface $em;
protected ValidatorInterface $validator;
protected LoggerInterface $logger;
protected UserPasswordEncoderInterface $passwordEncoder;
protected UserRepository $userRepository;
protected bool $doChanges = true;
protected OutputInterface $tempOutput;
protected InputInterface $tempInput;
/**
* Centers and aliases.
*
*
* key are aliases, values are an array of centers
*
* @var array
*/
protected $centers = [];
/**
*
* @var array
*/
protected $permissionGroups = [];
/**
*
* @var array
*/
protected $groupCenters = [];
/**
*
* @var Writer
*/
protected $output = null;
protected array $centers;
protected array $permissionGroups;
protected array $groupCenters;
protected Writer $output;
public function __construct(
EntityManagerInterface $em,
LoggerInterface $logger,
@ -109,15 +65,12 @@ class ChillImportUsersCommand extends Command
$this->passwordEncoder = $passwordEncoder;
$this->validator = $validator;
$this->logger = $logger;
$this->userRepository = $em->getRepository(User::class);
parent::__construct('chill:main:import-users');
}
protected function configure()
{
$this
@ -126,25 +79,24 @@ class ChillImportUsersCommand extends Command
->addArgument('csvfile', InputArgument::REQUIRED, 'Path to the csv file. Columns are: `username`, `email`, `center` (can contain alias), `permission group`')
->addOption('grouping-centers', null, InputOption::VALUE_OPTIONAL, 'Path to a csv file to aggregate multiple centers into a single alias')
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Do not commit the changes')
->addOption('csv-dump', null, InputOption::VALUE_REQUIRED, 'A path to dump a summary of the created file')
;
->addOption('csv-dump', null, InputOption::VALUE_REQUIRED, 'A path to dump a summary of the created file');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->tempOutput = $output;
$this->tempInput = $input;
if ($input->getOption('dry-run')) {
$this->doChanges = false;
}
$this->prepareWriter();
if ($input->hasOption('grouping-centers')) {
$this->prepareGroupingCenters();
}
try {
$this->loadUsers();
}
@ -152,19 +104,19 @@ class ChillImportUsersCommand extends Command
throw $e;
}
}
protected function prepareWriter()
{
$this->output = $output = Writer::createFromPath($this->tempInput
->getOption('csv-dump'), 'a+');
$output->insertOne([
'email',
'username',
'id'
]);
}
protected function appendUserToFile(User $user)
{
$this->output->insertOne( [
@ -173,35 +125,35 @@ class ChillImportUsersCommand extends Command
$user->getId()
]);
}
protected function loadUsers()
{
$reader = Reader::createFromPath($this->tempInput->getArgument('csvfile'));
$reader->setHeaderOffset(0);
foreach ($reader->getRecords() as $line => $r) {
$this->logger->debug("starting handling new line", [
'line' => $line
]);
if ($this->doesUserExists($r)) {
$this->tempOutput->writeln(sprintf("User with username '%s' already "
. "exists, skipping", $r["username"]));
$this->logger->info("One user already exists, skipping creation", [
'username_in_file' => $r['username'],
'email_in_file' => $r['email'],
'line' => $line
]);
continue;
}
$user = $this->createUser($line, $r);
$this->appendUserToFile($user);
}
}
protected function doesUserExists($data)
{
if ($this->userRepository->countByUsernameOrEmail($data['username']) > 0) {
@ -211,10 +163,10 @@ class ChillImportUsersCommand extends Command
if ($this->userRepository->countByUsernameOrEmail($data['email']) > 0) {
return true;
}
return false;
}
protected function createUser($offset, $data)
{
$user = new User();
@ -222,41 +174,41 @@ class ChillImportUsersCommand extends Command
->setEmail(\trim($data['email']))
->setUsername(\trim($data['username']))
->setEnabled(true)
->setPassword($this->passwordEncoder->encodePassword($user,
->setPassword($this->passwordEncoder->encodePassword($user,
\bin2hex(\random_bytes(32))))
;
$errors = $this->validator->validate($user);
if ($errors->count() > 0) {
$errorMessages = $this->concatenateViolations($errors);
$this->tempOutput->writeln(sprintf("%d errors found with user with username \"%s\" at line %d", $errors->count(), $data['username'], $offset));
$this->tempOutput->writeln($errorMessages);
throw new \RuntimeException("Found errors while creating an user. "
. "Watch messages in command output");
}
$pgs = $this->getPermissionGroup($data['permission group']);
$centers = $this->getCenters($data['center']);
foreach($pgs as $pg) {
foreach ($centers as $center) {
$groupcenter = $this->createOrGetGroupCenter($center, $pg);
if (FALSE === $user->getGroupCenters()->contains($groupcenter)) {
$user->addGroupCenter($groupcenter);
}
}
}
if ($this->doChanges) {
$this->em->persist($user);
$this->em->flush();
}
$this->logger->notice("Create user", [
'username' => $user->getUsername(),
'id' => $user->getId(),
@ -265,65 +217,58 @@ class ChillImportUsersCommand extends Command
return $user;
}
protected function getPermissionGroup($alias)
{
if (\array_key_exists($alias, $this->permissionGroups)) {
return $this->permissionGroups[$alias];
}
$permissionGroupsByName = [];
foreach($this->em->getRepository(PermissionsGroup::class)
->findAll() as $permissionGroup) {
$permissionGroupsByName[$permissionGroup->getName()] = $permissionGroup;
}
if (count($permissionGroupsByName) === 0) {
throw new \RuntimeException("no permission groups found. Create them "
. "before importing users");
}
$question = new ChoiceQuestion("To which permission groups associate with \"$alias\" ?",
$question = new ChoiceQuestion("To which permission groups associate with \"$alias\" ?",
\array_keys($permissionGroupsByName));
$question
->setMultiselect(true)
->setAutocompleterValues(\array_keys($permissionGroupsByName))
->setNormalizer(function($value) {
if (NULL === $value) { return ''; }
return \trim($value);
})
;
$helper = $this->getHelper('question');
$keys = $helper->ask($this->tempInput, $this->tempOutput, $question);
$this->tempOutput->writeln("You have chosen ".\implode(", ", $keys));
if ($helper->ask($this->tempInput, $this->tempOutput,
if ($helper->ask($this->tempInput, $this->tempOutput,
new ConfirmationQuestion("Are you sure ?", true))) {
foreach ($keys as $key) {
$this->permissionGroups[$alias][] = $permissionGroupsByName[$key];
}
return $this->permissionGroups[$alias];
} else {
$this->logger->error("Error while responding to a a question");
$this->tempOutput("Ok, I accept, but I do not know what to do. Please try again.");
throw new \RuntimeException("Error while responding to a question");
}
$this->logger->error('Error while responding to a a question');
$this->tempOutput->writeln('Ok, I accept, but I do not know what to do. Please try again.');
throw new \RuntimeException('Error while responding to a question');
}
/**
*
* @param Center $center
* @param \Chill\MainBundle\Command\PermissionGroup $pg
* @return GroupCenter
*/
protected function createOrGetGroupCenter(Center $center, PermissionsGroup $pg): GroupCenter
{
if (\array_key_exists($center->getId(), $this->groupCenters)) {
@ -331,36 +276,36 @@ class ChillImportUsersCommand extends Command
return $this->groupCenters[$center->getId()][$pg->getId()];
}
}
$repository = $this->em->getRepository(GroupCenter::class);
$groupCenter = $repository->findOneBy(array(
'center' => $center,
'permissionsGroup' => $pg
));
if ($groupCenter === NULL) {
$groupCenter = new GroupCenter();
$groupCenter
->setCenter($center)
->setPermissionsGroup($pg)
;
$this->em->persist($groupCenter);
}
$this->groupCenters[$center->getId()][$pg->getId()] = $groupCenter;
return $groupCenter;
}
protected function prepareGroupingCenters()
{
$reader = Reader::createFromPath($this->tempInput->getOption('grouping-centers'));
$reader->setHeaderOffset(0);
foreach ($reader->getRecords() as $r) {
$this->centers[$r['alias']] =
$this->centers[$r['alias']] =
\array_merge(
$this->centers[$r['alias']] ?? [],
$this->getCenters($r['center']
@ -368,18 +313,18 @@ class ChillImportUsersCommand extends Command
);
}
}
/**
* return a list of centers matching the name of alias.
*
*
* If the name match one center, this center is returned in an array.
*
* If the name match an alias, the centers corresponding to the alias are
*
* If the name match an alias, the centers corresponding to the alias are
* returned in an array.
*
*
* If the center is not found or alias is not created, a new center is created
* and suggested to user
*
*
* @param string $name the name of the center or the alias regrouping center
* @return Center[]
*/
@ -387,62 +332,62 @@ class ChillImportUsersCommand extends Command
{
// sanitize
$name = \trim($name);
if (\array_key_exists($name, $this->centers)) {
return $this->centers[$name];
}
// search for a center with given name
$center = $this->em->getRepository(Center::class)
->findOneByName($name);
if ($center instanceof Center) {
$this->centers[$name] = [$center];
return $this->centers[$name];
}
// suggest and create
$center = (new Center())
->setName($name);
$this->tempOutput->writeln("Center with name \"$name\" not found.");
$qFormatter = $this->getHelper('question');
$question = new ConfirmationQuestion("Create a center with name \"$name\" ?", true);
if ($qFormatter->ask($this->tempInput, $this->tempOutput, $question)) {
$this->centers[$name] = [ $center ];
$errors = $this->validator->validate($center);
if ($errors->count() > 0) {
$errorMessages = $this->concatenateViolations($errors);
$this->tempOutput->writeln(sprintf("%d errors found with center with name \"%s\"", $errors->count(), $name));
$this->tempOutput->writeln($errorMessages);
throw new \RuntimeException("Found errors while creating one center. "
. "Watch messages in command output");
}
$this->em->persist($center);
return $this->centers[$name];
}
return null;
}
protected function concatenateViolations(ConstraintViolationListInterface $list)
{
$str = [];
foreach ($list as $e) {
/* @var $e \Symfony\Component\Validator\ConstraintViolationInterface */
$str[] = $e->getMessage();
}
return \implode(";", $str);
}
}

View File

@ -1,20 +1,12 @@
<?php
declare(strict_types=1);
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Pagination\PaginatorFactory;
/**
*
*
*/
class AdminCountryCRUDController extends CRUDController
{
function __construct(PaginatorFactory $paginator)
{
$this->paginatorFactory = $paginator;
}
}

View File

@ -136,20 +136,17 @@ class UserController extends CRUDController
]);
}
/**
*
*
* @param User $user
* @return \Symfony\Component\Form\Form
*/
private function createEditPasswordForm(User $user)
private function createEditPasswordForm(User $user): FormInterface
{
return $this->createForm(UserPasswordType::class, null, array(
'user' => $user
))
return $this->createForm(
UserPasswordType::class,
null,
[
'user' => $user
]
)
->add('submit', SubmitType::class, array('label' => 'Change password'))
->remove('actual_password')
;
->remove('actual_password');
}
/**

View File

@ -1,23 +1,5 @@
<?php
/*
* Chill is a suite of a modules, Chill is a software for social workers
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.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\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
@ -28,38 +10,30 @@ use Doctrine\Common\Collections\ArrayCollection;
* @ORM\Entity
* @ORM\Table(name="role_scopes")
* @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="acl_cache_region")
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class RoleScope
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
private int $id;
/**
* @var string
*
* @ORM\Column(type="string", length=255)
*/
private $role;
private string $role;
/**
* @var Scope
*
* @ORM\ManyToOne(
* targetEntity="Chill\MainBundle\Entity\Scope",
* inversedBy="roleScopes")
* @ORM\JoinColumn(nullable=true, name="scope_id")
* @ORM\Cache(usage="NONSTRICT_READ_WRITE")
*/
private $scope;
private Scope $scope;
/**
* @var Collection
*
@ -68,16 +42,14 @@ class RoleScope
* mappedBy="roleScopes")
*/
private $permissionsGroups;
/**
* RoleScope constructor.
*/
private bool $new;
public function __construct() {
$this->new = true;
$this->permissionsGroups = new ArrayCollection();
}
/**
* @return int
*/
@ -101,7 +73,7 @@ class RoleScope
{
return $this->scope;
}
/**
* @param type $role
* @return RoleScope
@ -120,7 +92,7 @@ class RoleScope
public function setScope(Scope $scope = null)
{
$this->scope = $scope;
return $this;
}
}

View File

@ -1,50 +1,23 @@
<?php
/*
* Chill is a software for social workers
* Copyright (C) 2016 Champs-Libres Coopérative <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/>.
*/
declare(strict_types=1);
namespace Chill\MainBundle\Pagination;
/**
* PageGenerator associated with a Paginator
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
* PageGenerator associated with a Paginator.
*/
class PageGenerator implements \Iterator
{
/**
*
* @var Paginator
*/
protected $paginator;
/**
*
* @var int
*/
protected $current = 1;
public function __construct(Paginator $paginator)
protected Paginator $paginator;
protected int $current = 1;
public function __construct(Paginator $paginator)
{
$this->paginator = $paginator;;
}
public function current()
{
return $this->paginator->getPage($current);
@ -67,7 +40,7 @@ class PageGenerator implements \Iterator
public function valid()
{
return $this->current > 0
return $this->current > 0
&& $this->current <= $this->paginator->countPages();
}
}

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Chill\MainBundle\Routing;
use Symfony\Component\Routing\RouteCollection;
@ -8,43 +10,28 @@ use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;
use Symfony\Component\Translation\TranslatorInterface;
/**
* This class permit to build menu from the routing information
* stored in each bundle.
*
* how to must come here FIXME
*
* how to must come here FIXME
*
* @author julien
*/
class MenuComposer
{
/**
*
* @var RouterInterface
*/
private $router;
/**
*
* @var FactoryInterface
*/
private $menuFactory;
/**
*
* @var TranslatorInterface
*/
private $translator;
/**
*
* @var
*/
private $localMenuBuilders = [];
private RouterInterface $router;
private FactoryInterface $menuFactory;
private TranslatorInterface $translator;
private array $localMenuBuilders = [];
private RouteCollection $routeCollection;
function __construct(
RouterInterface $router,
FactoryInterface $menuFactory,
@ -60,7 +47,7 @@ class MenuComposer
* This function is needed for testing purpose: routeCollection is not
* available as a service (RouterInterface is provided as a service and
* added to this class as paramater in __construct)
*
*
* @param RouteCollection $routeCollection
*/
public function setRouteCollection(RouteCollection $routeCollection)
@ -71,7 +58,7 @@ class MenuComposer
/**
* Return an array of routes added to $menuId,
* The array is aimed to build route with MenuTwig
*
*
* @param string $menuId
* @param array $parameters see https://redmine.champs-libres.coop/issues/179
* @return array
@ -83,7 +70,7 @@ class MenuComposer
foreach ($routeCollection->all() as $routeKey => $route) {
if ($route->hasOption('menus')) {
if (array_key_exists($menuId, $route->getOption('menus'))) {
$route = $route->getOption('menus')[$menuId];
@ -101,12 +88,12 @@ class MenuComposer
return $routes;
}
public function getMenuFor($menuId, array $parameters = array())
{
$routes = $this->getRoutesFor($menuId, $parameters);
$menu = $this->menuFactory->createItem($menuId);
// build menu from routes
foreach ($routes as $order => $route) {
$menu->addChild($this->translator->trans($route['label']), [
@ -121,24 +108,24 @@ class MenuComposer
])
;
}
if ($this->hasLocalMenuBuilder($menuId)) {
foreach ($this->localMenuBuilders[$menuId] as $builder) {
/* @var $builder LocalMenuBuilderInterface */
$builder->buildMenu($menuId, $menu, $parameters['args']);
}
}
$this->reorderMenu($menu);
return $menu;
}
/**
* recursive function to resolve the order of a array of routes.
* If the order chosen in routing.yml is already in used, find the
* If the order chosen in routing.yml is already in used, find the
* first next order available.
*
*
* @param array $routes the routes previously added
* @param int $order
* @return int
@ -151,41 +138,41 @@ class MenuComposer
return $order;
}
}
private function reorderMenu(ItemInterface $menu)
private function reorderMenu(ItemInterface $menu)
{
$ordered = [];
$unordered = [];
foreach ($menu->getChildren() as $name => $item) {
$order = $item->getExtra('order');
if ($order !== null) {
$ordered[$this->resolveOrder($ordered, $order)] = $name;
} else {
$unordered = $name;
}
}
ksort($ordered);
$menus = \array_merge(\array_values($ordered), $unordered);
$menu->reorderChildren($menus);
}
public function addLocalMenuBuilder(LocalMenuBuilderInterface $menuBuilder, $menuId)
public function addLocalMenuBuilder(LocalMenuBuilderInterface $menuBuilder, $menuId)
{
$this->localMenuBuilders[$menuId][] = $menuBuilder;
}
/**
* Return true if the menu has at least one builder.
*
*
* This function is a helper to determine if the method `getMenuFor`
* should be used, or `getRouteFor`. The method `getMenuFor` should be used
* if the result is true (it **does** exists at least one menu builder.
*
*
* @param string $menuId
* @return bool
*/

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Chill\MainBundle\Search;
use Symfony\Component\Serializer\Annotation as Serializer;
@ -10,6 +12,8 @@ class SearchApiResult
private $result;
private float $relevance;
public function __construct(float $relevance)
{
$this->relevance = $relevance;
@ -20,7 +24,7 @@ class SearchApiResult
$this->result = $result;
return $this;
}
}
/**
* @Serializer\Groups({"read"})

View File

@ -1,34 +1,17 @@
<?php
/*
* Copyright (C) 2015 Julien Fastré <julien.fastre@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/>.
*/
declare(strict_types=1);
namespace Chill\MainBundle\Security\Authorization;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Voter for Chill software.
*
* This abstract Voter provide generic methods to handle object specific to Chill
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
abstract class AbstractChillVoter extends Voter implements ChillVoterInterface
{
@ -39,6 +22,8 @@ abstract class AbstractChillVoter extends Voter implements ChillVoterInterface
. 'getSupportedAttributes and getSupportedClasses methods.',
E_USER_DEPRECATED);
// @TODO: getSupportedAttributes() should be created in here and made abstract or in ChillVoterInterface.
// @TODO: getSupportedClasses() should be created in here and made abstract or in ChillVoterInterface.
return \in_array($attribute, $this->getSupportedAttributes($attribute))
&& \in_array(\get_class($subject), $this->getSupportedClasses());
}
@ -49,7 +34,7 @@ abstract class AbstractChillVoter extends Voter implements ChillVoterInterface
. 'methods introduced by Symfony 3.0, and do not rely on '
. 'isGranted method', E_USER_DEPRECATED);
// @TODO: isGranted() should be created in here and made abstract or in ChillVoterInterface.
return $this->isGranted($attribute, $subject, $token->getUser());
}
}

View File

@ -1,87 +1,62 @@
<?php
/*
* Copyright (C) 2015 Champs-Libres Coopérative <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/>.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Timeline\TimelineBuilder;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Role\Role;
class TimelinePersonController extends AbstractController
{
protected EventDispatcherInterface $eventDispatcher;
protected TimelineBuilder $timelineBuilder;
protected PaginatorFactory $paginatorFactory;
/**
* TimelinePersonController constructor.
*
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(
EventDispatcherInterface $eventDispatcher,
TimelineBuilder $timelineBuilder,
PaginatorFactory $paginatorFactory,
AuthorizationHelper $authorizationHelper
PaginatorFactory $paginatorFactory
) {
$this->eventDispatcher = $eventDispatcher;
$this->timelineBuilder = $timelineBuilder;
$this->paginatorFactory = $paginatorFactory;
$this->authorizationHelper = $authorizationHelper;
}
public function personAction(Request $request, $person_id)
{
$person = $this->getDoctrine()
->getRepository('ChillPersonBundle:Person')
->getRepository(Person::class)
->find($person_id);
if ($person === NULL) {
throw $this->createNotFoundException();
}
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
$nbItems = $this->timelineBuilder->countItems('person',
$nbItems = $this->timelineBuilder->countItems('person',
[ 'person' => $person ]
);
$paginator = $this->paginatorFactory->create($nbItems);
$event = new PrivacyEvent($person, array('action' => 'timeline'));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillPersonBundle:Timeline:index.html.twig', array
(
'timeline' => $this->timelineBuilder->getTimelineHTML(
'person',
'person',
array('person' => $person),
$paginator->getCurrentPage()->getFirstItemNumber(),
$paginator->getItemsPerPage()

View File

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\Person;
@ -24,6 +26,8 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
private CONST NUMBER_OF_HOUSEHOLD = 10;
private array $personIds;
public function __construct(MembersEditorFactory $editorFactory, EntityManagerInterface $em)
{
$this->editorFactory = $editorFactory;
@ -149,14 +153,14 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
private function preparePersonIds()
{
// @TODO: Remove this and make this service stateless
$this->personIds = $this->em
->createQuery('SELECT p.id FROM '.Person::class.' p '.
'JOIN p.center c '.
'WHERE c.name = :center '
)
->setParameter('center', 'Center A')
->getScalarResult()
;
->getScalarResult();
\shuffle($this->personIds);
}
@ -169,9 +173,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
for ($i=0; $i < $nb; $i++) {
$personId = \array_pop($this->personIds)['id'];
$persons[] = $this->em->getRepository(Person::class)
->find($personId)
;
$persons[] = $this->em->getRepository(Person::class)->find($personId);
}
return $persons;

View File

@ -1,28 +1,10 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.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/>.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Form;
use Chill\MainBundle\Form\Event\CustomizeFormEvent;
use Chill\MainBundle\Repository\CenterRepository;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
@ -30,12 +12,9 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Form\Type\PickCenterType;
use Chill\PersonBundle\Form\Type\GenderType;
use Chill\MainBundle\Form\Type\DataTransformer\CenterTransformer;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Form\Type\PersonAltNameType;
@ -43,27 +22,19 @@ final class CreationPersonType extends AbstractType
{
// TODO: This is only used in test.
// TODO: See if this is still valid and update accordingly.
const NAME = 'chill_personbundle_person_creation';
public const NAME = 'chill_personbundle_person_creation';
private CenterRepository $centerRepository;
/**
*
* @var ConfigPersonAltNamesHelper
*/
protected $configPersonAltNamesHelper;
private ConfigPersonAltNamesHelper $configPersonAltNamesHelper;
private EventDispatcherInterface $dispatcher;
private bool $askCenters;
public function __construct(
CenterRepository $centerRepository,
ConfigPersonAltNamesHelper $configPersonAltNamesHelper,
EventDispatcherInterface $dispatcher,
ParameterBagInterface $parameterBag
) {
$this->centerTransformer = $centerRepository;
$this->configPersonAltNamesHelper = $configPersonAltNamesHelper;
$this->dispatcher = $dispatcher;
$this->askCenters = $parameterBag->get('chill_main')['acl']['form_show_centers'];

View File

@ -1,22 +1,6 @@
<?php
/*
* Chill is a software for social workers
* 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/>.
*/
declare(strict_types=1);
namespace Chill\ReportBundle\Timeline;
@ -38,38 +22,39 @@ use Chill\MainBundle\Timeline\TimelineSingleQuery;
*/
class TimelineReportProvider implements TimelineProviderInterface
{
protected EntityManager $em;
protected AuthorizationHelper $helper;
protected CustomFieldsHelper $customFieldsHelper;
protected $showEmptyValues;
protected bool $showEmptyValues;
private Security $security;
public function __construct(
EntityManager $em,
AuthorizationHelper $helper,
Security $security,
CustomFieldsHelper $customFieldsHelper,
$showEmptyValues
)
{
) {
$this->em = $em;
$this->helper = $helper;
$this->security = $security;
$this->customFieldsHelper = $customFieldsHelper;
$this->showEmptyValues = $showEmptyValues;
}
/**
*
*
* {@inheritDoc}
*/
public function fetchQuery($context, array $args)
{
$this->checkContext($context);
$report = $this->em->getClassMetadata(Report::class);
[$where, $parameters] = $this->getWhereClause($context, $args);
@ -84,7 +69,7 @@ class TimelineReportProvider implements TimelineProviderInterface
'parameters' => $parameters
]);
}
private function getWhereClause(string $context, array $args): array
{
switch ($context) {
@ -102,7 +87,7 @@ class TimelineReportProvider implements TimelineProviderInterface
$report = $this->em->getClassMetadata(Report::class);
$person = $this->em->getClassMetadata(Person::class);
$role = new Role('CHILL_REPORT_SEE');
$reachableCenters = $this->helper->getReachableCenters($this->security->getUser(),
$reachableCenters = $this->helper->getReachableCenters($this->security->getUser(),
$role);
$reportPersonId = $report->getAssociationMapping('person')['joinColumns'][0]['name'];
$reportScopeId = $report->getAssociationMapping('scope')['joinColumns'][0]['name'];
@ -123,13 +108,13 @@ class TimelineReportProvider implements TimelineProviderInterface
}
// add the center id to the parameters
$parameters[] = $center->getId();
$parameters[] = $center->getId();
// loop over scopes
$scopeIds = [];
foreach ($this->helper->getReachableScopes($this->security->getUser(),
foreach ($this->helper->getReachableScopes($this->security->getUser(),
$role, $center) as $scope) {
if (\in_array($scope->getId(), $scopeIds)) {
continue;
continue;
}
$scopeIds[] = $scope->getId();
}
@ -173,7 +158,7 @@ class TimelineReportProvider implements TimelineProviderInterface
// this is the final clause that we are going to fill
$clause = "{report}.{person_id} = ? AND {report}.{scopes_id} IN ({scopes_ids})";
// iterate over reachable scopes
$scopes = $this->helper->getReachableScopes($this->security->getUser(), $role,
$scopes = $this->helper->getReachableScopes($this->security->getUser(), $role,
$args['person']->getCenter());
foreach ($scopes as $scope) {
@ -194,16 +179,16 @@ class TimelineReportProvider implements TimelineProviderInterface
$clause,
[
'{report}' => $report->getTableName(),
'{person_id}' => $reportPersonId,
'{person_id}' => $reportPersonId,
'{scopes_id}' => $reportScopeId,
'{scopes_ids}' => \implode(', ',
'{scopes_ids}' => \implode(', ',
\array_fill(0, \count($parameters)-1, '?'))
]
),
$parameters
];
}
private function getFromClause(string $context): string
{
$report = $this->em->getClassMetadata(Report::class);
@ -229,30 +214,30 @@ class TimelineReportProvider implements TimelineProviderInterface
}
/**
*
*
* {@inheritDoc}
*/
public function getEntities(array $ids)
{
$reports = $this->em->getRepository('ChillReportBundle:Report')
->findBy(array('id' => $ids));
$result = array();
foreach($reports as $report) {
$result[$report->getId()] = $report;
}
return $result;
}
/**
*
*
* {@inheritDoc}
*/
public function getEntityTemplate($entity, $context, array $args)
{
$this->checkContext($context);
return array(
'template' => 'ChillReportBundle:Timeline:report.html.twig',
'template_data' => array(
@ -262,19 +247,19 @@ class TimelineReportProvider implements TimelineProviderInterface
)
);
}
protected function getFieldsToRender(Report $entity, $context, array $args = array())
{
//gather all custom fields which should appears in summary
$gatheredFields = array();
if (array_key_exists('summary_fields', $entity->getCFGroup()->getOptions())) {
// keep in memory title
$title = null;
$subtitle = null;
foreach ($entity->getCFGroup()->getCustomFields() as $customField) {
if (in_array($customField->getSlug(),
if (in_array($customField->getSlug(),
$entity->getCFGroup()->getOptions()['summary_fields'])) {
// if we do not want to show empty values
if ($this->showEmptyValues === false) {
@ -304,23 +289,23 @@ class TimelineReportProvider implements TimelineProviderInterface
}
}
}
return $gatheredFields;
}
/**
*
*
* {@inheritDoc}
*/
public function supportsType($type)
{
return $type === 'report';
}
/**
* check if the context is supported
*
*
* @param string $context
* @throws \LogicException if the context is not supported
*/