diff --git a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php index 2a175eb27..3267b2225 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php +++ b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php @@ -90,11 +90,6 @@ final class DocGeneratorTemplateController extends AbstractController int $entityId, Request $request ): Response { - $entity = $this->getDoctrine()->getRepository($entityClassName)->find($entityId); - - if (null === $entity) { - throw new NotFoundHttpException("Entity with classname {$entityClassName} and id {$entityId} is not found"); - } try { $context = $this->contextManager->getContextByDocGeneratorTemplate($template); @@ -102,6 +97,12 @@ final class DocGeneratorTemplateController extends AbstractController throw new NotFoundHttpException($e->getMessage(), $e); } + $entity = $this->getDoctrine()->getRepository($context->getEntityClass())->find($entityId); + + if (null === $entity) { + throw new NotFoundHttpException("Entity with classname {$entityClassName} and id {$entityId} is not found"); + } + $contextGenerationData = []; if ($context instanceof DocGeneratorContextWithPublicFormInterface diff --git a/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php b/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php index 0a29af940..4f0a9f1ab 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php +++ b/src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php @@ -210,7 +210,17 @@ class DocGenObjectNormalizer implements NormalizerAwareInterface, NormalizerInte $value = $this->propertyAccess->getValue($object, $attribute->getName()); $key = $attribute->getSerializedName() ?? $attribute->getName(); - if (is_object($value)) { + if (is_iterable($value)) { + $arr = []; + foreach ($value as $k => $v) { + $arr[$k] = + $this->normalizer->normalize($v, $format, array_merge( + $context, + $attribute->getNormalizationContextForGroups($expectedGroups) + )); + } + $data[$key] = $arr; + } elseif (is_object($value)) { $data[$key] = $this->normalizer->normalize($value, $format, array_merge( $context, diff --git a/src/Bundle/ChillMainBundle/Entity/Scope.php b/src/Bundle/ChillMainBundle/Entity/Scope.php index 3a6cbd953..fc6084883 100644 --- a/src/Bundle/ChillMainBundle/Entity/Scope.php +++ b/src/Bundle/ChillMainBundle/Entity/Scope.php @@ -33,7 +33,7 @@ class Scope * @ORM\Id * @ORM\Column(name="id", type="integer") * @ORM\GeneratedValue(strategy="AUTO") - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) */ private $id; @@ -43,7 +43,7 @@ class Scope * @var array * * @ORM\Column(type="json") - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) */ private $name = []; diff --git a/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php index f046cb34f..22219b108 100644 --- a/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php +++ b/src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php @@ -45,6 +45,6 @@ class UserNormalizer implements NormalizerAwareInterface, NormalizerInterface public function supportsNormalization($data, ?string $format = null): bool { - return 'json' === $format && $data instanceof User; + return $data instanceof User && ('json' === $format || 'docgen' === $format); } } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 92d84610f..dcd3c2df0 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -259,7 +259,7 @@ class AccompanyingPeriod implements * cascade={"persist", "remove"}, * orphanRemoval=true * ) - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) * @ResourceDuplicateCheck(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED, "Default", "default"}) */ private Collection $resources; @@ -274,7 +274,7 @@ class AccompanyingPeriod implements * joinColumns={@ORM\JoinColumn(name="accompanying_period_id", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="scope_id", referencedColumnName="id")} * ) - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) * @Assert\Count(min=1, groups={AccompanyingPeriod::STEP_CONFIRMED}, minMessage="A course must be associated to at least one scope") */ private Collection $scopes; @@ -340,6 +340,7 @@ class AccompanyingPeriod implements $this->socialIssues = new ArrayCollection(); $this->comments = new ArrayCollection(); $this->works = new ArrayCollection(); + $this->resources = new ArrayCollection(); } /** @@ -575,6 +576,9 @@ class AccompanyingPeriod implements return $this->createdBy; } + /** + * @Groups({"docgen:read"}) + */ public function getCurrentParticipations(): Collection { return $this->getOpenParticipations(); diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php index ea20666fb..a11dc9b3d 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Resource.php @@ -41,11 +41,10 @@ class Resource * ) * @ORM\JoinColumn(nullable=false) */ - private $accompanyingPeriod; + private ?AccompanyingPeriod $accompanyingPeriod = null; /** * @ORM\ManyToOne(targetEntity=Comment::class) - * @ORM\JoinColumn(nullable=true) */ private $comment; @@ -53,21 +52,23 @@ class Resource * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) */ - private $id; + private ?int $id = null; /** * @ORM\ManyToOne(targetEntity=Person::class) * @ORM\JoinColumn(nullable=true) + * @Groups({"docgen:read"}) */ - private $person; + private ?Person $person = null; /** * @ORM\ManyToOne(targetEntity=ThirdParty::class) * @ORM\JoinColumn(nullable=true) + * @Groups({"docgen:read"}) */ - private $thirdParty; + private ?ThirdParty $thirdParty = null; public function getAccompanyingPeriod(): ?AccompanyingPeriod { diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriodParticipation.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriodParticipation.php index 862d268d2..ee3ac7dc9 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriodParticipation.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriodParticipation.php @@ -32,38 +32,38 @@ class AccompanyingPeriodParticipation * @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class, inversedBy="participations", cascade={"persist"}) * @ORM\JoinColumn(name="accompanyingperiod_id", referencedColumnName="id", nullable=false) */ - private $accompanyingPeriod; + private ?AccompanyingPeriod $accompanyingPeriod = null; /** * @ORM\Column(type="date", nullable=true) - * @Groups({"read", "read:docgen"}) + * @Groups({"read", "docgen:read"}) */ - private $endDate; + private ?\DateTime $endDate = null; /** * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Groups({"read", "read:docgen"}) + * @Groups({"read", "docgen:read"}) */ - private $id; + private ?int $id = null; /** * @ORM\ManyToOne(targetEntity=Person::class, inversedBy="accompanyingPeriodParticipations") * @ORM\JoinColumn(name="person_id", referencedColumnName="id", nullable=false) - * @Groups({"read", "read:docgen"}) + * @Groups({"read", "docgen:read"}) */ - private $person; + private ?Person $person = null; /** * @ORM\Column(type="date", nullable=false) - * @Groups({"read"}) + * @Groups({"read", "docgen:read"}) */ - private $startDate; + private ?\DateTime $startDate = null; public function __construct(AccompanyingPeriod $accompanyingPeriod, Person $person) { - $this->startDate = new DateTimeImmutable('now'); + $this->startDate = new \DateTime('now'); $this->accompanyingPeriod = $accompanyingPeriod; $this->person = $person; } @@ -73,10 +73,6 @@ class AccompanyingPeriodParticipation return $this->accompanyingPeriod; } - /* - * public function setStartDate(\DateTimeInterface $startDate): self { $this->startDate = $startDate; return $this; } - */ - public function getEndDate(): ?DateTimeInterface { return $this->endDate; diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php index c03644214..c5adbbd6a 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php @@ -59,7 +59,7 @@ class Household * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private ?int $id = null; @@ -68,17 +68,19 @@ class Household * targetEntity=HouseholdMember::class, * mappedBy="household" * ) - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private Collection $members; /** * @ORM\Column(type="boolean", name="waiting_for_birth", options={"default": false}) + * @Serializer\Groups({"docgen:read"}) */ private bool $waitingForBirth = false; /** * @ORM\Column(type="date_immutable", name="waiting_for_birth_date", nullable=true, options={"default": null}) + * @Serializer\Groups({"docgen:read"}) */ private ?DateTimeImmutable $waitingForBirthDate = null; @@ -134,7 +136,7 @@ class Household } /** - * @Serializer\Groups({ "read" }) + * @Serializer\Groups({"read", "docgen:read"}) * @Serializer\SerializedName("current_address") */ public function getCurrentAddress(?DateTime $at = null): ?Address @@ -154,6 +156,11 @@ class Household return null; } + /** + * @param DateTimeImmutable|null $now + * @return Collection + * @Serializer\Groups({"docgen:read"}) + */ public function getCurrentMembers(?DateTimeImmutable $now = null): Collection { return $this->getMembers()->matching($this->buildCriteriaCurrentMembers($now)); diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php index af3ead806..829bc3ade 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php @@ -28,13 +28,13 @@ class HouseholdMember { /** * @ORM\Column(type="string", length=255, nullable=true) - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private ?string $comment = null; /** * @ORM\Column(type="date_immutable", nullable=true, options={"default": null}) - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) * @Assert\GreaterThan( * propertyPath="startDate", * message="household_membership.The end date must be after start date", @@ -45,7 +45,7 @@ class HouseholdMember /** * @ORM\Column(type="boolean", options={"default": false}) - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private bool $holder = false; @@ -63,7 +63,7 @@ class HouseholdMember * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private $id; @@ -72,7 +72,7 @@ class HouseholdMember * @ORM\ManyToOne( * targetEntity="\Chill\PersonBundle\Entity\Person" * ) - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) * @Assert\Valid(groups={"household_memberships"}) * @Assert\NotNull(groups={"household_memberships"}) */ @@ -80,7 +80,7 @@ class HouseholdMember /** * @ORM\ManyToOne(targetEntity=Position::class) - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) * @Assert\NotNull(groups={"household_memberships_created"}) */ private ?Position $position = null; @@ -92,7 +92,7 @@ class HouseholdMember /** * @ORM\Column(type="date_immutable", nullable=true, options={"default": null}) - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) * @Assert\NotNull(groups={"household_memberships"}) */ private ?DateTimeImmutable $startDate = null; diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Position.php b/src/Bundle/ChillPersonBundle/Entity/Household/Position.php index 721c35433..b8f707126 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/Position.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Position.php @@ -33,25 +33,25 @@ class Position * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Serializer\Groups({ "read" }) + * @Serializer\Groups({"read", "docgen:read"}) */ private ?int $id; /** * @ORM\Column(type="json") - * @Serializer\Groups({ "read" }) + * @Serializer\Groups({"read", "docgen:read"}) */ private array $label = []; /** * @ORM\Column(type="float") - * @Serializer\Groups({ "read" }) + * @Serializer\Groups({"read"}) */ private float $ordering = 0.00; /** * @ORM\Column(type="boolean") - * @Serializer\Groups({ "read" }) + * @Serializer\Groups({"read"}) */ private bool $shareHouseHold = true; diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/Goal.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/Goal.php index 9c02a129d..f3d8f5289 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/Goal.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/Goal.php @@ -38,7 +38,7 @@ class Goal * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private $id; @@ -55,7 +55,7 @@ class Goal /** * @ORM\Column(type="json") - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private $title = []; diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/Result.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/Result.php index b2894d210..17d4ddd0a 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/Result.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/Result.php @@ -55,7 +55,7 @@ class Result * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private $id; @@ -66,7 +66,7 @@ class Result /** * @ORM\Column(type="json") - * @Serializer\Groups({"read"}) + * @Serializer\Groups({"read", "docgen:read"}) */ private $title = []; diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialActionNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialActionNormalizer.php index 94341197b..96af56e95 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialActionNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialActionNormalizer.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Serializer\Normalizer; use Chill\PersonBundle\Entity\SocialWork\SocialAction; +use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Templating\Entity\SocialActionRender; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; @@ -30,18 +31,48 @@ class SocialActionNormalizer implements NormalizerAwareInterface, NormalizerInte public function normalize($socialAction, ?string $format = null, array $context = []) { - return [ - 'id' => $socialAction->getId(), - 'type' => 'social_work_social_action', - 'text' => $this->render->renderString($socialAction, []), - 'parent' => $this->normalizer->normalize($socialAction->getParent()), - 'desactivationDate' => $this->normalizer->normalize($socialAction->getDesactivationDate()), - 'title' => $socialAction->getTitle(), - ]; + switch ($format) { + case 'json': + return [ + 'id' => $socialAction->getId(), + 'type' => 'social_work_social_action', + 'text' => $this->render->renderString($socialAction, []), + 'parent' => $this->normalizer->normalize($socialAction->getParent()), + 'desactivationDate' => $this->normalizer->normalize($socialAction->getDesactivationDate()), + 'title' => $socialAction->getTitle(), + ]; + case 'docgen': + + if (null === $socialAction) { + return ['id' => 0, 'title' => '', 'text' => '']; + } + + return [ + 'id' => $socialAction->getId(), + 'text' => $this->render->renderString($socialAction, []), + 'title' => $socialAction->getTitle(), + ]; + default: + throw new \Symfony\Component\Serializer\Exception\RuntimeException("format not supported"); + } } - public function supportsNormalization($data, ?string $format = null) + public function supportsNormalization($data, string $format = null, array $context = []) { - return $data instanceof SocialAction; + if ($data instanceof SocialAction && 'json' === $format) { + return true; + } + + if ('docgen' === $format) { + if ($data instanceof SocialAction) { + return true; + } + + if (null === $data && ($context['docgen:expects'] ?? null) === SocialAction::class) { + return true; + } + } + + return false; } } diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php index f255e6f8c..cfe7c0895 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php @@ -13,11 +13,12 @@ namespace Chill\PersonBundle\Serializer\Normalizer; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Templating\Entity\SocialIssueRender; +use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -class SocialIssueNormalizer implements NormalizerAwareInterface, NormalizerInterface +class SocialIssueNormalizer implements NormalizerAwareInterface, ContextAwareNormalizerInterface { use NormalizerAwareTrait; @@ -31,18 +32,46 @@ class SocialIssueNormalizer implements NormalizerAwareInterface, NormalizerInter public function normalize($socialIssue, ?string $format = null, array $context = []) { /** @var SocialIssue $socialIssue */ - return [ - 'type' => 'social_issue', - 'id' => $socialIssue->getId(), - 'parent_id' => $socialIssue->hasParent() ? $socialIssue->getParent()->getId() : null, - 'children_ids' => $socialIssue->getChildren()->map(static function (SocialIssue $si) { return $si->getId(); }), - 'title' => $socialIssue->getTitle(), - 'text' => $this->render->renderString($socialIssue, []), - ]; + switch ($format) { + case 'json': + return [ + 'type' => 'social_issue', + 'id' => $socialIssue->getId(), + 'parent_id' => $socialIssue->hasParent() ? $socialIssue->getParent()->getId() : null, + 'children_ids' => $socialIssue->getChildren()->map(static function (SocialIssue $si) { return $si->getId(); }), + 'title' => $socialIssue->getTitle(), + 'text' => $this->render->renderString($socialIssue, []), + ]; + case 'docgen': + + if (null === $socialIssue) { + return ['id' => 0, 'title' => '', 'text' => '']; + } + + return [ + 'id' => $socialIssue->getId(), + 'title' => $socialIssue->getTitle(), + 'text' => $this->render->renderString($socialIssue, []), + ]; + } } - public function supportsNormalization($data, ?string $format = null): bool + public function supportsNormalization($data, string $format = null, array $context = []) { - return $data instanceof SocialIssue; + if ($data instanceof SocialIssue && 'json' === $format) { + return true; + } + + if ('docgen' === $format) { + if ($data instanceof SocialIssue) { + return true; + } + + if (null === $data && ($context['docgen:expects'] ?? null) === SocialIssue::class) { + return true; + } + } + + return false; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php index 4c08db326..bd104bbe8 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizerTest.php @@ -13,6 +13,7 @@ namespace Serializer\Normalizer; use Chill\MainBundle\Entity\Scope; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; @@ -79,6 +80,22 @@ final class AccompanyingPeriodDocGenNormalizerTest extends KernelTestCase } } + public function testNormalizeParticipations() + { + $period = new AccompanyingPeriod(); + $period->addPerson($person = new Person()); + $person->setFirstName('test'); + + $data = $this->normalizer->normalize($period, 'docgen', ['docgen:expects' => AccompanyingPeriod::class]); + + $this->assertIsArray($data); + $this->assertArrayHasKey('participations', $data); + $this->assertCount(1, $data['participations']); + + $this->assertArrayHasKey('currentParticipations', $data); + $this->assertCount(1, $data['currentParticipations']); + } + public function testNormalizeNull() { $data = $this->normalizer->normalize(null, 'docgen', ['docgen:expects' => AccompanyingPeriod::class]);