summaryrefslogtreecommitdiff
path: root/src/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/view')
-rw-r--r--src/view/AbstractBuilder.php52
-rw-r--r--src/view/ArticleBuilder.php60
-rw-r--r--src/view/BlogBuilder.php49
-rw-r--r--src/view/BreadcrumbBuilder.php53
-rw-r--r--src/view/FooterBuilder.php64
-rw-r--r--src/view/GaleryBuilder.php49
-rw-r--r--src/view/GridBuilder.php55
-rw-r--r--src/view/HeadBuilder.php68
-rw-r--r--src/view/HeaderBuilder.php64
-rw-r--r--src/view/LoginBuilder.php15
-rw-r--r--src/view/MainBuilder.php30
-rw-r--r--src/view/NavBuilder.php61
-rw-r--r--src/view/NewBuilder.php93
-rw-r--r--src/view/ViewBuilder.php16
-rw-r--r--src/view/password.php152
-rw-r--r--src/view/templates/article.php15
-rw-r--r--src/view/templates/blog.php6
-rw-r--r--src/view/templates/footer.php15
-rw-r--r--src/view/templates/galery.php10
-rw-r--r--src/view/templates/grid.php8
-rw-r--r--src/view/templates/head.php11
-rw-r--r--src/view/templates/header.php23
-rw-r--r--src/view/templates/new.php21
23 files changed, 990 insertions, 0 deletions
diff --git a/src/view/AbstractBuilder.php b/src/view/AbstractBuilder.php
new file mode 100644
index 0000000..cd2b361
--- /dev/null
+++ b/src/view/AbstractBuilder.php
@@ -0,0 +1,52 @@
1<?php
2// src/view/AbstractBuilder.php
3
4use App\Entity\Node;
5
6abstract class AbstractBuilder
7{
8 protected const VIEWS_PATH = '../src/view/templates/';
9 protected string $html = '';
10
11 protected function useChildrenBuilder(Node $node): void
12 {
13 foreach($node->getChildren() as $child_node)
14 {
15 $builder_name = $this->snakeToPascalCase($child_node->getName()) . 'Builder';
16 $builder = new $builder_name($child_node);
17 $this->html .= $builder->render();
18
19 // pages spéciales où on n'assemble pas tout
20 if($builder_name === 'HeadBuilder' && $builder->getStop())
21 {
22 foreach($node->getChildren() as $target_node){
23 if($target_node->getName() === 'main'){
24 $main_node = $target_node;
25 break;
26 }
27 }
28 // on construit <main> et on s'arrête! les autres noeuds sont ignorés
29 $builder_name = $this->snakeToPascalCase($main_node->getName()) . 'Builder';
30 $builder = new $builder_name($main_node);
31 $this->html .= "<body>\n";
32 $this->html .= $builder->render() . "\n";
33 $this->html .= "</body>\n</html>";
34 break;
35 }
36 }
37 }
38
39 protected function snakeToPascalCase(string $input): string
40 {
41 return str_replace('_', '', ucwords($input, '_'));
42 }
43
44 public function render(): string // = getHTML()
45 {
46 return $this->html;
47 }
48 public function addHTML(string $html): void
49 {
50 $this->html .= $html;
51 }
52} \ No newline at end of file
diff --git a/src/view/ArticleBuilder.php b/src/view/ArticleBuilder.php
new file mode 100644
index 0000000..989da0d
--- /dev/null
+++ b/src/view/ArticleBuilder.php
@@ -0,0 +1,60 @@
1<?php
2// src/view/ArticleBuilder.php
3
4use App\Entity\Node;
5
6class ArticleBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11
12 if(file_exists($viewFile))
13 {
14 // id (timestamp)
15 if(!empty($node->getAttributes()))
16 {
17 extract($node->getAttributes());
18 }
19
20 // html
21 $title = $node->getArticle()->getTitle();
22 $html = $node->getArticle()->getContent();
23 $id = $node->getArticleTimestamp();
24
25 // partage
26 $share_link = new URL(['page' => CURRENT_PAGE], $id);
27 $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"';
28 $share_button = '<p><a href="' . $share_link . '" ' . $share_js . '><img class="action_icon" src="assets/share.svg"></a></p>' . "\n";
29
30 // modifier un article
31 $admin_buttons = '';
32 if($_SESSION['admin'])
33 {
34 $modify_js = 'onclick="openEditor(\'' . $id . '\')"';
35 $modify_article = '<p id="edit-' . $id . '"><a href="#"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></a></p>' . "\n";
36
37 $up_link = new URL(['page' => CURRENT_PAGE, 'id' => $id, 'action' => 'position_up']);
38 $up_button = '<p id="position_up-' . $id . '"><a href="' . $up_link . '"><img class="action_icon" src="assets/arrow-up.svg"></a></p>' . "\n";
39
40 $down_link = new URL(['page' => CURRENT_PAGE, 'id' => $id, 'action' => 'position_down']);
41 $down_button = '<p id="position_down-' . $id . '"><a href="' . $down_link . '"><img class="action_icon" src="assets/arrow-down.svg"></a></p>' . "\n";
42
43 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
44 $delete_article = '<p id="delete-' . $id . '"><a href="#"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></a></p>' . "\n";
45
46 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
47 $close_editor = '<p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>';
48
49 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"';
50 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p>';
51
52 $admin_buttons = $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article;
53 }
54
55 ob_start();
56 require($viewFile);
57 $this->html .= ob_get_clean();
58 }
59 }
60}
diff --git a/src/view/BlogBuilder.php b/src/view/BlogBuilder.php
new file mode 100644
index 0000000..8c2125f
--- /dev/null
+++ b/src/view/BlogBuilder.php
@@ -0,0 +1,49 @@
1<?php
2// src/view/BlogBuilder.php
3
4use App\Entity\Node;
5
6class BlogBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11
12 if(file_exists($viewFile))
13 {
14 if(!empty($node->getNodeData()->getData()))
15 {
16 extract($node->getNodeData()->getData());
17 }
18
19 // ajouter un article
20 $new_article = '';
21 $new_article_admin_buttons = '';
22 if($_SESSION['admin'])
23 {
24 $id = 'new';
25
26 //$link = new URL(['page' => CURRENT_PAGE, 'action' => 'open_editor']);
27 $js = 'onclick="openEditor(\'' . $id . '\')"';
28 //$new_article = '<article><a href="' . $link . '"><button>Nouvel article</button></a></article>';
29 $new_article = '<article><p id="new"></p>' . "\n" .
30 '<p id="new-' . $id . '"><a href="#"><button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>';
31
32 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
33 $close_editor = '<div class="article_admin_zone"><p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>';
34
35 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"';
36 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p></div></article>';
37
38 $new_article_admin_buttons = $close_editor . $submit_article;
39 }
40
41 $this->useChildrenBuilder($node);
42 $content = $this->html;
43
44 ob_start();
45 require $viewFile;
46 $this->html = ob_get_clean(); // pas de concaténation ici, on écrase
47 }
48 }
49} \ No newline at end of file
diff --git a/src/view/BreadcrumbBuilder.php b/src/view/BreadcrumbBuilder.php
new file mode 100644
index 0000000..f1fdddf
--- /dev/null
+++ b/src/view/BreadcrumbBuilder.php
@@ -0,0 +1,53 @@
1<?php
2// src/view/BreadcrumbBuilder.php
3
4use App\Entity\Node;
5
6class BreadcrumbBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $this->html = $this->breadcrumbHTML(false);
11 }
12
13 private function breadcrumbHTML(bool $links = false): string
14 {
15 $asset = 'assets/home.svg'; // => BDD?
16 $breadcrumb_array = Director::$page_path->getArray(); // tableau de Page
17 $html = '';
18 $nb_of_entries = count($breadcrumb_array);
19
20 if($nb_of_entries > 1)
21 {
22 // petite maison et flèche
23 $html .= '<nav class="breadcrumb" aria-label="Breadcrumb">' . "\n";
24 $html .= '<a href="' . new URL . '"><img src="' . $asset . '"></a><span class="arrow"> →</span>' . "\n";
25
26 // partie intermédiaire
27 for($i = 0; $i < ($nb_of_entries - 1); $i++)
28 {
29 // liens optionnels
30 if($links)
31 {
32 $html .= '<a href="';
33 for($j = 1; $j < $i; $j++) // chemin sans la fin
34 {
35 $html .= new URL(['page' => $breadcrumb_array[$i]->getPagePath()]);
36 }
37 $html .= '">';
38 }
39 $html .= '<span>' . $breadcrumb_array[$i]->getPageName() . '</span>';
40 if($links)
41 {
42 $html .= '</a>';
43 }
44 $html .= '<span class="arrow"> →</span>' . "\n";
45 }
46
47 // fin du chemin
48 $html .= '<span aria-current="page">' . $breadcrumb_array[$nb_of_entries - 1]->getPageName() . "</span>\n";
49 $html .= "</nav>\n";
50 }
51 return $html;
52 }
53} \ No newline at end of file
diff --git a/src/view/FooterBuilder.php b/src/view/FooterBuilder.php
new file mode 100644
index 0000000..49da71c
--- /dev/null
+++ b/src/view/FooterBuilder.php
@@ -0,0 +1,64 @@
1<?php
2// src/view/FooterBuilder.php
3
4use App\Entity\Node;
5
6class FooterBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11
12 if(file_exists($viewFile))
13 {
14 // $adresses postale et e-mail
15 if(!empty($node->getNodeData()->getData()))
16 {
17 extract($node->getNodeData()->getData());
18 }
19
20 $this->useChildrenBuilder($node);
21 $breadcrumb = $this->html;
22
23 // zone admin
24 $empty_admin_zone = '';
25 //$zone_admin = '';
26 if($_SESSION['admin'])
27 {
28 $div_admin = 'logged_in';
29 $empty_admin_zone = 'empty_admin_zone';
30 $link_edit_page = new URL(['page' => CURRENT_PAGE, 'action' => 'modif_page']);
31 $link_new_page = new URL(['from' => CURRENT_PAGE, 'page' => 'nouvelle_page']);
32 $link_change_paths = new URL(['from' => CURRENT_PAGE, 'page' => 'menu_chemins']);
33
34 $link_change_password = new URL(['from' => CURRENT_PAGE, 'action' => 'modif_mdp']);
35 isset($_GET['id']) ? $link_change_password->addParams(['id' => $_GET['id']]) : '';
36
37 $link_logout = new URL(['page' => CURRENT_PAGE, 'action' => 'deconnexion']);
38 isset($_GET['id']) ? $link_logout->addParams(['id' => $_GET['id']]) : '';
39
40 $zone_admin = '<p>Vous êtes en mode administrateur.' . "\n" .
41 '<a href="' . $link_edit_page . '"><button>Modifier la page</button></a>' . "\n" .
42 '<a href="' . $link_new_page . '"><button>Nouvelle page</button></a>' . "\n" .
43 '<a href="' . $link_change_paths . '"><button>Menu et chemins</button></a>' . "\n" .
44 '<a href="' . $link_change_password . '"><button>Changer de mot de passe</button></a>' . "\n" .
45 '<a href="' . $link_logout . '"><button>Déconnexion</button></a></p>' . "\n";
46 }
47 else
48 {
49 $div_admin = 'logged_out';
50 $zone_admin = '';
51 if(Director::$page_path->getLast()->getEndOfPath() === 'article' && isset($_GET['id'])){
52 $zone_admin = '<button><a href="' . new URL(['page' => 'connexion', 'from' => CURRENT_PAGE, 'id' => $_GET['id']]) . '">Mode admin</a></button>';
53 }
54 else{
55 $zone_admin = '<button><a href="' . new URL(['page' => 'connexion', 'from' => CURRENT_PAGE]) . '">Mode admin</a></button>';
56 }
57 }
58
59 ob_start();
60 require $viewFile;
61 $this->html = ob_get_clean();
62 }
63 }
64} \ No newline at end of file
diff --git a/src/view/GaleryBuilder.php b/src/view/GaleryBuilder.php
new file mode 100644
index 0000000..89be2b1
--- /dev/null
+++ b/src/view/GaleryBuilder.php
@@ -0,0 +1,49 @@
1<?php
2// src/view/GaleryBuilder.php
3
4use App\Entity\Node;
5
6class GaleryBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11
12 if(file_exists($viewFile))
13 {
14 if(!empty($node->getNodeData()->getData()))
15 {
16 extract($node->getNodeData()->getData());
17 }
18
19 // ajouter un article
20 $new_article = '';
21 $new_article_admin_buttons = '';
22 if($_SESSION['admin'])
23 {
24 $id = 'new';
25
26 //$link = new URL(['page' => CURRENT_PAGE, 'action' => 'open_editor']);
27 $js = 'onclick="openEditor(\'' . $id . '\')"';
28 //$new_article = '<article><a href="' . $link . '"><button>Nouvel article</button></a></article>';
29 $new_article = '<article><p id="new"></p>' . "\n" .
30 '<p id="new-' . $id . '"><a href="#"><button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>';
31
32 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
33 $close_editor = '<div class="article_admin_zone"><p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>';
34
35 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"';
36 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p></div></article>';
37
38 $new_article_admin_buttons = $close_editor . $submit_article;
39 }
40
41 $this->useChildrenBuilder($node);
42 $content = $this->html;
43
44 ob_start();
45 require $viewFile;
46 $this->html = ob_get_clean(); // pas de concaténation ici, on écrase
47 }
48 }
49} \ No newline at end of file
diff --git a/src/view/GridBuilder.php b/src/view/GridBuilder.php
new file mode 100644
index 0000000..6e16d46
--- /dev/null
+++ b/src/view/GridBuilder.php
@@ -0,0 +1,55 @@
1<?php
2// src/view/GridBuilder.php
3
4use App\Entity\Node;
5
6class GridBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11
12 if(file_exists($viewFile))
13 {
14 if(!empty($node->getNodeData()->getData()))
15 {
16 extract($node->getNodeData()->getData());
17 }
18
19 // ajouter un article
20 $new_article = '';
21 $new_article_admin_buttons = '';
22 if($_SESSION['admin'])
23 {
24 $id = 'new';
25 $js = 'onclick="openEditor(\'' . $id . '\')"';
26
27 if(Director::$page_path->getLast()->getEndOfPath() === 'accueil')
28 {
29 $new_article = '<article><p id="new"></p>' . "\n" .
30 '<p><a href="' . new URL(['page' => 'article']) . '"><button><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>';
31 }
32 else
33 {
34 $new_article = '<article><p id="new"></p>' . "\n" .
35 '<p id="new-' . $id . '"><a href="#"><button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>';
36 }
37
38 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
39 $close_editor = '<div class="article_admin_zone"><p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>';
40
41 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"';
42 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p></div></article>';
43
44 $new_article_admin_buttons = $close_editor . $submit_article;
45 }
46
47 $this->useChildrenBuilder($node);
48 $content = $this->html;
49
50 ob_start();
51 require $viewFile;
52 $this->html = ob_get_clean(); // pas de concaténation ici, on écrase
53 }
54 }
55} \ No newline at end of file
diff --git a/src/view/HeadBuilder.php b/src/view/HeadBuilder.php
new file mode 100644
index 0000000..c31c930
--- /dev/null
+++ b/src/view/HeadBuilder.php
@@ -0,0 +1,68 @@
1<?php
2// src/view/HeadBuilder.php
3
4use App\Entity\Node;
5
6class HeadBuilder extends AbstractBuilder
7{
8 private bool $stop = false;
9
10 public function __construct(Node $node)
11 {
12 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
13
14 if(file_exists($viewFile))
15 {
16 // css et js
17 if(!empty($node->getAttributes()))
18 {
19 extract($node->getAttributes());
20 }
21
22 // pages spéciales où on n'assemble pas tout
23 $this->stop = isset($stop) ? $stop : false;
24 $css = '';
25 foreach($css_array as $name)
26 {
27 $css .= '<link rel="stylesheet" href="css/' . $name . '.css">' . "\n";
28 }
29 $js = '';
30 foreach($js_array as $name)
31 {
32 $js .= '<script src="js/' . $name . '.js"></script>' . "\n";
33 }
34
35 // tinymce, nécéssite un script de copie dans composer.json
36 if($_SESSION['admin']){
37 $css .= '<link rel="stylesheet" href="css/tinymce.css">' . "\n";
38 $js .= '<script src="js/tinymce/tinymce.min.js"></script>' . "\n";
39 $js .= '<script src="js/tinymce.js"></script>' . "\n";
40 }
41
42 // titre et description
43 if(!empty($node->getNodeData()->getData()))
44 {
45 extract($node->getNodeData()->getData());
46 }
47
48 // favicon
49 foreach($node->getNodeData()->getImages() as $image)
50 {
51 if(str_contains($image->getFileName(), 'favicon'))
52 {
53 $favicon = rtrim($image->getFilePathMini(), '/');
54 $alt = $image->getAlt();
55 }
56 }
57
58 ob_start();
59 require $viewFile;
60 $this->html .= ob_get_clean();
61 }
62 }
63
64 public function getStop(): bool
65 {
66 return $this->stop;
67 }
68}
diff --git a/src/view/HeaderBuilder.php b/src/view/HeaderBuilder.php
new file mode 100644
index 0000000..252958a
--- /dev/null
+++ b/src/view/HeaderBuilder.php
@@ -0,0 +1,64 @@
1<?php
2// src/view/HeaderBuilder.php
3
4use App\Entity\Node;
5
6class HeaderBuilder extends AbstractBuilder
7{
8 private ?Node $nav = null;
9
10 public function __construct(Node $node)
11 {
12 // nav
13 // n'utilise pas useChildrenBuilder, il faudrait peut-être
14 $children = $node->getChildren();
15 foreach($children as $child)
16 {
17 if($child->getName() === 'nav')
18 {
19 $this->nav = $child;
20 $nav_builder = new NavBuilder($this->nav);
21 $nav = $nav_builder->render();
22 }
23 }
24
25 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
26
27 if(file_exists($viewFile))
28 {
29 // titre et description
30 if(!empty($node->getNodeData()->getData()))
31 {
32 extract($node->getNodeData()->getData());
33 }
34
35 // attributs, aucun pour l'instant
36 if(!empty($node->getAttributes()))
37 {
38 extract($node->getAttributes());
39 }
40
41 // header logo + réseaux sociaux
42 $targets = ['logo', 'facebook', 'instagram', 'fond_piscine'];
43 $i = 0;
44 foreach($node->getNodeData()->getImages() as $image)
45 {
46 if(str_contains($image->getFileName(), $targets[$i]))
47 {
48 $var = $targets[$i];
49 $$var = rtrim($image->getFilePathMini(), '/');
50 $var .= '_alt'; // ex: logo_alt
51 $$var = $image->getAlt();
52 }
53 $i++;
54 }
55
56 // générer HTML réseaux sociaux
57 //
58
59 ob_start();
60 require $viewFile;
61 $this->html .= ob_get_clean();
62 }
63 }
64} \ No newline at end of file
diff --git a/src/view/LoginBuilder.php b/src/view/LoginBuilder.php
new file mode 100644
index 0000000..ac9910f
--- /dev/null
+++ b/src/view/LoginBuilder.php
@@ -0,0 +1,15 @@
1<?php
2// src/view/LoginBuilder.php
3
4use App\Entity\Node;
5
6class LoginBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 global $entityManager;
11
12 // une classe Password ce serait pas mal!!
13 connect($this, $entityManager);
14 }
15}
diff --git a/src/view/MainBuilder.php b/src/view/MainBuilder.php
new file mode 100644
index 0000000..a44570b
--- /dev/null
+++ b/src/view/MainBuilder.php
@@ -0,0 +1,30 @@
1<?php
2// src/view/MainBuilder.php
3
4use App\Entity\Node;
5
6class MainBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $this->html .= "<main>\n";
11
12 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){
13 if($node->getTempChild() == null){
14 $new = new Node;
15 }
16 else{
17 $new = $node->getTempChild();
18 }
19 //$builder_name = $this->snakeToPascalCase($new->getName()) . 'Builder';
20 $builder_name = 'NewBuilder';
21 $builder = new $builder_name($new);
22 $this->html .= $builder->render();
23 }
24 else{
25 $this->useChildrenBuilder($node);
26 }
27
28 $this->html .= "</main>\n";
29 }
30}
diff --git a/src/view/NavBuilder.php b/src/view/NavBuilder.php
new file mode 100644
index 0000000..e7254b1
--- /dev/null
+++ b/src/view/NavBuilder.php
@@ -0,0 +1,61 @@
1<?php
2// src/view/NavBuilder.php
3
4declare(strict_types=1);
5
6use App\Entity\Node;
7use App\Entity\Page;
8
9class NavBuilder extends AbstractBuilder
10{
11 public function __construct(Node $node)
12 {
13 $this->html .= '<nav class="nav_main"><ul>';
14 $this->html .= $this->navMainHTML(Director::$menu_data, Director::$page_path->getArray());
15 $this->html .= '</ul></nav>';
16 }
17
18 private function navMainHTML(Page $nav_data, array $current): string
19 {
20 $nav_html = '';
21 static $level = 0;
22
23 foreach($nav_data->getChildren() as $data)
24 {
25 $class = '';
26 if(isset($current[$level]) && $data->getEndOfPath() === $current[$level]->getEndOfPath()){
27 $class = ' current';
28 }
29
30 if(count($data->getChildren()) > 0) // titre de catégorie
31 {
32 $nav_html .= '<li class="drop-down'. $class . '"><p>' . $data->getPageName() . '</p><ul class="sub-menu">' . "\n";
33 $level++;
34 $nav_html .= $this->navMainHTML($data, $current);
35 $level--;
36 $nav_html .= '</ul></li>' . "\n";
37 }
38 else
39 {
40 $target = '';
41 if(str_starts_with($data->getEndOfPath(), 'http')) // lien vers autre site
42 {
43 $link = $data->getEndOfPath(); // $link = chaine
44 $target = ' target="_blank"';
45 }
46 elseif($data->getEndOfPath() != '') // lien relatif
47 {
48 $link = new URL(['page' => $data->getPagePath()]); // $link = objet
49 }
50 /*else
51 {
52 echo "else page d'accueil" . '<br>';
53 $link = new URL; // page d'accueil
54 }*/
55
56 $nav_html .= '<a href="' . $link . '"' . $target . '><li class="'. $class . '"><p>' . $data->getPageName() . '</p></li></a>' . "\n";
57 }
58 }
59 return $nav_html;
60 }
61} \ No newline at end of file
diff --git a/src/view/NewBuilder.php b/src/view/NewBuilder.php
new file mode 100644
index 0000000..605c174
--- /dev/null
+++ b/src/view/NewBuilder.php
@@ -0,0 +1,93 @@
1<?php
2// src/view/NewBuilder.php
3
4use App\Entity\Node;
5
6class NewBuilder extends AbstractBuilder
7{
8 public function __construct(Node $node)
9 {
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11
12 if(file_exists($viewFile))
13 {
14 // id (timestamp)
15 if(!empty($node->getAttributes()))
16 {
17 extract($node->getAttributes());
18 }
19
20 // html, date
21 $title = $node->getArticle()->getTitle();
22 $preview = $node->getArticle()->getPreview();
23 $id = $node->getArticleTimestamp();
24 $content = '';
25
26 // page article unique
27 if(Director::$page_path->getLast()->getEndOfPath() === 'article')
28 {
29 $content = $node->getArticle()->getContent();
30 $from_to_button = '<p><a class="link_to_article" href="' . new URL(['page' => 'accueil']) . '"><button>Retour page d\'accueil</button></a></p>';
31 }
32 // page d'accueil (avec des news)
33 else
34 {
35 $from_to_button = '<p><a class="link_to_article" href="' . new URL(['page' => 'article', 'id' => $id]) . '"><button><img class="action_icon" src="assets/book-open.svg">Lire la suite</button></a></p>';
36 }
37
38
39 $date_object = $node->getArticle()->getDateTime(); // class DateTime
40 $date = 'le ' . str_replace(':', 'h', $date_object->format('d-m-Y à H:i'));
41
42 // partage
43 $share_link = new URL(['page' => CURRENT_PAGE], $id);
44 isset($_GET['id']) ? $share_link->addParams(['id' => $_GET['id']]) : '';
45 $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"';
46 $share_button = '<p><a href="' . $share_link . '" ' . $share_js . '><img class="action_icon" src="assets/share.svg"></a></p>' . "\n";
47
48 // modifier un article
49 $admin_buttons = '';
50 if($_SESSION['admin'])
51 {
52 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){
53 $modify_js = 'onclick="openEditor(\'' . $id . '\')"';
54 $modify_article = '<p id="edit-' . $id . '"><a href="#"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></a></p>' . "\n";
55
56 $up_button = '<p id="position_up-' . $id . '"></p>' . "\n";
57 $down_button = '<p id="position_down-' . $id . '"></p>' . "\n";
58
59 $delete_js = 'onclick="deleteArticle(\'' . $id . '\', \'' . CURRENT_PAGE . '\')"';
60 $delete_article = '<p id="delete-' . $id . '"><a href="#"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></a></p>' . "\n";
61
62 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
63 $close_editor = '<p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>';
64
65 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"';
66 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p>';
67 }
68 else{
69 $modify_article = '<p id="edit-' . $id . '"></p>' . "\n";
70
71 $up_link = new URL(['page' => CURRENT_PAGE, 'id' => $id, 'action' => 'position_up']);
72 $up_button = '<p id="position_up-' . $id . '"><a href="' . $up_link . '"><img class="action_icon" src="assets/arrow-up.svg"></a></p>' . "\n";
73
74 $down_link = new URL(['page' => CURRENT_PAGE, 'id' => $id, 'action' => 'position_down']);
75 $down_button = '<p id="position_down-' . $id . '"><a href="' . $down_link . '"><img class="action_icon" src="assets/arrow-down.svg"></a></p>' . "\n";
76
77 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
78 $delete_article = '<p id="delete-' . $id . '"><a href="#"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></a></p>' . "\n";
79
80 $close_editor = '<p id="cancel-' . $id . '" class="hidden"></p>';
81 $submit_article = '<p id="submit-' . $id . '" class="hidden"></p>';
82
83 $submit_article = '<p id="submit-' . $id . '" class="hidden"></p>';
84 }
85 $admin_buttons = $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article;
86 }
87
88 ob_start();
89 require($viewFile);
90 $this->html .= ob_get_clean();
91 }
92 }
93}
diff --git a/src/view/ViewBuilder.php b/src/view/ViewBuilder.php
new file mode 100644
index 0000000..acac972
--- /dev/null
+++ b/src/view/ViewBuilder.php
@@ -0,0 +1,16 @@
1<?php
2// src/view/ViewBuilder.php
3//
4// appelle les autres Builder
5
6declare(strict_types=1);
7
8use App\Entity\Node;
9
10class ViewBuilder extends AbstractBuilder
11{
12 public function __construct(Node $root_node)
13 {
14 $this->useChildrenBuilder($root_node);
15 }
16}
diff --git a/src/view/password.php b/src/view/password.php
new file mode 100644
index 0000000..0ff717c
--- /dev/null
+++ b/src/view/password.php
@@ -0,0 +1,152 @@
1<?php
2// src/view/password.php
3//
4// ce fichier contient le HTML de deux pages du site:
5// - connexion au mode admin
6// - changement de mot de passe
7//
8// rajouter la page "créationn du mot de passe"?
9
10// insertion du captcha
11ob_start();
12?>
13 <p>Montrez que vous n'êtes pas un robot.<br>
14 <label for="captcha" >Combien font <?= $captcha[0] ?> fois <?= $captcha[1] ?>?</label>
15 <input required type="text" id="captcha" name="captcha" autocomplete="off" size="1">
16 </p>
17<?php
18$captchaHtml = ob_get_clean();
19
20
21// formulaire connexion
22$link = new URL(['page' => 'connexion']);
23isset($_GET['from']) ? $link->addParams(['from' => $_GET['from']]) : '';
24isset($_GET['id']) ? $link->addParams(['id' => $_GET['id']]) : '';
25ob_start();
26?>
27 <form class="connexionFormulaire" method="post" action="<?= $link ?>" >
28 <p><label for="login" >Identifiant (E-mail):</label>
29 <input id="login" type="text" name="login" autofocus required></p>
30 <p><label for="password" >Mot de passe:</label>
31 <input id="password" type="password" name="password" required></p>
32
33 <?= $captchaHtml ?>
34
35 <input type="submit" value="Valider">
36 </form>
37<?php
38$formulaireConnexion = ob_get_clean();
39
40// formulaire création du mot de passe
41ob_start();
42?>
43 <form class="connexionFormulaire" method="post" action="index.php" >
44 <p><label for="login" >Identifiant (e-mail):</label>
45 <input id="login" type="text" name="login" autofocus required></p>
46 <p><label for="password" >Mot de passe:</label>
47 <input id="password" type="password" name="password" required></p>
48
49 <?= $captchaHtml ?>
50
51 <input type="submit" value="Valider">
52 </form>
53<?php
54$formulaireNouveauMDP = ob_get_clean();
55
56// formulaire changement de mot de passe
57$link = new URL(['action' => 'modif_mdp']);
58isset($_GET['from']) ? $link->addParams(['from' => $_GET['from']]) : '';
59isset($_GET['id']) ? $link->addParams(['id' => $_GET['id']]) : '';
60ob_start();
61?>
62 <form class="connexionFormulaire" method="post" action="<?= $link ?>" >
63 <label for="login" >Identifiant (e-mail):</label>
64 <input id="login" type="login" name="login" autofocus required ><br><br>
65 <label for="old_password" >Ancien mot de passe:</label>
66 <input id="old_password" type="password" name="old_password" required ><br><br>
67 <label for="new_password" >Nouveau mot de passe:</label>
68 <input id="new_password" type="password" name="new_password" required autocomplete="off">
69 <br><br>
70 <input type="submit" value="Valider" >
71 <!-- <a href="index.php<?= $from ?>" >
72 <input type="button" value="Annuler">
73 </a> -->
74 </form>
75<?php
76$formulaireModifMDP = ob_get_clean();
77
78// en-tête
79ob_start();
80?>
81<!DOCTYPE html>
82
83<html lang="fr">
84 <head>
85 <meta charset="utf-8">
86 <title><?= $title ?></title>
87
88 <link rel="icon" type="image/png" href="assets/favicon48x48.png">
89 <script src="js/main.js" ></script>
90 <meta name="viewport" content="width=device-width, initial-scale=1.0">
91 <style>
92 body{background-color: #E3F3FF;}
93 #bloc_page{text-align: center;}
94 .avertissement{color: red;}
95 </style>
96 </head>
97
98 <body>
99 <div id="bloc_page" >
100 <h2 class="connexionTitre" ><?= $title ?></h2>
101 <p class="connexionP" ><?= $subHeading ?></p>
102<?php
103$header = ob_get_clean();
104
105
106$error_messages = [
107 'error_non_valid_captcha' => '<p class="avertissement" >Erreur au test anti-robot, veuillez saisir un nombre entier.</p>',
108 'bad_solution_captcha' => '<p class="avertissement" >Erreur au test anti-robot, veuillez réessayer.</p>',
109 'bad_login_or_password' => '<p class="avertissement" >Saisir un Identifiant (e-mail) et un mot de passe.</p>',
110 'bad_password' => '<p class="avertissement" >Mauvais mot de passe, veuillez réessayer.</p>',
111 'forbidden_characters' => '<p class="avertissement" >Caractères interdits: espaces, tabulations, sauts CR/LF.</p>'
112];
113
114$warning_messages = [
115 'message_disconnect' => "<p class='connexionP' ><i>N'oubliez de cliquer sur 'déconnexion' quand vous aurez fini.</i></p>",
116 //'message_cookie' => "<p class='connexionP' style='color: red;'>Ce site utilise un cookie « obligatoire » lorsque vous êtes connecté ainsi que sur cette page.<br>Il sera supprimé à votre déconnexion ou dès que vous aurez quitté le site.</p>",
117 'private_browsing' =>"<p class='connexionP' >Au fait? Vous n'utilisez pas votre propre ordinateur ou téléphone?<br/>
118 Utilisez la navigation privée.</p>"
119];
120
121
122// confirmation modification du mot de passe
123$page = isset($_GET['from']) ? $_GET['from'] : 'accueil';
124$id = isset($_GET['id']) ? ', \'' . $_GET['id'] . '\'' : '';
125$js = "newPassword('" . $page . "'" . $id . ");";
126ob_start();
127?>
128<script><?= $js ?></script>
129<noscript>
130 <p class="avertissement" >Le mot de passe a été modifié<br>
131 <a href="<?= $link ?>" ><button>Retour au site.</button></a></p>
132</noscript>
133<?php
134$alertJSNewPassword = ob_get_clean();
135
136
137// bas de la page
138$link = new URL();
139isset($_GET['from']) ? $link->addParams(['page' => $_GET['from'] ]) : '';
140isset($_GET['id']) ? $link->addParams(['id' => $_GET['id']]) : '';
141ob_start();
142if(isset($_GET['from'])) // exclue la "création du mot de passe"
143{
144?>
145 <p class="connexionP connexionFooter" >
146 <a href="<?= $link ?>" >
147 <button>Retour au site.</button>
148 </a>
149 </p>
150<?php
151}
152$footer = ob_get_clean(); \ No newline at end of file
diff --git a/src/view/templates/article.php b/src/view/templates/article.php
new file mode 100644
index 0000000..d34697e
--- /dev/null
+++ b/src/view/templates/article.php
@@ -0,0 +1,15 @@
1<article>
2 <div class="article_content">
3 <div class="article_title_zone">
4 <h4><?= $title ?></h4>
5 <?= $share_button ?>
6 </div>
7 <div id="<?= $id ?>" class="html_from_editor">
8 <?= $html ?>
9 </div>
10 <div class="article_admin_zone">
11 <?= $admin_buttons ?>
12 </div>
13 </div>
14
15</article> \ No newline at end of file
diff --git a/src/view/templates/blog.php b/src/view/templates/blog.php
new file mode 100644
index 0000000..35cac8b
--- /dev/null
+++ b/src/view/templates/blog.php
@@ -0,0 +1,6 @@
1<section class="blog">
2 <h3><?= $title ?></h3>
3<?= $new_article ?>
4<?= $new_article_admin_buttons ?>
5<?= $content ?>
6</section> \ No newline at end of file
diff --git a/src/view/templates/footer.php b/src/view/templates/footer.php
new file mode 100644
index 0000000..5af7924
--- /dev/null
+++ b/src/view/templates/footer.php
@@ -0,0 +1,15 @@
1 <footer>
2 <div>
3 <p class="contact"><?= $contact_nom ?><br>
4 <?= $adresse ?><br>
5 <a href="mailto:<?= $e_mail ?>"><?= $e_mail ?></a></p>
6<?= $breadcrumb ?>
7 </div>
8 <div class="<?= $empty_admin_zone ?>"></div>
9 <div class="<?= $div_admin ?>">
10<?= $zone_admin ?>
11 </div>
12 </footer>
13 </div>
14 </body>
15</html> \ No newline at end of file
diff --git a/src/view/templates/galery.php b/src/view/templates/galery.php
new file mode 100644
index 0000000..306526f
--- /dev/null
+++ b/src/view/templates/galery.php
@@ -0,0 +1,10 @@
1<section class="galery">
2 <h3><?= $title ?></h3>
3<?= $new_article ?>
4<?= $new_article_admin_buttons ?>
5 <div class="galery_photos">
6 <a><p></p></a>
7<?= $content ?>
8 </div>
9 <script>enableGaleryScroller();</script>
10</section> \ No newline at end of file
diff --git a/src/view/templates/grid.php b/src/view/templates/grid.php
new file mode 100644
index 0000000..a09ed40
--- /dev/null
+++ b/src/view/templates/grid.php
@@ -0,0 +1,8 @@
1<section class="grid">
2 <h3><?= $title ?></h3>
3<?= $new_article ?>
4<?= $new_article_admin_buttons ?>
5 <div class="grid_columns">
6<?= $content ?>
7 </div>
8</section> \ No newline at end of file
diff --git a/src/view/templates/head.php b/src/view/templates/head.php
new file mode 100644
index 0000000..1ebb17e
--- /dev/null
+++ b/src/view/templates/head.php
@@ -0,0 +1,11 @@
1<!DOCTYPE html>
2<html lang="fr">
3 <head>
4 <meta charset="utf-8">
5 <title><?= $title ?></title>
6 <link rel="icon" type="image/png" href="<?= $favicon ?>" alt="<?= $alt ?>">
7 <meta name="description" content="<?= $description ?>">
8 <meta name="viewport" content="width=device-width">
9 <?= $css ?>
10 <?= $js ?>
11 </head> \ No newline at end of file
diff --git a/src/view/templates/header.php b/src/view/templates/header.php
new file mode 100644
index 0000000..fa55cea
--- /dev/null
+++ b/src/view/templates/header.php
@@ -0,0 +1,23 @@
1<body>
2 <div>
3 <header>
4 <div class="empty_nav_zone">
5 <?= $nav ?>
6 </div>
7
8 <div class="header-content">
9 <div class="head_logo">
10 <a href="<?= new URL ?>"><img src="<?= $logo ?>" alt="<?= $logo_alt ?>"></a>
11 </div>
12 <div class="site_title">
13 <a href="<?= new URL ?>"><h1><?= $title ?></h1></a>
14 <h2><?= $description ?></h2>
15 </div>
16 <div class="social">
17 <a href="<?= $facebook_link ?>" target="_blank" rel="noopener noreferrer">
18 <img src="<?= $facebook ?>" alt="<?= $facebook_alt ?>"></a>
19 <a href="<?= $instagram_link ?>" target="_blank" rel="noopener noreferrer">
20 <img src="<?= $instagram ?>" alt="<?= $instagram_alt ?>"></a>
21 </div>
22 </div>
23 </header> \ No newline at end of file
diff --git a/src/view/templates/new.php b/src/view/templates/new.php
new file mode 100644
index 0000000..9dd8969
--- /dev/null
+++ b/src/view/templates/new.php
@@ -0,0 +1,21 @@
1<article>
2 <div class="new_content">
3 <div class="article_title_zone">
4 <h4><?= $title ?></h4>
5 <?= $share_button ?>
6 </div>
7 <div class="new_content_text">
8 <?= $preview ?>
9 </div>
10 <div id="<?= $id ?>" class="article_content_text">
11 <?= $content ?>
12 </div>
13 <div class="under_an_article">
14 <p><img src="assets/calendar.svg"><?= $date ?></p>
15 <?= $from_to_button ?>
16 </div>
17 <div class="article_admin_zone">
18 <?= $admin_buttons ?>
19 </div>
20 </div>
21</article> \ No newline at end of file