From 90673ef19133e037cf401773f4262ba3d7d050bf Mon Sep 17 00:00:00 2001
From: polo
Date: Sun, 3 Aug 2025 04:06:53 +0200
Subject: =?UTF-8?q?r=C3=A9organisation=204:=20d=C3=A9placement=20de=20fich?=
=?UTF-8?q?iers,=20plus=20que=20des=20contr=C3=B4leurs=20dans=20/src/contr?=
=?UTF-8?q?oller?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/index.php | 4 +-
src/Captcha.php | 52 ++++++++
src/Config.php | 2 +-
src/Security.php | 117 +++++++++++++++++
src/URL.php | 88 +++++++++++++
src/controller/Captcha.php | 52 --------
src/controller/Security.php | 117 -----------------
src/controller/URL.php | 88 -------------
src/controller/installation.php | 178 --------------------------
src/controller/request_router.php | 256 --------------------------------------
src/installation.php | 178 ++++++++++++++++++++++++++
src/request_router.php | 256 ++++++++++++++++++++++++++++++++++++++
12 files changed, 694 insertions(+), 694 deletions(-)
create mode 100644 src/Captcha.php
create mode 100644 src/Security.php
create mode 100644 src/URL.php
delete mode 100644 src/controller/Captcha.php
delete mode 100644 src/controller/Security.php
delete mode 100644 src/controller/URL.php
delete mode 100644 src/controller/installation.php
delete mode 100644 src/controller/request_router.php
create mode 100644 src/installation.php
create mode 100644 src/request_router.php
diff --git a/public/index.php b/public/index.php
index ba0e354..b7eeeae 100644
--- a/public/index.php
+++ b/public/index.php
@@ -13,7 +13,7 @@ require "../vendor/autoload.php";
Config::load('../config/config.ini');
// les messages d'erreur de déploiement qu'on aime
-require('../src/controller/installation.php');
+require('../src/installation.php');
phpDependancies();
//installation(); // des mkdir et chmod, chiant en dev
@@ -54,7 +54,7 @@ if(!empty($_GET['id']))
}
/* -- routeur des données de formulaires et requêtes AJAX -- */
-require '../src/controller/request_router.php';
+require '../src/request_router.php';
/* -- affichage d'une page -- */
diff --git a/src/Captcha.php b/src/Captcha.php
new file mode 100644
index 0000000..c60a186
--- /dev/null
+++ b/src/Captcha.php
@@ -0,0 +1,52 @@
+a = rand(2, 9);
+ $this->b = rand(2, 9);
+ $this->solution = $this->a * $this->b;
+ }
+
+ public function getA(): string
+ {
+ return $this->toLettersFrench($this->a);
+ }
+ public function getB(): string
+ {
+ return $this->toLettersFrench($this->b);
+ }
+ public function getSolution(): int
+ {
+ return $this->solution;
+ }
+
+ private function toLettersFrench(int $number): string
+ {
+ return match($number){
+ 2 => 'deux',
+ 3 => 'trois',
+ 4 => 'quatre',
+ 5 => 'cinq',
+ 6 => 'six',
+ 7 => 'sept',
+ 8 => 'huit',
+ 9 => 'neuf',
+ default => '', // erreur
+ };
+ }
+ static public function controlInput(string $input = '0'): int
+ {
+ // un POST est une chaîne qu'on doit convertir en nombre dans deux conditions:
+ // test de format: $input est un nombre
+ // test d'intégrité: supprimer les décimales avec (int) ne change pas la valeur du nombre
+ return is_numeric($input) && $input == (int)$input ? (int)$input : 0;
+ }
+}
\ No newline at end of file
diff --git a/src/Config.php b/src/Config.php
index caa91d0..e25c180 100644
--- a/src/Config.php
+++ b/src/Config.php
@@ -1,5 +1,5 @@
1, // protection contre les élements et attributs dangereux
+
+ // liste blanche d'éléments HTML
+ 'elements'=> 'h1, h2, h3, h4, h5, h6, p, br, s, em, span, strong, a, ul, ol, li, sup, sub, code, blockquote, div, pre, table, caption, colgroup, col, tbody, tr, th, td, figure, img, figcaption, iframe, small',
+
+ // liste noire d'attributs HTML
+ 'deny_attribute'=> 'id, class' // on garde 'style'
+ );
+ // faire qu'un certain élément puisse n'avoir que certains attributs, regarder la doc
+ private static $specHtmLawed = '';
+
+ // ATTENTION, n'applique pas htmlspecialchars() !!
+ public static function secureString(string $chaine): string
+ {
+ return trim(htmLawed($chaine, self::$configHtmLawed, self::$specHtmLawed));
+ }
+
+ public static function secureFileName(string $chaine): string
+ {
+ // sécuriser un nom avec chemin avec basename?
+ //$chaine = basename($chaine);
+
+ /*
+ - caractères interdits sous windows / \ : * ? " < > |
+ - mac autorise les /
+ - mac interdit :
+ - linux autorise tout sauf les /
+ - imagemagick ne supporte pas les :
+
+ - 'espace' fonctionne
+ - / remplacé par firefox en :
+ - \ retire ce qui est devant le \
+ - * fonctionne
+ - ? permet le téléchargement mais pas l'affichage
+ - " ne fonctionne pas, remplacé par %22, filtrer %22
+ - < > fonctionnent
+ - | fonctionne
+ - = fonctionne, mais je filtre parce qu'on en trouve dans une URL
+ - ' ` fonctionnent
+ - % fonctionne
+ - (){}[] fonctionnent
+ - ^ fonctionne
+ - # ne fonctionne pas
+ - ~ fonctionne
+ - & fonctionne
+ - ^ pas encore testé
+ */
+
+ // => on remplace tout par des _
+ // filtrer / et \ semble inutile
+
+ /*$cibles = [' ', '/', '\\', ':', '*', '?', '<', '>', '|', '=', "'", '`', '"', '%22', '#'];
+ $chaine = str_replace($cibles, '_', $chaine); // nécéssite l'extension mbstring
+ $chaine = mb_strtolower($chaine);
+ return($chaine);*/
+
+ $chaine = preg_replace('/[^a-zA-Z0-9_-]/', '_', $chaine); // ne garder que les lettres, chiffres, tirets et underscores
+ $chaine = preg_replace('/_+/', '_', $chaine); // doublons d'underscores
+ return trim($chaine, '_');
+
+ // les problèmes avec \ persistent !!
+ // => javascript
+ // malheureusement document.getElementById('upload').files[0].name = chaine; ne marche pas! interdit!
+ // javascript ne doit pas pouvoir accéder au système de fichiers
+ // solutions:
+ // - au lieu de fournir une chaine (le chemin du fichier), donner un objet à files[0].name
+ // - créer une copie du fichier et l'envoyer à la place
+ // - envoyer le fichier en AJAX
+ // - envoyer le nom du fichier à part puis renommer en PHP
+ }
+}
+
+// erreurs à la création des mots de passe
+function removeSpacesTabsCRLF(string $chaine): string
+{
+ $cibles = [' ', "\t", "\n", "\r"]; // doubles quotes !!
+ return(str_replace($cibles, '', $chaine));
+}
+
+// lien sans http://
+function fixLinks($data)
+{
+ // 1/
+ // si une adresse est de type "domaine.fr" sans le http:// devant, le comportement des navigateurs est de rechercher un fichier comme si mon adresse commençait par file://
+ // tomber ainsi sur une page d'erreur est parfaitement déroutant
+
+ // regex pour détecter les balises et ajouter http:// au début des liens si nécessaire
+ $pattern = '#(]+href=")((?!https?://)[^>]+>)#';
+ //$data = preg_replace($pattern, '$1http://$2', $data);
+
+ // 2/
+ // cas où la regex fait mal son boulot:
+ // l'erreur 404 est gérée par le .htaccess
+ // et le visiteur est redirigé à la page "menu"
+ // (ça ne règle pas le problème mais c'est mieux)
+
+ // 3/
+ // quand l'éditeur est ouvert (avant de valider l'article),
+ // le lien qu'on vient de créer apparaît dans l'infobulle,
+ // cliquer dessus ouvre un onglet sur une erreur 404
+ // solution partielle avec le .htaccess
+ //
+ // solution? fermer ce nouvel onglet avec echo '';
+ // comment déclencher le JS? en faisant qu'une erreur 404 causée pour cette raison soit particulière?
+
+ return($data);
+}
diff --git a/src/URL.php b/src/URL.php
new file mode 100644
index 0000000..689332f
--- /dev/null
+++ b/src/URL.php
@@ -0,0 +1,88 @@
+params = $gets;
+ if($anchor != ''){
+ $this->setAnchor($anchor);
+ }
+ }
+
+ //setters normaux
+ public function addParams(array $gets): void
+ {
+ // array_merge est préféré à l'opérateur d'union +, si une clé existe déjà la valeur est écrasée
+ $this->params = array_merge($this->params, $gets);
+ }
+ public function setAnchor(string $anchor = ''): void
+ {
+ if($anchor != ''){
+ $this->anchor = '#' . ltrim($anchor, '#');
+ }
+ else{
+ $this->anchor = '';
+ }
+ }
+
+ private function makeParams(): string
+ {
+ $output = '';
+ $first = true;
+
+ foreach($this->params as $key => $value) {
+ if($first){
+ $output .= '?';
+ $first = false;
+ }
+ else{
+ $output .= '&';
+ }
+ $output .= $key . '=' . $value;
+ }
+ return $output;
+ }
+
+ public function __toString(): string
+ {
+ return self::$protocol . self::$host . self::$port . self::$path . $this->makeParams() . $this->anchor;
+ }
+}
\ No newline at end of file
diff --git a/src/controller/Captcha.php b/src/controller/Captcha.php
deleted file mode 100644
index da61a53..0000000
--- a/src/controller/Captcha.php
+++ /dev/null
@@ -1,52 +0,0 @@
-a = rand(2, 9);
- $this->b = rand(2, 9);
- $this->solution = $this->a * $this->b;
- }
-
- public function getA(): string
- {
- return $this->toLettersFrench($this->a);
- }
- public function getB(): string
- {
- return $this->toLettersFrench($this->b);
- }
- public function getSolution(): int
- {
- return $this->solution;
- }
-
- private function toLettersFrench(int $number): string
- {
- return match($number){
- 2 => 'deux',
- 3 => 'trois',
- 4 => 'quatre',
- 5 => 'cinq',
- 6 => 'six',
- 7 => 'sept',
- 8 => 'huit',
- 9 => 'neuf',
- default => '', // erreur
- };
- }
- static public function controlInput(string $input = '0'): int
- {
- // un POST est une chaîne qu'on doit convertir en nombre dans deux conditions:
- // test de format: $input est un nombre
- // test d'intégrité: supprimer les décimales avec (int) ne change pas la valeur du nombre
- return is_numeric($input) && $input == (int)$input ? (int)$input : 0;
- }
-}
\ No newline at end of file
diff --git a/src/controller/Security.php b/src/controller/Security.php
deleted file mode 100644
index b882d42..0000000
--- a/src/controller/Security.php
+++ /dev/null
@@ -1,117 +0,0 @@
-1, // protection contre les élements et attributs dangereux
-
- // liste blanche d'éléments HTML
- 'elements'=> 'h1, h2, h3, h4, h5, h6, p, br, s, em, span, strong, a, ul, ol, li, sup, sub, code, blockquote, div, pre, table, caption, colgroup, col, tbody, tr, th, td, figure, img, figcaption, iframe, small',
-
- // liste noire d'attributs HTML
- 'deny_attribute'=> 'id, class' // on garde 'style'
- );
- // faire qu'un certain élément puisse n'avoir que certains attributs, regarder la doc
- private static $specHtmLawed = '';
-
- // ATTENTION, n'applique pas htmlspecialchars() !!
- public static function secureString(string $chaine): string
- {
- return trim(htmLawed($chaine, self::$configHtmLawed, self::$specHtmLawed));
- }
-
- public static function secureFileName(string $chaine): string
- {
- // sécuriser un nom avec chemin avec basename?
- //$chaine = basename($chaine);
-
- /*
- - caractères interdits sous windows / \ : * ? " < > |
- - mac autorise les /
- - mac interdit :
- - linux autorise tout sauf les /
- - imagemagick ne supporte pas les :
-
- - 'espace' fonctionne
- - / remplacé par firefox en :
- - \ retire ce qui est devant le \
- - * fonctionne
- - ? permet le téléchargement mais pas l'affichage
- - " ne fonctionne pas, remplacé par %22, filtrer %22
- - < > fonctionnent
- - | fonctionne
- - = fonctionne, mais je filtre parce qu'on en trouve dans une URL
- - ' ` fonctionnent
- - % fonctionne
- - (){}[] fonctionnent
- - ^ fonctionne
- - # ne fonctionne pas
- - ~ fonctionne
- - & fonctionne
- - ^ pas encore testé
- */
-
- // => on remplace tout par des _
- // filtrer / et \ semble inutile
-
- /*$cibles = [' ', '/', '\\', ':', '*', '?', '<', '>', '|', '=', "'", '`', '"', '%22', '#'];
- $chaine = str_replace($cibles, '_', $chaine); // nécéssite l'extension mbstring
- $chaine = mb_strtolower($chaine);
- return($chaine);*/
-
- $chaine = preg_replace('/[^a-zA-Z0-9_-]/', '_', $chaine); // ne garder que les lettres, chiffres, tirets et underscores
- $chaine = preg_replace('/_+/', '_', $chaine); // doublons d'underscores
- return trim($chaine, '_');
-
- // les problèmes avec \ persistent !!
- // => javascript
- // malheureusement document.getElementById('upload').files[0].name = chaine; ne marche pas! interdit!
- // javascript ne doit pas pouvoir accéder au système de fichiers
- // solutions:
- // - au lieu de fournir une chaine (le chemin du fichier), donner un objet à files[0].name
- // - créer une copie du fichier et l'envoyer à la place
- // - envoyer le fichier en AJAX
- // - envoyer le nom du fichier à part puis renommer en PHP
- }
-}
-
-// erreurs à la création des mots de passe
-function removeSpacesTabsCRLF(string $chaine): string
-{
- $cibles = [' ', "\t", "\n", "\r"]; // doubles quotes !!
- return(str_replace($cibles, '', $chaine));
-}
-
-// lien sans http://
-function fixLinks($data)
-{
- // 1/
- // si une adresse est de type "domaine.fr" sans le http:// devant, le comportement des navigateurs est de rechercher un fichier comme si mon adresse commençait par file://
- // tomber ainsi sur une page d'erreur est parfaitement déroutant
-
- // regex pour détecter les balises et ajouter http:// au début des liens si nécessaire
- $pattern = '#(]+href=")((?!https?://)[^>]+>)#';
- //$data = preg_replace($pattern, '$1http://$2', $data);
-
- // 2/
- // cas où la regex fait mal son boulot:
- // l'erreur 404 est gérée par le .htaccess
- // et le visiteur est redirigé à la page "menu"
- // (ça ne règle pas le problème mais c'est mieux)
-
- // 3/
- // quand l'éditeur est ouvert (avant de valider l'article),
- // le lien qu'on vient de créer apparaît dans l'infobulle,
- // cliquer dessus ouvre un onglet sur une erreur 404
- // solution partielle avec le .htaccess
- //
- // solution? fermer ce nouvel onglet avec echo '';
- // comment déclencher le JS? en faisant qu'une erreur 404 causée pour cette raison soit particulière?
-
- return($data);
-}
diff --git a/src/controller/URL.php b/src/controller/URL.php
deleted file mode 100644
index 3ebc488..0000000
--- a/src/controller/URL.php
+++ /dev/null
@@ -1,88 +0,0 @@
-params = $gets;
- if($anchor != ''){
- $this->setAnchor($anchor);
- }
- }
-
- //setters normaux
- public function addParams(array $gets): void
- {
- // array_merge est préféré à l'opérateur d'union +, si une clé existe déjà la valeur est écrasée
- $this->params = array_merge($this->params, $gets);
- }
- public function setAnchor(string $anchor = ''): void
- {
- if($anchor != ''){
- $this->anchor = '#' . ltrim($anchor, '#');
- }
- else{
- $this->anchor = '';
- }
- }
-
- private function makeParams(): string
- {
- $output = '';
- $first = true;
-
- foreach($this->params as $key => $value) {
- if($first){
- $output .= '?';
- $first = false;
- }
- else{
- $output .= '&';
- }
- $output .= $key . '=' . $value;
- }
- return $output;
- }
-
- public function __toString(): string
- {
- return self::$protocol . self::$host . self::$port . self::$path . $this->makeParams() . $this->anchor;
- }
-}
\ No newline at end of file
diff --git a/src/controller/installation.php b/src/controller/installation.php
deleted file mode 100644
index d9ea44b..0000000
--- a/src/controller/installation.php
+++ /dev/null
@@ -1,178 +0,0 @@
-l'extension " . $extension . ' est manquante
');
- $flag = true;
- }
- }
- if(!extension_loaded('imagick') && !extension_loaded('gd')){
- echo("il manque une de ces extensions au choix pour le traitement des images: imagick (de préférence) ou gd.
");
- $flag = true;
- }
- if($flag){
- echo 'Réalisez les actions nécéssaires sur le serveur ou contactez l\'administrateur du site.
- Quand le problème sera résolu, il vous suffira de recharger la page.
';
- die;
- }
-}
-
-// inutilisée pour l'instant
-function installation(): void
-{
- /* -- droits des fichiers et dossiers -- */
- $droits_dossiers = 0700;
- $droits_fichiers = 0600;
-
- // accès interdit en HTTP
- if(!file_exists('../config/.htaccess')){
- $contenu = <<< HTACCESS
-
- Order Allow,Deny
- Deny from all
-
-HTACCESS;
-
- $fichier = fopen('../config/.htaccess', 'w');
- fputs($fichier, $contenu);
- fclose($fichier);
- chmod('../config/.htaccess', $droits_fichiers);
- //echo("danger
pas de .htaccess dans config
prévenez le responsable du site");
- //die;
- }
-
- // accès limité en local (600) pour config.ini
- if(substr(sprintf('%o', fileperms('../config/config.ini')), -4) != 600){
- chmod('../config/config.ini', $droits_fichiers);
- }
-
- // création de data et sous-dossiers
- if(!file_exists('../data')){
- mkdir('../data/');
- chmod('../data/', $droits_dossiers);
- }
- if(!touch('../data')){
- echo("dossier data non autorisé en écriture");
- die;
- }
- $sous_dossiers = array('images', 'images-mini', 'videos');
- foreach ($sous_dossiers as $sous_dossier){
- if(!file_exists('../data/' . $sous_dossier)){
- mkdir('../data/' . $sous_dossier);
- chmod('../data/' . $sous_dossier, $droits_dossiers);
- }
- if(!touch('../data/' . $sous_dossier)){
- echo("dossier data non autorisé en écriture");
- die;
- }
- }
-}
-
-// création d'un site minimal avec une page d'accueil à la toute 1ère visite du site
-// fonctiona appelée après la première requête envoyée en BDD,
-// en l'occurence dans Menu parce que count($bulk_data) === 0
-function makeStartPage(EntityManager $entityManager){
- /* -- table page -- */
- // paramètres: name_page, end_of_path, reachable, in_menu, hidden, position, parent
- $accueil = new Page('Accueil', 'accueil', true, true, false, 1, NULL);
- $article = new Page('Article', 'article', true, false, false, NULL, NULL);
- $connection = new Page('Connexion', 'connexion', true, false, false, NULL, NULL);
- $menu_paths = new Page("Menu et chemins", 'menu_chemins', true, false, false, NULL, NULL);
- //$edit_page = new Page("Modification d'une page", 'modif_page', true, false, false, NULL, NULL); // pas de page "Modification de la page"
- $new_page = new Page('Nouvelle page', 'nouvelle_page', true, false, false, NULL, NULL);
-
- /* -- table node -- */
- // paramètres: name_node, article_timestamp, attributes, position, parent, page, article
- $head_accueil = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'foot'], 'js_array' => ['main']], 1, NULL, $accueil, NULL);
- $head_article = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'foot'], 'js_array' => ['main']], 1, NULL, $article, NULL);
- $header = new Node('header', NULL, [], 2, NULL, NULL, NULL);
- $nav = new Node('nav', NULL, [], 1, $header, NULL, NULL);
- $main = new Node('main', NULL, [], 3, NULL, NULL, NULL);
- $footer = new Node('footer', NULL, [], 4, NULL, NULL, NULL);
- $breadcrumb = new Node('breadcrumb', NULL, [], 2, $header, NULL, NULL);
- $head_login = new Node('head', NULL, ["stop" => true, 'css_array' => ['body', 'head', 'nav'], 'js_array' => ['main']], 1, NULL, $connection, NULL);
- $login = new Node('login', NULL, [], 1, $main, $connection, NULL);
- $head_edit_menu = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'menu', 'foot'], 'js_array' => ['main', 'menu']], 1, NULL, $menu_paths, NULL);
- $bloc_edit_menu = new Node('menu', NULL, [], 1, $main, $menu_paths, NULL);
- $head_new_page = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'new_page', 'foot'], 'js_array' => ['main', 'new_page']], 1, NULL, $new_page, NULL);
- $bloc_new_page = new Node('new_page', NULL, [], 1, $main, $new_page, NULL);
-
- /* -- table image -- */
- // paramètres: file_name, file_path, file_path_mini, mime_type, alt
- $favicon = new Image("favicon48x48.png", NULL, "assets/favicon48x48.png", "image/png", "favicon");
- $facebook = new Image("facebook.svg", NULL, "assets/facebook.svg", "image/svg+xml", "facebook");
- $instagram = new Image("instagram.svg", NULL, "assets/instagram.svg", "image/svg+xml", "instagram");
- $linkedin = new Image("linkedin.svg", NULL, "assets/linkedin.svg", "image/svg+xml", "linkedin");
- $github = new Image("github.svg", NULL, "assets/github.svg", "image/svg+xml", "github");
-
- /* -- table node_data -- */
- // paramètres: data, node, images
- $head_accueil_data = new NodeData(["description" => "page d'accueil"], $head_accueil, new ArrayCollection([$favicon]));
- $head_login_data = new NodeData(["description" => "Connexion"], $head_login, new ArrayCollection([$favicon]));
- $head_article_data = new NodeData(["description" => ""], $head_article, new ArrayCollection([$favicon]));
- $head_edit_menu_data = new NodeData(["description" => "Menu et chemins"], $head_edit_menu, new ArrayCollection([$favicon]));
- $head_new_page_data = new NodeData(["description" => "Nouvelle page"], $head_new_page, new ArrayCollection([$favicon]));
- $header_data = new NodeData(["title" => "Titre", "description" => "Sous-titre", "header_logo" => "assets/logo-nb-et-ffn.png", "header_background" => "assets/fond-piscine.jpg",
- "social" => ["facebook" => "https://www.facebook.com", "instagram" => "https://www.instagram.com", "linkedin" => "https://www.linkedin.com"]],
- $header, new ArrayCollection([$facebook, $instagram, $linkedin, $github]));
- $footer_data = new NodeData(["contact_nom" => "Nom", "adresse" => "adresse", "e_mail" => "e-mail", "footer_logo" => "assets/logo-nb-et-ffn.png"], $footer);
-
- /* -- table page -- */
- $entityManager->persist($accueil);
- $entityManager->persist($article);
- $entityManager->persist($connection);
- $entityManager->persist($menu_paths);
- //$entityManager->persist($edit_page); // pas de page "Modification de la page"
- $entityManager->persist($new_page);
-
- /* -- table node -- */
- $entityManager->persist($head_accueil);
- $entityManager->persist($header);
- $entityManager->persist($nav);
- $entityManager->persist($main);
- $entityManager->persist($footer);
- $entityManager->persist($breadcrumb);
- $entityManager->persist($head_login);
- $entityManager->persist($login);
- $entityManager->persist($head_article);
- $entityManager->persist($head_edit_menu);
- $entityManager->persist($bloc_edit_menu);
- $entityManager->persist($head_new_page);
- $entityManager->persist($bloc_new_page);
-
- /* -- table image -- */
- $entityManager->persist($favicon);
- $entityManager->persist($facebook);
- $entityManager->persist($instagram);
- $entityManager->persist($linkedin);
- $entityManager->persist($github);
-
- /* -- table node_data -- */
- $entityManager->persist($head_accueil_data);
- $entityManager->persist($header_data);
- $entityManager->persist($footer_data);
- $entityManager->persist($head_login_data);
- $entityManager->persist($head_article_data);
- $entityManager->persist($head_edit_menu_data);
- $entityManager->persist($head_new_page_data);
-
- $entityManager->flush();
- header('Location: ' . new URL);
- die;
-}
\ No newline at end of file
diff --git a/src/controller/request_router.php b/src/controller/request_router.php
deleted file mode 100644
index 157bc80..0000000
--- a/src/controller/request_router.php
+++ /dev/null
@@ -1,256 +0,0 @@
-: position = nombre d'éléments de la fraterie + 1, l'élément précédent devient le parent
- if($_GET['menu_edit'] === 'move_one_level_down' && isset($json['id'])){
- MenuAndPathsController::MoveOneLevelDown($entityManager, $json);
- }
-
- if($_GET['menu_edit'] === 'switch_positions' && isset($json['id1']) && isset($json['id2'])){
- MenuAndPathsController::switchPositions($entityManager, $json);
- }
-
- if($_GET['menu_edit'] === 'displayInMenu' && isset($json['id']) && isset($json['checked'])){
- MenuAndPathsController::displayInMenu($entityManager, $json);
- }
- }
-
- /* -- mode Modification d'une page -- */
- // partie "page"
- elseif(isset($_GET['page_edit']))
- {
- // titre de la page
- if($_GET['page_edit'] === 'page_title'){
- PageManagementController::setPageTitle($entityManager, $json);
- }
- // description dans les métadonnées
- elseif($_GET['page_edit'] === 'page_description'){
- PageManagementController::setPageDescription($entityManager, $json);
- }
- }
-
- // partie "blocs"
- elseif(isset($_GET['bloc_edit']))
- {
- // renommage d'un bloc
- if($_GET['bloc_edit'] === 'rename_page_bloc')
- {
- PageManagementController::renameBloc($entityManager, $json);
- }
- // inversion des positions de deux blocs
- elseif($_GET['bloc_edit'] === 'switch_blocs_positions')
- {
- PageManagementController::SwitchBlocsPositions($entityManager, $json);
- }
- }
-
- /* -- upload d'image dans tinymce par copier-coller -- */
- // collage de HTML contenant une ou plusieurs balises
- if(isset($_GET['action']) && $_GET['action'] == 'upload_image_html'){
- ImageUploadController::uploadImageHtml();
- }
- // collage d'une image (code base64 dans le presse-papier) non encapsulée dans du HTML
- elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image_base64'){
- ImageUploadController::uploadImageBase64();
- }
-
- /* -- requêtes spécifiques au calendrier -- */
- if($_GET['action'] === 'new_event'){
- CalendarController::newEvent($json, $entityManager);
- }
- elseif($_GET['action'] === 'update_event'){
- CalendarController::updateEvent($json, $entityManager);
- }
- elseif($_GET['action'] === 'remove_event'){
- CalendarController::removeEvent($json, $entityManager);
- }
- else{
- echo json_encode(['success' => false]);
- }
- die;
- }
-
- // upload d'image dans tinymce avec le plugin (bouton "insérer une image" de l'éditeur)
- elseif(strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false && isset($_GET['action']) && $_GET['action'] === 'upload_image')
- {
- ImageUploadController::imageUploadTinyMce();
- }
- // requêtes XMLHttpRequest
- elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
- {
- //echo "requête XMLHttpRequest reçue par le serveur";
- echo json_encode(['success' => false]); // ça marche mais ça marche pas...
- die;
- }
-
- /* -- envoi d'un formulaire HTML -- */
- elseif($_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded')
- {
- /* -- nouvelle page -- */
- if(isset($_POST['page_name']) && $_POST['page_name'] !== null
- && isset($_POST['page_name_path']) && $_POST['page_name_path'] !== null
- && isset($_POST['page_location']) && $_POST['page_location'] !== null
- && isset($_POST['page_description']) && $_POST['page_description'] !== null
- && isset($_POST['new_page_hidden']) && $_POST['new_page_hidden'] === '')
- {
- PageManagementController::newPage($entityManager);
- }
-
- /* -- suppression d'une page -- */
- elseif(isset($_POST['page_id']) && $_POST['page_id'] !== null
- && isset($_POST['submit_hidden']) && $_POST['submit_hidden'] === '')
- {
- PageManagementController::deletePage($entityManager);
- }
-
- /* -- mode Modification d'une page -- */
-
- // modification du chemins en snake_case
- elseif(isset($_POST['page_menu_path']) && $_POST['page_menu_path'] !== null
- && isset($_POST['page_id']) && $_POST['page_id'] !== null
- && isset($_POST['page_name_path_hidden']) && $_POST['page_name_path_hidden'] === '')
- {
- PageManagementController::updatePageMenuPath($entityManager);
- }
- // ajout d'un bloc dans une page
- elseif(isset($_POST['bloc_title']) && $_POST['bloc_title'] !== null
- && isset($_POST['bloc_select']) && $_POST['bloc_select'] !== null
- && isset($_POST['bloc_title_hidden']) && $_POST['bloc_title_hidden'] === '') // contrôle anti-robot avec input hidden
- {
- PageManagementController::addBloc($entityManager);
- }
- // suppression d'un bloc de page
- elseif(isset($_POST['delete_bloc_id']) && $_POST['delete_bloc_id'] !== null
- && isset($_POST['delete_bloc_hidden']) && $_POST['delete_bloc_hidden'] === '') // contrôle anti-robot avec input hidden
- {
- PageManagementController::deleteBloc($entityManager);
- }
-
-
- /* -- page Menu et chemins -- */
-
- // création d'une entrée de menu avec une URL
- elseif(isset($_POST["label_input"]) && isset($_POST["url_input"]) && isset($_POST["location"])){
- MenuAndPathsController::newUrlMenuEntry($entityManager);
- }
- // suppression d'une entrée de menu avec une URL
- elseif(isset($_POST['delete']) && isset($_POST['x']) && isset($_POST['y'])){ // 2 params x et y sont là parce qu'on a cliqué sur une image
- MenuAndPathsController::deleteUrlMenuEntry($entityManager);
- }
-
- // redirection page d'accueil
- else{
- header("Location: " . new URL(['error' => 'paramètres inconnus']));
- die;
- }
- }
- }
-}
-
-// cas particulier d'un GET ajax non-admin par fullcalendar
-elseif($_SERVER['REQUEST_METHOD'] === 'GET'){
- /* -- non-admin -- */
- // chargement des évènements à la création du calendrier
- // et au changement de dates affichées (boutons flèches mais pas changement de vue)
- if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'get_events'
- && isset($_GET['start']) && isset($_GET['end']) && empty($_POST))
- {
- CalendarController::getData($entityManager);
- }
-
- if($_SESSION['admin'] === true){
- // ...
- }
-}
\ No newline at end of file
diff --git a/src/installation.php b/src/installation.php
new file mode 100644
index 0000000..295c583
--- /dev/null
+++ b/src/installation.php
@@ -0,0 +1,178 @@
+l'extension " . $extension . ' est manquante');
+ $flag = true;
+ }
+ }
+ if(!extension_loaded('imagick') && !extension_loaded('gd')){
+ echo("il manque une de ces extensions au choix pour le traitement des images: imagick (de préférence) ou gd.
");
+ $flag = true;
+ }
+ if($flag){
+ echo 'Réalisez les actions nécéssaires sur le serveur ou contactez l\'administrateur du site.
+ Quand le problème sera résolu, il vous suffira de recharger la page.
';
+ die;
+ }
+}
+
+// inutilisée pour l'instant
+function installation(): void
+{
+ /* -- droits des fichiers et dossiers -- */
+ $droits_dossiers = 0700;
+ $droits_fichiers = 0600;
+
+ // accès interdit en HTTP
+ if(!file_exists('../config/.htaccess')){
+ $contenu = <<< HTACCESS
+
+ Order Allow,Deny
+ Deny from all
+
+HTACCESS;
+
+ $fichier = fopen('../config/.htaccess', 'w');
+ fputs($fichier, $contenu);
+ fclose($fichier);
+ chmod('../config/.htaccess', $droits_fichiers);
+ //echo("danger
pas de .htaccess dans config
prévenez le responsable du site");
+ //die;
+ }
+
+ // accès limité en local (600) pour config.ini
+ if(substr(sprintf('%o', fileperms('../config/config.ini')), -4) != 600){
+ chmod('../config/config.ini', $droits_fichiers);
+ }
+
+ // création de data et sous-dossiers
+ if(!file_exists('../data')){
+ mkdir('../data/');
+ chmod('../data/', $droits_dossiers);
+ }
+ if(!touch('../data')){
+ echo("dossier data non autorisé en écriture");
+ die;
+ }
+ $sous_dossiers = array('images', 'images-mini', 'videos');
+ foreach ($sous_dossiers as $sous_dossier){
+ if(!file_exists('../data/' . $sous_dossier)){
+ mkdir('../data/' . $sous_dossier);
+ chmod('../data/' . $sous_dossier, $droits_dossiers);
+ }
+ if(!touch('../data/' . $sous_dossier)){
+ echo("dossier data non autorisé en écriture");
+ die;
+ }
+ }
+}
+
+// création d'un site minimal avec une page d'accueil à la toute 1ère visite du site
+// fonctiona appelée après la première requête envoyée en BDD,
+// en l'occurence dans Menu parce que count($bulk_data) === 0
+function makeStartPage(EntityManager $entityManager){
+ /* -- table page -- */
+ // paramètres: name_page, end_of_path, reachable, in_menu, hidden, position, parent
+ $accueil = new Page('Accueil', 'accueil', true, true, false, 1, NULL);
+ $article = new Page('Article', 'article', true, false, false, NULL, NULL);
+ $connection = new Page('Connexion', 'connexion', true, false, false, NULL, NULL);
+ $menu_paths = new Page("Menu et chemins", 'menu_chemins', true, false, false, NULL, NULL);
+ //$edit_page = new Page("Modification d'une page", 'modif_page', true, false, false, NULL, NULL); // pas de page "Modification de la page"
+ $new_page = new Page('Nouvelle page', 'nouvelle_page', true, false, false, NULL, NULL);
+
+ /* -- table node -- */
+ // paramètres: name_node, article_timestamp, attributes, position, parent, page, article
+ $head_accueil = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'foot'], 'js_array' => ['main']], 1, NULL, $accueil, NULL);
+ $head_article = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'foot'], 'js_array' => ['main']], 1, NULL, $article, NULL);
+ $header = new Node('header', NULL, [], 2, NULL, NULL, NULL);
+ $nav = new Node('nav', NULL, [], 1, $header, NULL, NULL);
+ $main = new Node('main', NULL, [], 3, NULL, NULL, NULL);
+ $footer = new Node('footer', NULL, [], 4, NULL, NULL, NULL);
+ $breadcrumb = new Node('breadcrumb', NULL, [], 2, $header, NULL, NULL);
+ $head_login = new Node('head', NULL, ["stop" => true, 'css_array' => ['body', 'head', 'nav'], 'js_array' => ['main']], 1, NULL, $connection, NULL);
+ $login = new Node('login', NULL, [], 1, $main, $connection, NULL);
+ $head_edit_menu = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'menu', 'foot'], 'js_array' => ['main', 'menu']], 1, NULL, $menu_paths, NULL);
+ $bloc_edit_menu = new Node('menu', NULL, [], 1, $main, $menu_paths, NULL);
+ $head_new_page = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'new_page', 'foot'], 'js_array' => ['main', 'new_page']], 1, NULL, $new_page, NULL);
+ $bloc_new_page = new Node('new_page', NULL, [], 1, $main, $new_page, NULL);
+
+ /* -- table image -- */
+ // paramètres: file_name, file_path, file_path_mini, mime_type, alt
+ $favicon = new Image("favicon48x48.png", NULL, "assets/favicon48x48.png", "image/png", "favicon");
+ $facebook = new Image("facebook.svg", NULL, "assets/facebook.svg", "image/svg+xml", "facebook");
+ $instagram = new Image("instagram.svg", NULL, "assets/instagram.svg", "image/svg+xml", "instagram");
+ $linkedin = new Image("linkedin.svg", NULL, "assets/linkedin.svg", "image/svg+xml", "linkedin");
+ $github = new Image("github.svg", NULL, "assets/github.svg", "image/svg+xml", "github");
+
+ /* -- table node_data -- */
+ // paramètres: data, node, images
+ $head_accueil_data = new NodeData(["description" => "page d'accueil"], $head_accueil, new ArrayCollection([$favicon]));
+ $head_login_data = new NodeData(["description" => "Connexion"], $head_login, new ArrayCollection([$favicon]));
+ $head_article_data = new NodeData(["description" => ""], $head_article, new ArrayCollection([$favicon]));
+ $head_edit_menu_data = new NodeData(["description" => "Menu et chemins"], $head_edit_menu, new ArrayCollection([$favicon]));
+ $head_new_page_data = new NodeData(["description" => "Nouvelle page"], $head_new_page, new ArrayCollection([$favicon]));
+ $header_data = new NodeData(["title" => "Titre", "description" => "Sous-titre", "header_logo" => "assets/logo-nb-et-ffn.png", "header_background" => "assets/fond-piscine.jpg",
+ "social" => ["facebook" => "https://www.facebook.com", "instagram" => "https://www.instagram.com", "linkedin" => "https://www.linkedin.com"]],
+ $header, new ArrayCollection([$facebook, $instagram, $linkedin, $github]));
+ $footer_data = new NodeData(["contact_nom" => "Nom", "adresse" => "adresse", "e_mail" => "e-mail", "footer_logo" => "assets/logo-nb-et-ffn.png"], $footer);
+
+ /* -- table page -- */
+ $entityManager->persist($accueil);
+ $entityManager->persist($article);
+ $entityManager->persist($connection);
+ $entityManager->persist($menu_paths);
+ //$entityManager->persist($edit_page); // pas de page "Modification de la page"
+ $entityManager->persist($new_page);
+
+ /* -- table node -- */
+ $entityManager->persist($head_accueil);
+ $entityManager->persist($header);
+ $entityManager->persist($nav);
+ $entityManager->persist($main);
+ $entityManager->persist($footer);
+ $entityManager->persist($breadcrumb);
+ $entityManager->persist($head_login);
+ $entityManager->persist($login);
+ $entityManager->persist($head_article);
+ $entityManager->persist($head_edit_menu);
+ $entityManager->persist($bloc_edit_menu);
+ $entityManager->persist($head_new_page);
+ $entityManager->persist($bloc_new_page);
+
+ /* -- table image -- */
+ $entityManager->persist($favicon);
+ $entityManager->persist($facebook);
+ $entityManager->persist($instagram);
+ $entityManager->persist($linkedin);
+ $entityManager->persist($github);
+
+ /* -- table node_data -- */
+ $entityManager->persist($head_accueil_data);
+ $entityManager->persist($header_data);
+ $entityManager->persist($footer_data);
+ $entityManager->persist($head_login_data);
+ $entityManager->persist($head_article_data);
+ $entityManager->persist($head_edit_menu_data);
+ $entityManager->persist($head_new_page_data);
+
+ $entityManager->flush();
+ header('Location: ' . new URL);
+ die;
+}
\ No newline at end of file
diff --git a/src/request_router.php b/src/request_router.php
new file mode 100644
index 0000000..0b31755
--- /dev/null
+++ b/src/request_router.php
@@ -0,0 +1,256 @@
+: position = nombre d'éléments de la fraterie + 1, l'élément précédent devient le parent
+ if($_GET['menu_edit'] === 'move_one_level_down' && isset($json['id'])){
+ MenuAndPathsController::MoveOneLevelDown($entityManager, $json);
+ }
+
+ if($_GET['menu_edit'] === 'switch_positions' && isset($json['id1']) && isset($json['id2'])){
+ MenuAndPathsController::switchPositions($entityManager, $json);
+ }
+
+ if($_GET['menu_edit'] === 'displayInMenu' && isset($json['id']) && isset($json['checked'])){
+ MenuAndPathsController::displayInMenu($entityManager, $json);
+ }
+ }
+
+ /* -- mode Modification d'une page -- */
+ // partie "page"
+ elseif(isset($_GET['page_edit']))
+ {
+ // titre de la page
+ if($_GET['page_edit'] === 'page_title'){
+ PageManagementController::setPageTitle($entityManager, $json);
+ }
+ // description dans les métadonnées
+ elseif($_GET['page_edit'] === 'page_description'){
+ PageManagementController::setPageDescription($entityManager, $json);
+ }
+ }
+
+ // partie "blocs"
+ elseif(isset($_GET['bloc_edit']))
+ {
+ // renommage d'un bloc
+ if($_GET['bloc_edit'] === 'rename_page_bloc')
+ {
+ PageManagementController::renameBloc($entityManager, $json);
+ }
+ // inversion des positions de deux blocs
+ elseif($_GET['bloc_edit'] === 'switch_blocs_positions')
+ {
+ PageManagementController::SwitchBlocsPositions($entityManager, $json);
+ }
+ }
+
+ /* -- upload d'image dans tinymce par copier-coller -- */
+ // collage de HTML contenant une ou plusieurs balises
+ if(isset($_GET['action']) && $_GET['action'] == 'upload_image_html'){
+ ImageUploadController::uploadImageHtml();
+ }
+ // collage d'une image (code base64 dans le presse-papier) non encapsulée dans du HTML
+ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image_base64'){
+ ImageUploadController::uploadImageBase64();
+ }
+
+ /* -- requêtes spécifiques au calendrier -- */
+ if($_GET['action'] === 'new_event'){
+ CalendarController::newEvent($json, $entityManager);
+ }
+ elseif($_GET['action'] === 'update_event'){
+ CalendarController::updateEvent($json, $entityManager);
+ }
+ elseif($_GET['action'] === 'remove_event'){
+ CalendarController::removeEvent($json, $entityManager);
+ }
+ else{
+ echo json_encode(['success' => false]);
+ }
+ die;
+ }
+
+ // upload d'image dans tinymce avec le plugin (bouton "insérer une image" de l'éditeur)
+ elseif(strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false && isset($_GET['action']) && $_GET['action'] === 'upload_image')
+ {
+ ImageUploadController::imageUploadTinyMce();
+ }
+ // requêtes XMLHttpRequest
+ elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
+ {
+ //echo "requête XMLHttpRequest reçue par le serveur";
+ echo json_encode(['success' => false]); // ça marche mais ça marche pas...
+ die;
+ }
+
+ /* -- envoi d'un formulaire HTML -- */
+ elseif($_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded')
+ {
+ /* -- nouvelle page -- */
+ if(isset($_POST['page_name']) && $_POST['page_name'] !== null
+ && isset($_POST['page_name_path']) && $_POST['page_name_path'] !== null
+ && isset($_POST['page_location']) && $_POST['page_location'] !== null
+ && isset($_POST['page_description']) && $_POST['page_description'] !== null
+ && isset($_POST['new_page_hidden']) && $_POST['new_page_hidden'] === '')
+ {
+ PageManagementController::newPage($entityManager);
+ }
+
+ /* -- suppression d'une page -- */
+ elseif(isset($_POST['page_id']) && $_POST['page_id'] !== null
+ && isset($_POST['submit_hidden']) && $_POST['submit_hidden'] === '')
+ {
+ PageManagementController::deletePage($entityManager);
+ }
+
+ /* -- mode Modification d'une page -- */
+
+ // modification du chemins en snake_case
+ elseif(isset($_POST['page_menu_path']) && $_POST['page_menu_path'] !== null
+ && isset($_POST['page_id']) && $_POST['page_id'] !== null
+ && isset($_POST['page_name_path_hidden']) && $_POST['page_name_path_hidden'] === '')
+ {
+ PageManagementController::updatePageMenuPath($entityManager);
+ }
+ // ajout d'un bloc dans une page
+ elseif(isset($_POST['bloc_title']) && $_POST['bloc_title'] !== null
+ && isset($_POST['bloc_select']) && $_POST['bloc_select'] !== null
+ && isset($_POST['bloc_title_hidden']) && $_POST['bloc_title_hidden'] === '') // contrôle anti-robot avec input hidden
+ {
+ PageManagementController::addBloc($entityManager);
+ }
+ // suppression d'un bloc de page
+ elseif(isset($_POST['delete_bloc_id']) && $_POST['delete_bloc_id'] !== null
+ && isset($_POST['delete_bloc_hidden']) && $_POST['delete_bloc_hidden'] === '') // contrôle anti-robot avec input hidden
+ {
+ PageManagementController::deleteBloc($entityManager);
+ }
+
+
+ /* -- page Menu et chemins -- */
+
+ // création d'une entrée de menu avec une URL
+ elseif(isset($_POST["label_input"]) && isset($_POST["url_input"]) && isset($_POST["location"])){
+ MenuAndPathsController::newUrlMenuEntry($entityManager);
+ }
+ // suppression d'une entrée de menu avec une URL
+ elseif(isset($_POST['delete']) && isset($_POST['x']) && isset($_POST['y'])){ // 2 params x et y sont là parce qu'on a cliqué sur une image
+ MenuAndPathsController::deleteUrlMenuEntry($entityManager);
+ }
+
+ // redirection page d'accueil
+ else{
+ header("Location: " . new URL(['error' => 'paramètres inconnus']));
+ die;
+ }
+ }
+ }
+}
+
+// cas particulier d'un GET ajax non-admin par fullcalendar
+elseif($_SERVER['REQUEST_METHOD'] === 'GET'){
+ /* -- non-admin -- */
+ // chargement des évènements à la création du calendrier
+ // et au changement de dates affichées (boutons flèches mais pas changement de vue)
+ if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'get_events'
+ && isset($_GET['start']) && isset($_GET['end']) && empty($_POST))
+ {
+ CalendarController::getData($entityManager);
+ }
+
+ if($_SESSION['admin'] === true){
+ // ...
+ }
+}
\ No newline at end of file
--
cgit v1.2.3