From f27cca08ff786ceff1870147f6d6bad14d71117f Mon Sep 17 00:00:00 2001 From: polo Date: Fri, 23 Oct 2026 00:47:32 +0200 Subject: =?UTF-8?q?dossiers=20avec=20majuscule,=20namespace=20pour=20toute?= =?UTF-8?q?s=20les=20classes,=20autoload=20psr-4,=20UserDataService::creat?= =?UTF-8?q?eZip=20d=C3=A9plac=C3=A9=20dans=20Backup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/View/AbstractBuilder.php | 81 +++++++++++++++++++ src/View/BreadcrumbBuilder.php | 53 ++++++++++++ src/View/CalendarBuilder.php | 31 +++++++ src/View/FooterBuilder.php | 122 ++++++++++++++++++++++++++++ src/View/FormBuilder.php | 55 +++++++++++++ src/View/GaleryBuilder.php | 72 +++++++++++++++++ src/View/HeadBuilder.php | 84 +++++++++++++++++++ src/View/HeaderBuilder.php | 131 ++++++++++++++++++++++++++++++ src/View/LoginBuilder.php | 56 +++++++++++++ src/View/MainBuilder.php | 99 +++++++++++++++++++++++ src/View/MaintenanceBuilder.php | 36 +++++++++ src/View/MenuBuilder.php | 101 +++++++++++++++++++++++ src/View/NavBuilder.php | 77 ++++++++++++++++++ src/View/NewBuilder.php | 157 ++++++++++++++++++++++++++++++++++++ src/View/NewPageBuilder.php | 53 ++++++++++++ src/View/NewsBlockBuilder.php | 76 +++++++++++++++++ src/View/PostBlockBuilder.php | 90 +++++++++++++++++++++ src/View/PostBuilder.php | 60 ++++++++++++++ src/View/ShowEmailsBuilder.php | 71 ++++++++++++++++ src/View/UserEditBuilder.php | 64 +++++++++++++++ src/View/ViewDirector.php | 30 +++++++ src/View/templates/calendar.php | 14 ++++ src/View/templates/footer.php | 43 ++++++++++ src/View/templates/form.php | 36 +++++++++ src/View/templates/form_admin.php | 73 +++++++++++++++++ src/View/templates/galery.php | 12 +++ src/View/templates/head.php | 13 +++ src/View/templates/header.php | 58 +++++++++++++ src/View/templates/login.php | 31 +++++++ src/View/templates/maintenance.php | 65 +++++++++++++++ src/View/templates/menu.php | 51 ++++++++++++ src/View/templates/modify_block.php | 61 ++++++++++++++ src/View/templates/modify_page.php | 62 ++++++++++++++ src/View/templates/new.php | 27 +++++++ src/View/templates/new_page.php | 38 +++++++++ src/View/templates/news_block.php | 14 ++++ src/View/templates/post.php | 14 ++++ src/View/templates/post_block.php | 14 ++++ src/View/templates/show_emails.php | 30 +++++++ src/View/templates/user_create.php | 54 +++++++++++++ src/View/templates/user_edit.php | 63 +++++++++++++++ 41 files changed, 2372 insertions(+) create mode 100644 src/View/AbstractBuilder.php create mode 100644 src/View/BreadcrumbBuilder.php create mode 100644 src/View/CalendarBuilder.php create mode 100644 src/View/FooterBuilder.php create mode 100644 src/View/FormBuilder.php create mode 100644 src/View/GaleryBuilder.php create mode 100644 src/View/HeadBuilder.php create mode 100644 src/View/HeaderBuilder.php create mode 100644 src/View/LoginBuilder.php create mode 100644 src/View/MainBuilder.php create mode 100644 src/View/MaintenanceBuilder.php create mode 100644 src/View/MenuBuilder.php create mode 100644 src/View/NavBuilder.php create mode 100644 src/View/NewBuilder.php create mode 100644 src/View/NewPageBuilder.php create mode 100644 src/View/NewsBlockBuilder.php create mode 100644 src/View/PostBlockBuilder.php create mode 100644 src/View/PostBuilder.php create mode 100644 src/View/ShowEmailsBuilder.php create mode 100644 src/View/UserEditBuilder.php create mode 100644 src/View/ViewDirector.php create mode 100644 src/View/templates/calendar.php create mode 100644 src/View/templates/footer.php create mode 100644 src/View/templates/form.php create mode 100644 src/View/templates/form_admin.php create mode 100644 src/View/templates/galery.php create mode 100644 src/View/templates/head.php create mode 100644 src/View/templates/header.php create mode 100644 src/View/templates/login.php create mode 100644 src/View/templates/maintenance.php create mode 100644 src/View/templates/menu.php create mode 100644 src/View/templates/modify_block.php create mode 100644 src/View/templates/modify_page.php create mode 100644 src/View/templates/new.php create mode 100644 src/View/templates/new_page.php create mode 100644 src/View/templates/news_block.php create mode 100644 src/View/templates/post.php create mode 100644 src/View/templates/post_block.php create mode 100644 src/View/templates/show_emails.php create mode 100644 src/View/templates/user_create.php create mode 100644 src/View/templates/user_edit.php (limited to 'src/View') diff --git a/src/View/AbstractBuilder.php b/src/View/AbstractBuilder.php new file mode 100644 index 0000000..170e871 --- /dev/null +++ b/src/View/AbstractBuilder.php @@ -0,0 +1,81 @@ +id_node = $node->getId(); + } + + protected function useChildrenBuilder(Node $node): void + { + foreach($node->getChildren() as $child_node) + { + // le double \\ permet de ne pas échapper la quote + $builder_name = 'App\View\\' . $this->snakeToPascalCase($child_node->getName()) . 'Builder'; + $builder = new $builder_name($child_node); + $this->html .= $builder->render(); + + // pages spéciales où on n'assemble pas tout + if($builder_name === 'HeadBuilder' && in_array(Model::$page_path->getString(), ['connection', 'user_edit'])) + { + foreach($node->getChildren() as $target_node){ + if($target_node->getName() === 'main'){ + $main_node = $target_node; + break; + } + } + // on construit
et on s'arrête! les autres noeuds sont ignorés + $builder_name = $this->snakeToPascalCase($main_node->getName()) . 'Builder'; + $builder = new $builder_name($main_node); + $this->html .= "\n"; + $this->html .= $builder->render() . "\n"; + $this->html .= "\n"; + break; + } + } + } + + private function snakeToPascalCase(string $input): string + { + return str_replace('_', '', ucwords($input, '_')); + } + + public function render(): string // = getHTML(), nécéssite d'être public + { + return $this->html; + } + protected function addHTML(string $html): void + { + $this->html .= $html; + } + + protected function insertSVG(string $path, array $attributes = []): string + { + $svg = file_get_contents($path); + + // modification des attributs + if(!empty($attributes)){ + $dom = new \DOMDocument(); + $dom->loadXML($svg); + $svg_elem = $dom->documentElement; + foreach($attributes as $key => $value){ + $svg_elem->setAttribute($key, $value); + } + $svg = $dom->saveXML($svg_elem); + } + return $svg; + } +} \ No newline at end of file diff --git a/src/View/BreadcrumbBuilder.php b/src/View/BreadcrumbBuilder.php new file mode 100644 index 0000000..81df0eb --- /dev/null +++ b/src/View/BreadcrumbBuilder.php @@ -0,0 +1,53 @@ +html = $this->breadcrumbHTML(); + } + + private function breadcrumbHTML(): string + { + $asset = 'assets/home.svg'; // => BDD? + $breadcrumb_array = Model::$page_path->getArray(); // tableau de Page + $html = ''; + $nb_of_entries = count($breadcrumb_array); + + if($nb_of_entries > 1) + { + // petite maison et flèche + $html .= '\n"; + } + return $html; + } +} \ No newline at end of file diff --git a/src/View/CalendarBuilder.php b/src/View/CalendarBuilder.php new file mode 100644 index 0000000..34b1952 --- /dev/null +++ b/src/View/CalendarBuilder.php @@ -0,0 +1,31 @@ +getName() . '.php'; + + $calendar_js_file = IS_ADMIN ? 'calendar_admin' : 'calendar'; + + if(file_exists($viewFile)) + { + if(!empty($node->getNodeData()->getData())) + { + extract($node->getNodeData()->getData()); + } + + ob_start(); + require $viewFile; + $this->html = ob_get_clean(); // pas de concaténation ici, on écrase + } + } +} \ No newline at end of file diff --git a/src/View/FooterBuilder.php b/src/View/FooterBuilder.php new file mode 100644 index 0000000..72a571d --- /dev/null +++ b/src/View/FooterBuilder.php @@ -0,0 +1,122 @@ +getName() . '.php'; + + if(file_exists($viewFile)) + { + $node_data = $node->getNodeData(); + // nom du contact, adresse et e-mail + if(!empty($node_data->getData())) + { + extract($node_data->getData()); + } + + $footer_logo = Asset::USER_PATH . $node_data->getAssetByRole('footer_logo')?->getFileName() ?? ''; + + $this->useChildrenBuilder($node); + $breadcrumb = $this->html; + + $empty_admin_zone = ''; + if(IS_ADMIN) + { + // données du footer + $admin_footer_name = ' + + + '; + $admin_footer_address = ' + + + '; + $admin_footer_email = ' + + + '; + + $admin_footer_logo = ' + + + '; + + // zone admin + $empty_admin_zone = 'empty_admin_zone'; + if(MainBuilder::$modif_mode){ + $mode = 'modification de page'; + $div_admin = 'logged_in modif_mode'; + } + else{ + $mode = 'administrateur'; + $div_admin = 'logged_in'; + } + + $link_change_password = new URL(['page' => 'user_edit', 'from' => CURRENT_PAGE]); + isset($_GET['id']) ? $link_change_password->addParams(['id' => $_GET['id']]) : ''; + + $link_logout = new URL(['action' => 'deconnection', 'from' => CURRENT_PAGE]); + isset($_GET['id']) ? $link_logout->addParams(['id' => $_GET['id']]) : ''; + + $zone_admin = '
+

Vous êtes en mode ' . $mode . ".

\n" . + '
' . "\n" . + $this->makePageModifModeButton() . "\n" . + '
' . "\n" . + '
' . "\n" . + '
' . "\n" . + '
' . "\n" . + '
' . "\n"; + } + else + { + $div_admin = 'logged_out'; + $url = new URL(['page' => 'connection', 'from' => CURRENT_PAGE]); + if(Model::$page_path->getLast()->getEndOfPath() === 'article' && isset($_GET['id'])){ + $url->addParams(['id' => $_GET['id']]); + } + $zone_admin = ''; + + $admin_footer_name = ''; + $admin_footer_address = ''; + $admin_footer_email = ''; + $admin_footer_logo = ''; + } + + ob_start(); + require $viewFile; + $this->html = ob_get_clean(); + } + } + + private function makePageModifModeButton(): string + { + $link_edit_page = new URL(['page' => CURRENT_PAGE]); + if(!in_array(CURRENT_PAGE, ViewController::SPECIAL_PAGES)) // cas impossibles: 'user_edit' et 'connection' qui n'ont pas de footer + { + if(MainBuilder::$modif_mode){ + $link_edit_label = 'Sortir du mode modification'; + } + else{ + $link_edit_page->addParams(['mode' => 'page_modif']); + $link_edit_label = 'Modifier la page'; + } + return '
'; + } + else{ + return ''; + } + } +} \ No newline at end of file diff --git a/src/View/FormBuilder.php b/src/View/FormBuilder.php new file mode 100644 index 0000000..df5687d --- /dev/null +++ b/src/View/FormBuilder.php @@ -0,0 +1,55 @@ +getNodeData()->getData())){ + extract($node->getNodeData()->getData()); + } + + // un seul captcha à la fois! + if(!self::$captcha){ + self::$captcha = new Captcha; + $_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 = $this->getRetentionPeriod($retention_period ?? null, Email::DEFAULT_RETENTION_PERIOD); + $retention_period_sensible = $this->getRetentionPeriod($retention_period_sensible ?? null, Email::DEFAULT_RETENTION_PERIOD_SENSITIVE); + + $admin_content = ''; + if(IS_ADMIN){ + ob_start(); + require self::VIEWS_PATH . 'form_admin.php'; + $admin_content = ob_get_clean(); + } + + ob_start(); + require self::VIEWS_PATH . $node->getName() . '.php'; + $this->html = ob_get_clean(); // pas de concaténation ici, on écrase + } + + private function getRetentionPeriod(mixed $period, int $default_period): int + { + return ($period === null || (int)$period <= 0) ? $default_period : (int)$period; // (int) est nécessaire à cause du stockage JSON + } +} \ No newline at end of file diff --git a/src/View/GaleryBuilder.php b/src/View/GaleryBuilder.php new file mode 100644 index 0000000..436cc36 --- /dev/null +++ b/src/View/GaleryBuilder.php @@ -0,0 +1,72 @@ +getName() . '.php'; + + if(file_exists($viewFile)) + { + if(!empty($node->getNodeData()->getData())) + { + extract($node->getNodeData()->getData()); + } + + // ajouter un article + $new_article = ''; + if(IS_ADMIN) + { + $id = 'n' . $this->id_node; + $js = 'onclick="openEditor(\'' . $id . '\')"'; + + $share_button = ''; + $html = ''; + + $new_button = '

' . "\n" . + '

'; + + $modify_js = 'onclick="openEditor(\'' . $id . '\')"'; + $modify_article = '' . "\n"; + + $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"'; + $up_button = '' . "\n"; + + $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"'; + $down_button = '' . "\n"; + + $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; + $delete_article = '' . "\n"; + + $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; + $close_editor = ''; + + $submit_js = 'onclick="submitArticle(\'' . $id . '\', \'\', clone' . $this->id_node . ')"'; + $submit_article = ''; + + $admin_buttons = $new_button . $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article; + + // squelette d'un nouvel article + ob_start(); + require self::VIEWS_PATH . 'post.php'; + $new_article = ob_get_clean(); + } + + // articles existants + $this->useChildrenBuilder($node); + $content = $this->html; + + ob_start(); + require $viewFile; + $this->html = ob_get_clean(); // pas de concaténation ici, on écrase + } + } +} \ No newline at end of file diff --git a/src/View/HeadBuilder.php b/src/View/HeadBuilder.php new file mode 100644 index 0000000..4d63457 --- /dev/null +++ b/src/View/HeadBuilder.php @@ -0,0 +1,84 @@ +getName() . '.php'; + + if(file_exists($viewFile)){ + // css et js + $page = Model::$page_path->getLast(); + + $css = ''; + foreach($page->getCSS() as $name){ + $css .= self::insertCSS($name); + } + + $js = ''; + foreach($page->getJS() as $name){ + $js .= self::insertJS($name); + } + + if(MainBuilder::$modif_mode){ + $css .= self::insertCSS('modif_page'); + $js .= self::insertJS('modif_page'); + } + + if(IS_ADMIN){ + // édition éléments sur toutes les pages (header, footer et favicon) + $js .= self::insertJS('Input'); + + // sert partout? + $js .= self::insertJS('Fetcher'); + + // tinymce, nécéssite un script post-install et post-update dans composer.json + $css .= self::insertCSS('tinymce'); + $js .= self::insertJS('tinymce/tinymce.min'); + $js .= self::insertJS('tinymce'); + } + + $title = Model::$page_path->getLast()->getPageName(); + $description = Model::$page_path->getLast()->getDescription(); + + // favicon + // ?-> est l'opérateur de navigation sécurisée => LOVE! + $favicon_name = ($favicon_object = $node->getNodeData()->getAssetByRole('head_favicon'))?->getFileName(); + $favicon = $favicon_name ? Asset::USER_PATH . $favicon_name : ''; + $favicon_type = $favicon_object?->getMimeType() ?? ''; + + ob_start(); + require $viewFile; + $this->html .= ob_get_clean(); + } + } + + static function insertCSS(string $name): string + { + return '' . "\n"; + } + static function insertJS(string $name, bool $module = false): string + { + return '' . "\n"; + } + + static function versionedFileURL(string $type, string $filename): string + { + $path = $type . '/' . $filename . '.' . $type; + + if(file_exists($path)){ + $version = substr(md5_file($path), 0, 8); + return $path . '?v=' . $version; + } + return $path; // sécurité fichier absent + } +} diff --git a/src/View/HeaderBuilder.php b/src/View/HeaderBuilder.php new file mode 100644 index 0000000..14f5ffa --- /dev/null +++ b/src/View/HeaderBuilder.php @@ -0,0 +1,131 @@ +getChildren(); + foreach($children as $child) + { + if($child->getName() === 'nav'){ + //$this->nav = $child; + // actuellement le noeud nav ne contient aucune info utile et l'envoyer à NavBuilder est inutile + $nav_builder = new NavBuilder(/*$this->nav*/); + + $nav = $nav_builder->render(); + } + elseif($child->getName() === 'breadcrumb'){ + //$this->breadcrumb = $child; + $breadcrumb_builder = new BreadcrumbBuilder(/*$this->breadcrumb*/); + $breadcrumb = $breadcrumb_builder->render(); + } + } + + $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; + + if(file_exists($viewFile)) + { + $node_data = $node->getNodeData(); + // titre et description + if(!empty($node_data->getData())) + { + extract($node_data->getData()); + } + + // réseaux sociaux + logo dans l'entête + // ?-> est l'opérateur de chainage optionnel + $header_logo = Asset::USER_PATH . $node_data->getAssetByRole('header_logo')?->getFileName() ?? ''; + $header_background_name = $node_data->getAssetByRole('header_background')?->getFileName(); + $header_background = $header_background_name ? Asset::USER_PATH . $header_background_name : ''; + $social_networks = ''; + + // boutons mode admin + if(IS_ADMIN){ + // assets dans classe header_additional_inputs + $admin_head_favicon = ' + + + '; + $admin_header_background = ' + + + '; + + // asset dans classe header_content + $admin_header_logo = ' + + + '; + + // texte dans classe header_content + $admin_header_title = ' + + + '; + $admin_header_description = ' + + + '; + + // icônes réseaux sociaux + // boucle sur la liste complète de réseaux sociaux + foreach(NodeData::$social_networks as $network){ + $checked = (isset($social_show[$network]) && $social_show[$network]) ? 'checked' : ''; + $href = (isset($social[$network]) && $social[$network] !== '') ? 'href="' . $social[$network] . '"' : ''; + + $social_networks .= '
+ + ' + . $this->insertSVG(self::ICON_PATH . $network . '.svg', ['id' => 'header_' . $network . '_content', 'class' => ($checked ? 'svg_fill_red' : '')]) + . ' + + + + + +
'; + // {'has_content': false} => InputToggle ne gèrera pas cette balise + } + } + else{ + $admin_head_favicon = ''; + $admin_header_background = ''; + $admin_header_logo = ''; + $admin_header_title = ''; + $admin_header_description = ''; + + if(isset($social_show)){ + // boucle sur les réseaux sociaux "activés" + foreach(array_keys($social_show) as $network){ + if($social_show[$network]){ + $href = (isset($social[$network]) && $social[$network] !== '') ? 'href="' . $social[$network] . '"' : ''; + $social_networks .= ''; + } + } + } + } + + ob_start(); + require $viewFile; + $this->html .= ob_get_clean(); + } + } +} \ No newline at end of file diff --git a/src/View/LoginBuilder.php b/src/View/LoginBuilder.php new file mode 100644 index 0000000..3a303b0 --- /dev/null +++ b/src/View/LoginBuilder.php @@ -0,0 +1,56 @@ +getName() . '.php'; + + $captcha = new Captcha; + $_SESSION['captcha'] = $captcha->getSolution(); // enregistrement de la réponse du captcha pour vérification + + //$this->html .= $header; + + $error_messages = [ + 'error_non_valid_captcha' => 'Erreur au test anti-robot, veuillez saisir un nombre entier.', + 'captcha_server_error' => 'captcha_server_error', + 'bad_solution_captcha' => 'Erreur au test anti-robot, veuillez réessayer.', + 'bad_login_or_password' => 'Mauvais identifiant ou mot de passe, veuillez réessayer.', // ne pas indiquer où est l'erreur + 'forbidden_characters' => 'Caractères interdits: espaces, tabulations, sauts CR/LF.' + ]; + + $link_form = new URL(['action' => 'connection']); + isset($_GET['from']) ? $link_form->addParams(['from' => $_GET['from']]) : ''; + isset($_GET['id']) ? $link_form->addParams(['id' => $_GET['id']]) : ''; + + $link_exit = new URL; + isset($_GET['from']) ? $link_exit->addParams(['page' => $_GET['from'] ]) : ''; + isset($_GET['id']) ? $link_exit->addParams(['id' => $_GET['id']]) : ''; + + $error = isset($_GET['error']) ? $error_messages[$_GET['error']] : ''; + + ob_start(); + require $viewFile; + $this->html = ob_get_clean(); // nouveau contenu + + //$this->html .=

Ce site utilise un cookie « obligatoire » lorsque vous êtes connecté ainsi que sur cette page.
Il sera supprimé à votre déconnexion ou dès que vous aurez quitté le site.

; + + //$this->html .= $footer; + } +} diff --git a/src/View/MainBuilder.php b/src/View/MainBuilder.php new file mode 100644 index 0000000..b5b9b00 --- /dev/null +++ b/src/View/MainBuilder.php @@ -0,0 +1,99 @@ +html .= "
\n"; + + // page article: cas particulier où l'article est greffé sur main + if(Model::$page_path->getLast()->getEndOfPath() === 'article'){ + // pas censé arriver + if(!isset($_GET['id'])){ + header('Location: ' . new URL); + die; + } + + // nouvel article + if($node->getAdoptedChild() == null){ + $date = new \DateTime; + $article = new Article('', $date); + $new = new Node('new', 0, null, null, $article); + } + // modification + else{ + $new = $node->getAdoptedChild(); + } + //$builder_name = 'App\View\\' . $this->snakeToPascalCase($new->getName()) . 'Builder'; + $builder_name = 'App\View\NewBuilder'; + $builder = new $builder_name($new); + $this->html .= $builder->render(); + } + else{ + // si action = "modif_page", affiche des commandes supplémentaires + if(IS_ADMIN && self::$modif_mode){ + // ajouter un contrôle du champ in_menu + $this->viewEditBlocks($node); + } + + // dans tous les cas + $this->useChildrenBuilder($node); + } + + $this->html .= "
\n"; + } + + // mode modification de page uniquement + private function viewEditBlocks(Node $node): void + { + $options = ''; + foreach(Presentation::BLOCKS as $key => $value){ + $options .= '\n"; + } + + // ceci pourrait être déplacé au début des blocs + $bloc_edit = ''; + foreach($node->getChildren() as $child_node){ + // ordre des articles 'news' + if($child_node->getName() === 'news_block'){ + $order = $child_node->getNodeData()->getChronoOrder() ? 'chrono' : 'antichrono'; + } + + // présentation par défaut + if(Presentation::hasPresentation($child_node->getName()) && $child_node->getNodeData()->getPresentation() === null){ + $child_node->getNodeData()->setPresentation('full_width'); // pas de persistence ici + } + + ob_start(); + require self::VIEWS_PATH . 'modify_block.php'; + $bloc_edit .= ob_get_clean(); + } + + ob_start(); + require self::VIEWS_PATH . 'modify_page.php'; + $this->html .= ob_get_clean(); + } + + // utilisée dans modify_block.php + private function makePresentationOptions(string $presentation): string + { + $options = ''; + foreach(Presentation::PRESENTATIONS as $key => $value){ + $options .= ''; + } + return $options; + } +} \ No newline at end of file diff --git a/src/View/MaintenanceBuilder.php b/src/View/MaintenanceBuilder.php new file mode 100644 index 0000000..13d391c --- /dev/null +++ b/src/View/MaintenanceBuilder.php @@ -0,0 +1,36 @@ +getName() . '.php'; + + // noter qu'un backup a été créé dans UserController::connect() + try{ + $backup_array = Backup::getBackupList(); + } + catch(\RuntimeException $e){ + $backup_array = []; + $_SESSION['flash_message'] = $e->getMessage(); // peut écraser une flash error déjà dans $_SESSION['flash_message'] + } + + $backup_options = ''; + for($i = count($backup_array) - 1; $i >= 0; $i--){ + $backup_options .= ''; + } + + if(file_exists($viewFile)){ + ob_start(); + require $viewFile; + $this->html = ob_get_clean(); + } + } +} \ No newline at end of file diff --git a/src/View/MenuBuilder.php b/src/View/MenuBuilder.php new file mode 100644 index 0000000..f14cea7 --- /dev/null +++ b/src/View/MenuBuilder.php @@ -0,0 +1,101 @@ +getName() . '.php'; + + if(file_exists($viewFile)) + { + if(IS_ADMIN){ + $this->unfoldMenu(Model::$menu); + + if($template){ + $this->unfoldOptions(Model::$menu); + } + } + else{ + header('Location: ' . new URL); + die; + } + + // si faux, n'utilise pas le template + if($template){ + ob_start(); + require $viewFile; // insertion de $this->html généré par unfoldMenu + $this->html = ob_get_clean(); // pas de concaténation .= cette fois on écrase + } + } + } + + private function unfoldMenu(Page $page): void + { + $this->html .= '
' . "\n"; + + foreach($page->getChildren() as $entry) + { + $checked = $entry->isHidden() ? '' : 'checked'; + $this->html .= '
+ + + + + + + '; + + // entrées URL: bouton poubelle + nom du lien + adresse + if(str_starts_with($entry->getEndOfPath(), 'http')){ + $this->html .= '
+ + +
+ + + + + + + + '; + } + else{ + $this->html .= ' + ' . $entry->getPagePath() . ''; + } + + if(count($entry->getChildren()) > 0){ + $this->unfoldMenu($entry); + } + $this->html .= '
' . "\n"; + } + $this->html .= "
\n"; + } + + private function unfoldOptions(Page $page): void + { + foreach($page->getChildren() as $entry){ + $this->options .= '\n"; + if(count($entry->getChildren()) > 0){ + $this->unfoldOptions($entry); + } + } + } +} \ No newline at end of file diff --git a/src/View/NavBuilder.php b/src/View/NavBuilder.php new file mode 100644 index 0000000..2e3cdbd --- /dev/null +++ b/src/View/NavBuilder.php @@ -0,0 +1,77 @@ +html .= ''; + } + + private function navMainHTML(Page $nav_data, array $current): string + { + $nav_html = ''; + static $level = 0; + + foreach($nav_data->getChildren() as $data) + { + if(!$data->isHidden()){ + $li_class = ''; + if(isset($current[$level]) && $data->getEndOfPath() === $current[$level]->getEndOfPath()){ + $li_class = 'current '; + } + + $link = ''; + if($data->isReachable()) // titre de catégorie du menu non clicable + { + if(str_starts_with($data->getEndOfPath(), 'http')) // lien vers autre site + { + $link .= ''; + } + elseif($data->getEndOfPath() != '') // lien relatif + { + $link .= ''; + } + } + else{ + $link .= ''; + } + + if(count($data->getChildren()) > 0) // titre de catégorie + { + $li_class .= $data->getParent() == null ? 'drop-down' : 'drop-right'; + + $nav_html .= '
  • ' . $link . '

    ' . $data->getPageName() . '

    + +
  • ' . "\n"; + } + else + { + $nav_html .= '
  • ' . $link . '

    ' . $data->getPageName() . '

  • ' . "\n"; + } + } + } + return $nav_html; + } +} \ No newline at end of file diff --git a/src/View/NewBuilder.php b/src/View/NewBuilder.php new file mode 100644 index 0000000..598bb1c --- /dev/null +++ b/src/View/NewBuilder.php @@ -0,0 +1,157 @@ +getName() . '.php'; + + if(file_exists($viewFile)) + { + if(self::$new_article_mode){ + $id = $_GET['id']; // ici l'id est le nom du block news_block parent + $title = ''; + $preview = ''; + + // lettre au début de l'id: t = title, p = preview, i = article, d = date + $id_title = $id; + $id_title[0] = 't'; + $id_preview = $id; + $id_preview[0] = 'p'; + $id_content = 'i' . $id; + $id_content[0] = 'i'; + $id_date = $id; + $id_date[0] = 'd'; + } + else{ + $id = (string)$node->getId(); + + // html, date + $title = $node->getArticle()->getTitle(); + $preview = $node->getArticle()->getPreview(); + + // lettre au début de l'id: t = title, p = preview, i = article, d = date + $id_title = 't' . $id; + $id_preview = 'p' . $id; + $id_content = 'i' . $id; + $id_date = 'd' . $id; + } + + $content = ''; + if(CURRENT_PAGE === 'article'){ + $content = $node->getArticle()->getContent(); + $from_to_button = '

    '; + $overflow = ''; + } + else{ + $from_to_button = '

    '; + $overflow = ' overflow_hidden'; + } + + $date = $node->getArticle()->getDateTime()->format('Y-m-d\TH:i:s.v\Z'); // format: 2025-07-17T13:54:00.000Z + // format(\DateTime::ATOM) produit le format: 2025-10-10T12:17:00+00:00, c'est aussi de la norme ISO, mais à éviter pour être compatible avec date.toISOString en JS + + // partage + $share_link = new URL(['page' => 'article', 'id' => $id]); + $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"'; + if(isset($_GET['id']) && $_GET['id'][0] === 'n'){ + $class = 'class="share hidden"'; + } + else{ + $class = 'class="share"'; + } + $share_button = '

    ' . "\n"; + + // modifier un article + $title_buttons = ''; + $preview_buttons = ''; + $article_buttons = ''; + $date_buttons = ''; + $admin_buttons = ''; + if(IS_ADMIN){ + if(CURRENT_PAGE === 'article'){ + $title_js = 'onclick="openEditor(\'' . $id_title . '\')"'; + $modify_title = '

    ' . "\n"; + $close_js_title = 'onclick="closeEditor(\'' . $id_title . '\')"'; + $close_editor_title = ''; + $submit_js_title = 'onclick="submitArticle(\'' . $id_title . '\')"'; + $submit_title = ''; + $title_buttons = '
    ' . $modify_title . $close_editor_title . $submit_title . '
    '; + + $preview_js = 'onclick="openEditor(\'' . $id_preview . '\')"'; + $modify_preview = '

    ' . "\n"; + $close_js_preview = 'onclick="closeEditor(\'' . $id_preview . '\')"'; + $close_editor_preview = ''; + $submit_js_preview = 'onclick="submitArticle(\'' . $id_preview . '\')"'; + $submit_preview = ''; + $preview_buttons = '
    ' . $modify_preview . $close_editor_preview . $submit_preview . '
    '; + + $article_js = 'onclick="openEditor(\'' . $id_content . '\')"'; + $modify_article = '

    ' . "\n"; + $close_js_article = 'onclick="closeEditor(\'' . $id_content . '\')"'; + $close_editor_article = ''; + $submit_js_article = 'onclick="submitArticle(\'' . $id_content . '\')"'; + $submit_article = ''; + $article_buttons = '
    ' . $modify_article . $close_editor_article . $submit_article . '
    '; + + $date_js = 'onclick="openDatetimeLocalInput(\'' . $id_date . '\', \'article\');'; + $modify_date = '

    ' . "\n"; + $close_js_date = 'onclick="closeInput(\'' . $id_date . '\')"'; + $close_editor_date = ''; + $submit_js_date = 'onclick="submitDate(\'' . $id_date . '\')"'; + $submit_date = ''; + $date_buttons = '
    ' . $modify_date . $close_editor_date . $submit_date . '
    '; + + // mode nouvel article + if(self::$new_article_mode){ + $delete_article = ''; + // valider la création d'un nouvel article + $submit_js = 'onclick="submitArticle(\'' . $_GET['id'] . '\')"'; + $submit_article = '

    ' . "\n"; + } + // mode article existant + else{ + $url = new URL(['action' => 'delete_article', 'id' => $_GET['id'], 'from' => $_GET['from'] ?? '']); + $delete_article = '
    +

    + Supprimer l\'article +

    ' . "\n"; // this.closest('form').submit() = submit du formulaire avec javascript + $submit_article = ''; + } + + $admin_buttons = $share_button . $delete_article . $submit_article . $from_to_button; + } + // autre page + else{ + $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; + $delete_article = '

    ' . "\n"; + + $close_editor = ''; + $submit_article = ''; + + $admin_buttons = $from_to_button . $share_button . $delete_article . $close_editor . $submit_article; + } + } + else{ + $admin_buttons = $share_button . $from_to_button; + } + + ob_start(); + require($viewFile); + $this->html .= ob_get_clean(); + } + } +} diff --git a/src/View/NewPageBuilder.php b/src/View/NewPageBuilder.php new file mode 100644 index 0000000..578a098 --- /dev/null +++ b/src/View/NewPageBuilder.php @@ -0,0 +1,53 @@ +getName() . '.php'; + + if(IS_ADMIN && file_exists($viewFile)) + { + /*if(!empty($node->getNodeData()->getData())) + { + extract($node->getNodeData()->getData()); + }*/ + + $this->unfoldOptions(Model::$menu); + + ob_start(); + require $viewFile; // insertion de $this->html généré par unfoldMenu + $this->html = ob_get_clean(); // pas de concaténation .= cette fois on écrase + } + else{ + header('Location: ' . new URL); + die; + } + } + + private function unfoldOptions(Page $page): void + { + foreach($page->getChildren() as $entry){ + $this->options .= '\n"; + if(count($entry->getChildren()) > 0){ + $this->unfoldOptions($entry); + } + } + } +} \ No newline at end of file diff --git a/src/View/NewsBlockBuilder.php b/src/View/NewsBlockBuilder.php new file mode 100644 index 0000000..6b3aba5 --- /dev/null +++ b/src/View/NewsBlockBuilder.php @@ -0,0 +1,76 @@ +getName() . '.php'; // = news_block.php, actuellement identique à post_block.php + + if(file_exists($viewFile)) + { + if(!empty($node->getNodeData()->getData())) + { + extract($node->getNodeData()->getData()); + } + + // stratégie d'affichage du contenu (utilisation de méthodes ou de classe List, GridPresentation, etc) + $section_class = $node->getNodeData()->getPresentation(); // = list, grid , mosaic ou carousel + $cols_min_width = ''; + if($section_class === 'grid'){ + $min_width = $node->getNodeData()->getColsMinWidth(); + $cols_min_width = 'grid-template-columns: repeat(auto-fit, minmax(' . (string)$min_width . 'px, 1fr));'; + } + $fetch_button_hidden = $node->getNodeData()->getNumberOfPages() > 1 ? '' : ' hidden'; + + // ajouter un article + $new_article = ''; + if(IS_ADMIN) + { + $id = 'n' . $this->id_node; + + $share_button = ''; + + $new_button = '

    '; + + $modify_js = 'onclick="openEditor(\'' . $id . '\')"'; + $modify_article = '' . "\n"; + + $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; + $delete_article = '' . "\n"; + + $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; + $close_editor = ''; + + $submit_js = 'onclick="submitArticle(\'' . $id . '\', clone' . $this->id_node . ')"'; + $submit_article = ''; + + $html = ''; + $admin_buttons = $new_button . $modify_article . $delete_article . $close_editor . $submit_article; + + // insérer post.php pour le bouton "Nouvel article", new.php pour les vrais articles + ob_start(); + require self::VIEWS_PATH . 'post.php'; // nécéssite $admin_buttons et $html + $new_article = ob_get_clean(); + } + + // articles existants + $this->useChildrenBuilder($node); + $content = $this->html; + + ob_start(); + require $viewFile; // utilise $content + $this->html = ob_get_clean(); // nouveau contenu + } + } +} \ No newline at end of file diff --git a/src/View/PostBlockBuilder.php b/src/View/PostBlockBuilder.php new file mode 100644 index 0000000..850364a --- /dev/null +++ b/src/View/PostBlockBuilder.php @@ -0,0 +1,90 @@ +getName() . '.php'; // = post_block.php, actuellement identique à news_block.php + + if(file_exists($viewFile)) + { + if(!empty($node->getNodeData()->getData())) + { + extract($node->getNodeData()->getData()); + } + + // stratégie d'affichage du contenu (utilisation de méthodes ou de classe List, GridPresentation, etc) + $section_class = $node->getNodeData()->getPresentation(); // = list, grid , mosaic ou carousel + $cols_min_width = ''; + if($section_class === 'grid'){ + $min_width = $node->getNodeData()->getColsMinWidth(); + $cols_min_width = 'grid-template-columns: repeat(auto-fit, minmax(' . (string)$min_width . 'px, 1fr));'; + } + $fetch_button_hidden = $node->getNodeData()->getNumberOfPages() > 1 ? '' : ' hidden'; + + // ajouter un article + // => fait un peu double emploi avec PostBuilder + $new_article = ''; + if(IS_ADMIN) + { + $id = 'n' . $this->id_node; + + $share_button = ''; + + $new_button = '

    ' . "\n" . '

    '; + + $modify_js = 'onclick="openEditor(\'' . $id . '\')"'; + $modify_article = '' . "\n"; + + $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"'; + $up_button = '' . "\n"; + + $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"'; + $down_button = '' . "\n"; + + $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; + $delete_article = '' . "\n"; + + $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; + $close_editor = ''; + + $position = ''; + + $submit_js = 'onclick="submitArticle(\'' . $id . '\', clone' . $this->id_node . ')"'; + $submit_article = ''; + + $html = ''; + $admin_buttons = $new_button . $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article . $position; + + // squelette d'un nouvel article + ob_start(); + require self::VIEWS_PATH . 'post.php'; + $new_article = ob_get_clean(); + } + + // articles existants + $this->useChildrenBuilder($node); + $content = $this->html; + + ob_start(); + require $viewFile; + $this->html = ob_get_clean(); // pas de concaténation ici, on écrase + } + } +} \ No newline at end of file diff --git a/src/View/PostBuilder.php b/src/View/PostBuilder.php new file mode 100644 index 0000000..ade7304 --- /dev/null +++ b/src/View/PostBuilder.php @@ -0,0 +1,60 @@ +getName() . '.php'; + + if(file_exists($viewFile)) + { + // html + $title = $node->getArticle()->getTitle(); + $html = $node->getArticle()->getContent(); + $id = (string)$node->getId(); + + // partage + $share_link = new URL(['page' => CURRENT_PAGE], $id); + $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"'; + $share_button = '' . "\n"; + + // modifier un article + // => fait un peu double emploi avec PostBlockBuilder + $admin_buttons = ''; + if(IS_ADMIN) + { + $modify_js = 'onclick="openEditor(\'' . $id . '\')"'; + $modify_article = '

    ' . "\n"; + + $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"'; + $up_button = '

    ' . "\n"; + + $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"'; + $down_button = '

    ' . "\n"; + + $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; + $delete_article = '

    ' . "\n"; + + $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; + $close_editor = ''; + + $submit_js = 'onclick="submitArticle(\'' . $id . '\')"'; + $submit_article = ''; + + $admin_buttons = $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article; + } + + ob_start(); + require($viewFile); + $this->html .= ob_get_clean(); + } + } +} diff --git a/src/View/ShowEmailsBuilder.php b/src/View/ShowEmailsBuilder.php new file mode 100644 index 0000000..b02174d --- /dev/null +++ b/src/View/ShowEmailsBuilder.php @@ -0,0 +1,71 @@ +getName() . '.php'; + if(file_exists($viewFile)) + { + // objets Email groupés par destinataire + $emails_by_recipient = []; + foreach($node->getNodeData()->getEmails() as $email){ + $recipient = $email->getRecipient(); + $emails_by_recipient[$recipient][] = $email; + } + + // affiche une table par destinataire + $emails = ''; + foreach($emails_by_recipient as $recipient => $emails_list){ + $html = '

    Destinataire: ' . $recipient . '

    + + + + + + + + + + + + + '; + + // insère les données + foreach($emails_list as $email){ + $html .= ' + + + + + + + + '; + } + + $html .= ' +
    ExpéditeurAdresseContenuDateEffacement prévu leSensible
    ' . htmlspecialchars($email->getSenderName()) . '' . htmlspecialchars($email->getSenderAddress()) . '' . htmlspecialchars($email->getContent()) . '' . $email->getDateTime()->format('d/m/Y') . '' . $email->getDeletionDate()->format('d/m/Y') . 'isSensitive() ? 'checked' : '') . ' onclick="toggleSensitiveEmail(' . $email->getId() . ')">
    '; + $emails .= $html; + } + + ob_start(); + require $viewFile; // insertion de $this->html généré par unfoldMenu + $this->html = ob_get_clean(); // pas de concaténation .= cette fois on écrase + } + else{ + header('Location: ' . new URL(['error' => 'show_emails_view_not_found'])); + die; + } + } +} \ No newline at end of file diff --git a/src/View/UserEditBuilder.php b/src/View/UserEditBuilder.php new file mode 100644 index 0000000..4a9fd90 --- /dev/null +++ b/src/View/UserEditBuilder.php @@ -0,0 +1,64 @@ +getName() . '.php'; + + $error_messages = [ + 'error_non_valid_captcha' => 'Erreur au test anti-robot, veuillez saisir un nombre entier.', + 'captcha_server_error' => 'captcha_server_error', + + 'bad_login_or_password' => 'Mauvais identifiant ou mot de passe, veuillez réessayer.', // ne pas indiquer où est l'erreur + 'bad_solution_captcha' => 'Erreur au test anti-robot, veuillez réessayer.', + 'forbidden_characters' => 'Caractères interdits: espaces, tabulations, sauts CR/LF.', + 'same_username_as_before' => 'Nouveau nom identique au précédent.', + 'same_password_as_before' => 'Nouveau mot de passe identique au précédent.' + ]; + + $error_username = isset($_GET['error_username']) ? $error_messages[$_GET['error_username']] : ''; + $success_username = (isset($_GET['success_username']) && $_GET['success_username']) ? 'Identifiant modifié avec succès.' : ''; + $error_password = isset($_GET['error_password']) ? $error_messages[$_GET['error_password']] : ''; + $success_password = (isset($_GET['success_password']) && $_GET['success_password']) ? 'Mot de passe modifié avec succès.' : ''; + + $captcha = new Captcha; + $_SESSION['captcha'] = $captcha->getSolution(); // enregistrement de la réponse du captcha pour vérification + + $link_user_form = new URL(['action' => 'update_username']); + isset($_GET['from']) ? $link_user_form->addParams(['from' => $_GET['from']]) : ''; + isset($_GET['id']) ? $link_user_form->addParams(['id' => $_GET['id']]) : ''; + + $link_password_form = new URL(['action' => 'update_password']); + isset($_GET['from']) ? $link_password_form->addParams(['from' => $_GET['from']]) : ''; + isset($_GET['id']) ? $link_password_form->addParams(['id' => $_GET['id']]) : ''; + + $link_exit = new URL; + isset($_GET['from']) ? $link_exit->addParams(['page' => $_GET['from'] ]) : ''; + isset($_GET['id']) ? $link_exit->addParams(['id' => $_GET['id']]) : ''; + + $link_logout = new URL(['action' => 'deconnection']); + isset($_GET['from']) ? $link_logout->addParams(['from' => $_GET['from'] ]) : ''; + isset($_GET['id']) ? $link_logout->addParams(['id' => $_GET['id']]) : ''; + + ob_start(); + require $viewFile; + $this->html = ob_get_clean(); // nouveau contenu + } +} \ No newline at end of file diff --git a/src/View/ViewDirector.php b/src/View/ViewDirector.php new file mode 100644 index 0000000..af35179 --- /dev/null +++ b/src/View/ViewDirector.php @@ -0,0 +1,30 @@ +root_node = $root_node; + $this->useChildrenBuilder($this->root_node); + + if(isset($_SESSION['flash_message'])){ + $this->html .= ''; + unset($_SESSION['flash_message']); + } + + return $this->html; + } +} \ No newline at end of file diff --git a/src/View/templates/calendar.php b/src/View/templates/calendar.php new file mode 100644 index 0000000..fd920fd --- /dev/null +++ b/src/View/templates/calendar.php @@ -0,0 +1,14 @@ + +
    + + + +

    +
    +
    + +
    +
    \ 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..cd8bd0a --- /dev/null +++ b/src/View/templates/footer.php @@ -0,0 +1,43 @@ + +
    + +
    +
    + + + +
    + + + + +
    +
    +
    + +
    +
    +
    + + + \ No newline at end of file diff --git a/src/View/templates/form.php b/src/View/templates/form.php new file mode 100644 index 0000000..384bde9 --- /dev/null +++ b/src/View/templates/form.php @@ -0,0 +1,36 @@ + +
    +

    + +
    + + + + + + + + + +
    + +
    + + +
    + +
    + + + + +
    + +
    + +

    +
    +

    + Une copie de votre e-mail (nom, adresse et message) sera conservée dans notre base de données dans le but de pouvoir mieux répondre à votre demande et éventuellement dans d'autres buts (prospection). Ces données seront traitées automatiquement par notre serveur et conservées pendant au maximum mois à compter de votre dernier message. Ce traitement repose sur votre consentement. Vous pouvez consulter, modifier ou supprimer vos 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 new file mode 100644 index 0000000..47bca38 --- /dev/null +++ b/src/View/templates/form_admin.php @@ -0,0 +1,73 @@ + +
    +

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

    +

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

    +

    +

    + + +

    +

    + + +

    + +
    +
    +

    Paramètres d'envoi

    +

    + + + + +

    +

    + + + +

    +

    + + + + +

    +

    + + + + +

    +

    Il s'agit du service qui acheminera les messages envoyés par ce formulaire.
    + Site web => serveur d'envoi => serveur de réception => votre application "mail"

    +

    + Ce formulaire utilise les paramètres dans le fichier config.ini sur le serveur à mois que vous n'en renseignez d'autres ci-dessus. Les adresses d'envoi et de réception peuvent être identiques. +

    +

    Le site web peut ne pas réussir à se connecter à certains fournisseurs.

    +
    +
    +

    Paramètres de réception

    +

    + + + + +

    +
    +
    +

    +

    Vérifie la connexion au serveur d'envoi. Pour tester la réception, consultez vos e-mails à l'adresse de réception.

    +

    +
    \ 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..97f8cd8 --- /dev/null +++ b/src/View/templates/galery.php @@ -0,0 +1,12 @@ + +
    +

    + + +
    + +
    + +
    \ 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..bce0a19 --- /dev/null +++ b/src/View/templates/head.php @@ -0,0 +1,13 @@ + + + + + + + <?= $title ?> + + + + + + \ 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..08bc478 --- /dev/null +++ b/src/View/templates/header.php @@ -0,0 +1,58 @@ + + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    +
    + +
    +
    + +
    +
    + + + +
    \ No newline at end of file diff --git a/src/View/templates/login.php b/src/View/templates/login.php new file mode 100644 index 0000000..3257690 --- /dev/null +++ b/src/View/templates/login.php @@ -0,0 +1,31 @@ + +
    +

    Connexion à l'espace d'administration

    +
    +

    Veuillez saisir votre identifiant et votre mot de passe.

    +

    +
    +

    +

    +

    +

    + + +

    Montrez que vous n'êtes pas un robot.
    + + +

    + + +
    +

    Au fait? Vous n'utilisez pas votre propre ordinateur ou téléphone?
    + Utilisez la navigation privée.

    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/View/templates/maintenance.php b/src/View/templates/maintenance.php new file mode 100644 index 0000000..5a8a46d --- /dev/null +++ b/src/View/templates/maintenance.php @@ -0,0 +1,65 @@ + +
    +

    Maintenance du site

    +
    +

    +
    + Qui a essayé de se connecter, quand et a-t'il réussi? +

    +
    +

    + +
    +
    +

    + + reçus depuis tous les formulaires de contact +

    +
    +
    +

    + + +
    + Obtenir un fichier SQL à conserver. Une sauvegarde (désignée par "auto") est réalisée à chaque connexion au mode admin. +

    +
    +
    +

    Restaurer la base de données à partir d'un fichier SQL.
    + Attention, l'actuelle BDD sera écrasée! (à l'exception de la table user) +

    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    +

    + + +
    + Toutes vos photos et vos documents dans un .zip +

    +

    +
    + Gérer les fichiers multimedia, fonction actuellement indisponible +

    +
    + + +
    \ No newline at end of file diff --git a/src/View/templates/menu.php b/src/View/templates/menu.php new file mode 100644 index 0000000..5a15fdb --- /dev/null +++ b/src/View/templates/menu.php @@ -0,0 +1,51 @@ + + +
    + +
    \ No newline at end of file diff --git a/src/View/templates/modify_block.php b/src/View/templates/modify_block.php new file mode 100644 index 0000000..bb5abd3 --- /dev/null +++ b/src/View/templates/modify_block.php @@ -0,0 +1,61 @@ + +
    +
    + +

    + + +

    +
    +

    + + +

    +
    + + + +
    +
    +
    +getName() === 'news_block'){ +?> +
    + + +
    +getName())){ +?> +
    +
    + + +
    +
    + + pixels +
    +
    +
    + +
    + +
    \ No newline at end of file diff --git a/src/View/templates/modify_page.php b/src/View/templates/modify_page.php new file mode 100644 index 0000000..773277b --- /dev/null +++ b/src/View/templates/modify_page.php @@ -0,0 +1,62 @@ + +
    +

    Modification de la page

    +
    +
    +

    + + + +

    +
    + + + + +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    +

    Ajouter un bloc de page

    +
    +

    +

    +

    + + +

    +
    +
    +

    Articles libres: textes riches générés par l'éditeur et librement positionnables

    +

    Actualités: contenus structurés avec titre, aperçu, date et possédant une page dédiée

    + +
    +
    +
    +

    Modifier un bloc

    + +
    +
    +
    \ 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..30b244f --- /dev/null +++ b/src/View/templates/new.php @@ -0,0 +1,27 @@ + +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + + Chargement... +

    +
    + +
    + +
    +
    +
    \ No newline at end of file diff --git a/src/View/templates/new_page.php b/src/View/templates/new_page.php new file mode 100644 index 0000000..535d88d --- /dev/null +++ b/src/View/templates/new_page.php @@ -0,0 +1,38 @@ + +
    +

    Création d'une nouvelle page

    +
    +
    +

    + + +

    +

    + + +

    +

    + + +

    + +

    + + +

    + +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/View/templates/news_block.php b/src/View/templates/news_block.php new file mode 100644 index 0000000..43dbe01 --- /dev/null +++ b/src/View/templates/news_block.php @@ -0,0 +1,14 @@ + +
    +

    + + +
    + +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/View/templates/post.php b/src/View/templates/post.php new file mode 100644 index 0000000..d0d01b2 --- /dev/null +++ b/src/View/templates/post.php @@ -0,0 +1,14 @@ + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/src/View/templates/post_block.php b/src/View/templates/post_block.php new file mode 100644 index 0000000..43dbe01 --- /dev/null +++ b/src/View/templates/post_block.php @@ -0,0 +1,14 @@ + +
    +

    + + +
    + +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/View/templates/show_emails.php b/src/View/templates/show_emails.php new file mode 100644 index 0000000..f561dc7 --- /dev/null +++ b/src/View/templates/show_emails.php @@ -0,0 +1,30 @@ + +
    +

    Table "email" de la base de données

    +

    + Les e-mails ci-dessous sont des copies de ceux arrivés dans votre boite de messagerie depuis tous les formulaires existant sur le site. Ils sont conservés dans un but pratique (historique, prospection) ou dans tout autre but justifiant leur conservation. Cette conservation est optionnelle et règlementée par la loi européenne RGPD.
    + Notez qu'utiliser cette application ne vous garantit pas d'être en conformité avec la loi, c'est un outil vous permettant de faire les choses comme vous l'entendez. Si tout ceci vous gêne, désactivez le stockage des e-mails et supprimez ceux déjà enregistrés (ci-dessous). +

    +

    Durées de conservation

    +

    + 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ù les personnes concernées le demandent.
    +

    +

    + 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 est considéré inactif).
    + Les e-mails sensibles quand à eux sont supprimés 5 ans après être devenus sensibles (durée juridique d'une preuve). +

    +

    + Un nettoyeur supprimant les messages dépassant ces durées est exécuté au moment de votre connexion au mode administrateur.
    + Si vos connexions sont rares, il est possible d'automatiser ce nettoyage à l'aide d'une tâche CRON. Pour cela, vous devez configurer le serveur pour qu'il exécute periodiquement la commande "php /chemin/du/site/bin/cron.php". +

    +

    Données sensibles

    +

    + 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.
    + 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. +

    +

    + Les spams ne sont pas sensibles, c'est juste de la pollution, supprimez-les! +

    + + +
    \ No newline at end of file diff --git a/src/View/templates/user_create.php b/src/View/templates/user_create.php new file mode 100644 index 0000000..662d9ac --- /dev/null +++ b/src/View/templates/user_create.php @@ -0,0 +1,54 @@ + 'Erreur au test anti-robot, veuillez saisir un nombre entier.', + 'captcha_server_error' => 'captcha_server_error', + 'bad_solution_captcha' => 'Erreur au test anti-robot, veuillez réessayer.', + 'bad_login_or_password' => 'Mauvais identifiant ou mot de passe, veuillez réessayer.', + 'different_passwords' => 'Les deux mots de passe saisis sont différents', + 'forbidden_characters' => 'Caractères interdits: espaces, tabulations, sauts CR/LF.' +]; +$error = isset($_GET['error']) ? $error_messages[$_GET['error']] : ''; + +$captcha = new Captcha; +$_SESSION['captcha'] = $captcha->getSolution(); // enregistrement de la réponse du captcha pour vérification +?> + + + + + Bienvenue + + + + + +
    +
    +

    Bienvenue.

    +

    Pour commencer, veuillez créer un compte administrateur.

    +
    +

    +
    +

    +

    +

    +

    +

    +

    + + +

    Montrez que vous n'êtes pas un robot.
    + + +

    + + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/src/View/templates/user_edit.php b/src/View/templates/user_edit.php new file mode 100644 index 0000000..9191e7d --- /dev/null +++ b/src/View/templates/user_edit.php @@ -0,0 +1,63 @@ + +
    +
    +
    +

    Mon compte

    +
    + +
    +
    +
    +
    +
    +

    Modifier mon nom d'utilisateur.

    +

    +

    +
    +

    +

    +

    +

    +

    +

    + + +

    Montrez que vous n'êtes pas un robot.
    + + +

    + + +
    +
    +
    +

    Modifier mon mot de passe.

    +

    +

    +
    +

    +

    +

    +

    +

    +

    + + +

    Montrez que vous n'êtes pas un robot.
    + + +

    + + +
    +
    +
    +
    +
    + +
    \ No newline at end of file -- cgit v1.2.3