add a discrimnator type on onbjects

This commit is contained in:
2021-05-12 17:51:37 +02:00
parent f7a807473d
commit 91e4d585ff
17 changed files with 236 additions and 109 deletions

View File

@@ -58,12 +58,12 @@ class AccompanyingCourseApiController extends ApiController
if ($errors->count() > 0) {
// only format accepted
return $this->json($errors);
return $this->json($errors, 422);
}
$this->getDoctrine()->getManager()->flush();
return $this->json($participation);
return $this->json($participation, 200, [], ['groups' => [ 'read' ]]);
}
public function requestorApi($id, Request $request, string $_format): Response
@@ -102,12 +102,12 @@ class AccompanyingCourseApiController extends ApiController
if ($errors->count() > 0) {
// only format accepted
return $this->json($errors);
return $this->json($errors, 422);
}
$this->getDoctrine()->getManager()->flush();
return $this->json($accompanyingPeriod->getRequestor());
return $this->json($accompanyingPeriod->getRequestor(), 200, [], ['groups' => [ 'read']]);
}
protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response

View File

@@ -34,12 +34,16 @@ use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
/**
* AccompanyingPeriod Class
*
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\AccompanyingPeriodRepository")
* @ORM\Table(name="chill_person_accompanying_period")
* @DiscriminatorMap(typeProperty="type", mapping={
* "accompanying_period"=AccompanyingPeriod::class
* })
*/
class AccompanyingPeriod
{
@@ -156,6 +160,7 @@ class AccompanyingPeriod
/**
* @var string
* @ORM\Column(type="string", length=32, nullable=true)
* @Groups({"read"})
*/
private $step = self::STEP_DRAFT;
@@ -532,7 +537,7 @@ class AccompanyingPeriod
return $this->requestorPerson;
}
public function setRequestorPerson(Person $requestorPerson = null): self
private function setRequestorPerson(Person $requestorPerson = null): self
{
$this->requestorPerson = $requestorPerson;
@@ -544,7 +549,7 @@ class AccompanyingPeriod
return $this->requestorThirdParty;
}
public function setRequestorThirdParty(ThirdParty $requestorThirdParty = null): self
private function setRequestorThirdParty(ThirdParty $requestorThirdParty = null): self
{
$this->requestorThirdParty = $requestorThirdParty;
@@ -567,10 +572,10 @@ class AccompanyingPeriod
* The requestor is either an instance of ThirdParty, or an
* instance of Person
*
* @param $requestor Person|ThirdParty
* param $requestor Person|ThirdParty
* @return self
* @throw UnexpectedValueException if the requestor is not a Person or ThirdParty
*
* @Groups({"write"})
*/
public function setRequestor($requestor): self
{

View File

@@ -26,6 +26,8 @@ use Chill\PersonBundle\Repository\AccompanyingPeriodParticipationRepository;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
/**
* AccompanyingPeriodParticipation Class
@@ -33,6 +35,9 @@ use Doctrine\ORM\Mapping as ORM;
* @package Chill\PersonBundle\Entity
* @ORM\Entity(repositoryClass=AccompanyingPeriodParticipationRepository::class)
* @ORM\Table(name="chill_person_accompanying_period_participation")
* @DiscriminatorMap(typeProperty="type", mapping={
* "accompanying_period_participation"=AccompanyingPeriodParticipation::class
* })
*/
class AccompanyingPeriodParticipation
{
@@ -40,12 +45,14 @@ class AccompanyingPeriodParticipation
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"read"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="accompanyingPeriodParticipations")
* @ORM\JoinColumn(name="person_id", referencedColumnName="id", nullable=false)
* @Groups({"read"})
*/
private $person;
@@ -57,11 +64,13 @@ class AccompanyingPeriodParticipation
/**
* @ORM\Column(type="date", nullable=false)
* @Groups({"read"})
*/
private $startDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"read"})
*/
private $endDate = null;

View File

@@ -34,6 +34,7 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
/**
* Person Class
@@ -45,6 +46,9 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
* columns={"firstName", "lastName"}
* )})
* @ORM\HasLifecycleCallbacks()
* @DiscriminatorMap(typeProperty="type", mapping={
* "person"=Person::class
* })
*/
class Person implements HasCenterInterface
{

View File

@@ -41,6 +41,7 @@ class AccompanyingPeriodParticipationNormalizer implements NormalizerInterface,
public function supportsNormalization($data, string $format = null): bool
{
return false;
return $data instanceof AccompanyingPeriodParticipation;
}

View File

@@ -26,6 +26,7 @@ use Chill\PersonBundle\Repository\PersonRepository;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
/**
* Serialize a Person entity
@@ -33,21 +34,15 @@ use Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension;
*/
class PersonNormalizer implements
NormalizerInterface,
NormalizerAwareInterface,
DenormalizerInterface
NormalizerAwareInterface
{
protected NormalizerInterface $normalizer;
protected PersonRepository $repository;
private ChillEntityRenderExtension $render;
public const GET_PERSON = 'get_person';
public function __construct(PersonRepository $repository, ChillEntityRenderExtension $render)
public function __construct(ChillEntityRenderExtension $render)
{
$this->repository = $repository;
$this->render = $render;
}
@@ -56,7 +51,7 @@ class PersonNormalizer implements
/** @var Person $person */
return [
'type' => 'person',
'person_id' => $person->getId(),
'id' => $person->getId(),
'text' => $this->render->renderString($person),
'firstName' => $person->getFirstName(),
'lastName' => $person->getLastName(),
@@ -80,33 +75,11 @@ class PersonNormalizer implements
}
public function denormalize($data, string $type, string $format = null, array $context = []): Person
{
if ($context[self::GET_PERSON] ?? true) {
$id = $data['person_id'] ?? null;
if (NULL === $id) {
throw new RuntimeException("missing person_id into person object");
}
}
/** var Person $person */
$person = $this->repository->findOneById($id);
if (NULL === $person) {
throw new 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)
{

View File

@@ -100,14 +100,14 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
[], // parameters
[], // files
[], // server parameters
\json_encode([ 'person_id' => $personId ])
\json_encode([ 'type' => 'person', 'id' => $personId ])
);
$response = $this->client->getResponse();
$data = \json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode());
$this->assertArrayHasKey('person_id', $data);
$this->assertEquals($personId, $data['person_id']);
$this->assertArrayHasKey('id', $data);
$this->assertEquals($personId, $data['id']);
// check into database
$period = $em->getRepository(AccompanyingPeriod::class)
@@ -122,14 +122,14 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
[], // parameters
[], // files
[], // server parameters
\json_encode([ 'thirdparty_id' => $thirdPartyId ])
\json_encode([ 'type' => 'thirdparty', 'id' => $thirdPartyId ])
);
$response = $this->client->getResponse();
$data = \json_decode($response->getContent(), true);
$this->assertEquals(200, $response->getStatusCode());
$this->assertArrayHasKey('thirdparty_id', $data);
$this->assertEquals($thirdPartyId, $data['thirdparty_id']);
$this->assertArrayHasKey('id', $data);
$this->assertEquals($thirdPartyId, $data['id']);
// check into database
$period = $em->getRepository(AccompanyingPeriod::class)
@@ -152,6 +152,36 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
$this->assertNull($period->getRequestor());
}
/**
*
* @dataProvider dataGenerateRandomAccompanyingCourse
*/
public function testAccompanyingPeriodPatch(int $personId, AccompanyingPeriod $period)
{
$initialValueEmergency = $period->isEmergency();
$em = self::$container->get(EntityManagerInterface::class);
$this->client->request(
Request::METHOD_PATCH,
sprintf('/api/1.0/person/accompanying-course/%d.json', $period->getId()),
[], // parameters
[], // files
[], // server parameters
\json_encode([ 'type' => 'accompanying_period', 'emergency' => !$initialValueEmergency ])
);
$response = $this->client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$period = $em->getRepository(AccompanyingPeriod::class)
->find($period->getId());
$em->refresh($period);
$this->assertEquals(!$initialValueEmergency, $period->isEmergency());
// restore the initial valud
$period->setEmergency($initialValueEmergency);
$em->flush();
}
public function dataGenerateRandomRequestorValidData(): \Iterator
{
$dataLength = 2;
@@ -208,7 +238,7 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
[], // parameters
[], // files
[], // server parameters
\json_encode([ 'person_id' => $personId ])
\json_encode([ 'type' => 'person', 'id' => $personId ])
);
$response = $this->client->getResponse();
$data = \json_decode($response->getContent(), true);
@@ -227,7 +257,7 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
// check that the person id is contained
$participationsPersonsIds = \array_map(
function($participation) { return $participation->person->person_id; },
function($participation) { return $participation->person->id; },
$data->participations);
$this->assertContains($personId, $participationsPersonsIds);
@@ -239,7 +269,7 @@ class AccompanyingCourseApiControllerTest extends WebTestCase
[], // parameters
[], // files
[], // server parameters
\json_encode([ 'person_id' => $personId ])
\json_encode([ 'type' => 'person', 'id' => $personId ])
);
$response = $this->client->getResponse();
$data = \json_decode($response->getContent(), true);

View File

@@ -17,6 +17,9 @@ components:
AccompanyingPeriod:
type: object
properties:
type:
type: string
x-fixed-value: 'accompanying_period'
id:
type: integer
requestorAnonymous:

View File

@@ -2,7 +2,11 @@ parameters:
# cl_chill_person.example.class: Chill\PersonBundle\Example
services:
Chill\PersonBundle\Serializer\Normalizer\:
resource: '../Serializer/Normalizer/'
autowire: true
tags:
- { name: 'serializer.normalizer', priority: 64 }
chill.person.form.type.select2maritalstatus:
class: Chill\PersonBundle\Form\Type\Select2MaritalStatusType

View File

@@ -1,12 +1,3 @@
---
services:
Chill\PersonBundle\Serializer\Normalizer\PersonNormalizer:
arguments:
$repository: '@Chill\PersonBundle\Repository\PersonRepository'
$render: '@Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension'
tags:
- { name: 'serializer.normalizer', priority: 64 }
Chill\PersonBundle\Serializer\Normalizer\AccompanyingPeriodParticipationNormalizer:
tags:
- { name: 'serializer.normalizer', priority: 64 }
# note: normalizers are loaded from ../services.yaml