aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2025-12-16 22:41:57 +0100
committerpolo <ordipolo@gmx.fr>2025-12-16 22:41:57 +0100
commit423755b019a09111b971e36c53e2557e2f5a704f (patch)
tree022c0a911133d676dd8e4e90379f8b186863fc88
parent22da81bbcb9bb61fa484c9af6fbb667b685d2f9b (diff)
downloadcms-423755b019a09111b971e36c53e2557e2f5a704f.tar.gz
cms-423755b019a09111b971e36c53e2557e2f5a704f.tar.bz2
cms-423755b019a09111b971e36c53e2557e2f5a704f.zip
page emails, application du RGPD: table email et nettoyeur, renommage de $id_email
-rw-r--r--bin/cron.php12
-rw-r--r--composer.json2
-rw-r--r--public/css/form.css3
-rw-r--r--public/css/show_emails.css24
-rw-r--r--public/js/form.js62
-rw-r--r--src/EmailService.php26
-rw-r--r--src/controller/ContactFormController.php16
-rw-r--r--src/controller/UserController.php2
-rw-r--r--src/controller/ViewController.php2
-rw-r--r--src/installation.php8
-rw-r--r--src/model/Model.php17
-rw-r--r--src/model/entities/Email.php90
-rw-r--r--src/model/entities/Node.php37
-rw-r--r--src/model/entities/NodeData.php10
-rw-r--r--src/model/entities/NodeDataAsset.php1
-rw-r--r--src/router.php13
-rw-r--r--src/view/ShowEmailsBuilder.php69
-rw-r--r--src/view/templates/form.php6
-rw-r--r--src/view/templates/form_admin.php3
-rw-r--r--src/view/templates/show_emails.php27
20 files changed, 375 insertions, 55 deletions
diff --git a/bin/cron.php b/bin/cron.php
new file mode 100644
index 0000000..f71c559
--- /dev/null
+++ b/bin/cron.php
@@ -0,0 +1,12 @@
1#!/usr/bin/env php
2<?php
3// bin/cron.php
4
5declare(strict_types=1);
6
7chdir('bin');
8require('../src/Config.php');
9Config::load('../config/config.ini');
10require '../src/model/doctrine-bootstrap.php';
11
12EmailService::cleanEmails($entityManager); \ No newline at end of file
diff --git a/composer.json b/composer.json
index a661963..eb19164 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
1{ 1{
2 "name": "ordipolo/cms", 2 "name": "ordipolo/cms",
3 "description": "CMS maison avec PHP, doctrine et tinMCE", 3 "description": "CMS maison avec PHP, doctrine et tinyMCE",
4 "require": { 4 "require": {
5 "doctrine/dbal": "^4.3", 5 "doctrine/dbal": "^4.3",
6 "doctrine/orm": "^3.5", 6 "doctrine/orm": "^3.5",
diff --git a/public/css/form.css b/public/css/form.css
index c17662d..09d4140 100644
--- a/public/css/form.css
+++ b/public/css/form.css
@@ -35,6 +35,9 @@
35.form .admin_form i{ 35.form .admin_form i{
36 font-size: smaller; 36 font-size: smaller;
37} 37}
38.form_gdpr{
39 font-size: smaller;
40}
38 41
39@media screen and (max-width: 600px){ 42@media screen and (max-width: 600px){
40 .form_inputs{ 43 .form_inputs{
diff --git a/public/css/show_emails.css b/public/css/show_emails.css
new file mode 100644
index 0000000..4fb9f3b
--- /dev/null
+++ b/public/css/show_emails.css
@@ -0,0 +1,24 @@
1.show_emails p{
2 font-size: smaller;
3}
4.show_emails table{
5
6 padding: 10px;
7 border-collapse: collapse;
8 font-size: smaller;
9}
10.show_emails table th, .show_emails table td{
11 background-color: white;
12 border: 1px black solid;
13}
14.show_emails table td{
15 vertical-align: top;
16 text-align: center;
17}
18.show_emails table .email_delete_button{
19 /*background-color: initial;*/
20 /*border: none;*/
21}
22.show_emails .action_icon{
23 width: 20px;
24} \ No newline at end of file
diff --git a/public/js/form.js b/public/js/form.js
index 4be83c6..b498b40 100644
--- a/public/js/form.js
+++ b/public/js/form.js
@@ -1,5 +1,3 @@
1//function sendMessage(){}
2
3// modif des paramètres d'e-mail: e-mail source/dest, mot de passe, serveur smtp & chiffrement tls/ssl 1// modif des paramètres d'e-mail: e-mail source/dest, mot de passe, serveur smtp & chiffrement tls/ssl
4function setEmailParam(what_param, id){ 2function setEmailParam(what_param, id){
5 const value = document.getElementById(what_param + '_' + id).value; 3 const value = document.getElementById(what_param + '_' + id).value;
@@ -28,8 +26,8 @@ function setEmailParam(what_param, id){
28 }); 26 });
29} 27}
30 28
31function checkCase(){ 29function checkCase(id){
32 if(document.getElementById('email_address').value.match('[A-Z]')){ 30 if(document.getElementById('email_address_' + id).value.match('[A-Z]')){
33 toastNotify("Votre e-mail comporte une lettre majuscule, il s'agit probablement d'une erreur."); 31 toastNotify("Votre e-mail comporte une lettre majuscule, il s'agit probablement d'une erreur.");
34 } 32 }
35} 33}
@@ -118,4 +116,60 @@ function sendVisitorEmail(id){
118 .catch(error => { 116 .catch(error => {
119 console.error('Erreur:', error); 117 console.error('Erreur:', error);
120 }); 118 });
119}
120
121function deleteEmail(id){
122 const table_row = document.getElementById(id);
123 if(!table_row){
124 return;
125 }
126
127 if(confirm('Voulez-vous supprimer cet e-mail ?')){
128 fetch('index.php?action=delete_email', {
129 method: 'POST',
130 headers: {
131 'Content-Type': 'application/json'
132 },
133 body: JSON.stringify({
134 id: id
135 })
136 })
137 .then(response => response.json())
138 .then(data => {
139 table_row.remove();
140 toastNotify("E-mail supprimé");
141 })
142 .catch(error => {
143 console.error('Erreur:', error);
144 });
145 }
146}
147
148function toggleSensitiveEmail(id){
149 const table_row = document.getElementById(id);
150 const checkbox = table_row.querySelector("input[class='make_checkbox_sensitive']");
151 const deletion_date = table_row.querySelector(".deletion_date");
152 if(!table_row || !checkbox || !deletion_date){
153 return;
154 }
155
156 fetch('index.php?action=toggle_sensitive_email', {
157 method: 'POST',
158 headers: {
159 'Content-Type': 'application/json'
160 },
161 body: JSON.stringify({
162 id: id,
163 checked: checkbox.checked
164 })
165 })
166 .then(response => response.json())
167 .then(data => {
168 checkbox.checked = data.checked;
169 deletion_date.innerHTML = data.deletion_date;
170 console.log(data.checked ? "Cet e-mail est maintenant considéré comme sensible." : "Cet e-mail n'est plus sensible.");
171 })
172 .catch(error => {
173 console.error('Erreur:', error);
174 });
121} \ No newline at end of file 175} \ No newline at end of file
diff --git a/src/EmailService.php b/src/EmailService.php
index 1bcca0f..8671817 100644
--- a/src/EmailService.php
+++ b/src/EmailService.php
@@ -65,16 +65,36 @@ class EmailService
65 65
66 // copie en BDD 66 // copie en BDD
67 if(!$test_email){ 67 if(!$test_email){
68 $db_email = new Email($email, Config::$email_dest, $message); 68 $db_email = new Email($name, $email, Config::$email_dest, $message);
69 $entityManager->persist($db_email); 69 $entityManager->persist($db_email);
70 self::updateLastContactDate($entityManager, $email);
70 $entityManager->flush(); 71 $entityManager->flush();
71 } 72 }
72 73
73 return true; 74 return true;
74 } 75 }
75 catch(Exception $e){ 76 catch(Exception $e){
76 return false; 77 echo "Le message n'a pas pu être envoyé. Erreur : {$e} <br> {$mail->ErrorInfo}";
77 //echo "Le message n'a pas pu être envoyé. Erreur : {$mail->ErrorInfo}"; 78 return false;
78 } 79 }
79 } 80 }
81
82 static public function updateLastContactDate(EntityManager $entityManager, string $sender): void
83 {
84 foreach($entityManager->getRepository('App\Entity\Email')->findAll() as $email){
85 $email->getSenderAddress() === $sender ? $email->updateLastContactDate() : null;
86 }
87 }
88
89 // peut être appelée par bin/clean_emails_cron.php
90 static public function cleanEmails(EntityManager $entityManager): void
91 {
92 $emails = $entityManager->getRepository('App\Entity\Email')->findAll();
93 foreach($emails as $email){
94 if($email->getDeletionDate() < new \DateTime()){
95 $entityManager->remove($email);
96 }
97 }
98 $entityManager->flush();
99 }
80} \ No newline at end of file 100} \ No newline at end of file
diff --git a/src/controller/ContactFormController.php b/src/controller/ContactFormController.php
index 181e93c..01faa72 100644
--- a/src/controller/ContactFormController.php
+++ b/src/controller/ContactFormController.php
@@ -80,4 +80,20 @@ class ContactFormController
80 } 80 }
81 die; 81 die;
82 } 82 }
83 static public function deleteEmail(EntityManager $entityManager, array $json): void
84 {
85 $email = $entityManager->find('App\Entity\Email', $json['id']);
86 $entityManager->remove($email);
87 $entityManager->flush();
88 echo json_encode(['success' => true]);
89 die;
90 }
91 static public function toggleSensitiveEmail(EntityManager $entityManager, array $json): void
92 {
93 $email = $entityManager->find('App\Entity\Email', $json['id']);
94 $email->makeSensitive($json['checked']);
95 $entityManager->flush();
96 echo json_encode(['success' => true, 'checked' => $json['checked'], 'deletion_date' => $email->getDeletionDate()->format('d/m/Y')]);
97 die;
98 }
83} \ No newline at end of file 99} \ No newline at end of file
diff --git a/src/controller/UserController.php b/src/controller/UserController.php
index a35b09e..f3c99e7 100644
--- a/src/controller/UserController.php
+++ b/src/controller/UserController.php
@@ -90,6 +90,8 @@ class UserController
90 $_SESSION['user'] = $_POST['login']; 90 $_SESSION['user'] = $_POST['login'];
91 $_SESSION['admin'] = true; 91 $_SESSION['admin'] = true;
92 92
93 EmailService::cleanEmails($entityManager);
94
93 $url = new URL(isset($_GET['from']) ? ['page' => $_GET['from']] : []); 95 $url = new URL(isset($_GET['from']) ? ['page' => $_GET['from']] : []);
94 isset($_GET['id']) ? $url->addParams(['id' => $_GET['id']]) : ''; 96 isset($_GET['id']) ? $url->addParams(['id' => $_GET['id']]) : '';
95 } 97 }
diff --git a/src/controller/ViewController.php b/src/controller/ViewController.php
index 9139dd4..8c95526 100644
--- a/src/controller/ViewController.php
+++ b/src/controller/ViewController.php
@@ -55,7 +55,7 @@ class ViewController extends AbstractBuilder // ViewController est aussi le prem
55 self::$root_node = $model->getNode(); 55 self::$root_node = $model->getNode();
56 56
57 57
58 /* 3/ 2ème contrôle utilisant les données récupérées */ 58 /* 3/ 2ème contrôle des paramètres avec les données récupérées */
59 59
60 // article non trouvé en BDD 60 // article non trouvé en BDD
61 if(CURRENT_PAGE === 'article' && !$_SESSION['admin'] && self::$root_node->getNodeByName('main')->getAdoptedChild() === null){ 61 if(CURRENT_PAGE === 'article' && !$_SESSION['admin'] && self::$root_node->getNodeByName('main')->getAdoptedChild() === null){
diff --git a/src/installation.php b/src/installation.php
index 3d75449..78f1768 100644
--- a/src/installation.php
+++ b/src/installation.php
@@ -100,6 +100,9 @@ function fillStartingDatabase(EntityManager $entityManager){
100 $new_page = new Page('Nouvelle page', 'new_page', "Nouvelle page", true, false, false, NULL, NULL); 100 $new_page = new Page('Nouvelle page', 'new_page', "Nouvelle page", true, false, false, NULL, NULL);
101 $new_page->addCSS('new_page'); 101 $new_page->addCSS('new_page');
102 $new_page->addJS('new_page'); 102 $new_page->addJS('new_page');
103 $emails = new Page("Courriels", 'emails', "Consulter les courriels en base de données", true, false, false, NULL, NULL);
104 $emails->addCSS('show_emails');
105 $emails->addJS('form');
103 106
104 /* -- table node -- */ 107 /* -- table node -- */
105 // paramètres: name_node, article_timestamp, attributes, position, parent, page, article 108 // paramètres: name_node, article_timestamp, attributes, position, parent, page, article
@@ -113,12 +116,14 @@ function fillStartingDatabase(EntityManager $entityManager){
113 $user_edit = new Node('user_edit', 1, $main, $my_account, NULL); 116 $user_edit = new Node('user_edit', 1, $main, $my_account, NULL);
114 $bloc_edit_menu = new Node('menu', 1, $main, $menu_paths, NULL); 117 $bloc_edit_menu = new Node('menu', 1, $main, $menu_paths, NULL);
115 $bloc_new_page = new Node('new_page', 1, $main, $new_page, NULL); 118 $bloc_new_page = new Node('new_page', 1, $main, $new_page, NULL);
119 $bloc_emails = new Node('show_emails', 1, $main, $emails, NULL);
116 120
117 /* -- table node_data -- */ 121 /* -- table node_data -- */
118 // paramètres: data, node, images 122 // paramètres: data, node, images
119 $head_data = new NodeData([], $head); 123 $head_data = new NodeData([], $head);
120 $header_data = new NodeData([], $header); 124 $header_data = new NodeData([], $header);
121 $footer_data = new NodeData([], $footer); 125 $footer_data = new NodeData([], $footer);
126 $emails_data = new NodeData([], $bloc_emails);
122 127
123 /* -- table page -- */ 128 /* -- table page -- */
124 $entityManager->persist($accueil); 129 $entityManager->persist($accueil);
@@ -127,6 +132,7 @@ function fillStartingDatabase(EntityManager $entityManager){
127 $entityManager->persist($my_account); 132 $entityManager->persist($my_account);
128 $entityManager->persist($menu_paths); 133 $entityManager->persist($menu_paths);
129 $entityManager->persist($new_page); 134 $entityManager->persist($new_page);
135 $entityManager->persist($emails);
130 136
131 /* -- table node -- */ 137 /* -- table node -- */
132 $entityManager->persist($head); 138 $entityManager->persist($head);
@@ -139,11 +145,13 @@ function fillStartingDatabase(EntityManager $entityManager){
139 $entityManager->persist($user_edit); 145 $entityManager->persist($user_edit);
140 $entityManager->persist($bloc_edit_menu); 146 $entityManager->persist($bloc_edit_menu);
141 $entityManager->persist($bloc_new_page); 147 $entityManager->persist($bloc_new_page);
148 $entityManager->persist($bloc_emails);
142 149
143 /* -- table node_data -- */ 150 /* -- table node_data -- */
144 $entityManager->persist($head_data); 151 $entityManager->persist($head_data);
145 $entityManager->persist($header_data); 152 $entityManager->persist($header_data);
146 $entityManager->persist($footer_data); 153 $entityManager->persist($footer_data);
154 $entityManager->persist($emails_data);
147 155
148 $entityManager->flush(); 156 $entityManager->flush();
149 header('Location: ' . new URL); 157 header('Location: ' . new URL);
diff --git a/src/model/Model.php b/src/model/Model.php
index b650183..de391ff 100644
--- a/src/model/Model.php
+++ b/src/model/Model.php
@@ -58,11 +58,16 @@ class Model
58 ->setParameter('page', $this->page) 58 ->setParameter('page', $this->page)
59 ->getResult(); 59 ->getResult();
60 60
61 // groupes d'articles triés par bloc, permet de paginer par bloc
62 foreach($bulk_data as $parent_block){ 61 foreach($bulk_data as $parent_block){
62 // groupes d'articles triés par bloc, permet de paginer par bloc
63 if(Blocks::hasPresentation($parent_block->getName())){ // = post_block ou news_block 63 if(Blocks::hasPresentation($parent_block->getName())){ // = post_block ou news_block
64 $bulk_data = array_merge($bulk_data, $this->getNextArticles($parent_block, $request)[0]); 64 $bulk_data = array_merge($bulk_data, $this->getNextArticles($parent_block, $request)[0]);
65 } 65 }
66
67 // emails
68 if($parent_block->getName() === 'show_emails'){
69 $parent_block->getNodeData()->setEmails($this->getAllEmails());
70 }
66 } 71 }
67 } 72 }
68 else{ // page "article" 73 else{ // page "article"
@@ -283,4 +288,14 @@ class Model
283 $this->node->addChild($child); 288 $this->node->addChild($child);
284 } 289 }
285 } 290 }
291
292 private function getAllEmails(): array
293 {
294 $dql = 'SELECT e FROM App\Entity\Email e';
295 return $this->entityManager
296 ->createQuery($dql)
297 //->setParameter('page', $this->page)
298 ->getResult();
299 }
300 //private function getEmails(string $sender): array
286} 301}
diff --git a/src/model/entities/Email.php b/src/model/entities/Email.php
index 9d87f1f..c66625f 100644
--- a/src/model/entities/Email.php
+++ b/src/model/entities/Email.php
@@ -11,13 +11,20 @@ use Doctrine\ORM\Mapping as ORM;
11#[ORM\Table(name: TABLE_PREFIX . "email")] 11#[ORM\Table(name: TABLE_PREFIX . "email")]
12class Email 12class Email
13{ 13{
14 // en mois
15 const LEGAL_RETENTION_PERIOD = 36; // 3 ans, justification = prospection, durée "glissante", date de suppression remise à jour à chaque nouvel e-mail
16 const LEGAL_RETENTION_PERIOD_SENSITIVE = 60; // 5 ans pour données sensibles ou litige, durée de preuve légale, durée non glissante
17
14 #[ORM\Id] 18 #[ORM\Id]
15 #[ORM\GeneratedValue] 19 #[ORM\GeneratedValue]
16 #[ORM\Column(type: "integer")] 20 #[ORM\Column(type: "integer")]
17 private int $id_log; 21 private int $id_email;
22
23 #[ORM\Column(type: "string", length: 255)]
24 private string $sender_name;
18 25
19 #[ORM\Column(type: "string", length: 320)] 26 #[ORM\Column(type: "string", length: 320)]
20 private string $sender; 27 private string $sender_address;
21 28
22 #[ORM\Column(type: "string", length: 320)] 29 #[ORM\Column(type: "string", length: 320)]
23 private string $recipient; 30 private string $recipient;
@@ -30,12 +37,81 @@ class Email
30 private string $content; 37 private string $content;
31 38
32 #[ORM\Column(type: 'datetime', options: ['default' => 'CURRENT_TIMESTAMP'])] 39 #[ORM\Column(type: 'datetime', options: ['default' => 'CURRENT_TIMESTAMP'])]
33 private ?\DateTime $date_time ; 40 private \DateTime $date_time;
41
42 #[ORM\Column(type: 'boolean')]
43 private bool $is_sensitive; // "sensitive" tout court est un mot réservé
44
45 #[ORM\Column(type: 'datetime', options: ['default' => 'CURRENT_TIMESTAMP'])]
46 private \DateTime $last_contact_date;
47
48 #[ORM\Column(type: 'datetime', nullable: true)]
49 private ?\DateTime $is_sensitive_since;
34 50
35 public function __construct(string $sender, string $recipient, string $content){ 51 public function __construct(string $sender_name, string $sender_address, string $recipient, string $content, bool $sensitive = false){
36 $this->sender = strtolower($sender); 52 $this->sender_name = strtolower($sender_name);
53 $this->sender_address = strtolower($sender_address);
37 $this->recipient = strtolower($recipient); 54 $this->recipient = strtolower($recipient);
38 $this->content = $content; 55 $this->content = $content;
39 $this->date_time = new \DateTime(); 56 $this->date_time = new \DateTime;
57 $this->last_contact_date = new \DateTime;
58 $this->makeSensitive($sensitive);
59 }
60
61 public function getId(): int
62 {
63 return $this->id_email;
64 }
65 public function getSenderName(): string
66 {
67 return $this->sender_name;
68 }
69 public function getSenderAddress(): string
70 {
71 return $this->sender_address;
72 }
73 public function getRecipient(): string
74 {
75 return $this->recipient;
76 }
77 public function getContent(): string
78 {
79 return $this->content;
80 }
81 public function getDateTime(): \DateTime
82 {
83 return $this->date_time;
84 }
85 /*public function getLastContactDate(): \DateTime
86 {
87 return $this->last_contact_date;
88 }*/
89 public function isSensitive(): bool
90 {
91 return $this->is_sensitive;
92 }
93 public function isSensitiveSince(): ?\DateTime
94 {
95 return $this->is_sensitive_since;
96 }
97
98 public function makeSensitive(bool $sensitive = true): void
99 {
100 $this->is_sensitive = $sensitive;
101 if($sensitive && $this->is_sensitive_since === null){
102 $this->is_sensitive_since = new \DateTime();
103 }
104 }
105
106 public function updateLastContactDate(): void
107 {
108 $this->last_contact_date = new \DateTime;
109 }
110
111 public function getDeletionDate(): \DateTime
112 {
113 return $this->is_sensitive // oui durée 5 ans, non durée 3 ans "glissante"
114 ? (clone $this->is_sensitive_since)->modify('+ ' . (string)self::LEGAL_RETENTION_PERIOD_SENSITIVE . ' month') // erreur si vrai mais sans date (pas censé arriver)
115 : (clone $this->last_contact_date)->modify('+ ' . (string)self::LEGAL_RETENTION_PERIOD . ' month');
40 } 116 }
41} 117} \ No newline at end of file
diff --git a/src/model/entities/Node.php b/src/model/entities/Node.php
index fe3a1e5..71c159d 100644
--- a/src/model/entities/Node.php
+++ b/src/model/entities/Node.php
@@ -72,42 +72,7 @@ class Node
72 { 72 {
73 $this->name_node = $name; 73 $this->name_node = $name;
74 }*/ 74 }*/
75 75
76 /*public function getAttributes(): array
77 {
78 return $this->attributes;
79 }
80 public function setDefaultAttributes(array $attributes): void
81 {
82 $this->attributes = $attributes;
83 }
84 public function useDefaultAttributes(): void
85 {
86 $this->attributes = self::$default_attributes;
87 }
88 public function addAttribute(string $key, string $value): void
89 {
90 if(!isset($this->attributes[$key])) { // sécurité $key inexistante
91 $this->attributes[$key] = [];
92 }
93 if(!in_array($value, $this->attributes[$key])){
94 $this->attributes[$key][] = $value;
95 }
96 }*/
97 /*public function removeAttribute(string $key, string $value): void
98 {
99 if(isset($this->attributes[$key])) // sécurité $key inexistante
100 {
101 // supprime et réindex avec un nouveau tableau
102 $tmp_array = $this->attributes[$key];
103 $this->attributes[$key] = [];
104 foreach($tmp_array as $entry){
105 if($entry !== $value){
106 $this->attributes[$key][] = $entry;
107 }
108 }
109 }
110 }*/
111 public function getParent(): ?self 76 public function getParent(): ?self
112 { 77 {
113 return $this->parent; 78 return $this->parent;
diff --git a/src/model/entities/NodeData.php b/src/model/entities/NodeData.php
index b25b540..19670fe 100644
--- a/src/model/entities/NodeData.php
+++ b/src/model/entities/NodeData.php
@@ -45,6 +45,7 @@ class NodeData
45 private Collection $nda_collection; 45 private Collection $nda_collection;
46 46
47 private int $nb_pages = 1; 47 private int $nb_pages = 1;
48 private array $emails = []; // noeud show_emails uniquement
48 49
49 public function __construct(array $data, Node $node, Collection $nda_collection = new ArrayCollection, ?string $presentation = null, ?bool $chrono_order = null) 50 public function __construct(array $data, Node $node, Collection $nda_collection = new ArrayCollection, ?string $presentation = null, ?bool $chrono_order = null)
50 { 51 {
@@ -179,4 +180,13 @@ class NodeData
179 $this->new_nda = new NodeDataAsset($this, $asset, $role); 180 $this->new_nda = new NodeDataAsset($this, $asset, $role);
180 $this->addNodeDataAsset($this->new_nda); 181 $this->addNodeDataAsset($this->new_nda);
181 }*/ 182 }*/
183
184 public function getEmails(): array
185 {
186 return $this->emails;
187 }
188 public function setEmails(array $emails): void
189 {
190 $this->emails = $emails;
191 }
182} \ No newline at end of file 192} \ No newline at end of file
diff --git a/src/model/entities/NodeDataAsset.php b/src/model/entities/NodeDataAsset.php
index 7f92fd1..d5eb141 100644
--- a/src/model/entities/NodeDataAsset.php
+++ b/src/model/entities/NodeDataAsset.php
@@ -15,7 +15,6 @@ use Doctrine\ORM\Mapping as ORM;
15class NodeDataAsset 15class NodeDataAsset
16{ 16{
17 // clé primaire double 17 // clé primaire double
18 // inconvénient: impossible d'utiliser deux fois la même paire node_data/asset, même pour des rôles différents
19 #[ORM\Id] 18 #[ORM\Id]
20 #[ORM\ManyToOne(targetEntity: NodeData::class, inversedBy: 'nda_collection')] 19 #[ORM\ManyToOne(targetEntity: NodeData::class, inversedBy: 'nda_collection')]
21 #[ORM\JoinColumn(name: 'node_data_id', referencedColumnName: 'id_node_data', onDelete: 'CASCADE')] 20 #[ORM\JoinColumn(name: 'node_data_id', referencedColumnName: 'id_node_data', onDelete: 'CASCADE')]
diff --git a/src/router.php b/src/router.php
index 15d5a4c..d2eba18 100644
--- a/src/router.php
+++ b/src/router.php
@@ -38,6 +38,12 @@ if($request->getMethod() === 'GET'){
38 CalendarController::getData($entityManager); 38 CalendarController::getData($entityManager);
39 } 39 }
40 40
41 // pages interdites
42 if(!$_SESSION['admin'] && in_array(CURRENT_PAGE, ['menu_paths', 'new_page', 'user_edit', 'emails'])){
43 header('Location: ' . new URL);
44 die;
45 }
46
41 if($_SESSION['admin'] === true){ 47 if($_SESSION['admin'] === true){
42 // ... 48 // ...
43 } 49 }
@@ -113,6 +119,13 @@ elseif($request->getMethod() === 'POST'){
113 ContactFormController::sendTestEmail($entityManager, $json); 119 ContactFormController::sendTestEmail($entityManager, $json);
114 } 120 }
115 121
122 /* -- page emails -- */
123 elseif($_GET['action'] === 'delete_email'){
124 ContactFormController::deleteEmail($entityManager, $json);
125 }
126 elseif($_GET['action'] === 'toggle_sensitive_email'){
127 ContactFormController::toggleSensitiveEmail($entityManager, $json);
128 }
116 129
117 /* -- upload d'image dans tinymce par copier-coller -- */ 130 /* -- upload d'image dans tinymce par copier-coller -- */
118 // collage de HTML contenant une ou plusieurs balises <img> 131 // collage de HTML contenant une ou plusieurs balises <img>
diff --git a/src/view/ShowEmailsBuilder.php b/src/view/ShowEmailsBuilder.php
new file mode 100644
index 0000000..3d2d6a9
--- /dev/null
+++ b/src/view/ShowEmailsBuilder.php
@@ -0,0 +1,69 @@
1<?php
2// src/view/ShowEmailsBuilder.php
3
4declare(strict_types=1);
5
6use App\Entity\Node;
7use App\Entity\Page;
8
9class ShowEmailsBuilder extends AbstractBuilder
10{
11 public function __construct(Node $node = null)
12 {
13 //parent::__construct($node);
14 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
15 if(file_exists($viewFile))
16 {
17 // objets Email groupés par destinataire
18 $emails_by_recipient = [];
19 foreach($node->getNodeData()->getEmails() as $email){
20 $recipient = $email->getRecipient();
21 $emails_by_recipient[$recipient][] = $email;
22 }
23
24 // affiche une table par destinataire
25 $emails = '';
26 foreach($emails_by_recipient as $recipient => $emails_list){
27 $html = '<h4>Destinataire: ' . $recipient . '</h4>
28 <table>
29 <thead>
30 <tr>
31 <th>Expéditeur</th>
32 <th>Adresse</th>
33 <th>Contenu</th>
34 <th>Date</th>
35 <th>Effacement prévu le</th>
36 <th>Sensible</th>
37 <th class="email_delete_button"></th>
38 </tr>
39 </thead>
40 <tbody>';
41
42 // insère les données
43 foreach($emails_list as $email){
44 $html .= '<tr id="' . $email->getId() . '">
45 <td>' . htmlspecialchars($email->getSenderName()) . '</td>
46 <td>' . htmlspecialchars($email->getSenderAddress()) . '</td>
47 <td>' . htmlspecialchars($email->getContent()) . '</td>
48 <td>' . $email->getDateTime()->format('d/m/Y') . '</td>
49 <td class="deletion_date">' . $email->getDeletionDate()->format('d/m/Y') . '</td>
50 <td><input class="make_checkbox_sensitive" type="checkbox" ' . ($email->isSensitive() ? 'checked' : '') . ' onclick="toggleSensitiveEmail(' . $email->getId() . ')"></td>
51 <td class="email_delete_button"><img class="action_icon" src="assets/delete-bin.svg" onclick="deleteEmail(' . $email->getId() . ')"></td>
52 </tr>';
53 }
54
55 $html .= '</tbody>
56 </table>';
57 $emails .= $html;
58 }
59
60 ob_start();
61 require $viewFile; // insertion de $this->html généré par unfoldMenu
62 $this->html = ob_get_clean(); // pas de concaténation .= cette fois on écrase
63 }
64 else{
65 header('Location: ' . new URL(['error' => 'show_emails_view_not_found']));
66 die;
67 }
68 }
69} \ No newline at end of file
diff --git a/src/view/templates/form.php b/src/view/templates/form.php
index 5c959a0..df1dd0f 100644
--- a/src/view/templates/form.php
+++ b/src/view/templates/form.php
@@ -7,7 +7,7 @@
7 <input id="email_name_<?= $node->getNodeData()->getId() ?>" type="text" name="email_name" value=""> 7 <input id="email_name_<?= $node->getNodeData()->getId() ?>" type="text" name="email_name" value="">
8 8
9 <label for="email_address">Votre e-mail</label> 9 <label for="email_address">Votre e-mail</label>
10 <input id="email_address_<?= $node->getNodeData()->getId() ?>" type="email" name="email_address" placeholder="mon-adresse@email.fr" value="" onchange="checkCase()"> 10 <input id="email_address_<?= $node->getNodeData()->getId() ?>" type="email" name="email_address" placeholder="mon-adresse@email.fr" value="" onchange="checkCase(<?= $node->getNodeData()->getId() ?>)">
11 11
12 <label for="email_message">Votre message</label> 12 <label for="email_message">Votre message</label>
13 <textarea id="email_message_<?= $node->getNodeData()->getId() ?>" type="text" name="email_message" rows="4"></textarea> 13 <textarea id="email_message_<?= $node->getNodeData()->getId() ?>" type="text" name="email_message" rows="4"></textarea>
@@ -30,4 +30,8 @@
30 30
31 <p class="send_email_success_<?= $node->getNodeData()->getId() ?> full_width_column"></p> 31 <p class="send_email_success_<?= $node->getNodeData()->getId() ?> full_width_column"></p>
32 </div> 32 </div>
33 <p class="form_gdpr"><i>
34 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.<br>
35 Ce traitement repose sur votre consentement. Vous pouvez consulter, modifier ou supprimer vos données en base de données sur simple demande.
36 </i></p>
33</section> \ No newline at end of file 37</section> \ No newline at end of file
diff --git a/src/view/templates/form_admin.php b/src/view/templates/form_admin.php
index 3559d25..cabfeb0 100644
--- a/src/view/templates/form_admin.php
+++ b/src/view/templates/form_admin.php
@@ -4,6 +4,9 @@ declare(strict_types=1);
4// note: l'id ici n'est pas celui du noeud bloc mais celui de l'entrée dans node_data correspondante 4// note: l'id ici n'est pas celui du noeud bloc mais celui de l'entrée dans node_data correspondante
5?> 5?>
6<div class="admin_form"> 6<div class="admin_form">
7 <a href="<?= new URL(['page' => 'emails']) ?>"><button>Consulter tous les e-mails</button></a>
8</div>
9<div class="admin_form">
7 <h3>Paramètres d'envoi</h3> 10 <h3>Paramètres d'envoi</h3>
8 <p> 11 <p>
9 <label for="smtp_host_<?= $node->getNodeData()->getId() ?>">Adresse serveur SMTP</label> 12 <label for="smtp_host_<?= $node->getNodeData()->getId() ?>">Adresse serveur SMTP</label>
diff --git a/src/view/templates/show_emails.php b/src/view/templates/show_emails.php
new file mode 100644
index 0000000..9954c6f
--- /dev/null
+++ b/src/view/templates/show_emails.php
@@ -0,0 +1,27 @@
1<?php declare(strict_types=1); ?>
2<section class="show_emails">
3 <h3>Table "<?= TABLE_PREFIX ?>email" de la base de données</h3>
4 <p><i>
5 Les e-mails ci-dessous sont des copies de ceux arrivés dans votre boite de messagerie. Ils sont conservés dans un but pratique et éventuellement dans un but de prospection, ou dans tout autre but permettant de justifier leur conservation.<br>
6 Ils sont "effacés" automatiquement au bout d'un certain temps comme le requièrt le RGPD. Un nettoyeur est exécuté à chaque connexion au mode admin ou éventuellement à l'aide d'une tâche CRON (le serveur doit pour ça être configuré pour exécuter periodiquement la commande "php /chemin/du/site/bin/cron.php").
7 </i></p>
8 <h4>Durées de conservation</h4>
9 <p><i>
10 Ce sont des durées maximales, les données peuvent être supprimées plus tôt ou même immédiatement. Le faire est d'ailleurs une obligation dans le cas où leur expéditeur le demande.<br>
11 Théoriquement, ce même nettoyage des vieux messages devrait être également réalisé par vous-même dans votre boite de messagerie.
12 </i></p>
13 <p><i>
14 Les e-mails ordinaires d'un même expéditeur (même adresse e-mail) sont tous supprimés simultanément lorsque le plus récent d'entre eux atteint les 3 ans (utilisateur "inactif").<br>
15 Les e-mails sensibles quand à eux sont supprimés 5 ans après être devenus sensibles (durée juridique d'une preuve).
16 </i></p>
17 <h4>Données sensibles</h4>
18 <p><i>
19 Un e-mail peut-être considéré comme "sensible". Vous pouvez rendre un e-mail sensible lorsqu'il possède une valeur de preuve dans le cas d'un litige.<br>
20 Lorsqu'une personne demande la suppression de ses données personnelles du serveur, les e-mails sensibles peuvent être conservés, vous aurez noté que la durée de conservation est calculée différement.
21 </i></p>
22 <p><i>
23 Les spams ne sont pas sensibles, c'est juste de la pollution, supprimez-les!
24 </i></p>
25
26 <?= $emails ?>
27</section> \ No newline at end of file