diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93cb442dd..deb66aba9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,13 +11,20 @@ and this project adheres to
## Unreleased
-* [Documents] Validate storedObject and allow for null data (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/565)
-* [Activity form] invert 'incoming' and 'receiving' in Activity form
-* [Activity form] keep the same order for 'attendee' field in new and edit form
-* [list with period] use "sameas" test operator to introduce requestor in list
+* Load relationships without gender in french fixtures
+* Add command to remove old draft accompanying periods
## Test releases
+### 2021-04-28
+
+* [address] fix bug when editing address: update location and addressreferenceId + better update of the map in edition (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/593)
+* [main] avoid address reference search on undefined post code (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/561)
+* [person] prevent duplicate relationship in filiation/household graph (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/560)
+* [Documents] Validate storedObject and allow for null data (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/565)
+* [parcours]: Comments can be unpinned + edit/delete for all users that are allowed to edit parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/566)
+
+
### 2021-04-26
* [Datepickers] datepickers fixed when using keyboard to enter date (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/545)
diff --git a/phpstan-critical.neon b/phpstan-critical.neon
index 262d3012f..1dc516834 100644
--- a/phpstan-critical.neon
+++ b/phpstan-critical.neon
@@ -5,11 +5,6 @@ parameters:
count: 1
path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
- -
- message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$currentHouseholdParticipationAt\\.$#"
- count: 3
- path: src/Bundle/ChillPersonBundle/Entity/Person.php
-
-
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$relation\\.$#"
count: 1
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index edec00554..3322f9539 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -3,6 +3,7 @@ parameters:
paths:
- src/
excludePaths:
+ - .php_cs*
- docs/
- src/Bundle/*/Tests/*
- src/Bundle/*/tests/*
diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php
index a780af78a..9bf43b37e 100644
--- a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php
+++ b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php
@@ -16,9 +16,9 @@ use Chill\MainBundle\Serializer\Model\Collection;
use Exception;
use LogicException;
use RuntimeException;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
@@ -55,7 +55,7 @@ class ApiController extends AbstractCRUDController
return $this->entityDelete('_entity', $request, $id, $_format);
default:
- throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This method is not implemented');
+ throw new BadRequestHttpException('This method is not implemented');
}
}
@@ -120,7 +120,7 @@ class ApiController extends AbstractCRUDController
return $this->entityPostAction('_entity', $request, $_format);
default:
- throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This method is not implemented');
+ throw new BadRequestHttpException('This method is not implemented');
}
}
@@ -160,7 +160,7 @@ class ApiController extends AbstractCRUDController
try {
$entity = $this->deserialize($action, $request, $_format, $entity);
} catch (NotEncodableValueException $e) {
- throw new BadRequestException('invalid json', 400, $e);
+ throw new BadRequestHttpException('invalid json', 400, $e);
}
$errors = $this->validate($action, $request, $_format, $entity);
@@ -273,7 +273,7 @@ class ApiController extends AbstractCRUDController
try {
$postedData = $this->getSerializer()->deserialize($request->getContent(), $postedDataType, $_format, $postedDataContext);
} catch (\Symfony\Component\Serializer\Exception\UnexpectedValueException $e) {
- throw new BadRequestException(sprintf('Unable to deserialize posted ' .
+ throw new BadRequestHttpException(sprintf('Unable to deserialize posted ' .
'data: %s', $e->getMessage()), 0, $e);
}
@@ -290,7 +290,7 @@ class ApiController extends AbstractCRUDController
break;
default:
- throw new BadRequestException('this method is not supported');
+ throw new BadRequestHttpException('this method is not supported');
}
$errors = $this->validate($action, $request, $_format, $entity, [$postedData]);
@@ -408,7 +408,7 @@ class ApiController extends AbstractCRUDController
return $this->json($entity, Response::HTTP_OK, [], $context);
}
- throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This format is not implemented');
+ throw new BadRequestHttpException('This format is not implemented');
}
protected function entityPostAction($action, Request $request, string $_format): Response
@@ -418,7 +418,7 @@ class ApiController extends AbstractCRUDController
try {
$entity = $this->deserialize($action, $request, $_format, $entity);
} catch (NotEncodableValueException $e) {
- throw new BadRequestException('invalid json', 400, $e);
+ throw new BadRequestHttpException('invalid json', 400, $e);
}
$errors = $this->validate($action, $request, $_format, $entity);
diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php
index 62d587ab3..edca07b41 100644
--- a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php
+++ b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php
@@ -25,6 +25,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -1140,6 +1141,6 @@ class CRUDController extends AbstractController
return $this->json($entity, Response::HTTP_OK, [], $context);
}
- throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException('This format is not implemented');
+ throw new BadRequestHttpException('This format is not implemented');
}
}
diff --git a/src/Bundle/ChillMainBundle/Controller/SearchController.php b/src/Bundle/ChillMainBundle/Controller/SearchController.php
index 41349336a..496538665 100644
--- a/src/Bundle/ChillMainBundle/Controller/SearchController.php
+++ b/src/Bundle/ChillMainBundle/Controller/SearchController.php
@@ -22,7 +22,6 @@ use Chill\MainBundle\Search\UnknowSearchNameException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -216,7 +215,7 @@ class SearchController extends AbstractController
$types = $request->query->get('type', []);
if (count($types) === 0) {
- throw new BadRequestException('The request must contains at '
+ throw new BadRequestHttpException('The request must contains at '
. ' one type');
}
diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php
index 103de6d84..2803ff254 100644
--- a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php
+++ b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php
@@ -25,7 +25,6 @@ use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -144,7 +143,7 @@ class WorkflowController extends AbstractController
public function getAccessByAccessKey(EntityWorkflowStep $entityWorkflowStep, Request $request): Response
{
if (null === $accessKey = $request->query->get('accessKey', null)) {
- throw new BadRequestException('accessKey is missing');
+ throw new BadRequestHttpException('accessKey is missing');
}
if (!$this->getUser() instanceof User) {
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue
index e351109a8..fcd64ed70 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue
@@ -628,6 +628,10 @@ export default {
newAddress = Object.assign(newAddress, {
'addressReference': this.entity.selected.address.addressReference
});
+ } else {
+ newAddress = Object.assign(newAddress, {
+ 'addressReference': null
+ });
}
if (this.validFrom) {
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue
index c6abd92d5..80d2ca01a 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue
@@ -8,12 +8,15 @@ import L from 'leaflet';
import markerIconPng from 'leaflet/dist/images/marker-icon.png'
import 'leaflet/dist/leaflet.css';
-let map;
-let marker;
-
export default {
name: 'AddressMap',
props: ['entity'],
+ data() {
+ return {
+ map: null,
+ marker: null
+ }
+ },
computed: {
center() {
return this.entity.selected.addressMap.center;
@@ -21,30 +24,33 @@ export default {
},
methods:{
init() {
- map = L.map('address_map').setView([46.67059, -1.42683], 12);
+ this.map = L.map('address_map').setView([46.67059, -1.42683], 12);
- map.scrollWheelZoom.disable();
+ this.map.scrollWheelZoom.disable();
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
- }).addTo(map);
+ }).addTo(this.map);
const markerIcon = L.icon({
iconUrl: markerIconPng,
iconAnchor: [12, 41],
});
- marker = L.marker([48.8589, 2.3469], {icon: markerIcon}).addTo(map);
-
+ this.marker = L.marker([48.8589, 2.3469], {icon: markerIcon});
+ this.marker.addTo(this.map);
},
update() {
- //console.log('update map with : ', this.address.addressMap.center)
- marker.setLatLng(this.entity.addressMap.center);
- map.setView(this.entity.addressMap.center, 15);
+ //console.log('update map with : ', this.entity.addressMap.center)
+ if (this.marker && this.entity.addressMap.center) {
+ this.marker.setLatLng(this.entity.addressMap.center);
+ this.map.setView(this.entity.addressMap.center, 15);
+ }
}
},
mounted(){
- this.init()
+ this.init();
+ this.update();
}
}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue
index 18e0caca3..2c8e17687 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue
@@ -119,7 +119,7 @@ export default {
},
listenInputSearch(query) {
//console.log('listenInputSearch', query, this.isAddressSelectorOpen);
- if (!this.entity.selected.writeNew.postcode) {
+ if (!this.entity.selected.writeNew.postcode && 'id' in this.entity.selected.city) {
if (query.length > 2) {
this.isLoading = true;
searchReferenceAddresses(query, this.entity.selected.city).then(
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue
index ca5d01b50..9dd85fa73 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue
@@ -106,6 +106,9 @@ export default {
this.$emit('getReferenceAddresses', this.value);
if (this.value.center) {
this.updateMapCenter(this.value.center);
+ if (this.value.center.coordinates) {
+ this.entity.selected.postcode.coordinates = this.value.center.coordinates;
+ }
}
}
},
diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php
index ccb48c160..0809863f6 100644
--- a/src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php
+++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php
@@ -71,6 +71,7 @@ class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAw
'id' => $address->getPostCode()->getId(),
'name' => $address->getPostCode()->getName(),
'code' => $address->getPostCode()->getCode(),
+ 'center' => $address->getPostcode()->getCenter(),
],
'country' => [
'id' => $address->getPostCode()->getCountry()->getId(),
diff --git a/src/Bundle/ChillPersonBundle/Command/RemoveOldDraftAccompanyingPeriodCommand.php b/src/Bundle/ChillPersonBundle/Command/RemoveOldDraftAccompanyingPeriodCommand.php
new file mode 100644
index 000000000..5d503007f
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Command/RemoveOldDraftAccompanyingPeriodCommand.php
@@ -0,0 +1,64 @@
+logger = $logger;
+ $this->remover = $remover;
+ }
+
+ protected function configure(): void
+ {
+ $this
+ ->setDescription('Remove draft accompanying period which are still draft and unused')
+ ->addArgument('interval', InputArgument::OPTIONAL, 'The interval for unactive periods', 'P15D');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $this->logger->info('[' . $this->getName() . '] started', [
+ 'interval' => $input->getArgument('interval'),
+ ]);
+
+ try {
+ $interval = new DateInterval($input->getArgument('interval'));
+ } catch (Exception $e) {
+ $this->logger->error('[' . $this->getName() . '] bad interval');
+
+ throw $e;
+ }
+
+ $this->remover->remove($interval);
+
+ $this->logger->info('[' . $this->getName() . '] end of command');
+
+ return 0;
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php
index f1306640b..21db6b00c 100644
--- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php
@@ -33,10 +33,10 @@ use DateInterval;
use DateTimeImmutable;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Serializer\Exception\RuntimeException;
@@ -185,7 +185,7 @@ final class AccompanyingCourseApiController extends ApiController
->deserialize($request->getContent(), Person::class, $_format, []);
if (null === $person) {
- throw new BadRequestException('person id not found');
+ throw new BadRequestHttpException('person id not found');
}
// TODO add acl
@@ -204,7 +204,7 @@ final class AccompanyingCourseApiController extends ApiController
break;
default:
- throw new BadRequestException('This method is not supported');
+ throw new BadRequestHttpException('This method is not supported');
}
$errors = $this->validator->validate($accompanyingPeriod);
@@ -247,12 +247,12 @@ final class AccompanyingCourseApiController extends ApiController
}
if (null === $requestor) {
- throw new BadRequestException('Could not find any person or thirdparty', 0, null);
+ throw new BadRequestHttpException('Could not find any person or thirdparty', 0, null);
}
$accompanyingPeriod->setRequestor($requestor);
} else {
- throw new BadRequestException('method not supported');
+ throw new BadRequestHttpException('method not supported');
}
$errors = $this->validator->validate($accompanyingPeriod);
diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseCommentController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseCommentController.php
index be6bcab07..09af4a3cf 100644
--- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseCommentController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseCommentController.php
@@ -186,6 +186,24 @@ class AccompanyingCourseCommentController extends AbstractController
]);
}
+ /**
+ * @Route("/{_locale}/parcours/comment/{id}/unpin", name="chill_person_accompanying_period_comment_unpin")
+ */
+ public function unpinComment(AccompanyingPeriod\Comment $comment): Response
+ {
+ $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::EDIT, $comment->getAccompanyingPeriod());
+
+ $comment->getAccompanyingPeriod()->setPinnedComment(null);
+
+ $this->getDoctrine()->getManager()->flush();
+
+ $this->addFlash('success', $this->translator->trans('accompanying_course.comment is unpinned'));
+
+ return $this->redirectToRoute('chill_person_accompanying_period_comment_list', [
+ 'accompanying_period_id' => $comment->getAccompanyingPeriod()->getId(),
+ ]);
+ }
+
private function createCommentForm(AccompanyingPeriod\Comment $comment, string $step): FormInterface
{
return $this->formFactory->createNamed($step, AccompanyingCourseCommentType::class, $comment);
diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php
index b15f8adb9..4d78bb42b 100644
--- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php
@@ -21,9 +21,9 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
@@ -255,7 +255,7 @@ class AccompanyingCourseController extends Controller
$personIds = $request->query->get('person_id');
if (false === is_array($personIds)) {
- throw new BadRequestException('person_id parameter should be an array');
+ throw new BadRequestHttpException('person_id parameter should be an array');
}
foreach ($personIds as $personId) {
diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php
index 7b6dc201e..503867a3e 100644
--- a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php
@@ -21,8 +21,8 @@ use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
@@ -202,7 +202,7 @@ class HouseholdController extends AbstractController
$this->denyAccessUnlessGranted(HouseholdVoter::EDIT, $household);
if (!$request->query->has('address_id')) {
- throw new BadRequestException('parameter address_id is missing');
+ throw new BadRequestHttpException('parameter address_id is missing');
}
$address_id = $request->query->getInt('address_id');
@@ -218,7 +218,7 @@ class HouseholdController extends AbstractController
}
if (null === $address) {
- throw new BadRequestException('The edited address does not belongs to the household');
+ throw new BadRequestHttpException('The edited address does not belongs to the household');
}
$form = $this->createForm(AddressDateType::class, $address, []);
diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php
index 2ec72a786..cacba0630 100644
--- a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php
@@ -20,9 +20,9 @@ use Chill\PersonBundle\Form\HouseholdMemberType;
use Chill\PersonBundle\Household\MembersEditor;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Serializer\Exception;
@@ -105,7 +105,7 @@ class HouseholdMemberController extends ApiController
$ids = $request->query->get('persons', []);
if (0 === count($ids)) {
- throw new BadRequestException('parameters persons in query ' .
+ throw new BadRequestHttpException('parameters persons in query ' .
'is not an array or empty');
}
@@ -121,7 +121,8 @@ class HouseholdMemberController extends ApiController
}
}
- if ($householdId = $request->query->get('household', false)) {
+ if ($request->query->has('household')) {
+ $householdId = $request->query->get('household', false);
$household = $em->getRepository(Household::class)
->find($householdId);
$allowHouseholdCreate = false;
@@ -189,7 +190,7 @@ class HouseholdMemberController extends ApiController
['groups' => ['read']]
);
} catch (Exception\InvalidArgumentException|Exception\UnexpectedValueException $e) {
- throw new BadRequestException("Deserialization error: {$e->getMessage()}", 45896, $e);
+ throw new BadRequestHttpException("Deserialization error: {$e->getMessage()}", 45896, $e);
}
// TODO ACL
diff --git a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadRelations.php b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadRelations.php
index e2bb469bc..c7ce18091 100644
--- a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadRelations.php
+++ b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadRelations.php
@@ -21,23 +21,13 @@ class LoadRelations extends Fixture implements FixtureGroupInterface
public const RELATION_KEY = 'relations';
public const RELATIONS = [
- ['title' => ['fr' => 'Mère'], 'reverseTitle' => ['fr' => 'Fille']],
- ['title' => ['fr' => 'Mère'], 'reverseTitle' => ['fr' => 'Fils']],
- ['title' => ['fr' => 'Père'], 'reverseTitle' => ['fr' => 'Fille']],
- ['title' => ['fr' => 'Père'], 'reverseTitle' => ['fr' => 'Fils']],
-
- ['title' => ['fr' => 'Frère'], 'reverseTitle' => ['fr' => 'Frère']],
- ['title' => ['fr' => 'Soeur'], 'reverseTitle' => ['fr' => 'Soeur']],
- ['title' => ['fr' => 'Frère'], 'reverseTitle' => ['fr' => 'Soeur']],
-
- ['title' => ['fr' => 'Demi-frère'], 'reverseTitle' => ['fr' => 'Demi-frère']],
- ['title' => ['fr' => 'Demi-soeur'], 'reverseTitle' => ['fr' => 'Demi-soeur']],
- ['title' => ['fr' => 'Demi-frère'], 'reverseTitle' => ['fr' => 'Demi-soeur']],
-
- ['title' => ['fr' => 'Oncle'], 'reverseTitle' => ['fr' => 'Neveu']],
- ['title' => ['fr' => 'Oncle'], 'reverseTitle' => ['fr' => 'Nièce']],
- ['title' => ['fr' => 'Tante'], 'reverseTitle' => ['fr' => 'Neveu']],
- ['title' => ['fr' => 'Tante'], 'reverseTitle' => ['fr' => 'Nièce']],
+ ['title' => ['fr' => 'Parent'], 'reverseTitle' => ['fr' => 'Enfant']],
+ ['title' => ['fr' => 'En couple'], 'reverseTitle' => ['fr' => 'En couple']],
+ ['title' => ['fr' => 'Beau parent'], 'reverseTitle' => ['fr' => 'Belle-fille·beau-fils']],
+ ['title' => ['fr' => 'Frère·Sœur'], 'reverseTitle' => ['fr' => 'Frère·Sœur']],
+ ['title' => ['fr' => 'Demi-frère·sœur'], 'reverseTitle' => ['fr' => 'Demi-frère·sœur']],
+ ['title' => ['fr' => 'Grand-parent'], 'reverseTitle' => ['fr' => 'Petit-enfant']],
+ ['title' => ['fr' => 'Oncle·Tante'], 'reverseTitle' => ['fr' => 'Neveu·Nièce']],
];
public static function getGroups(): array
diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
index 7615e59fe..8495afa89 100644
--- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
+++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
@@ -1258,10 +1258,6 @@ class AccompanyingPeriod implements
*/
public function setPinnedComment(?Comment $comment = null): self
{
- if (null !== $this->pinnedComment) {
- $this->removeComment($this->pinnedComment);
- }
-
if (null !== $this->pinnedComment) {
$this->addComment($this->pinnedComment);
}
diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php
index ef522f068..7f2630a1e 100644
--- a/src/Bundle/ChillPersonBundle/Entity/Person.php
+++ b/src/Bundle/ChillPersonBundle/Entity/Person.php
@@ -240,6 +240,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
*/
private array $currentHouseholdAt = [];
+ /**
+ * Cache for the computation of current household participation.
+ */
+ private array $currentHouseholdParticipationAt = [];
+
/**
* The current person address.
*
diff --git a/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php b/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php
index d51881bb2..62fbb63a9 100644
--- a/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php
+++ b/src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php
@@ -15,6 +15,7 @@ use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\Person;
+use Chill\PersonBundle\Validator\Constraints\Relationship\RelationshipNoDuplicate;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
@@ -31,6 +32,7 @@ use Symfony\Component\Validator\Constraints as Assert;
* @DiscriminatorMap(typeProperty="type", mapping={
* "relationship": Relationship::class
* })
+ * @RelationshipNoDuplicate
*/
class Relationship implements TrackCreationInterface, TrackUpdateInterface
{
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue
index f5db187b9..f86c68576 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue
@@ -472,15 +472,25 @@ export default {
case 'create':
return postRelationship(this.modal.data)
- .then(relationship => new Promise(resolve => {
- //console.log('post relationship response', relationship)
- this.$store.dispatch('addLinkFromRelationship', relationship)
- this.modal.showModal = false
- this.resetForm()
- this.forceUpdateComponent()
- resolve()
- }))
- .catch()
+ .then(relationship => new Promise(resolve => {
+ //console.log('post relationship response', relationship)
+ this.$store.dispatch('addLinkFromRelationship', relationship)
+ this.modal.showModal = false
+ this.resetForm()
+ this.forceUpdateComponent()
+ resolve()
+ }))
+ .catch( error => {
+ if (error.name === 'ValidationException') {
+ for (let v of error.violations) {
+ this.$toast.open({message: v });
+ console.log(v)
+ }
+ } else {
+ this.$toast.open({message: 'An error occurred'});
+ }
+ }
+ )
case 'edit':
return patchRelationship(this.modal.data)
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js
index 448ff6633..01c335436 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js
@@ -1,50 +1,5 @@
-import { splitId } from './vis-network'
-
-/**
- * @function makeFetch
- * @param method
- * @param url
- * @param body
- * @returns {Promise}
- */
-const makeFetch = (method, url, body) => {
- return fetch(url, {
- method: method,
- headers: {
- 'Content-Type': 'application/json;charset=utf-8'
- },
- body: (body !== null) ? JSON.stringify(body) : null
- })
- .then(response => {
-
- if (response.ok) {
- return response.json();
- }
-
- if (response.status === 422) {
- return response.json().then(violations => {
- throw ValidationException(violations)
- });
- }
-
- throw {
- msg: 'Error while updating AccompanyingPeriod Course.',
- sta: response.status,
- txt: response.statusText,
- err: new Error(),
- body: response.body
- };
- });
-}
-
-/**
- * @param violations
- * @constructor
- */
-const ValidationException = (violations) => {
- this.violations = violations
- this.name = 'ValidationException'
-}
+import { splitId } from './vis-network';
+import {makeFetch} from 'ChillMainAssets/lib/api/apiMethods.js';
/**
* @function getFetch
@@ -136,7 +91,7 @@ const getRelationsList = () => {
* @returns {Promise}
*/
const postRelationship = (relationship) => {
- //console.log(relationship)
+ //console.log(relationship);
return postFetch(
`/api/1.0/relations/relationship.json`,
{
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js
index 5e8989e49..a64afd4a1 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js
@@ -3,8 +3,10 @@ import { store } from "./store.js"
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
import { visMessages } from './i18n'
import App from './App.vue'
+import VueToast from 'vue-toast-notification';
+import 'vue-toast-notification/dist/theme-sugar.css';
-import './vis-network'
+import './vis-network';
const i18n = _createI18n(visMessages)
const container = document.getElementById('relationship-graph')
@@ -25,5 +27,11 @@ const app = createApp({
})
.use(store)
.use(i18n)
+.use(VueToast, {
+ position: "bottom-right",
+ type: "error",
+ duration: 5000,
+ dismissible: true
+ })
.component('app', App)
.mount('#relationship-graph')
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/Comment/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/Comment/index.html.twig
index d5ece68a9..47238fa9d 100644
--- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/Comment/index.html.twig
+++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/Comment/index.html.twig
@@ -8,6 +8,17 @@
{% macro recordAction(comment, isPinned) %}
{% if isPinned is defined and isPinned == true %}
+
+
+
{% else %}
{% endif %}
- {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_COMMENT_EDIT', comment) %}
+ {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', comment.accompanyingPeriod) %}
{% endif %}
- {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_COMMENT_DELETE', comment) %}
+ {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', comment.accompanyingPeriod) %}
diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodCommentVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodCommentVoter.php
index 37a6ec6ac..6e326b990 100644
--- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodCommentVoter.php
+++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodCommentVoter.php
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Security\Authorization;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
+use Symfony\Component\Security\Core\Security;
use UnexpectedValueException;
class AccompanyingPeriodCommentVoter extends Voter
@@ -22,6 +23,13 @@ class AccompanyingPeriodCommentVoter extends Voter
public const EDIT = 'CHILL_PERSON_ACCOMPANYING_PERIOD_COMMENT_EDIT';
+ private Security $security;
+
+ public function __construct(Security $security)
+ {
+ $this->security = $security;
+ }
+
protected function supports($attribute, $subject)
{
return $subject instanceof Comment;
@@ -32,8 +40,10 @@ class AccompanyingPeriodCommentVoter extends Voter
/** @var Comment $subject */
switch ($attribute) {
case self::EDIT:
+ return $this->security->isGranted(AccompanyingPeriodVoter::EDIT, $subject->getAccompanyingPeriod());
+
case self::DELETE:
- return $subject->getCreator() === $token->getUser();
+ return $this->security->isGranted(AccompanyingPeriodVoter::EDIT, $subject->getAccompanyingPeriod());
default:
throw new UnexpectedValueException("This attribute {$attribute} is not supported");
diff --git a/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemover.php b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemover.php
new file mode 100644
index 000000000..47a34e88c
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemover.php
@@ -0,0 +1,103 @@
+em = $em;
+ $this->logger = $logger;
+ }
+
+ public function remove(DateInterval $interval): void
+ {
+ $this->logger->debug('[' . __CLASS__ . '] start to remove old periods', [
+ 'interval' => $interval->format('%d days'),
+ ]);
+
+ $beforeDate = (new DateTimeImmutable('now'))->sub($interval);
+
+ $results = $this->em->wrapInTransaction(static function (EntityManagerInterface $em) use ($beforeDate) {
+ $subDQL = 'SELECT p FROM ' . AccompanyingPeriod::class . ' p WHERE p.createdAt < :beforeDate AND p.step = :draft';
+ $parameters = [
+ 'beforeDate' => $beforeDate,
+ 'draft' => AccompanyingPeriod::STEP_DRAFT,
+ ];
+
+ $resources = $em->createQuery(
+ 'DELETE ' . AccompanyingPeriod\Resource::class . " r WHERE r.accompanyingPeriod IN ({$subDQL})"
+ )
+ ->setParameters($parameters)
+ ->getSingleScalarResult();
+
+ $participations = $em->createQuery(
+ 'DELETE ' . AccompanyingPeriodParticipation::class . " part WHERE part.accompanyingPeriod IN ({$subDQL})"
+ )
+ ->setParameters($parameters)
+ ->getSingleScalarResult();
+
+ $userHistory = $em->createQuery(
+ 'DELETE ' . AccompanyingPeriod\UserHistory::class . " h WHERE h.accompanyingPeriod IN ({$subDQL})"
+ )
+ ->setParameters($parameters)
+ ->getSingleScalarResult();
+
+ $comments = $em->createQuery(
+ 'DELETE ' . AccompanyingPeriod\Comment::class . " c WHERE c.accompanyingPeriod IN ({$subDQL})"
+ )
+ ->setParameters($parameters)
+ ->getSingleScalarResult();
+
+ $documents = $em->createQuery(
+ 'DELETE ' . AccompanyingCourseDocument::class . " d WHERE d.course IN ({$subDQL})"
+ )
+ ->setParameters($parameters)
+ ->getSingleScalarResult();
+
+ $periods = $em
+ ->createQuery(
+ 'DELETE ' . AccompanyingPeriod::class . ' p WHERE p.createdAt < :beforeDate
+ AND p.step = :draft'
+ )
+ ->setParameter(':beforeDate', $beforeDate, Types::DATETIME_IMMUTABLE)
+ ->setParameter(':draft', AccompanyingPeriod::STEP_DRAFT)
+ ->getSingleScalarResult();
+
+ return [
+ 'comments' => $comments,
+ 'documents' => $documents,
+ 'participations' => $participations,
+ 'periods' => $periods,
+ 'resources' => $resources,
+ 'userHistory' => $userHistory,
+ ];
+ });
+
+ $this->logger->info('[' . __CLASS__ . '] periods removed', array_merge($results, [
+ 'interval' => $interval->format('%d days'),
+ ]));
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemoverInterface.php b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemoverInterface.php
new file mode 100644
index 000000000..882fefe3b
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriod/OldDraftAccompanyingPeriodRemoverInterface.php
@@ -0,0 +1,19 @@
+relationshipRepository = $relationshipRepository;
+ }
+
+ public function validate($relationship, Constraint $constraint)
+ {
+ if (!$constraint instanceof RelationshipNoDuplicate) {
+ throw new UnexpectedTypeException($constraint, RelationshipNoDuplicate::class);
+ }
+
+ $fromPerson = $relationship->getFromPerson();
+ $toPerson = $relationship->getToPerson();
+
+ $relationships = $this->relationshipRepository->findBy([
+ 'fromPerson' => [$fromPerson, $toPerson],
+ 'toPerson' => [$fromPerson, $toPerson],
+ ]);
+
+ foreach ($relationships as $r) {
+ if (
+ $r->getFromPerson() === $fromPerson
+ || $r->getFromPerson() === $toPerson
+ || $r->getToPerson() === $fromPerson
+ || $r->getToPerson() === $toPerson
+ ) {
+ $this->context->buildViolation($constraint->message)
+ ->addViolation();
+ }
+ }
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20220425000000.php b/src/Bundle/ChillPersonBundle/migrations/Version20220425000000.php
new file mode 100644
index 000000000..1dd50d224
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/migrations/Version20220425000000.php
@@ -0,0 +1,36 @@
+addSql('DROP INDEX IDX_RELATIONSHIPS000');
+ }
+
+ public function getDescription(): string
+ {
+ return 'Add constraint with a index on chill_person_relationships.';
+ }
+
+ public function up(Schema $schema): void
+ {
+ $this->addSql('CREATE UNIQUE INDEX IDX_RELATIONSHIPS000 ON chill_person_relationships (least(fromperson_id, toperson_id), greatest(fromperson_id, toperson_id))');
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20220429133023.php b/src/Bundle/ChillPersonBundle/migrations/Version20220429133023.php
new file mode 100644
index 000000000..70ef42202
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/migrations/Version20220429133023.php
@@ -0,0 +1,39 @@
+addSql('ALTER TABLE "accompanying_periods_scopes"
+ DROP CONSTRAINT "fk_87c4eab032a7a428",
+ ADD CONSTRAINT "fk_87c4eab032a7a428" FOREIGN KEY (accompanying_period_id) REFERENCES chill_person_accompanying_period(id)
+ ');
+ }
+
+ public function getDescription(): string
+ {
+ return 'apply CASCADE DELETE on entity related to accompanying periods';
+ }
+
+ public function up(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE "accompanying_periods_scopes"
+ DROP CONSTRAINT "fk_87c4eab032a7a428",
+ ADD CONSTRAINT "fk_87c4eab032a7a428" FOREIGN KEY (accompanying_period_id) REFERENCES chill_person_accompanying_period(id) ON DELETE CASCADE
+ ');
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
index 77ff2bdb2..70441965c 100644
--- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
@@ -465,6 +465,7 @@ fix it: Compléter
accompanying_course:
administrative_location: Localisation administrative
comment is pinned: Le commentaire est épinglé
+ comment is unpinned: Le commentaire est désépinglé
show: Montrer
hide: Masquer
closed periods: parcours clôturer
@@ -474,6 +475,7 @@ Accompanying Course Comment: Commentaire
Accompanying Course Comment list: Commentaires du parcours
pinned: épinglé
Pin comment: Épingler
+Unpin comment: Désépingler
Post a new comment: Poster un nouveau commentaire
Write a new comment: Écrire un nouveau commentaire
Edit a comment: Modifier le commentaire
diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
index 13fcb54fb..b2bc549d7 100644
--- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
@@ -62,3 +62,7 @@ You cannot associate a resource with the same person: Vous ne pouvez pas ajouter
#location
The period must remain located: 'Un parcours doit être localisé'
The person where the course is located must be associated to the course. Change course's location before removing the person.: "Le parcours est localisé auprès cet usager. Veuillez changer la localisation du parcours avant de suprimer l'usager"
+
+#relationship
+relationship:
+ duplicate: Une relation de filiation existe déjà entre ces 2 personnes
\ No newline at end of file
diff --git a/src/Bundle/ChillReportBundle/Controller/ReportController.php b/src/Bundle/ChillReportBundle/Controller/ReportController.php
index bca915090..33ddd3a39 100644
--- a/src/Bundle/ChillReportBundle/Controller/ReportController.php
+++ b/src/Bundle/ChillReportBundle/Controller/ReportController.php
@@ -334,7 +334,7 @@ class ReportController extends AbstractController
$cFGroupId = $request->query->get('cFGroup');
- if ($cFGroupId) {
+ if ($request->query->has('cFGroup')) {
return $this->redirect(
$this->generateUrl(
'report_new',
@@ -391,7 +391,7 @@ class ReportController extends AbstractController
{
$cFGroupId = $request->query->get('cFGroup');
- if ($cFGroupId) {
+ if ($request->query->has('cFGroup')) {
return $this->redirect(
$this->generateUrl(
'report_export_list',
diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php
index b4b6727b2..355015215 100644
--- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php
+++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php
@@ -33,7 +33,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormFactoryInterface;
-use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -494,7 +493,7 @@ final class SingleTaskController extends AbstractController
);
default:
- throw new BadRequestException("format not supported: {$_format}");
+ throw new BadRequestHttpException("format not supported: {$_format}");
}
}