Add limited access path, drag and drop files, rename/delete/create files

This commit is contained in:
Nicolas H 2022-04-13 14:42:43 +02:00
parent 6a4313f384
commit 30dba0b0ca
16 changed files with 479 additions and 59 deletions

View File

@ -1,7 +1,7 @@
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
RewriteCond %{HTTPS} !=on #RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] #RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?doc=$1 [NC,L,QSA,R] RewriteRule ^(.*)$ /index.php?doc=$1 [NC,L,QSA,R]

View File

@ -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;
}

View File

@ -5,7 +5,7 @@ define('VIEWABLE_FORMAT', 'md');
define('TITLE', 'Documentation'); define('TITLE', 'Documentation');
define('ICON', 'fa-book-open'); define('ICON', 'fa-book-open');
define('ALLOWED_EXT','jpg,svg,gif,png,c,tgz,tar.gz,gz,tar,sql,ico'); 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('LOG_FILE', 'log.txt');
define('ACCESS_IP', ''); define('ACCESS_IP', '');
define('HISTORY_FILE', 'history'); define('HISTORY_FILE', 'history');

View File

@ -1,6 +1,6 @@
# About author # 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 * > *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 *

View File

@ -11,11 +11,13 @@
5. Admin access logging 5. Admin access logging
6. Table of contents 6. Table of contents
7. Password protected area 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 ## Planned
1. Complete File Manager 1. Emoji menu in Markdown editor
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

View File

@ -39,13 +39,16 @@ define('VIEWABLE_FORMAT', 'md');
define('TITLE', 'Documentation'); define('TITLE', 'Documentation');
define('ICON', 'fa-book-open'); define('ICON', 'fa-book-open');
define('ALLOWED_EXT','jpg,svg,gif,png,c,tgz,tar.gz,gz,tar,sql,ico'); 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('LOG_FILE', 'log.txt');
define('ACCESS_IP', ''); define('ACCESS_IP', '');
define('HISTORY_FILE', 'history.txt'); define('HISTORY_FILE', 'history.txt');
define('MAX_HISTORY_FILES', 5); define('MAX_HISTORY_FILES', 5);
define('LANG', 'en'); define('LANGUAGE', 'en');
define('ACCESS_PRIVATE', 'false'); 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**: **NOTE**:

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -1,3 +1,3 @@
[Home](/index.md) [Home](/:HOME)
[Sitemap](/:SITEMAP) [Sitemap](/:SITEMAP)
[Glossary](/:GLOSSAIRE) [Glossary](/:GLOSSAIRE)

1
hosts/localhost/log.txt Normal file
View File

@ -0,0 +1 @@
a:0:{}

140
index.php
View File

@ -10,7 +10,6 @@
*/ */
### Global defines ### Global defines
define('PRIVATE', true);
define('ROOT_DIR', realpath(dirname(__FILE__)) .'/'); define('ROOT_DIR', realpath(dirname(__FILE__)) .'/');
define('LIB_DIR', ROOT_DIR.'lib/'); define('LIB_DIR', ROOT_DIR.'lib/');
define('HOST_DIR',ROOT_DIR.'hosts/'.$_SERVER['SERVER_NAME'].'/'); 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."/ParsedownExtra.php";
include LIB_DIR."/ParsedownExtraPlus.php"; include LIB_DIR."/ParsedownExtraPlus.php";
include LIB_DIR."/functions.php"; include LIB_DIR."/functions.php";
$supported_image = array('gif','jpg','jpeg','png','webp','bmp','svg','ico');
### Translations ### Translations
loadlang(LANGUAGE); loadlang(LANGUAGE);
@ -36,30 +36,35 @@ logprotect();
### Sessions ### Sessions
session_name('markdoc'); session_name('markdoc');
session_start(); session_start();
//echo "<br><br>";
//var_dump($_POST);
//var_dump($_GET);
/*var_dump($_POST); $file=explode('?', ($_GET['doc']=="")?$LANG['INDEXMD']:$_GET['doc'], 2)[0] ?? "";
var_dump($_GET);*/
$file=explode('?', ($_GET['doc']=="")?"index.md":$_GET['doc'], 2)[0] ?? "";
$filedetail = pathinfo($file); $filedetail = pathinfo($file);
if (isset($_GET['logout'])) { if (isset($_GET['logout'])) {
unset($_SESSION['md_admin']); unset($_SESSION['md_admin']);
unset($_SESSION['md_user']);
redirect(); redirect();
} }
else if (isset($_POST['action'])) 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 ($_POST['action']=='ident')
{ {
if (isset($_POST['md_password']) && empty($_POST['md_password']) === false) 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; $_SESSION['md_admin'] = true;
redirect(); redirect();
} }
else if (hash('sha512', $_POST['md_password']) === USER_PASSWORD)
{
$_SESSION['md_user'] = true;
redirect($file);
}
else else
{ {
$content = '<h1>'.$LANG['BADPASS'].'</h1>'; $content = '<h1>'.$LANG['BADPASS'].'</h1>';
@ -93,32 +98,105 @@ else if (isset($_POST['action']))
case 'children': case 'children':
print(json_encode(filesJSON(CONTENT_DIR,false))); print(json_encode(filesJSON(CONTENT_DIR,false)));
exit; 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': case 'allchildren':
print(json_encode(filesJSON(CONTENT_DIR,true))); print(json_encode(filesJSON(CONTENT_DIR,true)));
exit; exit;
case 'open': case 'open':
$file=urldecode($_POST['file']); $file=urldecode($_POST['file']);
$filedetail = pathinfo($file);
if (substr($file,0,2)=="/:") if (substr($file,0,2)=="/:")
specialurl($file,true); specialurl($file,true);
else else
{ {
$md=strpos('.md',$file)>=0; if (ACCESS_LIMITED!="" && strpos($filedetail['dirname'],ACCESS_LIMITED)!==false && !isset($_SESSION['md_user']))
print(getcontent($file,$md,true)); {
$content=specialurl("/:ADMIN",true);
}
print(getcontent($file,$md=$filedetail['extension']=='md',true));
exit; exit;
} }
case 'realopen': case 'realopen':
$file=urldecode($_POST['file']); $file=urldecode($_POST['file']);
print(getcontent($file,false,true)); $filedetail = pathinfo($file);
exit; 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': case 'save':
$file=urldecode($_POST['file']); $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; exit;
case 'search': case 'search':
$results=searchstr(CONTENT_DIR,$_POST['search']); $results=searchstr(CONTENT_DIR,$_POST['search']);
$content=sprintf($LANG['FOUND'],$results['totalFiles']); $content=sprintf($LANG['FOUND'],$results['totalFiles']);
foreach($results['files'] as $key => $value) foreach($results['files'] as $key => $value)
$content.='<p class="filefound"><a href="'.$key.'">'.$key.'</a></p><p class="textfound">'.$value.'</p>'; {
$filedetail = pathinfo($key);
if (ACCESS_LIMITED=="" || strpos($filedetail['dirname'],ACCESS_LIMITED)===false || isset($_SESSION['md_user']))
$content.='<p class="filefound"><a href="'.$key.'">'.$key.'</a></p><p class="textfound">'.$value.'</p>';
}
if ($_POST['type']=="js") if ($_POST['type']=="js")
{ {
print($content); print($content);
@ -130,10 +208,14 @@ else if (ACCESS_PRIVATE && !isset($_SESSION['md_admin']))
{ {
$content=specialurl("/:ADMIN",false); $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") else if ($filedetail['extension']=="md")
{ {
$content=getcontent($file); $content=getcontent($file);
@ -173,11 +255,22 @@ else
<?php print(($_SESSION['md_admin'] == true)?'<link rel="stylesheet" href="/css/codemirror.min.css" />':''); ?> <?php print(($_SESSION['md_admin'] == true)?'<link rel="stylesheet" href="/css/codemirror.min.css" />':''); ?>
</head> </head>
<body> <body>
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript" src="/js/popper.min.js"></script>
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/js/jstree.min.js"></script>
<script type="text/javascript" src="/js/prism.js"></script>
<script type="text/javascript" src="/js/emoji.min.js"></script>
<script type="text/javascript" src="/js/toc.bundle.js"></script>
<script type="text/javascript" src="/js/magnifik.js"></script>
<script type="text/javascript">
var LANG = <?php echo $JSLANG; ?>
</script>
<div id="title" style="display: none;"><?php echo TITLE; ?></div> <div id="title" style="display: none;"><?php echo TITLE; ?></div>
<div id="head" class=""> <div id="head" class="">
<span id="forkongithub"><a href="https://github.com/dahut87/MarkDoc"><?php print($LANG['FORK']); ?></a></span> <span id="forkongithub"><a href="https://github.com/dahut87/MarkDoc"><?php print($LANG['FORK']); ?></a></span>
<nav class="navbar fixed-top navbar-expand-md <?php print(($_SESSION['md_admin'] == true)?"navbar-custom":"bg-dark navbar-dark"); ?>"> <nav class="navbar fixed-top navbar-expand-md <?php print(($_SESSION['md_admin'] == true)?"navbar-custom":"bg-dark navbar-dark"); ?>">
<a class="navbar-brand" href="/index.md"><i class="fas <?php echo ICON; ?>"></i>&nbsp;<?php echo TITLE; ?></a> <a class="navbar-brand" href="/<?php echo $LANG['ABOUTMD']; ?>"><i class="fas <?php echo ICON; ?>"></i>&nbsp;<?php echo TITLE; ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -205,7 +298,7 @@ print(($_SESSION['md_admin'] == true)?'<li class="nav-item dropdown">
</ul> </ul>
<form class="form-inline" id="form" name="form" action="/index.php" method="POST"> <form class="form-inline" id="form" name="form" action="/index.php" method="POST">
<input type="hidden" id="action" name="action" value="search"/> <input type="hidden" id="action" name="action" value="search"/>
<?php print(($_SESSION['md_admin'] == true)?'<input class="btn btn-outline-light" my-2 my-sm-0" value="'.$LANG['VIEW'].'" name="voir" id="voir" type="submit"/>&nbsp;&nbsp;<input class="btn btn-outline-light" my-2 my-sm-0" value="'.$LANG['SAVE'].'" name="save" id="save" type="button"/>&nbsp;&nbsp;':''); ?> <?php print(($_SESSION['md_admin'] == true)?'<input class="btn btn-outline-light" my-2 my-sm-0" value="'.$LANG['DELETE'].'" name="del" id="del" type="submit"/>&nbsp;&nbsp;<input class="btn btn-outline-light" my-2 my-sm-0" value="'.$LANG['RENAME'].'" name="ren" id="ren" type="submit"/>&nbsp;&nbsp;<input class="btn btn-outline-light" my-2 my-sm-0" value="'.$LANG['NEW'].'" name="nouveau" id="nouveau" type="submit"/>&nbsp;&nbsp;<input class="btn btn-outline-light" my-2 my-sm-0" value="'.$LANG['VIEW'].'" name="voir" id="voir" type="submit"/>&nbsp;&nbsp;<input class="btn btn-outline-light" my-2 my-sm-0" value="'.$LANG['SAVE'].'" name="save" id="save" type="button"/>&nbsp;&nbsp;':''); ?>
<input class="btn <?php print(($_SESSION['md_admin'] == true)?"btn-outline-light":"btn-outline-info"); ?> my-2 my-sm-0" value="<?php print($LANG['TOC']); ?>" name="toc" id="toc" type="button" style="display: none;"/>&nbsp;&nbsp; <input class="btn <?php print(($_SESSION['md_admin'] == true)?"btn-outline-light":"btn-outline-info"); ?> my-2 my-sm-0" value="<?php print($LANG['TOC']); ?>" name="toc" id="toc" type="button" style="display: none;"/>&nbsp;&nbsp;
<input class="form-control mr-sm-2" type="text" id="search" name="search"/> <input class="form-control mr-sm-2" type="text" id="search" name="search"/>
<input class="btn <?php print(($_SESSION['md_admin'] == true)?"btn-outline-light":"btn-outline-info"); ?> my-2 my-sm-0" value="<?php print($LANG['SEARCH']); ?>" name="submit" id="submit" type="submit"/> <input class="btn <?php print(($_SESSION['md_admin'] == true)?"btn-outline-light":"btn-outline-info"); ?> my-2 my-sm-0" value="<?php print($LANG['SEARCH']); ?>" name="submit" id="submit" type="submit"/>
@ -235,17 +328,6 @@ print(($_SESSION['md_admin'] == true)?'<li class="nav-item dropdown">
?> ?>
</div> </div>
<div class="alert"></div> <div class="alert"></div>
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript" src="/js/popper.min.js"></script>
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/js/jstree.min.js"></script>
<script type="text/javascript" src="/js/prism.js"></script>
<script type="text/javascript" src="/js/emoji.min.js"></script>
<script type="text/javascript" src="/js/toc.bundle.js"></script>
<script type="text/javascript" src="/js/magnifik.js"></script>
<script type="text/javascript">
var LANG = <?php echo $JSLANG; ?>
</script>
<?php print(($_SESSION['md_admin'] == true)?'<link rel="stylesheet" href="/css/simplemde.min.css"> <?php print(($_SESSION['md_admin'] == true)?'<link rel="stylesheet" href="/css/simplemde.min.css">
<script src="/js/simplemde.min.js"></script> <script src="/js/simplemde.min.js"></script>
<script type="text/javascript" src="/js/functionsadmin.js"></script>':'<script type="text/javascript" src="/js/functions.js"></script>'); ?> <script type="text/javascript" src="/js/functionsadmin.js"></script>':'<script type="text/javascript" src="/js/functions.js"></script>'); ?>

View File

@ -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){ $("#save").click(function(e){
e.preventDefault(); e.preventDefault();
viewfile=""; viewfile="";
@ -174,7 +250,9 @@ $(function(){
if ($("#files").jstree("is_leaf",nodes.node)) if ($("#files").jstree("is_leaf",nodes.node))
openlink(file,false); openlink(file,false);
else else
alertBox(LANG['NOTCODED'],'danger'); {
sendmode();
}
}); });
$("input[name=submit]").click(function(e) { $("input[name=submit]").click(function(e) {
@ -231,6 +309,11 @@ function openlink(dest,majtree)
imagemode(dest); imagemode(dest);
return; return;
} }
if (!dest.match(/.(md|txt)$/i))
{
nomode(dest);
return;
}
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "/index.php", url: "/index.php",
@ -254,6 +337,7 @@ function searchtree(file)
var flag; var flag;
$("#files").jstree("deselect_all"); $("#files").jstree("deselect_all");
node=$("#files").jstree("get_node", "ul > li:first"); node=$("#files").jstree("get_node", "ul > li:first");
if (file !== null)
file.split('/').forEach(function (item) { file.split('/').forEach(function (item) {
flag=false; flag=false;
subnodes=$("#files").jstree("get_children_dom",node); 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('<div id="drop-area"><form class="my-form"><p>'+LANG['UPLOAD_MSG']+'</p><input type="file" id="fileElem" multiple accept="image/*" onchange="handleFiles(this.files)"><label class="button" for="fileElem">'+LANG['UPLOAD_BTN']+'</label></form><progress id="progress-bar" max=100 value=0></progress><div id="gallery" /></div></div>');
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) function editmode(data)
{ {
$(window).scrollTop(0); $(window).scrollTop(0);
@ -319,6 +433,16 @@ function viewmode(data)
$("#voir").val("Editer"); $("#voir").val("Editer");
} }
function nomode(dest)
{
$(window).scrollTop(0);
$("#editor").hide();
$("#content").hide();
$("#save").hide();
$("#image").hide();
$("#voir").hide();
}
function editlink(dest) function editlink(dest)
{ {
$.ajax({ $.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)
}

View File

@ -7,8 +7,12 @@
"ABOUTMARKDOC" : "# MarkDoc\r\n\r\n**PHP Markdown-based documentation management system, Free &amp; 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)", "ABOUTMARKDOC" : "# MarkDoc\r\n\r\n**PHP Markdown-based documentation management system, Free &amp; 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", "ADMIN" : "Admin",
"ABOUT" : "About...", "ABOUT" : "About...",
"ABOUTMD" : "about.md", "ABOUTMD" : "About.md",
"INDEXMD" : "Home.md",
"SEARCH" : "Search", "SEARCH" : "Search",
"DELETE" : "Delete",
"RENAME" : "Rename",
"NEW" : "New",
"VIEW" : "View", "VIEW" : "View",
"TOC" : "Toc", "TOC" : "Toc",
"SAVE" : "Save", "SAVE" : "Save",
@ -30,7 +34,13 @@
"NOIP": "Your IP address is not allowed to access this page.", "NOIP": "Your IP address is not allowed to access this page.",
"FORK": "Fork me on GitHub", "FORK": "Fork me on GitHub",
"CREATED": "File created.", "CREATED": "File created.",
"SAVED": "Filed saved.", "SAVED": "File saved.",
"DELETED": "File deleted.",
"RENAMED": "File renamed.",
"PROTECTED": "File is protected.", "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"
} }

View File

@ -7,8 +7,12 @@
"ABOUTMARKDOC" : "# MarkDoc\r\n\r\n**Syst\u00E8me de gestion de documents Mardown \u00E9crits en PHP, Gratuit &amp; 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)", "ABOUTMARKDOC" : "# MarkDoc\r\n\r\n**Syst\u00E8me de gestion de documents Mardown \u00E9crits en PHP, Gratuit &amp; 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", "ADMIN" : "Admin",
"ABOUT" : "A propos", "ABOUT" : "A propos",
"ABOUTMD" : "apropos.md", "ABOUTMD" : "A propos.md",
"INDEXMD" : "Accueil.md",
"SEARCH" : "Chercher", "SEARCH" : "Chercher",
"DELETE" : "Supprimer",
"RENAME" : "Renommer",
"NEW" : "Nouveau",
"VIEW" : "Voir", "VIEW" : "Voir",
"TOC" : "TDM", "TOC" : "TDM",
"SAVE" : "Sauver", "SAVE" : "Sauver",
@ -31,6 +35,12 @@
"FORK": "Fork moi sur GitHub", "FORK": "Fork moi sur GitHub",
"CREATED": "Fichier créé.", "CREATED": "Fichier créé.",
"SAVED": "Fichier enregistré.", "SAVED": "Fichier enregistré.",
"DELETED": "Fichier supprimé.",
"RENAMED": "Fichier renommé.",
"PROTECTED": "Fichier protégé.", "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"
} }

View File

@ -59,16 +59,43 @@ function specialurl($url,$quit)
$extra = new ParsedownExtraplus(); $extra = new ParsedownExtraplus();
$content=$extra->text($LANG['ABOUTMARKDOC']); $content=$extra->text($LANG['ABOUTMARKDOC']);
break; break;
case '/:HOME':
$extra = new ParsedownExtraplus();
$file=getcontent($LANG['INDEXMD'],true, false);
$content=$extra->text($file);
break;
case '/:ADMIN': case '/:ADMIN':
if (isset($_SESSION['md_admin']) === false || $_SESSION['md_admin'] !== true) if (isset($_SESSION['md_admin']) === false || $_SESSION['md_admin'] !== true)
$content = '<form method="post"><div style="text-align:center"><h1></h1>' . (isset($error) ? '<p style="color:#dd0000">' . $error . '</p>' : null) . '<input id="mdsimple_password" name="md_password" type="password" value="" placeholder="Password&hellip;" tabindex="1"><br><br><input type="hidden" id="action" name="action" value="ident"><input type="submit" value="'.$LANG['LOGIN'].'" tabindex="2"></div></form><script type="text/javascript">$("#md_password").focus();</script>'; $content = '<form method="post" name="pass" id="pass"><div style="text-align:center"><h1></h1>' . (isset($error) ? '<p style="color:#dd0000">' . $error . '</p>' : null) . '<input id="mdsimple_password" name="md_password" type="password" value="" placeholder="Password&hellip;" tabindex="1"><br><br><input type="hidden" id="action" name="action" value="ident"><input type="submit" value="'.$LANG['LOGIN'].'" tabindex="2"></div></form>
<script type="text/javascript">
$("#md_password").focus()
$("#pass").submit(function(event){
event.preventDefault();
var serializedData = $("#pass").serialize();
request = $.ajax({
url: "/index.php",
type: "post",
data: serializedData
});
request.done(function (response, textStatus, jqXHR){
window.location.reload();
});
});
</script>';
else else
$content = '<h1>'.$LANG['ALREADYLOG'].'</h1>'; $content = '<h1>'.$LANG['ALREADYLOG'].'</h1>';
break; break;
case '/:SITEMAP': case '/:SITEMAP':
$content='<h1>'.$LANG['SITEMAP'].'</h1>'; $content='<h1>'.$LANG['SITEMAP'].'</h1>';
foreach(plan(CONTENT_DIR) as $file) foreach(plan(CONTENT_DIR) as $file)
$content.='<p class="fileletter"><a href="'.$file.'">'.$file.'</a></p>' ; {
$ext=pathinfo($file);
if ($ext['dirname']=='.')
$final=$ext['filename'];
Else
$final=$ext['dirname']."/".$ext['filename'];
$content.='<p class="fileletter"><a href="'.$file.'">'.$final.'</a></p>';
}
break; break;
case '/:GLOSSAIRE': case '/:GLOSSAIRE':
$content='<h1>'.$LANG['GLOSSARY'].'</h1>'; $content='<h1>'.$LANG['GLOSSARY'].'</h1>';
@ -76,7 +103,10 @@ function specialurl($url,$quit)
{ {
$content.='<p class="letter">'.$letter.'</p>'; $content.='<p class="letter">'.$letter.'</p>';
foreach($files as $file) foreach($files as $file)
$content.='<p class="fileletter"><a href="'.$file.'">'.$file.'</a></p>' ; {
$ext=pathinfo($file);
$content.='<p class="fileletter"><a href="'.$file.'">'.$ext['filename'].'</a></p>';
}
} }
break; break;
} }
@ -94,15 +124,15 @@ function plan($path){
$files = $matches = array(); $files = $matches = array();
while($dir->valid()) while($dir->valid())
{ {
$dir->next();
if (!$dir->isDot()) if (!$dir->isDot())
{ {
$ext = pathinfo($dir->getSubPathName()); $ext = pathinfo($dir->getSubPathName());
if ($ext['extension']=="md") if ($ext['extension']=="md" && $ext['dirname']!='special')
{ {
array_push($files,$dir->getSubPathName()); array_push($files,$dir->getSubPathName());
} }
} }
$dir->next();
} }
ksort($files); ksort($files);
return $files; return $files;
@ -113,18 +143,18 @@ function glossary($path){
$files = $matches = array(); $files = $matches = array();
while($dir->valid()) while($dir->valid())
{ {
$dir->next();
if (!$dir->isDot()) if (!$dir->isDot())
{ {
$ext = pathinfo($dir->getSubPathName()); $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)) if (!array_key_exists($letter,$files))
$files[$letter]=array(); $files[$letter]=array();
array_push($files[$letter],$dir->getSubPathName()); array_push($files[$letter],$dir->getSubPathName());
} }
} }
$dir->next();
} }
ksort($files); ksort($files);
return $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) function setcontent($url,$data)
{ {
@ -247,13 +311,18 @@ function getcontent($url,$md=true,$header=false)
return $content; return $content;
} }
function sortByOption($a, $b) {
return strcmp($a['text'], $b['text']);
}
function filesJSON($path,$all,$first=true) function filesJSON($path,$all,$first=true)
{ {
$alldata = array(); $alldata = array();
$dir= new DirectoryIterator($path); $dir= new DirectoryIterator($path);
foreach($dir as $node) 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(); $data = array();
if ( $node->isDir() && !$node->isDot() ) if ( $node->isDir() && !$node->isDot() )
{ {
@ -282,10 +351,11 @@ function filesJSON($path,$all,$first=true)
} }
$alldata[]=$data; $alldata[]=$data;
} }
if ($first) usort($alldata, 'sortByOption');
return array('icon'=>"fas fa-atlas",'text'=>$_SERVER['SERVER_NAME'],'children'=>$alldata,'state' => array('opened'=>true)); if ($first)
return array('icon'=>"fas fa-atlas",'text'=>$_SERVER['SERVER_NAME'],'children'=>array_values($alldata),'state' => array('opened'=>true));
else else
return $alldata; return array_values($alldata);
} }
function getnav() function getnav()