From 30dba0b0ca1ed8c85c05ce8d4eedeb616875a4fb Mon Sep 17 00:00:00 2001 From: Nicolas H Date: Wed, 13 Apr 2022 14:42:43 +0200 Subject: [PATCH] Add limited access path, drag and drop files, rename/delete/create files --- .htaccess | 4 +- css/style.css | 39 ++++ hosts/localhost/config.php | 2 +- .../localhost/content/{about.md => About.md} | 2 +- .../{dependencies.md => Dependencies.md} | 0 .../content/{features.md => Features.md} | 12 +- hosts/localhost/content/{index.md => Home.md} | 0 .../localhost/content/{usage.md => Usage.md} | 7 +- hosts/localhost/content/{ => images}/moi.jpg | Bin hosts/localhost/content/special/nav.md | 2 +- hosts/localhost/log.txt | 1 + index.php | 140 +++++++++--- js/functionsadmin.js | 205 +++++++++++++++++- lang/en.json | 16 +- lang/fr.json | 14 +- lib/functions.php | 94 +++++++- 16 files changed, 479 insertions(+), 59 deletions(-) rename hosts/localhost/content/{about.md => About.md} (87%) rename hosts/localhost/content/{dependencies.md => Dependencies.md} (100%) rename hosts/localhost/content/{features.md => Features.md} (72%) rename hosts/localhost/content/{index.md => Home.md} (100%) rename hosts/localhost/content/{usage.md => Usage.md} (85%) rename hosts/localhost/content/{ => images}/moi.jpg (100%) create mode 100644 hosts/localhost/log.txt diff --git a/.htaccess b/.htaccess index 94bbd61..dacc5fd 100644 --- a/.htaccess +++ b/.htaccess @@ -1,7 +1,7 @@ RewriteEngine On -RewriteCond %{HTTPS} !=on -RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] +#RewriteCond %{HTTPS} !=on +#RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php?doc=$1 [NC,L,QSA,R] diff --git a/css/style.css b/css/style.css index bc68ee8..62f971a 100644 --- a/css/style.css +++ b/css/style.css @@ -272,3 +272,42 @@ flex-wrap: wrap; } } +#drop-area { + border: 2px dashed #ccc; + border-radius: 20px; + width: 480px; + margin: 50px auto; + padding: 20px; +} +#drop-area.highlight { + border-color: purple; +} +p { + margin-top: 0; +} +.my-form { + margin-bottom: 10px; +} +#gallery { + margin-top: 10px; +} +#gallery img { + width: 150px; + margin-bottom: 10px; + margin-right: 10px; + vertical-align: middle; +} +.button { + display: inline-block; + padding: 10px; + background: #ccc; + cursor: pointer; + border-radius: 5px; + border: 1px solid #ccc; +} +.button:hover { + background: #ddd; +} +#fileElem { + display: none; +} diff --git a/hosts/localhost/config.php b/hosts/localhost/config.php index 29d6891..756978b 100644 --- a/hosts/localhost/config.php +++ b/hosts/localhost/config.php @@ -5,7 +5,7 @@ define('VIEWABLE_FORMAT', 'md'); define('TITLE', 'Documentation'); define('ICON', 'fa-book-open'); define('ALLOWED_EXT','jpg,svg,gif,png,c,tgz,tar.gz,gz,tar,sql,ico'); -define('PASSWORD', 'c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec'); +define('ADMIN_PASSWORD', 'c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec'); define('LOG_FILE', 'log.txt'); define('ACCESS_IP', ''); define('HISTORY_FILE', 'history'); diff --git a/hosts/localhost/content/about.md b/hosts/localhost/content/About.md similarity index 87% rename from hosts/localhost/content/about.md rename to hosts/localhost/content/About.md index f44cc6f..f281464 100644 --- a/hosts/localhost/content/about.md +++ b/hosts/localhost/content/About.md @@ -1,6 +1,6 @@ # About author -![moi](/moi.jpg?80-left)**Hordé Nicolas** +![moi](/images/moi.jpg?80-left)**Hordé Nicolas** > *Passionate about computer and more particularly development. I started from a young age (17 years) in system programming. I handle about thirty programming languages ​​among which there are many low level languages :wink:! I am also the author of MarkDoc, the Markdown-based documentation management system you are currently viewing * diff --git a/hosts/localhost/content/dependencies.md b/hosts/localhost/content/Dependencies.md similarity index 100% rename from hosts/localhost/content/dependencies.md rename to hosts/localhost/content/Dependencies.md diff --git a/hosts/localhost/content/features.md b/hosts/localhost/content/Features.md similarity index 72% rename from hosts/localhost/content/features.md rename to hosts/localhost/content/Features.md index bbdf75d..c5f21ba 100644 --- a/hosts/localhost/content/features.md +++ b/hosts/localhost/content/Features.md @@ -11,11 +11,13 @@ 5. Admin access logging 6. Table of contents 7. Password protected area +8. Keeping the history of edited files and changes +9. Uploading multiple files by drag and drop + +## In progress + +1. Complete File Manager ## Planned -1. Complete File Manager -3. Keeping the history of edited files and changes -4. Configuration viewer -5. Emoji menu in Markdown editor -6. Uploading multiple files by drag and drop +1. Emoji menu in Markdown editor diff --git a/hosts/localhost/content/index.md b/hosts/localhost/content/Home.md similarity index 100% rename from hosts/localhost/content/index.md rename to hosts/localhost/content/Home.md diff --git a/hosts/localhost/content/usage.md b/hosts/localhost/content/Usage.md similarity index 85% rename from hosts/localhost/content/usage.md rename to hosts/localhost/content/Usage.md index 56cffa4..f2adc9e 100644 --- a/hosts/localhost/content/usage.md +++ b/hosts/localhost/content/Usage.md @@ -39,13 +39,16 @@ define('VIEWABLE_FORMAT', 'md'); define('TITLE', 'Documentation'); define('ICON', 'fa-book-open'); define('ALLOWED_EXT','jpg,svg,gif,png,c,tgz,tar.gz,gz,tar,sql,ico'); -define('PASSWORD', '[sha512 encoded password]'); +define('ADMIN_PASSWORD', '[sha512 encoded password]'); define('LOG_FILE', 'log.txt'); define('ACCESS_IP', ''); define('HISTORY_FILE', 'history.txt'); define('MAX_HISTORY_FILES', 5); -define('LANG', 'en'); +define('LANGUAGE', 'en'); define('ACCESS_PRIVATE', 'false'); +define('ACCESS_LIMITED', ''); #A PATH WHERE USER PASSWORD IS NEEDED +define('USER_PASSWORD', ''); #FOR A PATH LIMITED ACCESS +define('IMAGE_EXT','jpg,svg,gif,png,webp'); ``` **NOTE**: diff --git a/hosts/localhost/content/moi.jpg b/hosts/localhost/content/images/moi.jpg similarity index 100% rename from hosts/localhost/content/moi.jpg rename to hosts/localhost/content/images/moi.jpg diff --git a/hosts/localhost/content/special/nav.md b/hosts/localhost/content/special/nav.md index a0d381b..c9d0666 100644 --- a/hosts/localhost/content/special/nav.md +++ b/hosts/localhost/content/special/nav.md @@ -1,3 +1,3 @@ -[Home](/index.md) +[Home](/:HOME) [Sitemap](/:SITEMAP) [Glossary](/:GLOSSAIRE) diff --git a/hosts/localhost/log.txt b/hosts/localhost/log.txt new file mode 100644 index 0000000..c856afc --- /dev/null +++ b/hosts/localhost/log.txt @@ -0,0 +1 @@ +a:0:{} \ No newline at end of file diff --git a/index.php b/index.php index e9ca9c1..1bec7cf 100644 --- a/index.php +++ b/index.php @@ -10,7 +10,6 @@ */ ### Global defines -define('PRIVATE', true); define('ROOT_DIR', realpath(dirname(__FILE__)) .'/'); define('LIB_DIR', ROOT_DIR.'lib/'); define('HOST_DIR',ROOT_DIR.'hosts/'.$_SERVER['SERVER_NAME'].'/'); @@ -24,6 +23,7 @@ include LIB_DIR."/Parsedown.php"; include LIB_DIR."/ParsedownExtra.php"; include LIB_DIR."/ParsedownExtraPlus.php"; include LIB_DIR."/functions.php"; +$supported_image = array('gif','jpg','jpeg','png','webp','bmp','svg','ico'); ### Translations loadlang(LANGUAGE); @@ -36,30 +36,35 @@ logprotect(); ### Sessions session_name('markdoc'); session_start(); +//echo "

"; +//var_dump($_POST); +//var_dump($_GET); -/*var_dump($_POST); -var_dump($_GET);*/ - -$file=explode('?', ($_GET['doc']=="")?"index.md":$_GET['doc'], 2)[0] ?? ""; +$file=explode('?', ($_GET['doc']=="")?$LANG['INDEXMD']:$_GET['doc'], 2)[0] ?? ""; $filedetail = pathinfo($file); - if (isset($_GET['logout'])) { unset($_SESSION['md_admin']); + unset($_SESSION['md_user']); redirect(); } else if (isset($_POST['action'])) { - if ((isset($_SESSION['md_admin']) === false || $_SESSION['md_admin'] !== true)) + if ((isset($_SESSION['md_admin']) === false || $_SESSION['md_admin'] !== true) && (isset($_SESSION['md_user']) === false || $_SESSION['md_user'] !== true)) { if ($_POST['action']=='ident') { if (isset($_POST['md_password']) && empty($_POST['md_password']) === false) { - if (hash('sha512', $_POST['md_password']) === PASSWORD) + if (hash('sha512', $_POST['md_password']) === ADMIN_PASSWORD) { $_SESSION['md_admin'] = true; redirect(); } + else if (hash('sha512', $_POST['md_password']) === USER_PASSWORD) + { + $_SESSION['md_user'] = true; + redirect($file); + } else { $content = '

'.$LANG['BADPASS'].'

'; @@ -93,32 +98,105 @@ else if (isset($_POST['action'])) case 'children': print(json_encode(filesJSON(CONTENT_DIR,false))); exit; + case 'new': + $file=urldecode($_POST['file']); + $filedetail = pathinfo($file); + if (!isset($_SESSION['md_admin'])) + { + $content=specialurl("/:ADMIN",true); + } + else + { + setcontent($file,"## Titre"); + print(getcontent($file,$md=$filedetail['extension']=='md',true)); + } + exit; + case 'rename': + $file=urldecode($_POST['file']); + $file2=urldecode($_POST['file2']); + if (!isset($_SESSION['md_admin'])) + { + $content=specialurl("/:ADMIN",true); + } + else + { + print(rencontent($file,$file2)); + } + exit; + case 'delete': + $file=urldecode($_POST['file']); + if (!isset($_SESSION['md_admin'])) + { + $content=specialurl("/:ADMIN",true); + } + else + { + print(delcontent($file)); + } + exit; + case 'sendfile': + $file=urldecode($_POST['name']); + $filedetail = pathinfo($file); + $data=$_POST['file']; + if (!isset($_SESSION['md_admin'])) + { + $content=specialurl("/:ADMIN",true); + } + else + { + if (in_array($filedetail['extension'], $supported_image)) + $path="/images"; + else + $path="/documents"; + print(setcontent($path."/".$file,$data)); + } + exit; case 'allchildren': print(json_encode(filesJSON(CONTENT_DIR,true))); exit; case 'open': $file=urldecode($_POST['file']); + $filedetail = pathinfo($file); if (substr($file,0,2)=="/:") specialurl($file,true); else { - $md=strpos('.md',$file)>=0; - print(getcontent($file,$md,true)); + if (ACCESS_LIMITED!="" && strpos($filedetail['dirname'],ACCESS_LIMITED)!==false && !isset($_SESSION['md_user'])) + { + $content=specialurl("/:ADMIN",true); + } + print(getcontent($file,$md=$filedetail['extension']=='md',true)); exit; } case 'realopen': $file=urldecode($_POST['file']); - print(getcontent($file,false,true)); - exit; + $filedetail = pathinfo($file); + if (ACCESS_LIMITED!="" && strpos($filedetail['dirname'],ACCESS_LIMITED)!==false && !isset($_SESSION['md_user'])) + { + $content=specialurl("/:ADMIN",true); + } + else + print(getcontent($file,false,true)); + exit; case 'save': $file=urldecode($_POST['file']); - print(setcontent($file,$_POST['data'])); + $filedetail = pathinfo($file); + if (!isset($_SESSION['md_admin'])) + { + $content=specialurl("/:ADMIN",true); + } + else + print(setcontent($file,$_POST['data'])); exit; case 'search': $results=searchstr(CONTENT_DIR,$_POST['search']); $content=sprintf($LANG['FOUND'],$results['totalFiles']); foreach($results['files'] as $key => $value) - $content.='

'.$key.'

'.$value.'

'; + { + $filedetail = pathinfo($key); + if (ACCESS_LIMITED=="" || strpos($filedetail['dirname'],ACCESS_LIMITED)===false || isset($_SESSION['md_user'])) + $content.='

'.$key.'

'.$value.'

'; + } if ($_POST['type']=="js") { print($content); @@ -130,10 +208,14 @@ else if (ACCESS_PRIVATE && !isset($_SESSION['md_admin'])) { $content=specialurl("/:ADMIN",false); } -else if (substr($file,0,2)=="/:") +else if (substr($file,0,1)==":") { - $content=specialurl($file,false); + $content=specialurl("/".$file,false); } +else if (ACCESS_LIMITED!="" && strpos($filedetail['dirname'],ACCESS_LIMITED)!==false && !isset($_SESSION['md_user'])) +{ + $content=specialurl("/:ADMIN",false); +} else if ($filedetail['extension']=="md") { $content=getcontent($file); @@ -173,11 +255,22 @@ else ':''); ?> + + + + + + + + +
- - - - - - - - - ':''); ?> diff --git a/js/functionsadmin.js b/js/functionsadmin.js index 676b2d1..2b30f1f 100644 --- a/js/functionsadmin.js +++ b/js/functionsadmin.js @@ -144,6 +144,82 @@ $(function(){ } }); + $("#nouveau").click(function(e){ + e.preventDefault(); + viewfile=""; + node=$("#files").jstree("get_selected"); + file="/"+$("#files").jstree("get_path",node,"/").replace(/^.+?[/]/, ''); + if ($("#files").jstree("is_leaf",node)) + { + file=file.substring(0, file.lastIndexOf("/")); + } + file=file+"/"+$("#search").val()+".md"; + $.ajax({ + type: "POST", + url: "/index.php", + data: { action: "new", file: encodeURIComponent(file) }, + success: function(data){ + data = data.split("|"); + alertBox(data[1], data[0]); + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + alertBox(LANG['AJAXERROR'],'danger'); + } + }); + }) + + $("#del").click(function(e){ + e.preventDefault(); + viewfile=""; + node=$("#files").jstree("get_selected"); + file="/"+$("#files").jstree("get_path",node,"/").replace(/^.+?[/]/, ''); + if ($("#files").jstree("is_leaf",node)) + { + if (confirm(LANG['CONFIRM_DEL']) == true) { + $.ajax({ + type: "POST", + url: "/index.php", + data: { action: "delete", file: encodeURIComponent(file) }, + success: function(data){ + data = data.split("|"); + alertBox(data[1], data[0]); + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + alertBox(LANG['AJAXERROR'],'danger'); + } + }); + } + } + }) + + + $("#ren").click(function(e){ + e.preventDefault(); + viewfile=""; + node=$("#files").jstree("get_selected"); + file="/"+$("#files").jstree("get_path",node,"/").replace(/^.+?[/]/, ''); + file2=file.substring(0, file.lastIndexOf("/"))+"/"+$("#search").val()+".md"; + alert(file); + alert(file2); + if ($("#files").jstree("is_leaf",node)) + { + if (confirm(LANG['CONFIRM_REN']) == true) { + $.ajax({ + type: "POST", + url: "/index.php", + data: { action: "rename", file: encodeURIComponent(file), file2: encodeURIComponent(file2) }, + success: function(data){ + data = data.split("|"); + alertBox(data[1], data[0]); + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + alertBox(LANG['AJAXERROR'],'danger'); + } + }); + } + } + }) + $("#save").click(function(e){ e.preventDefault(); viewfile=""; @@ -174,7 +250,9 @@ $(function(){ if ($("#files").jstree("is_leaf",nodes.node)) openlink(file,false); else - alertBox(LANG['NOTCODED'],'danger'); + { + sendmode(); + } }); $("input[name=submit]").click(function(e) { @@ -231,6 +309,11 @@ function openlink(dest,majtree) imagemode(dest); return; } + if (!dest.match(/.(md|txt)$/i)) + { + nomode(dest); + return; + } $.ajax({ type: "POST", url: "/index.php", @@ -254,6 +337,7 @@ function searchtree(file) var flag; $("#files").jstree("deselect_all"); node=$("#files").jstree("get_node", "ul > li:first"); + if (file !== null) file.split('/').forEach(function (item) { flag=false; subnodes=$("#files").jstree("get_children_dom",node); @@ -278,6 +362,36 @@ function searchtree(file) }); } +function sendmode(data) +{ + $(window).scrollTop(0); + $("#editor").hide(); + if (data !== undefined) editor.value(data); + $("#content").show(); + $("#save").hide(); + $("#image").hide(); + $("#voir").hide(); + $("#voir").val("Voir"); + $("#content").html('

'+LANG['UPLOAD_MSG']+'

'); + let dropArea = document.getElementById("drop-area") + dropArea.replaceWith(dropArea.cloneNode(true)); + + ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { + dropArea.addEventListener(eventName, preventDefaults, false) + document.body.addEventListener(eventName, preventDefaults, false) + }) + + ;['dragenter', 'dragover'].forEach(eventName => { + dropArea.addEventListener(eventName, highlight, false) + }) + + ;['dragleave', 'drop'].forEach(eventName => { + dropArea.addEventListener(eventName, unhighlight, false) + }) + + dropArea.addEventListener('drop', handleDrop, false) +} + function editmode(data) { $(window).scrollTop(0); @@ -319,6 +433,16 @@ function viewmode(data) $("#voir").val("Editer"); } +function nomode(dest) +{ + $(window).scrollTop(0); + $("#editor").hide(); + $("#content").hide(); + $("#save").hide(); + $("#image").hide(); + $("#voir").hide(); +} + function editlink(dest) { $.ajax({ @@ -365,3 +489,82 @@ function search(arg) } }); } + +function preventDefaults (e) { + e.preventDefault() + e.stopPropagation() +} + +function highlight(e) { + document.getElementById("drop-area").classList.add('highlight') +} + +function unhighlight(e) { + document.getElementById("drop-area").classList.remove('active') +} + +function handleDrop(e) { + var dt = e.dataTransfer + var files = dt.files + handleFiles(files) +} + +let uploadProgress = [] + +function initializeProgress(numFiles) { + document.getElementById("progress-bar").value = 0 + uploadProgress = [] + + for(let i = numFiles; i > 0; i--) { + uploadProgress.push(0) + } +} + +function updateProgress(fileNumber, percent) { + uploadProgress[fileNumber] = percent + let total = uploadProgress.reduce((tot, curr) => tot + curr, 0) / uploadProgress.length + document.getElementById("progress-bar").value = total +} + +function handleFiles(files) { + files = [...files] + initializeProgress(files.length) + files.forEach(uploadFile) + files.forEach(previewFile) +} + +function previewFile(file) { + let reader = new FileReader() + reader.readAsDataURL(file) + reader.onloadend = function() { + let img = document.createElement('img') + img.title = file.name + img.src = reader.result + document.getElementById('gallery').appendChild(img) + } +} + +function uploadFile(file, i) { + var url = 'index.php' + var xhr = new XMLHttpRequest() + var formData = new FormData() + xhr.open('POST', url, true) + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest') + + xhr.upload.addEventListener("progress", function(e) { + updateProgress(i, (e.loaded * 100.0 / e.total) || 100) + }) + + xhr.addEventListener('readystatechange', function(e) { + if (xhr.readyState == 4 && xhr.status == 200) { + updateProgress(i, 100) + } + else if (xhr.readyState == 4 && xhr.status != 200) { + } + }) + + formData.append('file', file) + formData.append('name', file.name); + formData.append('action','sendfile'); + xhr.send(formData) +} diff --git a/lang/en.json b/lang/en.json index 5196dfb..46463dc 100644 --- a/lang/en.json +++ b/lang/en.json @@ -7,8 +7,12 @@ "ABOUTMARKDOC" : "# MarkDoc\r\n\r\n**PHP Markdown-based documentation management system, Free & OpenSource :heart_eyes: for easily create your documentation website**\r\n \r\nThis website is heavily formated with markdown format !\r\n```\r\n __ __ _ _____ \r\n | \\\/ | | | | __ \\ \r\n | \\ \/ | __ _ _ __| | _| | | | ___ ___ \r\n | |\\\/| |\/ _` | '__| |\/ \/ | | |\/ _ \\ \/ __|\r\n | | | | (_| | | | <| |__| | (_) | (__ \r\n |_| |_|\\__,_|_| |_|\\_\\_____\/ \\___\/ \\___|\r\n``` \r\n\r\n![gplV3](https:\/\/www.gnu.org\/graphics\/gplv3-127x51.png) Sous licence GPLv3 [Licence](\/special\/gpl-3.0.md) - *Sources downloadables on [GitHub](https:\/\/github.com\/dahut87\/MarkDoc)*\r\n \r\nBased on Pheditor \"PHP file editor\" released under MIT license\r\n \r\n *Specials thanks to Hamid Samak*\r\n \r\n Made in 2020 by Nicolas H.\r\n \r\n---\r\n \r\nFor more informations, visit the demo website running MarkDoc engine at : [https:\/\/markdoc.palon.fr](https:\/\/markdoc.palon.fr)", "ADMIN" : "Admin", "ABOUT" : "About...", - "ABOUTMD" : "about.md", + "ABOUTMD" : "About.md", + "INDEXMD" : "Home.md", "SEARCH" : "Search", + "DELETE" : "Delete", + "RENAME" : "Rename", + "NEW" : "New", "VIEW" : "View", "TOC" : "Toc", "SAVE" : "Save", @@ -30,7 +34,13 @@ "NOIP": "Your IP address is not allowed to access this page.", "FORK": "Fork me on GitHub", "CREATED": "File created.", - "SAVED": "Filed saved.", + "SAVED": "File saved.", + "DELETED": "File deleted.", + "RENAMED": "File renamed.", "PROTECTED": "File is protected.", - "INDETERMINED": "Indeterminated Error." + "INDETERMINED": "Indeterminated Error.", + "CONFIRM_DEL" : "Are you sure to want to delete this file ?", + "CONFIRM_REN" : "Are you sure to want to rename this file ?", + "UPLOAD_MSG" : "Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region.", + "UPLOAD_BTN" : "Upload files" } \ No newline at end of file diff --git a/lang/fr.json b/lang/fr.json index c9de554..8058c9d 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -7,8 +7,12 @@ "ABOUTMARKDOC" : "# MarkDoc\r\n\r\n**Syst\u00E8me de gestion de documents Mardown \u00E9crits en PHP, Gratuit & OpenSource :heart_eyes: afin de facilement cr\u00E9er vos sites internet de documentation**\r\n \r\nCe site est lourdement format\u00E9 au format Markdown !\r\n```\r\n __ __ _ _____ \r\n | \\\/ | | | | __ \\ \r\n | \\ \/ | __ _ _ __| | _| | | | ___ ___ \r\n | |\\\/| |\/ _` | '__| |\/ \/ | | |\/ _ \\ \/ __|\r\n | | | | (_| | | | <| |__| | (_) | (__ \r\n |_| |_|\\__,_|_| |_|\\_\\_____\/ \\___\/ \\___|\r\n``` \r\n \r\n![gplV3](https:\/\/www.gnu.org\/graphics\/gplv3-127x51.png) Sous licence GPLv3 [Licence](\/special\/gpl-3.0.md) - *Sources t\u00E9l\u00E9chargeables sur [GitHub](https:\/\/github.com\/dahut87\/MarkDoc)*\r\n \r\nBas\u00E9 sur Pheditor \"PHP file editor\" sous licence MIT\r\n \r\n*Merci \u00E0 Hamid Samak*\r\n \r\nR\u00E9alis\u00E9 en 2020 par Nicolas H.\r\n \r\n---\r\n \r\nPour plus d'informations, visitez le site internet de d\u00E9monstration \u00E0 l'url suivante : [https:\/\/markdoc.palon.fr](https:\/\/markdoc.palon.fr)", "ADMIN" : "Admin", "ABOUT" : "A propos", - "ABOUTMD" : "apropos.md", + "ABOUTMD" : "A propos.md", + "INDEXMD" : "Accueil.md", "SEARCH" : "Chercher", + "DELETE" : "Supprimer", + "RENAME" : "Renommer", + "NEW" : "Nouveau", "VIEW" : "Voir", "TOC" : "TDM", "SAVE" : "Sauver", @@ -31,6 +35,12 @@ "FORK": "Fork moi sur GitHub", "CREATED": "Fichier créé.", "SAVED": "Fichier enregistré.", + "DELETED": "Fichier supprimé.", + "RENAMED": "Fichier renommé.", "PROTECTED": "Fichier protégé.", - "INDETERMINED": "Erreur indéterminée." + "INDETERMINED": "Erreur indéterminée.", + "CONFIRM_DEL" : "Etes vous sur de vouloir supprimer ce fichier ?", + "CONFIRM_REN" : "Etes vous sur de vouloir renommer ce fichier ?", + "UPLOAD_MSG" : "Télécharger de multiples fichier avec la fenêtre de dialogue ou en glissant déposant des fichier sur la zone de réception prévue à cet effet.", + "UPLOAD_BTN" : "Télécharger" } diff --git a/lib/functions.php b/lib/functions.php index 96e19c6..d4dcf25 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -59,16 +59,43 @@ function specialurl($url,$quit) $extra = new ParsedownExtraplus(); $content=$extra->text($LANG['ABOUTMARKDOC']); break; + case '/:HOME': + $extra = new ParsedownExtraplus(); + $file=getcontent($LANG['INDEXMD'],true, false); + $content=$extra->text($file); + break; case '/:ADMIN': if (isset($_SESSION['md_admin']) === false || $_SESSION['md_admin'] !== true) - $content = '

' . (isset($error) ? '

' . $error . '

' : null) . '

'; + $content = '

' . (isset($error) ? '

' . $error . '

' : null) . '

+'; else $content = '

'.$LANG['ALREADYLOG'].'

'; break; case '/:SITEMAP': $content='

'.$LANG['SITEMAP'].'

'; foreach(plan(CONTENT_DIR) as $file) - $content.='

'.$file.'

' ; + { + $ext=pathinfo($file); + if ($ext['dirname']=='.') + $final=$ext['filename']; + Else + $final=$ext['dirname']."/".$ext['filename']; + $content.='

'.$final.'

'; + } break; case '/:GLOSSAIRE': $content='

'.$LANG['GLOSSARY'].'

'; @@ -76,7 +103,10 @@ function specialurl($url,$quit) { $content.='

'.$letter.'

'; foreach($files as $file) - $content.='

'.$file.'

' ; + { + $ext=pathinfo($file); + $content.='

'.$ext['filename'].'

'; + } } break; } @@ -94,15 +124,15 @@ function plan($path){ $files = $matches = array(); while($dir->valid()) { + $dir->next(); if (!$dir->isDot()) { $ext = pathinfo($dir->getSubPathName()); - if ($ext['extension']=="md") + if ($ext['extension']=="md" && $ext['dirname']!='special') { array_push($files,$dir->getSubPathName()); } } - $dir->next(); } ksort($files); return $files; @@ -113,18 +143,18 @@ function glossary($path){ $files = $matches = array(); while($dir->valid()) { + $dir->next(); if (!$dir->isDot()) { $ext = pathinfo($dir->getSubPathName()); - if ($ext['extension']=="md") + if ($ext['extension']=="md" && $ext['dirname']!='special') { - $letter=strtoupper(substr(basename($dir->getSubPathName()),0,1)); + $letter=strtoupper(substr($ext['filename'],0,1)); if (!array_key_exists($letter,$files)) $files[$letter]=array(); array_push($files[$letter],$dir->getSubPathName()); } } - $dir->next(); } ksort($files); return $files; @@ -200,6 +230,40 @@ function history($file) } } +function delcontent($url) +{ + global $LANG; + $file = CONTENT_DIR.$url; + if (is_writable($file)) + { + history($file); + unlink($file); + $content='success|'.$LANG['DELETED']; + } + else if (!is_writable($file)) + $content='danger|'.$LANG['PROTECTED']; + else + $content='danger|'.$LANG['INDETERMINED']; + return $content; +} + +function rencontent($url,$url2) +{ + global $LANG; + $file = CONTENT_DIR.$url; + $file2 = CONTENT_DIR.$url2; + if (is_writable($file)) + { + history($file); + rename($file,$file2); + $content='success|'.$LANG['RENAMED']; + } + else if (!is_writable($file)) + $content='danger|'.$LANG['PROTECTED']; + else + $content='danger|'.$LANG['INDETERMINED']; + return $content; +} function setcontent($url,$data) { @@ -247,13 +311,18 @@ function getcontent($url,$md=true,$header=false) return $content; } +function sortByOption($a, $b) { + return strcmp($a['text'], $b['text']); +} + function filesJSON($path,$all,$first=true) { $alldata = array(); $dir= new DirectoryIterator($path); foreach($dir as $node) { - if (($node->getFilename() =="images") || ($node->getFilename() =="documents") || ($node->getFilename() =="special") || (SHOW_HIDDEN_FILES === false && substr($node->getFilename(), 0, 1) === '.') || (($node->getExtension() != VIEWABLE_FORMAT && $all==false) && $node->isFile())) continue; + if ( ($node->getFilename() == ".") || ($node->getFilename() == "..") ) continue; + if ( (!isset($_SESSION['md_admin'])) && (($node->getFilename() =="images") || ($node->getFilename() =="documents") || ($node->getFilename() =="special") || (SHOW_HIDDEN_FILES === false && substr($node->getFilename(), 0, 1) === '.') || ($node->getExtension() != VIEWABLE_FORMAT && $all==false && $node->isFile()))) continue; $data = array(); if ( $node->isDir() && !$node->isDot() ) { @@ -282,10 +351,11 @@ function filesJSON($path,$all,$first=true) } $alldata[]=$data; } - if ($first) - return array('icon'=>"fas fa-atlas",'text'=>$_SERVER['SERVER_NAME'],'children'=>$alldata,'state' => array('opened'=>true)); + usort($alldata, 'sortByOption'); + if ($first) + return array('icon'=>"fas fa-atlas",'text'=>$_SERVER['SERVER_NAME'],'children'=>array_values($alldata),'state' => array('opened'=>true)); else - return $alldata; + return array_values($alldata); } function getnav()