Commit b2119dba authored by Andreas Müller's avatar Andreas Müller

Added file management

parent 5feab15e
......@@ -23,6 +23,11 @@ if (ISHTTPS)
$url = str_replace("http", "https", $url);
}
if (substr($url, -1) == '/')
{
$url = substr($url, 0, strlen($url) -1);
}
define('BASEURL', $url);
?>
\ No newline at end of file
......@@ -44,15 +44,15 @@ $page->setTitle('SSD BS Erlangen');
$page->setFooter('&copy; '.date('Y').' BS Erlangen | <a href="'.BASEURL.'/?p=imprint">Impressum</a> - <a href="'.BASEURL.'/?p=privacy">Datenschutz</a>');
// Load CSS and JS files needed
$page->addCSS('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
$page->addCSS('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');
$page->addCSS(BASEURL.'/css/bootstrap-outline.min.css');
$page->addCSS('https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css');
$page->addCSS('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css');
$page->addCSS(BASEURL.'/submodules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css');
$page->addCSS(BASEURL.'/css/layout.min.css');
$page->addCSS(BASEURL.'/css/main.css');
$page->addJS('https://code.jquery.com/jquery-2.2.3.min.js');
$page->addJS('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js');
$page->addJS('https://code.jquery.com/jquery-3.2.1.min.js');
$page->addJS('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js');
$page->addJS(BASEURL.'/submodules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js');
$page->addJS(BASEURL.'/submodules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.de.min.js');
$page->addJS(BASEURL.'/js/api.js');
......
/**
* files.js
* (c) Andreas Mueller <webmaster@am-wd.de>
*/
if (typeof jQuery == 'undefined')
throw new Error('jQuery required');
function setButtonStates()
{
var checked = false;
$('#fileList input[type="checkbox"]').each(function (idx, el) {
if ($(el).is(':checked'))
{
checked = true;
}
});
$('#delete').prop('disabled', !checked);
}
$(function() {
setButtonStates();
$('#selectAll').click(function() {
$('#fileList input[type="checkbox"]').each(function (idx, el) {
$(el).prop('checked', true);
});
setButtonStates();
});
$('#fileList input[type="checkbox"]').click(function () {
setButtonStates();
});
$('#delete').click(function () {
var ack = confirm('Sollen die Dateien gelöscht werden?');
if (!ack)
{
return;
}
var path = getGET('path');
if (path === undefined || path === null) {
path = '/';
}
var files = [];
$('#fileList input[type="checkbox"]:checked').each(function (idx, el) {
files[files.length] = $(el).val();
});
api('files_delete', { path: path, files: files }, function(result) {
if (result.error === '')
{
window.location.reload();
}
else
{
console.log("Error:\n" + result.error);
}
});
});
$('#newFileLine').click(function(e) {
e.preventDefault();
var line = '<tr><td><input type="file" name="files[]" /></td><td><button type="button" class="btn btn-xs btn-danger-outline delLine"><span class="fa fa-times"></span></button></td></tr>';
$('#newFileList').append(line);
});
$('#newFolderLine').click(function(e) {
e.preventDefault();
var line = '<tr><td><input type="text" class="form-control" placeholder="Ordnername" name="folders[]" /></td><td><button type="button" class="btn btn-sm btn-danger-outline delLine"><span class="fa fa-times"></span></button></td></tr>';
$('#newFolderList').append(line);
});
$(document).on('click', '.delLine', function(e) {
e.preventDefault();
$(this).parents('tr').remove();
});
});
......@@ -6,6 +6,39 @@
if (typeof jQuery == 'undefined')
throw new Error('jQuery required');
function getGET(key) {
if (key === undefined || typeof key != 'string') {
throw 'Key name is missing';
}
var url = window.location.href;
var tmp = url.split('?');
if (tmp.length > 2) {
throw 'Url invalid';
}
if (tmp.length == 1) {
return undefined;
}
var result = undefined;
var queries = tmp[1].split('&');
queries.forEach(function(element, index, array) {
var kvp = element.split('=');
if (kvp[0] == key) {
if (kvp.length == 1) {
result = null;
}
else {
result = kvp[1];
}
return;
}
});
return result;
}
$(function() {
// Open links with class = blank on new tab/window
$('a').on('click', function(e) {
......
<?php
/**
* files.api.php
* (c) Andreas Mueller <webmaster@am-wd.de>
*/
function files_delete($data)
{
if (empty($_SESSION['id']))
{
return false;
}
$basePath = BASEDIR.'/doku'.$data->path;
foreach ($data->files as $file) {
$path = str_replace('//', '/', $basePath.'/'.$file);
if (is_dir($path))
{
rrmdir($path);
}
else
{
unlink($path);
}
}
return true;
}
?>
\ No newline at end of file
......@@ -28,11 +28,228 @@ if (!in_array('admin', $_SESSION['permissions']))
$page->addJS(BASEURL.'/js/files.js');
// TODO:
// - check for directory
// - create folder if not exists (/doku)
// - List files
// - create/delete/browse folders
// - upload/delete files
if (!is_dir(BASEDIR.'/doku') && !mkdir(BASEDIR.'/doku'))
{
$content = '<div class="alert alert-danger-outline">
<strong><span class="fa fa-exclamation-triangle"></span> Fehler:</strong> Das Verzeichnis <code>/doku</code> existiert nicht und kann nicht erzeugt werden.
</div>';
$page->setContent($content);
return;
}
if (!is_writable(BASEDIR.'/doku'))
{
$content = '<div class="alert alert-danger-outline">
<strong><span class="fa fa-exclamation-triangle"></span> Fehler:</strong> Das Verzeichnis <code>/doku</code> hat fehlerhafte Zugriffsrechte.
</div>';
$page->setContent($content);
return;
}
$relPath = '/';
if (!empty($_GET['path']))
{
$relPath = $_GET['path'];
}
$absPath = BASEDIR.'/doku'.$relPath;
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
switch ($_POST['action'])
{
// --- Upload files
// ==================================
case 'files':
for ($i = 0; $i < count($_FILES['files']['name']); $i++)
{
$error = intval($_FILES['files']['error'][$i]);
if ($error == 0)
{
$name = $_FILES['files']['name'][$i];
$tmp = $_FILES['files']['tmp_name'][$i];
move_uploaded_file($tmp, str_replace('//', '/', $absPath.'/'.$name));
}
}
break;
// --- Create folders
// ==================================
case 'folders':
foreach ($_POST['folders'] as $foldername)
{
$abs = str_replace('//', '/', $absPath.'/'.$foldername);
mkdir($abs);
}
break;
}
}
// --- List files and folders
// ==================================
$list = array();
if ($handle = opendir($absPath))
{
while (($entry = readdir($handle)) !== false)
{
if ($entry == '.' || $entry == '..')
{
continue;
}
$obj = new stdClass();
$obj->isFolder = is_dir($absPath.'/'.$entry);
$obj->name = $entry;
$obj->size = size($absPath.'/'.$entry);
$list[] = $obj;
}
closedir($handle);
}
$table = array();
if ($relPath != '/')
{
$link = '#';
$parent = dirname($relPath);
if ($parent == '/')
{
$link = BASEURL.'/?p=files';
}
else
{
$link = BASEURL.'/?p=files&path='.$parent;
}
$table[] = '<tr>
<td>&nbsp;</td>
<td><span class="fa fa-folder-open-o"></span> <a href="'.$link.'">Ebene höher</a></td>
<td></td>
</tr>';
}
foreach ($list as $el)
{
$line = '<tr><td><input type="checkbox" name="selected[]" value="'.$el->name.'" /></td>';
if ($el->isFolder)
{
$link = BASEURL.'/?p=files&path='.str_replace('//', '/', $relPath.'/'.$el->name);
$line .= '<td><span class="fa fa-folder"></span> <a href="'.$link.'">'.$el->name.'</a></td>';
}
else
{
$link = BASEURL.'/doku'.$relPath.'/'.$el->name;
$line .= '<td><span class="fa fa-file-o"></span> <a href="'.$link.'" class="blank">'.$el->name.'</a></td>';
}
$line .= '<td>'.$el->size.'</td>';
$line .= '</tr>';
$table[] = $line;
}
$content = '
<div class="table-responsive">
<div class="clearfix">
<div class="pull-left">
<button type="button" class="btn btn-bs-outline btn-sm" id="selectAll"><span class="fa fa-check-square-o"></span> Alles auswählen</button>
<button type="button" class="btn btn-danger-outline btn-sm" id="delete"><span class="fa fa-trash"></span> Löschen</button>
</div>
<div class="pull-right" style="margin-right: 1px;">
<div class="input-group-btn">
<button type="button" class="btn btn-success-outline btn-sm dropdown-toggle" style="border-radius: 4px;" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="fa fa-plus"></span></button>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="#" id="newFile" data-toggle="modal" data-target="#fileModal"><span class="fa fa-file-o"></span> Datei</a></li>
<li><a href="#" id="newFolder" data-toggle="modal" data-target="#folderModal"><span class="fa fa-folder-open-o"></span> Ordner</a></li>
</ul>
</div>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>&nbsp;</th>
<th>Name</th>
<th>Größe</th>
</tr>
</thead>
<tbody id="fileList">
'.implode(PHP_EOL, $table).'
</tbody>
</table>
</div>';
$page->setContent($content);
$content = '
<form class="modal fade" id="fileModal" tabindex="-1" role="dialog" aria-labelledby="fileModalLabel" method="post" action="'.BASEURL.'/?p=files'.($relPath == '/' ? '' : '&path='.$_GET['path']).'" enctype="multipart/form-data">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="fileModalLabel">Neue Datei(en)</h4>
</div>
<div class="modal-body">
<table class="table table-condensed">
<thead>
<tr>
<th>&nbsp;</th>
<th><button type="button" class="btn btn-xs btn-success-outline" id="newFileLine"><span class="fa fa-plus"></span></button></th>
</tr>
</thead>
<tbody id="newFileList">
<tr>
<td><input type="file" name="files[]" /></td>
<td><button type="button" class="btn btn-xs btn-danger-outline delLine"><span class="fa fa-times"></span></button></td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="submit" name="action" value="files" class="btn btn-success-outline"><span class="fa fa-upload"></span> Hochladen</button>
<button type="button" class="btn btn-primary-outline" data-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</form>
';
$page->addContent($content);
$content = '
<form class="modal fade" id="folderModal" tabindex="-1" role="dialog" aria-labelledby="folderModalLabel" method="post" action="'.BASEURL.'/?p=files'.($relPath == '/' ? '' : '&path='.$_GET['path']).'">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="fileModalLabel">Neue(r) Ordner</h4>
</div>
<div class="modal-body">
<table class="table table-condensed">
<thead>
<tr>
<th>&nbsp;</th>
<th><button type="button" class="btn btn-sm btn-success-outline" id="newFolderLine"><span class="fa fa-plus"></span></button></th>
</tr>
</thead>
<tbody id="newFolderList">
<tr>
<td><input type="text" class="form-control" placeholder="Ordnername" name="folders[]" /></td>
<td><button type="button" class="btn btn-sm btn-danger-outline delLine"><span class="fa fa-times"></span></button></td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="submit" name="action" value="folders" class="btn btn-success-outline"><span class="fa fa-plus-circle"></span> Erzeugen</button>
<button type="button" class="btn btn-primary-outline" data-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</form>
';
$page->addContent($content);
?>
\ No newline at end of file
......@@ -48,7 +48,7 @@ else
if (in_array('admin', $_SESSION['permissions']))
{
$node->addSubmenu(new AMWD\MenuNode('<span class="fa fa-fs fa-cogs"></span> Schuljahr & Ferien', BASEURL.'/?p=holidays', $p == 'holidays'));
// $node->addSubmenu(new AMWD\MenuNode('<span class="fa fa-fs fa-files-o"></span> Dateien', BASEURL.'/?p=files', $p == 'files'));
$node->addSubmenu(new AMWD\MenuNode('<span class="fa fa-fs fa-files-o"></span> Dateien', BASEURL.'/?p=files', $p == 'files'));
}
}
......
......@@ -21,4 +21,50 @@ if(!function_exists('hash_equals'))
}
}
if (!function_exists('size'))
{
function size($path)
{
if (is_dir($path))
{
return null;
}
$bytes = filesize($path);
if ($bytes < 1024)
{
return $bytes.' B';
}
else if ($bytes < 1024 * 1024)
{
return round($bytes / 1024, 2).' KB';
}
else if ($bytes < 1024 * 1024 * 1024)
{
return round($bytes / (1024 * 1024), 2).' MB';
}
else if ($bytes < 1024 * 1024 * 1024 * 1024)
{
return round($bytes / (1024 * 1024 * 1024), 2).' GB';
}
else
{
return round($bytes / (1024 * 1024 * 1024 * 1024), 2).' TB';
}
}
}
if (!function_exists('rrmdir'))
{
function rrmdir($dir)
{
$files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file)
{
is_dir($dir.'/'.$file) ? rrmdir($dir.'/'.$file) : unlink($dir.'/'.$file);
}
return rmdir($dir);
}
}
?>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment