From 774437d3196878388e294a3833a73e900000b5e4 Mon Sep 17 00:00:00 2001 From: polo Date: Tue, 23 Dec 2025 15:20:48 +0100 Subject: =?UTF-8?q?choix=20dur=C3=A9e=20stockage=20e-mails,=20relation=20e?= =?UTF-8?q?ntit=C3=A9s=20Email=20<=3D>=20NodeData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/form.js | 30 +++++++++++++++++++++++++ src/EmailService.php | 2 +- src/controller/ContactFormController.php | 9 ++++++++ src/model/Model.php | 16 +++++++++++--- src/model/entities/Email.php | 30 ++++++++++++++++++++----- src/model/entities/NodeData.php | 38 ++++++-------------------------- src/router.php | 3 +++ src/view/FormBuilder.php | 3 +++ src/view/templates/form.php | 2 +- src/view/templates/form_admin.php | 10 ++++++--- 10 files changed, 98 insertions(+), 45 deletions(-) diff --git a/public/js/form.js b/public/js/form.js index 7cee970..d8849c8 100644 --- a/public/js/form.js +++ b/public/js/form.js @@ -58,6 +58,36 @@ function keepEmails(block_id){ console.error('Erreur:', error); }); } +function setEmailsRetentionPeriod(block_id){ + const form = document.getElementById('retention_period_' + block_id); + if(!form){ + return; + } + + fetch('index.php?action=set_retention_period', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + id: block_id, + months: form.value + }) + }) + .then(response => response.json()) + .then(data => { + if(data.success){ + form.value = data.months; + console.log(data.months + " mois"); + } + else{ + toastNotify("Erreur, le réglage n'a pas été enregistré par le serveur."); + } + }) + .catch(error => { + console.error('Erreur:', error); + }); +} function checkCase(id){ if(document.getElementById('email_address_' + id).value.match('[A-Z]')){ diff --git a/src/EmailService.php b/src/EmailService.php index 5d1b2eb..c6d97b4 100644 --- a/src/EmailService.php +++ b/src/EmailService.php @@ -67,7 +67,7 @@ class EmailService // copie en BDD if(!$test_email && ($form_data->getData()['keep_emails'] ?? self::KEEP_EMAILS_DEFAULT)){ - $db_email = new Email($name, $email, Config::$email_dest, $message); + $db_email = new Email($name, $email, Config::$email_dest, $message, $form_data); $entityManager->persist($db_email); self::updateLastContactDate($entityManager, $email); $entityManager->flush(); diff --git a/src/controller/ContactFormController.php b/src/controller/ContactFormController.php index 243740f..0724401 100644 --- a/src/controller/ContactFormController.php +++ b/src/controller/ContactFormController.php @@ -16,6 +16,15 @@ class ContactFormController echo json_encode(['success' => true, 'checked' => $json['checked']]); die; } + static public function setEmailsRetentionPeriod(EntityManager $entityManager, array $json): void + { + $form_data = $entityManager->find('App\Entity\NodeData', $json['id']); + $form_data->updateData('retention_period', (int)$json['months']); + $entityManager->persist($form_data); + $entityManager->flush(); + echo json_encode(['success' => true, 'months' => $json['months']]); + die; + } static public function setEmailParam(EntityManager $entityManager, array $json): void { $form = new FormValidation($json, 'email_params'); diff --git a/src/model/Model.php b/src/model/Model.php index de391ff..1054d57 100644 --- a/src/model/Model.php +++ b/src/model/Model.php @@ -65,8 +65,11 @@ class Model } // emails - if($parent_block->getName() === 'show_emails'){ + if($parent_block->getName() === 'show_emails'){ // show_emails = l'afficheur $parent_block->getNodeData()->setEmails($this->getAllEmails()); + + // aller chercher les formulaires à la place (future MAJ?) + //$this->getFormsNodeData(); } } } @@ -294,8 +297,15 @@ class Model $dql = 'SELECT e FROM App\Entity\Email e'; return $this->entityManager ->createQuery($dql) - //->setParameter('page', $this->page) ->getResult(); } - //private function getEmails(string $sender): array + /*private function getFormsNodeData(): array + { + $dql = 'SELECT fd FROM App\Entity\NodeData fd WHERE node.name_node = form'; + return $this->entityManager + ->createQuery($dql) + //->setParameter('page', $this->page) + ->getResult(); + }*/ + //private function getEmailsBySender(string $sender): array } diff --git a/src/model/entities/Email.php b/src/model/entities/Email.php index c66625f..d54b3cc 100644 --- a/src/model/entities/Email.php +++ b/src/model/entities/Email.php @@ -12,8 +12,8 @@ use Doctrine\ORM\Mapping as ORM; class Email { // en mois - const LEGAL_RETENTION_PERIOD = 36; // 3 ans, justification = prospection, durée "glissante", date de suppression remise à jour à chaque nouvel e-mail - const LEGAL_RETENTION_PERIOD_SENSITIVE = 60; // 5 ans pour données sensibles ou litige, durée de preuve légale, durée non glissante + const DEFAULT_RETENTION_PERIOD = 36; // 3 ans, justification = prospection, durée "glissante", date de suppression remise à jour à chaque nouvel e-mail + const DEFAULT_RETENTION_PERIOD_SENSITIVE = 60; // 5 ans pour données sensibles ou litige, durée de preuve légale, durée non glissante #[ORM\Id] #[ORM\GeneratedValue] @@ -48,13 +48,18 @@ class Email #[ORM\Column(type: 'datetime', nullable: true)] private ?\DateTime $is_sensitive_since; - public function __construct(string $sender_name, string $sender_address, string $recipient, string $content, bool $sensitive = false){ + #[ORM\ManyToOne(targetEntity: NodeData::class)] + #[ORM\JoinColumn(name: "node_data_id", referencedColumnName: "id_node_data", nullable: true)] + private ?NodeData $node_data; + + public function __construct(string $sender_name, string $sender_address, string $recipient, string $content, NodeData $node_data, bool $sensitive = false){ $this->sender_name = strtolower($sender_name); $this->sender_address = strtolower($sender_address); $this->recipient = strtolower($recipient); $this->content = $content; $this->date_time = new \DateTime; $this->last_contact_date = new \DateTime; + $this->node_data = $node_data; $this->makeSensitive($sensitive); } @@ -108,10 +113,23 @@ class Email $this->last_contact_date = new \DateTime; } + // la durée de conservation $period est propre au bloc formulaire (NodeData) + // la date de dernier contact public function getDeletionDate(): \DateTime { - return $this->is_sensitive // oui durée 5 ans, non durée 3 ans "glissante" - ? (clone $this->is_sensitive_since)->modify('+ ' . (string)self::LEGAL_RETENTION_PERIOD_SENSITIVE . ' month') // erreur si vrai mais sans date (pas censé arriver) - : (clone $this->last_contact_date)->modify('+ ' . (string)self::LEGAL_RETENTION_PERIOD . ' month'); + // deux tests: + // => e-mail associé à un formulaire? + // => ce formulaire dispose d'une durée de stockage spécifique? + $period = $this->node_data === null ? null : ($this->node_data->getData()['retention_period'] ?? null); + + $period = (int)$period; + if($period === null || $period <= 0){ + $period = $this->is_sensitive ? self::DEFAULT_RETENTION_PERIOD_SENSITIVE : self::DEFAULT_RETENTION_PERIOD; + } + + $date = $this->is_sensitive ? (clone $this->is_sensitive_since) : (clone $this->last_contact_date); // oui durée 5 ans, non durée 3 ans "glissante" + // erreur si "sensible" mais sans date disponible (pas censé arriver) + + return $date->modify('+ ' . (string)$period . ' month'); } } \ No newline at end of file diff --git a/src/model/entities/NodeData.php b/src/model/entities/NodeData.php index 4c07a69..d2f10ba 100644 --- a/src/model/entities/NodeData.php +++ b/src/model/entities/NodeData.php @@ -44,8 +44,11 @@ class NodeData #[ORM\OneToMany(mappedBy: 'node_data', targetEntity: NodeDataAsset::class, cascade: ['persist', 'remove'])] private Collection $nda_collection; + /*#[ORM\OneToMany(mappedBy: 'node_data', targetEntity: Email::class, cascade: ['persist', 'remove'])] // => noeud "form", inutilisé et conflit avec le tableau $emails + private Collection $emails;*/ + private int $nb_pages = 1; - private array $emails = []; // noeud show_emails uniquement + private array $emails = []; // => noeud "show_emails" public function __construct(array $data, Node $node, Collection $nda_collection = new ArrayCollection, ?string $presentation = null, ?bool $chrono_order = null) { @@ -70,7 +73,7 @@ class NodeData { $this->data = $data; }*/ - public function updateData(string $key, string|bool|array $value = ''): void + public function updateData(string $key, string|int|bool|array $value = ''): void { if($value !== ''){ $this->data[$key] = $value; @@ -153,39 +156,12 @@ class NodeData } return $nda->getAsset() ?? null; } - /*public function addNodeDataAsset(NodeDataAsset $nda): self - { - if(!$this->nda_collection->contains($nda)){ // sécurité contrainte UNIQUE - $this->nda_collection->add($nda); - } - return $this; - }*/ - /*public function removeNodeDataAsset(NodeDataAsset $nda): self // inutile on peut faire: $node_data->getNodeDataAssets()->removeElement($nda); - { - $this->nda_collection->removeElement($nda); - // pas de synchro dans NodeDataAsset, les champs de cette table ne sont pas nullables - return $this; - }*/ - - // LE setter, sélectionne l'asset à utiliser en remplaçant l'entrée dans NodeDataAsset en fonction du rôle - // à mettre théoriquement dans une classe metier dans "service" - /*public function replaceAssetForRole(string $role, Asset $asset): void - { - foreach($this->nda_collection as $nda){ - if($nda->getRole() === $role){ - $this->removeNodeDataAsset($nda); - break; - } - } - $this->new_nda = new NodeDataAsset($this, $asset, $role); - $this->addNodeDataAsset($this->new_nda); - }*/ - public function getEmails(): array + public function getEmails(): array // appelée dans ShowEmailsBuilder { return $this->emails; } - public function setEmails(array $emails): void + public function setEmails(array $emails): void // appelée dans Model { $this->emails = $emails; } diff --git a/src/router.php b/src/router.php index 228fae2..7348f2b 100644 --- a/src/router.php +++ b/src/router.php @@ -115,6 +115,9 @@ elseif($request->getMethod() === 'POST'){ elseif($_GET['action'] === 'keep_emails'){ ContactFormController::keepEmails($entityManager, $json); } + elseif($_GET['action'] === 'set_retention_period'){ + ContactFormController::setEmailsRetentionPeriod($entityManager, $json); + } elseif($_GET['action'] === 'set_email_param'){ ContactFormController::setEmailParam($entityManager, $json); } diff --git a/src/view/FormBuilder.php b/src/view/FormBuilder.php index 7952357..e2389b0 100644 --- a/src/view/FormBuilder.php +++ b/src/view/FormBuilder.php @@ -24,10 +24,13 @@ class FormBuilder extends AbstractBuilder $_SESSION['captcha'] = self::$captcha->getSolution(); } + // données stockées en vrac dans du JSON et récupérées avec extract => changer ça un jour $smtp_host = $smtp_host ?? Config::$smtp_host; $smtp_secure = $smtp_secure ?? Config::$smtp_secure; $smtp_username = $smtp_username ?? Config::$smtp_username; $email_dest = $email_dest ?? Config::$email_dest; + $keep_emails = (bool)$keep_emails ?? false; // (bool) est inutile mais plus clair + $retention_period = (int)($retention_period ?? App\Entity\Email::DEFAULT_RETENTION_PERIOD); // (int) est nécessaire à cause du stockage JSON $admin_content = ''; if($_SESSION['admin']) diff --git a/src/view/templates/form.php b/src/view/templates/form.php index 54dcd02..8fb4735 100644 --- a/src/view/templates/form.php +++ b/src/view/templates/form.php @@ -31,7 +31,7 @@

- Une copie de votre e-mail (nom, adresse et message) sera conservée dans notre base de données dans le but de pouvoir répondre à votre demande et et éventuellement dans un but de prospection. Ces données seront traitées automatiquement par notre serveur et conservées pendant au maximum 3 ans à compter de votre dernier message.
+ Une copie de votre e-mail (nom, adresse et message) sera conservée dans notre base de données dans le but de pouvoir répondre à votre demande et éventuellement dans un but de prospection. Ces données seront traitées automatiquement par notre serveur et conservées pendant au maximum 3 ans à compter de votre dernier message.
Ce traitement repose sur votre consentement. Vous pouvez consulter, modifier ou supprimer vos données en base de données sur simple demande.

\ No newline at end of file diff --git a/src/view/templates/form_admin.php b/src/view/templates/form_admin.php index bf281b5..457f770 100644 --- a/src/view/templates/form_admin.php +++ b/src/view/templates/form_admin.php @@ -6,9 +6,13 @@ declare(strict_types=1);

- onclick="keepEmails(getNodeData()->getId() ?>)"> + onclick="keepEmails(getNodeData()->getId() ?>)">

Notez que ces enregistrements sont des données personnelles et sont concernés par le RGPD.

+

+ + +

@@ -23,8 +27,8 @@ declare(strict_types=1);

-- cgit v1.2.3