diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonController.php b/src/Bundle/ChillPersonBundle/Controller/PersonController.php
index f33e9cce8..77a564157 100644
--- a/src/Bundle/ChillPersonBundle/Controller/PersonController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/PersonController.php
@@ -29,11 +29,16 @@ use Chill\PersonBundle\Form\PersonType;
use Chill\PersonBundle\Form\CreationPersonType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\Form\Extension\Core\Type\ButtonType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\MainBundle\Search\SearchProvider;
use Chill\PersonBundle\Repository\PersonRepository;
@@ -94,7 +99,8 @@ final class PersonController extends AbstractController
ConfigPersonAltNamesHelper $configPersonAltNameHelper,
LoggerInterface $logger,
ValidatorInterface $validator,
- EntityManagerInterface $em
+ EntityManagerInterface $em,
+ Security $security
) {
$this->similarPersonMatcher = $similarPersonMatcher;
$this->translator = $translator;
@@ -104,6 +110,7 @@ final class PersonController extends AbstractController
$this->logger = $logger;
$this->validator = $validator;
$this->em = $em;
+ $this->security = $security;
}
public function getCFGroup()
@@ -209,11 +216,21 @@ final class PersonController extends AbstractController
}
}
- public function newAction()
+ /**
+ * Method for creating a new person
+ *
+ *The controller register data from a previous post on the form, and
+ * register it in the session.
+ *
+ * The next post compare the data with previous one and, if yes, show a
+ * review page if there are "alternate persons".
+ *
+ * @param Request $request
+ * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
+ */
+ public function newAction(Request $request)
{
- // this is a dummy default center.
- $defaultCenter = $this->get('security.token_storage')
- ->getToken()
+ $defaultCenter = $this->security
->getUser()
->getGroupCenters()[0]
->getCenter();
@@ -221,38 +238,103 @@ final class PersonController extends AbstractController
$person = (new Person(new \DateTime('now')))
->setCenter($defaultCenter);
- $form = $this->createForm(
- CreationPersonType::class,
- $person,
- array(
- 'action' => $this->generateUrl('chill_person_review'),
- 'form_status' => CreationPersonType::FORM_NOT_REVIEWED
- ));
+ $form = $this->createForm(CreationPersonType::class, $person, [
+ 'validation_groups' => ['create']
+ ])->add('editPerson', SubmitType::class, [
+ 'label' => 'Add the person'
+ ])->add('createPeriod', SubmitType::class, [
+ 'label' => 'Add the person and create an accompanying period'
+ ]);
- return $this->_renderNewForm($form);
+ $form->handleRequest($request);
+
+ if ($request->getMethod() === Request::METHOD_GET) {
+ $this->lastPostDataReset();
+ } elseif ($request->getMethod() === Request::METHOD_POST
+ && $form->isValid()) {
+
+ $alternatePersons = $this->similarPersonMatcher
+ ->matchPerson($person);
+
+ if (
+ FALSE === $this->isLastPostDataChanges($form, $request, true)
+ ||
+ count($alternatePersons) === 0
+ ) {
+ $this->em->persist($person);
+
+ $this->em->flush();
+ $this->lastPostDataReset();
+
+ if ($form->get('createPeriod')->isClicked()) {
+ return $this->redirectToRoute('chill_person_accompanying_course_new', [
+ 'person_id' => [ $person->getId() ]
+ ]);
+ }
+
+ return $this->redirectToRoute('chill_person_general_edit',
+ ['person_id' => $person->getId()]);
+ }
+ } elseif ($request->getMethod() === Request::METHOD_POST) {
+ $this->addFlash('error', $this->translator->trans('This form contains errors'));
+ }
+
+ return $this->render('@ChillPerson/Person/create.html.twig',
+ [
+ 'form' => $form->createView(),
+ 'alternatePersons' => $alternatePersons ?? []
+ ]
+ );
}
- private function _renderNewForm($form)
+ private function isLastPostDataChanges(Form $form, Request $request, bool $replace = false): bool
{
- return $this->render('ChillPersonBundle:Person:create.html.twig',
- array(
- 'form' => $form->createView()
- ));
+ /** @var SessionInterface $session */
+ $session = $this->get('session');
+ if (!$session->has('last_person_data')) {
+ return true;
+ }
+
+ $newPost = $this->lastPostDataBuildHash($form, $request);
+
+ $isChanged = $newPost !== $session->get('last_person_data');
+
+ if ($replace) {
+ $session->set('last_person_data', $newPost);
+ }
+
+ return $isChanged ;
+ }
+
+ private function lastPostDataReset(): void
+ {
+ $this->get('session')->set('last_person_data', "");
}
/**
+ * build the hash for posted data
*
- * @param type $form
- * @return \Chill\PersonBundle\Entity\Person
+ * For privacy reasons, the data are hashed using sha512
+ *
+ * @param Form $form
+ * @param Request $request
+ * @return string
*/
- private function _bindCreationForm($form)
+ private function lastPostDataBuildHash(Form $form, Request $request): string
{
- /**
- * @var Person
- */
- $person = $form->getData();
+ $fields = [];
+ $ignoredFields = ['form_status', '_token'];
- return $person;
+ foreach ($request->request->all()[$form->getName()] as $field => $value) {
+ if (\in_array($field, $ignoredFields)) {
+ continue;
+ }
+ $fields[$field] = \is_array($value) ?
+ \implode(",", $value) : $value;
+ }
+ ksort($fields);
+
+ return \hash('sha512', \implode("&", $fields));
}
/**
@@ -281,120 +363,6 @@ final class PersonController extends AbstractController
return $errors;
}
- public function reviewAction(Request $request, PersonNotDuplicateRepository $personNotDuplicateRepository)
- {
- if ($request->getMethod() !== 'POST') {
- $r = new Response("You must send something to review the creation of a new Person");
- $r->setStatusCode(400);
- return $r;
- }
-
- $form = $this->createForm(
- CreationPersonType::class,
- new Person(),
- array(
- 'action' => $this->generateUrl('chill_person_create'),
- 'form_status' => CreationPersonType::FORM_BEING_REVIEWED
- ));
-
- $form->handleRequest($request);
-
- $person = $this->_bindCreationForm($form);
-
- $errors = $this->_validatePersonAndAccompanyingPeriod($person);
- $this->logger->info(sprintf('Person created with %d errors ', count($errors)));
-
- if ($errors->count() > 0) {
- $this->logger->info('The created person has errors');
- $flashBag = $this->get('session')->getFlashBag();
- $translator = $this->get('translator');
-
- $flashBag->add('error', $translator->trans('The person data are not valid'));
-
- foreach($errors as $error) {
- $flashBag->add('info', $error->getMessage());
- }
-
- $form = $this->createForm(
- CreationPersonType::class,
- $person,
- array(
- 'action' => $this->generateUrl('chill_person_review'),
- 'form_status' => CreationPersonType::FORM_NOT_REVIEWED
- ));
-
- $form->handleRequest($request);
-
- return $this->_renderNewForm($form);
- } else {
- $this->logger->info('Person created without errors');
- }
-
- $this->em->persist($person);
-
- $alternatePersons = $this->similarPersonMatcher->matchPerson($person, $personNotDuplicateRepository);
-
- if (count($alternatePersons) === 0) {
- return $this->forward('ChillPersonBundle:Person:create');
- }
-
- $this->get('session')->getFlashBag()->add('info',
- $this->get('translator')->trans(
- '%nb% person with similar name. Please verify that this is a new person',
- array('%nb%' => count($alternatePersons)))
- );
-
- return $this->render('ChillPersonBundle:Person:create_review.html.twig',
- array(
- 'person' => $person,
- 'alternatePersons' => $alternatePersons,
- 'firstName' => $form['firstName']->getData(),
- 'lastName' => $form['lastName']->getData(),
- 'birthdate' => $form['birthdate']->getData(),
- 'gender' => $form['gender']->getData(),
- 'form' => $form->createView()));
- }
-
- public function createAction(Request $request)
- {
-
- if ($request->getMethod() !== 'POST') {
- $r = new Response('You must send something to create a person !');
- $r->setStatusCode(400);
- return $r;
- }
-
- $form = $this->createForm(CreationPersonType::class, null, array(
- 'form_status' => CreationPersonType::FORM_REVIEWED
- ));
-
- $form->handleRequest($request);
-
- $person = $this->_bindCreationForm($form);
-
- $errors = $this->_validatePersonAndAccompanyingPeriod($person);
-
- $this->denyAccessUnlessGranted('CHILL_PERSON_CREATE', $person,
- 'You are not allowed to create this person');
-
- if ($errors->count() === 0) {
- $this->em->persist($person);
-
- $this->em->flush();
-
- return $this->redirect($this->generateUrl('chill_person_general_edit',
- array('person_id' => $person->getId())));
- } else {
- $text = "this should not happen if you reviewed your submission\n";
- foreach ($errors as $error) {
- $text .= $error->getMessage()."\n";
- }
- $r = new Response($text);
- $r->setStatusCode(400);
- return $r;
- }
- }
-
/**
* easy getting a person by his id
* @return \Chill\PersonBundle\Entity\Person
diff --git a/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php b/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php
index c001185ca..32b7a69f2 100644
--- a/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php
+++ b/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php
@@ -21,6 +21,7 @@
namespace Chill\PersonBundle\Form;
+use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -48,7 +49,7 @@ final class CreationPersonType extends AbstractType
* @var CenterTransformer
*/
private $centerTransformer;
-
+
/**
*
* @var ConfigPersonAltNamesHelper
@@ -69,57 +70,22 @@ final class CreationPersonType extends AbstractType
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
- if ($options['form_status'] === self::FORM_BEING_REVIEWED) {
+ $builder
+ ->add('firstName')
+ ->add('lastName')
+ ->add('birthdate', ChillDateType::class, [
+ 'required' => false,
+ ])
+ ->add('gender', GenderType::class, array(
+ 'required' => true, 'placeholder' => null
+ ))
+ ->add('center', CenterType::class)
+ ;
- $dateToStringTransformer = new DateTimeToStringTransformer(
- null, null, 'd-m-Y', false);
-
- $builder->add('firstName', HiddenType::class)
- ->add('lastName', HiddenType::class)
- ->add('birthdate', HiddenType::class, array(
- 'property_path' => 'birthdate'
- ))
- ->add('gender', HiddenType::class)
- ->add('form_status', HiddenType::class, array(
- 'mapped' => false,
- 'data' => $options['form_status']
- ))
- ->add('center', HiddenType::class)
- ;
-
- if ($this->configPersonAltNamesHelper->hasAltNames()) {
- $builder->add('altNames', PersonAltNameType::class, [
- 'by_reference' => false,
- 'force_hidden' => true
- ]);
- }
-
- $builder->get('birthdate')
- ->addModelTransformer($dateToStringTransformer);
- $builder->get('center')
- ->addModelTransformer($this->centerTransformer);
- } else {
- $builder
- ->add('firstName')
- ->add('lastName')
- ->add('birthdate', ChillDateType::class, [
- 'required' => false,
- ])
- ->add('gender', GenderType::class, array(
- 'required' => true, 'placeholder' => null
- ))
- ->add('form_status', HiddenType::class, array(
- 'data' => $options['form_status'],
- 'mapped' => false
- ))
- ->add('center', CenterType::class)
- ;
-
- if ($this->configPersonAltNamesHelper->hasAltNames()) {
- $builder->add('altNames', PersonAltNameType::class, [
- 'by_reference' => false
- ]);
- }
+ if ($this->configPersonAltNamesHelper->hasAltNames()) {
+ $builder->add('altNames', PersonAltNameType::class, [
+ 'by_reference' => false
+ ]);
}
}
@@ -129,15 +95,8 @@ final class CreationPersonType extends AbstractType
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
- 'data_class' => 'Chill\PersonBundle\Entity\Person'
+ 'data_class' => Person::class
));
-
- $resolver->setRequired('form_status')
- ->setAllowedValues('form_status', array(
- self::FORM_BEING_REVIEWED,
- self::FORM_NOT_REVIEWED,
- self::FORM_REVIEWED
- ));
}
/**
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Person/create.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Person/create.html.twig
index 036dc5d01..9718308ed 100644
--- a/src/Bundle/ChillPersonBundle/Resources/views/Person/create.html.twig
+++ b/src/Bundle/ChillPersonBundle/Resources/views/Person/create.html.twig
@@ -20,27 +20,70 @@
{% block content %}
+
{{ 'Add a person'|trans }}
+
+ {% if alternatePersons is not empty %}
+
+
+ {% transchoice alternatePersons|length with { '%nb%': alternatePersons|length } %}
+ %nb% person with similar name. Please verify that this is a new person
+ {% endtranschoice %}
+
+
{{ form_end(form) }}
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Person/create_review.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Person/create_review.html.twig
deleted file mode 100644
index cf3e37beb..000000000
--- a/src/Bundle/ChillPersonBundle/Resources/views/Person/create_review.html.twig
+++ /dev/null
@@ -1,97 +0,0 @@
-{#
- * Copyright (C) 2014, Champs Libres Cooperative SCRLFS,
- *
- * 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 .
-#}
-{% extends "@ChillMain/layout.html.twig" %}
-
-{% block title %}{{ 'Alreay existing person'|trans }}{% endblock title %}
-
-{% block content %}
-
-
-
-
- {% transchoice alternatePersons|length with { '%nb%': alternatePersons|length } %}
- %nb% person with similar name. Please verify that this is a new person
- {% endtranschoice %}
-
-