src/Entity/Cvs/PublicCvDraft.php line 40

Open in your IDE?
  1. <?php
  2. namespace App\Entity\Cvs;
  3. use Doctrine\ORM\Mapping as ORM;
  4. /**
  5. * Brouillon de CV public — V6 (PDF stocké dans la draft, Candidates uniquement à register)
  6. *
  7. * Cycle de vie :
  8. * 1. CHOICE/THEME/FORM : visiteur remplit le CV
  9. * → cv_data + cv_settings écrits dans la draft (autosave debounced)
  10. * → AUCUN Candidates créé
  11. *
  12. * 2. POST /generate (clic "Générer mon CV") :
  13. * → Python lit cvs_candidates_drafts via --public-slug
  14. * → PDF généré dans uploadPath
  15. * → cv_pdf_path stocké dans la draft (pas dans Candidates)
  16. * → renvoie pdf_url au front pour preview
  17. *
  18. * 3. POST /register (clic "Créer mon compte") :
  19. * → CRÉATION Users + CRÉATION Candidates
  20. * → Transfert cv_data + cv_settings + cv_pdf_path : draft → Candidates
  21. * → DELETE draft
  22. *
  23. * 4. ABANDON (cron purge à 48h) :
  24. * → Si draft expirée : DELETE draft + DELETE PDF sur disque
  25. *
  26. * @ORM\Table(
  27. * name="cvs_candidates_drafts",
  28. * uniqueConstraints={
  29. * @ORM\UniqueConstraint(name="UNIQ_CVS_CANDIDATES_DRAFTS_PUBLIC_SLUG", columns={"public_slug"})
  30. * },
  31. * indexes={
  32. * @ORM\Index(name="IDX_CVS_CANDIDATES_DRAFTS_EXPIRES_AT", columns={"expires_at"})
  33. * }
  34. * )
  35. * @ORM\Entity(repositoryClass="App\Repository\Cvs\PublicCvDraftRepository")
  36. */
  37. class PublicCvDraft
  38. {
  39. /**
  40. * @var int|null
  41. *
  42. * @ORM\Column(name="id", type="integer")
  43. * @ORM\Id
  44. * @ORM\GeneratedValue(strategy="AUTO")
  45. */
  46. private $id;
  47. /**
  48. * @var string
  49. *
  50. * @ORM\Column(name="public_slug", type="string", length=20, unique=true)
  51. */
  52. private $publicSlug;
  53. /**
  54. * @var \DateTimeInterface
  55. *
  56. * @ORM\Column(name="expires_at", type="datetime")
  57. */
  58. private $expiresAt;
  59. /**
  60. * @var \DateTimeInterface
  61. *
  62. * @ORM\Column(name="created_at", type="datetime")
  63. */
  64. private $createdAt;
  65. /**
  66. * @var \DateTimeInterface
  67. *
  68. * @ORM\Column(name="updated_at", type="datetime")
  69. */
  70. private $updatedAt;
  71. // -------------------------------------------------------------------------
  72. // Colonnes typées (identifiants — pré-remplissage formulaire register)
  73. // -------------------------------------------------------------------------
  74. /**
  75. * @var string|null
  76. *
  77. * @ORM\Column(name="first_name", type="string", length=255, nullable=true)
  78. */
  79. private $firstName;
  80. /**
  81. * @var string|null
  82. *
  83. * @ORM\Column(name="last_name", type="string", length=255, nullable=true)
  84. */
  85. private $lastName;
  86. /**
  87. * @var string|null
  88. *
  89. * @ORM\Column(name="email", type="string", length=255, nullable=true)
  90. */
  91. private $email;
  92. /**
  93. * @var string|null
  94. *
  95. * @ORM\Column(name="phone", type="string", length=255, nullable=true)
  96. */
  97. private $phone;
  98. /**
  99. * @var string|null
  100. *
  101. * @ORM\Column(name="city", type="string", length=255, nullable=true)
  102. */
  103. private $city;
  104. /**
  105. * @var string|null
  106. *
  107. * @ORM\Column(name="country", type="string", length=255, nullable=true)
  108. */
  109. private $country;
  110. /**
  111. * @var string|null
  112. *
  113. * @ORM\Column(name="locale", type="string", length=8, nullable=true)
  114. */
  115. private $locale;
  116. // -------------------------------------------------------------------------
  117. // Colonnes JSON
  118. // -------------------------------------------------------------------------
  119. /**
  120. * @var string|null
  121. *
  122. * @ORM\Column(name="cv_data", type="text", nullable=true)
  123. */
  124. private $cvData;
  125. /**
  126. * @var string|null
  127. *
  128. * @ORM\Column(name="cv_settings", type="text", nullable=true)
  129. */
  130. private $cvSettings;
  131. /**
  132. * @var string|null
  133. *
  134. * @ORM\Column(name="mode", type="string", length=16, nullable=true)
  135. */
  136. private $mode;
  137. /**
  138. * Chemin absolu du PDF généré (sur disque, dans PYTHON_SCRIPT_CV_UPLOADPATH).
  139. * Renseigné après /generate, transféré à Candidates.cv_pdf_path à /register.
  140. *
  141. * @var string|null
  142. *
  143. * @ORM\Column(name="cv_pdf_path", type="string", length=500, nullable=true)
  144. */
  145. private $cvPdfPath;
  146. // =========================================================================
  147. // Getters / Setters
  148. // =========================================================================
  149. public function getId(): ?int { return $this->id; }
  150. public function getPublicSlug(): ?string { return $this->publicSlug; }
  151. public function setPublicSlug(string $publicSlug): self { $this->publicSlug = $publicSlug; return $this; }
  152. public function getExpiresAt(): ?\DateTimeInterface { return $this->expiresAt; }
  153. public function setExpiresAt(\DateTimeInterface $expiresAt): self { $this->expiresAt = $expiresAt; return $this; }
  154. public function getCreatedAt(): ?\DateTimeInterface { return $this->createdAt; }
  155. public function setCreatedAt(\DateTimeInterface $createdAt): self { $this->createdAt = $createdAt; return $this; }
  156. public function getUpdatedAt(): ?\DateTimeInterface { return $this->updatedAt; }
  157. public function setUpdatedAt(\DateTimeInterface $updatedAt): self { $this->updatedAt = $updatedAt; return $this; }
  158. public function getFirstName(): ?string { return $this->firstName; }
  159. public function setFirstName(?string $firstName): self { $this->firstName = $firstName; return $this; }
  160. public function getLastName(): ?string { return $this->lastName; }
  161. public function setLastName(?string $lastName): self { $this->lastName = $lastName; return $this; }
  162. public function getEmail(): ?string { return $this->email; }
  163. public function setEmail(?string $email): self { $this->email = $email; return $this; }
  164. public function getPhone(): ?string { return $this->phone; }
  165. public function setPhone(?string $phone): self { $this->phone = $phone; return $this; }
  166. public function getCity(): ?string { return $this->city; }
  167. public function setCity(?string $city): self { $this->city = $city; return $this; }
  168. public function getCountry(): ?string { return $this->country; }
  169. public function setCountry(?string $country): self { $this->country = $country; return $this; }
  170. public function getLocale(): ?string { return $this->locale; }
  171. public function setLocale(?string $locale): self { $this->locale = $locale; return $this; }
  172. public function getCvData(): ?string { return $this->cvData; }
  173. public function setCvData(?string $cvData): self { $this->cvData = $cvData; return $this; }
  174. public function getCvSettings(): ?string { return $this->cvSettings; }
  175. public function setCvSettings(?string $cvSettings): self { $this->cvSettings = $cvSettings; return $this; }
  176. public function getMode(): ?string { return $this->mode; }
  177. public function setMode(?string $mode): self { $this->mode = $mode; return $this; }
  178. public function getCvPdfPath(): ?string { return $this->cvPdfPath; }
  179. public function setCvPdfPath(?string $cvPdfPath): self { $this->cvPdfPath = $cvPdfPath; return $this; }
  180. // =========================================================================
  181. // Helpers
  182. // =========================================================================
  183. public function isExpired(?\DateTimeInterface $now = null): bool
  184. {
  185. $now = $now ?? new \DateTime();
  186. return $this->expiresAt < $now;
  187. }
  188. public function getCvDataArray(): array
  189. {
  190. if (empty($this->cvData)) {
  191. return [];
  192. }
  193. $decoded = json_decode($this->cvData, true);
  194. return is_array($decoded) ? $decoded : [];
  195. }
  196. public function getCvSettingsArray(): array
  197. {
  198. if (empty($this->cvSettings)) {
  199. return [];
  200. }
  201. $decoded = json_decode($this->cvSettings, true);
  202. return is_array($decoded) ? $decoded : [];
  203. }
  204. }