diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php
index 2eb6d1215..234e1203d 100644
--- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php
+++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php
@@ -47,11 +47,11 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
{
/**
* widget factory
- *
+ *
* @var WidgetFactoryInterface[]
*/
protected $widgetFactories = array();
-
+
/**
* @param WidgetFactoryInterface $factory
*/
@@ -59,7 +59,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
{
$this->widgetFactories[] = $factory;
}
-
+
/**
* @return WidgetFactoryInterface[]
*/
@@ -67,7 +67,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
{
return $this->widgetFactories;
}
-
+
/**
* {@inheritDoc}
* @param array $configs
@@ -79,31 +79,31 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
// configuration for main bundle
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
-
+
$container->setParameter('chill_main.installation_name',
$config['installation_name']);
$container->setParameter('chill_main.available_languages',
$config['available_languages']);
-
- $container->setParameter('chill_main.routing.resources',
- $config['routing']['resources']);
-
+
+ $container->setParameter('chill_main.routing.resources',
+ $config['routing']['resources']);
+
$container->setParameter('chill_main.pagination.item_per_page',
$config['pagination']['item_per_page']);
-
- $container->setParameter('chill_main.notifications',
+
+ $container->setParameter('chill_main.notifications',
$config['notifications']);
-
- $container->setParameter('chill_main.redis',
+
+ $container->setParameter('chill_main.redis',
$config['redis']);
-
- $container->setParameter('chill_main.phone_helper',
+
+ $container->setParameter('chill_main.phone_helper',
$config['phone_helper'] ?? []);
-
+
// add the key 'widget' without the key 'enable'
- $container->setParameter('chill_main.widgets',
- isset($config['widgets']['homepage']) ?
+ $container->setParameter('chill_main.widgets',
+ isset($config['widgets']['homepage']) ?
array('homepage' => $config['widgets']['homepage']):
array()
);
@@ -131,10 +131,11 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
$loader->load('services/templating.yaml');
$loader->load('services/timeline.yaml');
$loader->load('services/search.yaml');
-
+ $loader->load('services/serializer.yaml');
+
$this->configureCruds($container, $config['cruds'], $loader);
}
-
+
/**
* @param array $config
* @param ContainerBuilder $container
@@ -144,11 +145,11 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
{
return new Configuration($this->widgetFactories, $container);
}
-
+
/**
* @param ContainerBuilder $container
*/
- public function prepend(ContainerBuilder $container)
+ public function prepend(ContainerBuilder $container)
{
//add installation_name and date_format to globals
$chillMainConfig = $container->getExtensionConfig($this->getAlias());
@@ -163,7 +164,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
'form_themes' => array('@ChillMain/Form/fields.html.twig')
);
$container->prependExtensionConfig('twig', $twigConfig);
-
+
//add DQL function to ORM (default entity_manager)
$container->prependExtensionConfig('doctrine', array(
'orm' => array(
@@ -182,7 +183,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
)
)
));
-
+
//add dbal types (default entity_manager)
$container->prependExtensionConfig('doctrine', array(
'dbal' => [
@@ -191,23 +192,23 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
]
]
));
-
+
//add current route to chill main
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
'resources' => array(
'@ChillMainBundle/config/routes.yaml'
)
-
+
)
));
-
+
//add a channel to log app events
$container->prependExtensionConfig('monolog', array(
'channels' => array('chill')
));
}
-
+
/**
* @param ContainerBuilder $container
* @param array $config the config under 'cruds' key
@@ -218,31 +219,31 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
if (count($config) === 0) {
return;
}
-
+
$loader->load('services/crud.yaml');
-
+
$container->setParameter('chill_main_crud_route_loader_config', $config);
-
+
$definition = new Definition();
$definition
->setClass(\Chill\MainBundle\CRUD\Routing\CRUDRoutesLoader::class)
->addArgument('%chill_main_crud_route_loader_config%')
;
-
+
$container->setDefinition('chill_main_crud_route_loader', $definition);
-
+
$alreadyExistingNames = [];
-
+
foreach ($config as $crudEntry) {
$controller = $crudEntry['controller'];
$controllerServiceName = 'cscrud_'.$crudEntry['name'].'_controller';
$name = $crudEntry['name'];
-
+
// check for existing crud names
if (\in_array($name, $alreadyExistingNames)) {
throw new LogicException(sprintf("the name %s is defined twice in CRUD", $name));
}
-
+
if (!$container->has($controllerServiceName)) {
$controllerDefinition = new Definition($controller);
$controllerDefinition->addTag('controller.service_arguments');
@@ -250,7 +251,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
$controllerDefinition->setClass($crudEntry['controller']);
$container->setDefinition($controllerServiceName, $controllerDefinition);
}
-
+
$container->setParameter('chill_main_crud_config_'.$name, $crudEntry);
$container->getDefinition($controllerServiceName)
->addMethodCall('setCrudConfig', ['%chill_main_crud_config_'.$name.'%']);
diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/CenterNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/CenterNormalizer.php
new file mode 100644
index 000000000..26182d936
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/CenterNormalizer.php
@@ -0,0 +1,44 @@
+
+ *
+ * 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 .
+ */
+
+namespace Chill\MainBundle\Serializer\Normalizer;
+
+use Chill\MainBundle\Entity\Center;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ *
+ *
+ */
+class CenterNormalizer implements NormalizerInterface
+{
+ public function normalize($center, string $format = null, array $context = array())
+ {
+ /** @var Center $center */
+ return [
+ 'id' => $center->getId(),
+ 'name' => $center->getName()
+ ];
+ }
+
+ public function supportsNormalization($data, string $format = null): bool
+ {
+ return $data instanceof Center;
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php
new file mode 100644
index 000000000..fd902b184
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php
@@ -0,0 +1,39 @@
+
+ *
+ * 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 .
+ */
+
+namespace Chill\MainBundle\Serializer\Normalizer;
+
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+class DateNormalizer implements NormalizerInterface
+{
+ public function normalize($date, string $format = null, array $context = array())
+ {
+ /** @var \DateTimeInterface $date */
+ return [
+ 'datetime' => $date->format(\DateTimeInterface::ISO8601),
+ 'u' => $date->getTimestamp()
+ ];
+ }
+
+ public function supportsNormalization($data, string $format = null): bool
+ {
+ return $data instanceof \DateTimeInterface;
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php
new file mode 100644
index 000000000..2a71de52b
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php
@@ -0,0 +1,44 @@
+
+ *
+ * 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 .
+ */
+
+namespace Chill\MainBundle\Serializer\Normalizer;
+
+use Chill\MainBundle\Entity\User;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ *
+ *
+ */
+class UserNormalizer implements NormalizerInterface
+{
+ public function normalize($user, string $format = null, array $context = array())
+ {
+ /** @var User $user */
+ return [
+ 'id' => $user->getId(),
+ 'username' => $user->getUsername()
+ ];
+ }
+
+ public function supportsNormalization($data, string $format = null): bool
+ {
+ return $data instanceof User;
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/config/services/serializer.yaml b/src/Bundle/ChillMainBundle/config/services/serializer.yaml
new file mode 100644
index 000000000..763576a5c
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/config/services/serializer.yaml
@@ -0,0 +1,13 @@
+---
+services:
+ Chill\MainBundle\Serializer\Normalizer\CenterNormalizer:
+ tags:
+ - { name: 'serializer.normalizer', priority: 64 }
+
+ Chill\MainBundle\Serializer\Normalizer\DateNormalizer:
+ tags:
+ - { name: 'serializer.normalizer', priority: 64 }
+
+ Chill\MainBundle\Serializer\Normalizer\UserNormalizer:
+ tags:
+ - { name: 'serializer.normalizer', priority: 64 }
diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php
index e92c84765..9bc732d87 100644
--- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php
@@ -4,17 +4,21 @@ namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
+use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
use Chill\PersonBundle\Entity\Person;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
+use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Class AccompanyingCourseController
@@ -23,6 +27,21 @@ use Symfony\Component\Serializer\SerializerInterface;
*/
class AccompanyingCourseController extends Controller
{
+ protected SerializerInterface $serializer;
+
+ protected EventDispatcherInterface $dispatcher;
+
+ protected ValidatorInterface $validator;
+
+ public function __construct(
+ SerializerInterface $serializer,
+ EventDispatcherInterface $dispatcher,
+ ValidatorInterface $validator
+ ) {
+ $this->serializer = $serializer;
+ $this->dispatcher = $dispatcher;
+ $this->validator = $validator;
+ }
/**
* Homepage of Accompanying Course section
*
@@ -68,45 +87,75 @@ class AccompanyingCourseController extends Controller
}
/**
- * Sérialise temporairement quelques données pour donner à manger au composant vuejs
+ * Get API Data for showing endpoint
+ *
* @Route(
- * "/{_locale}/api/parcours/{accompanying_period_id}/show",
- * name="chill_person_accompanying_course_api_show")
+ * "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/show.{_format}",
+ * name="chill_person_accompanying_course_api_show"
+ * )
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
- * @param SerializerInterface $serializer
*/
- public function showAPI(AccompanyingPeriod $accompanyingCourse): Response
+ public function showAPI(AccompanyingPeriod $accompanyingCourse, $_format): Response
{
- $persons = [];
- foreach ($accompanyingCourse->getParticipations() as $k => $participation ) {
- /**
- * @var AccompanyingPeriodParticipation $participation
- * @var Person $person
- */
- $person = $participation->getPerson();
- $persons[$k] = [
- 'id' => $person->getId(),
- 'firstname' => $person->getFirstName(),
- 'lastname' => $person->getLastName(),
- 'email' => $person->getEmail(),
- 'phone' => $person->getPhonenumber(),
- 'startdate' => ($participation->getStartDate()) ? $participation->getStartDate()->format('Y-m-d') : null,
- 'enddate' => ($participation->getEndDate()) ? $participation->getEndDate()->format('Y-m-d') : null
- ];
- }
- $data = [
- 'id' => $accompanyingCourse->getId(),
- 'remark' => $accompanyingCourse->getRemark(),
- 'closing_motive' => $accompanyingCourse->getClosingMotive() ? $accompanyingCourse->getClosingMotive()->getName()['fr'] : null,
- 'opening_date' => ($accompanyingCourse->getOpeningDate()) ? $accompanyingCourse->getOpeningDate()->format('Y-m-d') : null,
- 'closing_date' => ($accompanyingCourse->getClosingDate()) ? $accompanyingCourse->getClosingDate()->format('Y-m-d') : null,
- 'persons' => $persons
- ];
+ // TODO check ACL on AccompanyingPeriod
+
+ $this->dispatcher->dispatch(
+ AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
+ new AccompanyingPeriodPrivacyEvent($accompanyingCourse, [
+ 'action' => 'showApi'
+ ])
+ );
+
+ switch ($_format) {
+ case 'json':
+ return $this->json($accompanyingCourse);
+ default:
+ throw new BadRequestException('Unsupported format');
+ }
- $serialized = \json_encode($data);
- $response = new Response($serialized);
- $response->headers->set('Content-Type', 'application/json');
- return $response;
}
+ /**
+ * Get API Data for showing endpoint
+ *
+ * @Route(
+ * "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/participation.{_format}",
+ * name="chill_person_accompanying_course_api_add_participation",
+ * methods={"POST"},
+ * format="json",
+ * requirements={
+ * "_format": "json",
+ * }
+ * )
+ * @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
+ */
+ public function addParticipationAPI(Request $request, AccompanyingPeriod $accompanyingCourse, $_format): Response
+ {
+ switch ($_format) {
+ case 'json':
+ $person = $this->serializer->deserialize($request->getContent(), Person::class, $_format, [
+
+ ]);
+ break;
+ default:
+ throw new BadRequestException('Unsupported format');
+ }
+
+ if (NULL === $person) {
+ throw new BadRequestException('person id not found');
+ }
+
+ // TODO add acl
+ $accompanyingCourse->addPerson($person);
+ $errors = $this->validator->validate($accompanyingCourse);
+
+ if ($errors->count() > 0) {
+ // only format accepted
+ return $this->json($errors);
+ }
+
+ $this->getDoctrine()->getManager()->flush();
+
+ return new JsonResponse();
+ }
}
diff --git a/src/Bundle/ChillPersonBundle/Controller/ApiPersonController.php b/src/Bundle/ChillPersonBundle/Controller/ApiPersonController.php
new file mode 100644
index 000000000..bfaf22d7b
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Controller/ApiPersonController.php
@@ -0,0 +1,30 @@
+
+ *
+ * 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 .
+ */
+namespace Chill\PersonBundle\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+
+class ApiPersonController extends Controller
+{
+ public function viewAction($id, $_format)
+ {
+
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php
index f8e8173de..9eaa5d17f 100644
--- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php
+++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php
@@ -38,7 +38,7 @@ use Chill\PersonBundle\Doctrine\DQL\AddressPart;
*/
class ChillPersonExtension extends Extension implements PrependExtensionInterface
{
-
+
/**
* {@inheritDoc}
* @param array $configs
@@ -49,14 +49,14 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
-
+
// set configuration for validation
$container->setParameter('chill_person.validation.birtdate_not_before',
$config['validation']['birthdate_not_after']);
-
+
$this->handlePersonFieldsParameters($container, $config['person_fields']);
$this->handleAccompanyingPeriodsFieldsParameters($container, $config['accompanying_periods_fields']);
-
+
$container->setParameter('chill_person.allow_multiple_simultaneous_accompanying_periods',
$config['allow_multiple_simultaneous_accompanying_periods']);
@@ -75,19 +75,20 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$loader->load('services/repository.yaml');
$loader->load('services/templating.yaml');
$loader->load('services/alt_names.yaml');
-
+ $loader->load('services/serializer.yaml');
+
// load service advanced search only if configure
if ($config['search']['search_by_phone'] != 'never') {
$loader->load('services/search_by_phone.yaml');
$container->setParameter('chill_person.search.search_by_phone',
$config['search']['search_by_phone']);
}
-
+
if ($container->getParameter('chill_person.accompanying_period') !== 'hidden') {
$loader->load('services/exports_accompanying_period.yaml');
}
}
-
+
/**
* @param ContainerBuilder $container
* @param $config
@@ -97,9 +98,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
if (array_key_exists('enabled', $config)) {
unset($config['enabled']);
}
-
+
$container->setParameter('chill_person.person_fields', $config);
-
+
foreach ($config as $key => $value) {
switch($key) {
case 'accompanying_period':
@@ -111,7 +112,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
}
}
}
-
+
/**
* @param ContainerBuilder $container
* @param $config
@@ -119,7 +120,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
private function handleAccompanyingPeriodsFieldsParameters(ContainerBuilder $container, $config)
{
$container->setParameter('chill_person.accompanying_period_fields', $config);
-
+
foreach ($config as $key => $value) {
switch($key) {
case 'enabled':
@@ -130,7 +131,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
}
}
}
-
+
/**
* @param ContainerBuilder $container
* @throws MissingBundleException
@@ -150,7 +151,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
)
);
}
-
+
/**
* @param ContainerBuilder $container
* @throws MissingBundleException
@@ -161,7 +162,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$this->prependHomepageWidget($container);
$this->prependDoctrineDQL($container);
$this->prependCruds($container);
-
+
//add person_fields parameter as global
$chillPersonConfig = $container->getExtensionConfig($this->getAlias());
$config = $this->processConfiguration(new Configuration(), $chillPersonConfig);
@@ -179,7 +180,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$container->prependExtensionConfig('twig', $twigConfig);
$this-> declarePersonAsCustomizable($container);
-
+
//declare routes for person bundle
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
@@ -189,7 +190,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
)
));
}
-
+
/**
* Add a widget "add a person" on the homepage, automatically
*
@@ -208,7 +209,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
)
));
}
-
+
/**
* Add role hierarchy.
*
@@ -225,7 +226,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
)
));
}
-
+
/**
* Add DQL function linked with person
*
@@ -234,7 +235,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
protected function prependDoctrineDQL(ContainerBuilder $container)
{
//add DQL function to ORM (default entity_manager)
-
+
$container->prependExtensionConfig('doctrine', array(
'orm' => array(
'dql' => array(
@@ -257,7 +258,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
)
));
}
-
+
/**
* @param ContainerBuilder $container
*/
diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
index f66df6a2d..18ee535b8 100644
--- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
+++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
@@ -103,7 +103,7 @@ class AccompanyingPeriod
* @ORM\Column(type="text")
*/
private $remark = '';
-
+
/**
* @var Collection
*
@@ -112,7 +112,7 @@ class AccompanyingPeriod
* )
*/
private $comments;
-
+
/**
* @var Collection
*
@@ -121,7 +121,7 @@ class AccompanyingPeriod
* cascade={"persist", "remove", "merge", "detach"})
*/
private $participations;
-
+
/**
* @var AccompanyingPeriod\ClosingMotive
*
@@ -130,19 +130,19 @@ class AccompanyingPeriod
* @ORM\JoinColumn(nullable=true)
*/
private $closingMotive = null;
-
+
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=true)
*/
private $user;
-
+
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=true)
*/
private $createdBy;
-
+
/**
* @var string
* @ORM\Column(type="string", length=32, nullable=true)
@@ -154,7 +154,7 @@ class AccompanyingPeriod
* @ORM\JoinColumn(nullable=true)
*/
private $origin;
-
+
/**
* @var string
* @ORM\Column(type="string", nullable=true)
@@ -214,7 +214,7 @@ class AccompanyingPeriod
* )
*/
private $resources;
-
+
/**
* AccompanyingPeriod constructor.
*
@@ -246,7 +246,7 @@ class AccompanyingPeriod
public function setOpeningDate($openingDate)
{
$this->openingDate = $openingDate;
-
+
return $this;
}
@@ -272,7 +272,7 @@ class AccompanyingPeriod
public function setClosingDate($closingDate)
{
$this->closingDate = $closingDate;
-
+
return $this;
}
@@ -285,7 +285,7 @@ class AccompanyingPeriod
{
return $this->closingDate;
}
-
+
/**
* @return boolean
*/
@@ -298,43 +298,43 @@ class AccompanyingPeriod
if ($this->getClosingDate() === null) {
return true;
}
-
+
return false;
}
-
+
public function setRemark(string $remark): self
{
if ($remark === null) {
$remark = '';
}
-
+
$this->remark = $remark;
-
+
return $this;
}
-
+
public function getRemark(): string
{
return $this->remark;
}
-
+
public function getComments(): Collection
{
return $this->comments;
}
-
+
public function addComment(Comment $comment): self
{
$this->comments[] = $comment;
-
+
return $this;
}
-
+
public function removeComment(Comment $comment): void
{
$this->comments->removeElement($comment);
}
-
+
/**
* Get Participations Collection
*/
@@ -342,7 +342,7 @@ class AccompanyingPeriod
{
return $this->participations;
}
-
+
/**
* This private function scan Participations Collection,
* searching for a given Person
@@ -357,7 +357,7 @@ class AccompanyingPeriod
return null;
}
-
+
/**
* This public function is the same but return only true or false
*/
@@ -365,7 +365,7 @@ class AccompanyingPeriod
{
return ($this->participationsContainsPerson($person) === null) ? false : true;
}
-
+
/**
* Add Person
*/
@@ -373,36 +373,36 @@ class AccompanyingPeriod
{
$participation = new AccompanyingPeriodParticipation($this, $person);
$this->participations[] = $participation;
-
+
return $this;
}
-
+
/**
* Remove Person
*/
public function removePerson(Person $person): void
{
$participation = $this->participationsContainsPerson($person);
-
+
if (! null === $participation) {
$participation->setEndDate(new \DateTimeImmutable('now'));
$this->participations->removeElement($participation);
}
}
-
-
+
+
public function getClosingMotive(): ?ClosingMotive
{
return $this->closingMotive;
}
-
+
public function setClosingMotive(ClosingMotive $closingMotive = null): self
{
$this->closingMotive = $closingMotive;
-
+
return $this;
}
-
+
/**
* If the period can be reopened.
*
@@ -414,7 +414,7 @@ class AccompanyingPeriod
if ($this->isOpen() === true) {
return false;
}
-
+
$participation = $this->participationsContainsPerson($person);
if (!null === $participation)
{
@@ -422,10 +422,10 @@ class AccompanyingPeriod
$periods = $person->getAccompanyingPeriodsOrdered();
return end($periods) === $this;
}
-
+
return false;
}
-
+
/**
*/
public function reOpen(): void
@@ -442,14 +442,14 @@ class AccompanyingPeriod
if ($this->isOpen()) {
return;
}
-
+
if (! $this->isClosingAfterOpening()) {
$context->buildViolation('The date of closing is before the date of opening')
->atPath('dateClosing')
->addViolation();
}
}
-
+
/**
* Returns true if the closing date is after the opening date.
*
@@ -467,16 +467,16 @@ class AccompanyingPeriod
}
return false;
}
-
+
function getUser(): ?User
{
return $this->user;
}
-
+
function setUser(User $user): self
{
$this->user = $user;
-
+
return $this;
}
@@ -484,38 +484,38 @@ class AccompanyingPeriod
{
return $this->origin;
}
-
+
public function setOrigin(Origin $origin): self
{
$this->origin = $origin;
-
+
return $this;
}
-
+
public function getRequestorPerson(): ?Person
{
return $this->requestorPerson;
}
-
+
public function setRequestorPerson(Person $requestorPerson): self
{
$this->requestorPerson = ($this->requestorThirdParty === null) ? $requestorPerson : null;
-
+
return $this;
}
-
+
public function getRequestorThirdParty(): ?ThirdParty
{
return $this->requestorThirdParty;
}
-
+
public function setRequestorThirdParty(ThirdParty $requestorThirdParty): self
{
$this->requestorThirdParty = ($this->requestorPerson === null) ? $requestorThirdParty : null;
-
+
return $this;
}
-
+
/**
* @return Person|ThirdParty
*/
@@ -523,48 +523,48 @@ class AccompanyingPeriod
{
return $this->requestorPerson ?? $this->requestorThirdParty;
}
-
+
public function isRequestorAnonymous(): bool
{
return $this->requestorAnonymous;
}
-
+
public function setRequestorAnonymous(bool $requestorAnonymous): self
{
$this->requestorAnonymous = $requestorAnonymous;
-
+
return $this;
}
-
+
public function isEmergency(): bool
{
return $this->emergency;
}
-
+
public function setEmergency(bool $emergency): self
{
$this->emergency = $emergency;
-
+
return $this;
}
-
+
public function isConfidential(): bool
{
return $this->confidential;
}
-
+
public function setConfidential(bool $confidential): self
{
$this->confidential = $confidential;
-
+
return $this;
}
-
+
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
-
+
public function setCreatedBy(User $createdBy): self
{
$this->createdBy = $createdBy;
@@ -576,11 +576,11 @@ class AccompanyingPeriod
{
return $this->step;
}
-
+
public function setStep(string $step): self
{
$this->step = $step;
-
+
return $this;
}
@@ -588,45 +588,57 @@ class AccompanyingPeriod
{
return $this->intensity;
}
-
+
public function setIntensity(string $intensity): self
{
$this->intensity = $intensity;
-
+
return $this;
}
-
+
public function getScopes(): Collection
{
return $this->scopes;
}
-
+
public function addScope(Scope $scope): self
{
$this->scopes[] = $scope;
-
+
return $this;
}
-
+
public function removeScope(Scope $scope): void
{
$this->scopes->removeElement($scope);
}
-
+
public function getResources(): Collection
{
return $this->resources;
}
-
+
public function addResource(Resource $resource): self
{
$this->resources[] = $resource;
-
+
return $this;
}
-
+
public function removeResource(Resource $resource): void
{
$this->resources->removeElement($resource);
}
+
+ /**
+ * Get a list of all persons which are participating to this course
+ */
+ public function getPersons(): Collection
+ {
+ return $this->participations->map(
+ function(AccompanyingPeriodParticipation $participation) {
+ return $participation->getPerson();
+ }
+ );
+ }
}
diff --git a/src/Bundle/ChillPersonBundle/Privacy/AccompanyingPeriodPrivacyEvent.php b/src/Bundle/ChillPersonBundle/Privacy/AccompanyingPeriodPrivacyEvent.php
new file mode 100644
index 000000000..e8610b4c1
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Privacy/AccompanyingPeriodPrivacyEvent.php
@@ -0,0 +1,52 @@
+,
+ *
+ * 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 .
+ */
+
+use Symfony\Component\EventDispatcher\Event;
+use Chill\PersonBundle\Entity\Person;
+use Chill\PersonBundle\Entity\AccompanyingPeriod;
+
+class AccompanyingPeriodPrivacyEvent extends Event
+{
+ public const ACCOMPANYING_PERIOD_PRIVACY_EVENT = 'chill_person.accompanying_period_privacy_event';
+
+ protected AccompanyingPeriod $period;
+
+ protected array $args;
+
+ public function __construct($period, $args = [])
+ {
+ $this->period = $period;
+ $this->args = $args;
+ }
+
+ public function getPeriod(): AccompanyingPeriod
+ {
+ return $this->period;
+ }
+
+ public function getArgs(): array
+ {
+ return $this->args;
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php b/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php
index b6cc50e54..c37fc67b2 100644
--- a/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php
+++ b/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php
@@ -26,20 +26,21 @@ use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Chill\PersonBundle\Entity\Person;
+use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
class PrivacyEventSubscriber implements EventSubscriberInterface
{
-
+
/**
* @var LoggerInterface
*/
protected $logger;
-
+
/**
* @var TokenStorageInterface
*/
protected $token;
-
+
/**
* PrivacyEventSubscriber constructor.
*
@@ -50,40 +51,64 @@ class PrivacyEventSubscriber implements EventSubscriberInterface
$this->logger = $logger;
$this->token = $token;
}
-
+
public static function getSubscribedEvents()
{
- return array(PrivacyEvent::PERSON_PRIVACY_EVENT => array(
- array('onPrivacyEvent')
- ));
+ return [
+ PrivacyEvent::PERSON_PRIVACY_EVENT => [
+ ['onPrivacyEvent']
+ ],
+ AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT => [
+ ['onAccompanyingPeriodPrivacyEvent']
+ ]
+ ];
}
-
+
+ public function onAccompanyingPeriodPrivacyEvent(AccompanyingPeriodPrivacyEvent $event)
+ {
+ $involved = $this->getInvolved();
+ $involved['period_id'] = $event->getPeriod()->getId();
+ $involved['persons'] = $event->getPeriod()->getPersons()
+ ->map(function(Person $p) { return $p->getId(); })
+ ->toArray();
+
+ $this->logger->notice(
+ "[Privacy Event] An accompanying period has been viewed",
+ array_merge($involved, $event->getArgs())
+ );
+ }
+
public function onPrivacyEvent(PrivacyEvent $event)
{
- $persons = array();
-
+ $persons = [];
+
if ($event->hasPersons() === true) {
foreach ($event->getPersons() as $person) {
$persons[] = $person->getId();
}
}
- $involved = array(
- 'by_user' => $this->token->getToken()->getUser()->getUsername(),
- 'by_user_id' => $this->token->getToken()->getUser()->getId(),
- 'person_id' => $event->getPerson()->getId(),
- );
-
+ $involved = $this->getInvolved();
+ $involved['person_id'] = $event->getPerson()->getId();
+
if ($event->hasPersons()) {
$involved['persons'] = \array_map(
- function(Person $p) { return $p->getId(); },
+ function(Person $p) { return $p->getId(); },
$event->getPersons()
);
}
-
+
$this->logger->notice(
"[Privacy Event] A Person Folder has been viewed",
array_merge($involved, $event->getArgs())
);
}
-}
\ No newline at end of file
+
+ protected function getInvolved(): array
+ {
+ return [
+ 'by_user' => $this->token->getToken()->getUser()->getUsername(),
+ 'by_user_id' => $this->token->getToken()->getUser()->getId(),
+ ];
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodNormalizer.php
new file mode 100644
index 000000000..55a59700d
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodNormalizer.php
@@ -0,0 +1,59 @@
+
+ *
+ * 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 .
+ */
+namespace Chill\PersonBundle\Serializer\Normalizer;
+
+use Chill\PersonBundle\Entity\AccompanyingPeriod;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
+use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+
+
+class AccompanyingPeriodNormalizer implements NormalizerInterface, NormalizerAwareInterface {
+
+ protected ?NormalizerInterface $normalizer = null;
+
+ public function normalize($period, string $format = null, array $context = array())
+ {
+ /** @var AccompanyingPeriod $period */
+ return [
+ 'id' => $period->getId(),
+ 'openingDate' => $this->normalizer->normalize($period->getOpeningDate(), $format),
+ 'closingDate' => $this->normalizer->normalize($period->getClosingDate(), $format),
+ 'remark' => $period->getRemark(),
+ 'participations' => $this->normalizer->normalize($period->getParticipations(), $format),
+ 'closingMotive' => $this->normalizer->normalize($period->getClosingMotive(), $format),
+ 'user' => $period->getUser() ? $this->normalize($period->getUser(), $format) : null,
+ 'step' => $period->getStep(),
+ 'origin' => $this->normalizer->normalize($period->getOrigin(), $format),
+ 'intensity' => $period->getIntensity(),
+ 'emergency' => $period->isEmergency(),
+ 'confidential' => $period->isConfidential()
+ ];
+ }
+
+ public function supportsNormalization($data, string $format = null): bool
+ {
+ return $data instanceof AccompanyingPeriod;
+ }
+
+ public function setNormalizer(NormalizerInterface $normalizer)
+ {
+ $this->normalizer = $normalizer;
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodParticipationNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodParticipationNormalizer.php
new file mode 100644
index 000000000..59e430827
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodParticipationNormalizer.php
@@ -0,0 +1,51 @@
+
+ *
+ * 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 .
+ */
+namespace Chill\PersonBundle\Serializer\Normalizer;
+
+use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
+use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+
+
+class AccompanyingPeriodParticipationNormalizer implements NormalizerInterface, NormalizerAwareInterface {
+
+ protected ?NormalizerInterface $normalizer = null;
+
+ public function normalize($participation, string $format = null, array $context = array())
+ {
+ /** @var AccompanyingPeriodParticipation $participation */
+ return [
+ 'id' => $participation->getId(),
+ 'startDate' => $this->normalizer->normalize($participation->getStartDate(), $format),
+ 'endDate' => $this->normalizer->normalize($participation->getEndDate(), $format),
+ 'person' => $this->normalizer->normalize($participation->getPerson(), $format)
+ ];
+ }
+
+ public function supportsNormalization($data, string $format = null): bool
+ {
+ return $data instanceof AccompanyingPeriodParticipation;
+ }
+
+ public function setNormalizer(NormalizerInterface $normalizer)
+ {
+ $this->normalizer = $normalizer;
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonNormalizer.php
new file mode 100644
index 000000000..90a816ebc
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonNormalizer.php
@@ -0,0 +1,95 @@
+
+ *
+ * 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 .
+ */
+namespace Chill\PersonBundle\Serializer\Normalizer;
+
+use Chill\PersonBundle\Entity\Person;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
+use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
+use Chill\PersonBundle\Repository\PersonRepository;
+use Symfony\Component\Serializer\Exception\RuntimeException;
+use Symfony\Component\Serializer\Exception\UnexpectedValueException;
+
+
+/**
+ * Serialize a Person entity
+ *
+ */
+class PersonNormalizer implements
+ NormalizerInterface,
+ NormalizerAwareInterface,
+ DenormalizerInterface
+{
+
+ protected NormalizerInterface $normalizer;
+
+ protected PersonRepository $repository;
+
+ public const GET_PERSON = 'get_person';
+
+ public function __construct(PersonRepository $repository)
+ {
+ $this->repository = $repository;
+ }
+
+ public function normalize($person, string $format = null, array $context = array())
+ {
+ /** @var Person $person */
+ return [
+ 'id' => $person->getId(),
+ 'firstName' => $person->getFirstName(),
+ 'lastName' => $person->getLastName(),
+ 'birthdate' => $person->getBirthdate(),
+ 'center' => $this->normalizer->normalize($person->getCenter())
+ ];
+ }
+
+ public function denormalize($data, string $type, string $format = null, array $context = []): Person
+ {
+ if ($context[self::GET_PERSON] ?? true) {
+ $id = $data['id'] ?? null;
+ if (NULL === $id) {
+ throw new RuntimeException("missing id into person object");
+ }
+ }
+ /** var Person $person */
+ $person = $this->repository->findOneById($id);
+
+ if (NULL === $person) {
+ return UnexpectedValueException("person id not found");
+ }
+
+ return $person;
+ }
+
+ public function supportsNormalization($data, string $format = null): bool
+ {
+ return $data instanceof Person;
+ }
+
+ public function supportsDenormalization($data, string $type, ?string $format = NULL): bool
+ {
+ return Person::class === $type;
+ }
+
+ public function setNormalizer(NormalizerInterface $normalizer)
+ {
+ $this->normalizer = $normalizer;
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/config/services/controller.yaml b/src/Bundle/ChillPersonBundle/config/services/controller.yaml
index 24b35a8e3..893b1cfd3 100644
--- a/src/Bundle/ChillPersonBundle/config/services/controller.yaml
+++ b/src/Bundle/ChillPersonBundle/config/services/controller.yaml
@@ -40,4 +40,8 @@ services:
tags: ['controller.service_arguments']
Chill\PersonBundle\Controller\AccompanyingCourseController:
+ arguments:
+ $serializer: '@Symfony\Component\Serializer\SerializerInterface'
+ $dispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
+ $validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
tags: ['controller.service_arguments']
diff --git a/src/Bundle/ChillPersonBundle/config/services/serializer.yaml b/src/Bundle/ChillPersonBundle/config/services/serializer.yaml
new file mode 100644
index 000000000..092dc2320
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/config/services/serializer.yaml
@@ -0,0 +1,15 @@
+---
+services:
+ Chill\PersonBundle\Serializer\Normalizer\PersonNormalizer:
+ arguments:
+ $repository: '@Chill\PersonBundle\Repository\PersonRepository'
+ tags:
+ - { name: 'serializer.normalizer', priority: 64 }
+
+ Chill\PersonBundle\Serializer\Normalizer\AccompanyingPeriodNormalizer:
+ tags:
+ - { name: 'serializer.normalizer', priority: 64 }
+
+ Chill\PersonBundle\Serializer\Normalizer\AccompanyingPeriodParticipationNormalizer:
+ tags:
+ - { name: 'serializer.normalizer', priority: 64 }