1
0
mirror of https://github.com/misterunknown/ifm.git synced 2025-08-13 03:23:59 +02:00

some organizational code changes, prepare for JS templates

This commit is contained in:
Marco Dickert
2017-07-04 16:02:45 +02:00
parent ea3f3922f3
commit ffb9447352
3 changed files with 933 additions and 452 deletions

693
ifm.php

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +1,44 @@
// IFM - js app /**
* IFM constructor
function IFM() { */
function IFM( params ) {
var self = this; // reference to ourself, because "this" does not work within callbacks var self = this; // reference to ourself, because "this" does not work within callbacks
this.IFM_SCFN = "<?=basename($_SERVER['SCRIPT_NAME'])?>"; // set the backend for the application
this.config = jQuery.parseJSON('<?php echo json_encode(IFMConfig::getConstants()); ?>'); // serialize the PHP config array, so we can use it in JS too if( ! params.api ) {
throw new Error( "IFM: no backend configured" );
} else {
self.api = params.api;
}
// load the configuration from the backend
$.ajax({
url: self.api,
type: "POST",
data: {
api: "getConfig"
},
dataType: "json",
success: function(d) {
self.config = d;
self.log( "configuration loaded" );
},
error: function() {
throw new Error( "IFM: could not load configuration" );
}
});
this.isDocroot = <?php echo realpath( IFMConfig::root_dir ) == dirname( __FILE__ ) ? "true" : "false"; ?>; this.isDocroot = <?php echo realpath( IFMConfig::root_dir ) == dirname( __FILE__ ) ? "true" : "false"; ?>;
this.editor = null; // global ace editor this.editor = null; // global ace editor
this.fileChanged = false; // flag for check if file was changed already this.fileChanged = false; // flag for check if file was changed already
this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests
// modal functions /**
* Shows a bootstrap modal
*
* @param string content - content of the modal
* @param object options - options for the modal
*/
this.showModal = function( content, options = {} ) { this.showModal = function( content, options = {} ) {
var modal = $( document.createElement( 'div' ) ) var modal = $( document.createElement( 'div' ) )
.addClass( "modal fade" ) .addClass( "modal fade" )
@@ -36,24 +64,38 @@ function IFM() {
modal.modal('show'); modal.modal('show');
}; };
/**
* Hides a bootstrap modal
*/
this.hideModal = function() { this.hideModal = function() {
$('#ifmmodal').modal('hide'); $('#ifmmodal').modal('hide');
}; };
/**
* Reloads the file table
*/
this.refreshFileTable = function () { this.refreshFileTable = function () {
var id=self.generateGuid(); var id = self.generateGuid();
self.task_add("Refresh", id); self.task_add( "Refresh", id );
$.ajax({ $.ajax({
url: self.IFM_SCFN, url: self.api,
type: "POST", type: "POST",
data: "api=getFiles&dir=" + self.currentDir, data: {
api: "getFiles",
dir: self.currentDir
},
dataType: "json", dataType: "json",
success: self.rebuildFileTable, success: self.rebuildFileTable,
error: function(response) { ifm.showMessage("General error occured: No or broken response", "e"); }, error: function( response ) { self.showMessage( "General error occured: No or broken response", "e" ); },
complete: function() { self.task_done( id ); } complete: function() { self.task_done( id ); }
}); });
}; };
/**
* Rebuilds the file table with fetched items
*
* @param object data - object with items
*/
this.rebuildFileTable = function( data ) { this.rebuildFileTable = function( data ) {
var newTBody = $(document.createElement('tbody')); var newTBody = $(document.createElement('tbody'));
for( var i=0; i < data.length; i++ ) { for( var i=0; i < data.length; i++ ) {
@@ -142,12 +184,18 @@ function IFM() {
}); });
}; };
/**
* Changes the current directory
*
* @param string newdir - target directory
* @param object options - options for changing the directory
*/
this.changeDirectory = function( newdir, options={} ) { this.changeDirectory = function( newdir, options={} ) {
config = { absolute: false, pushState: true }; config = { absolute: false, pushState: true };
jQuery.extend( config, options ); jQuery.extend( config, options );
if( ! config.absolute ) newdir = self.pathCombine( self.currentDir, newdir ); if( ! config.absolute ) newdir = self.pathCombine( self.currentDir, newdir );
$.ajax({ $.ajax({
url: self.IFM_SCFN, url: self.api,
type: "POST", type: "POST",
data: ({ data: ({
api: "getRealpath", api: "getRealpath",
@@ -164,6 +212,9 @@ function IFM() {
}); });
}; };
/**
* Shows a file, either a new file or an existing
*/
this.showFileForm = function () { this.showFileForm = function () {
var filename = arguments.length > 0 ? arguments[0] : "newfile.txt"; var filename = arguments.length > 0 ? arguments[0] : "newfile.txt";
var content = arguments.length > 1 ? arguments[1] : ""; var content = arguments.length > 1 ? arguments[1] : "";
@@ -211,6 +262,9 @@ function IFM() {
}); });
}; };
/**
* Shows the create directory dialog
*/
this.createDirForm = function() { this.createDirForm = function() {
self.showModal( '<form id="createDir">\ self.showModal( '<form id="createDir">\
<div class="modal-body">\ <div class="modal-body">\
@@ -226,114 +280,12 @@ function IFM() {
</form>' ); </form>' );
}; };
this.ajaxRequestDialog = function() { /**
self.showModal( '<form id="ajaxrequest">\ * Create a directory
<div class="modal-body">\ */
<fieldset>\
<label>URL</label><br>\
<input onkeypress="return ifm.preventEnter(event);" class="form-control" type="text" id="ajaxurl" required><br>\
<label>Data</label><br>\
<textarea class="form-control" id="ajaxdata"></textarea><br>\
<label>Method</label><br>\
<input type="radio" name="arMethod" value="GET">GET</input><input type="radio" name="arMethod" value="POST" checked="checked">POST</input><br>\
<button type="button" class="btn btn-success" onclick="ifm.ajaxRequest();return false;">Request</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">Close</button><br>\
<label>Response</label><br>\
<textarea class="form-control" id="ajaxresponse"></textarea>\
</fieldset>\
</form>\
</div>');
};
this.ajaxRequest = function() {
$.ajax({
url : $("#ajaxurl").val(),
cache : false,
data : $('#ajaxdata').val().replace(/\n/g,"&"),
type : $('#ajaxrequest input[name=arMethod]:checked').val(),
success : function(response) { $("#ajaxresponse").text(response); },
error : function(e) { self.showMessage("Error: "+e, "e"); console.log(e); }
});
};
this.saveFile = function() {
$.ajax({
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "saveFile",
dir: self.currentDir,
filename: $("#showFile input[name^=filename]").val(),
content: ifm.editor.getValue()
}),
dataType: "json",
success: function( data ) {
if( data.status == "OK" ) {
self.showMessage( "File successfully edited/created.", "s" );
self.refreshFileTable();
} else self.showMessage( "File could not be edited/created:" + data.message, "e" );
},
error: function() { self.showMessage( "General error occured", "e" ); }
});
self.fileChanged = false;
};
this.editFile = function( name ) {
$.ajax({
url: self.IFM_SCFN,
type: "POST",
dataType: "json",
data: ({
api: "getContent",
dir: self.currentDir,
filename: name
}),
success: function( data ) {
if( data.status == "OK" && data.data.content != null ) {
self.showFileForm( data.data.filename, data.data.content );
}
else if( data.status == "OK" && data.data.content == null ) {
self.showMessage( "The content of this file cannot be fetched.", "e" );
}
else self.showMessage( "Error: "+data.message, "e" );
},
error: function() { self.showMessage( "This file can not be displayed or edited.", "e" ); }
});
};
this.deleteFileDialog = function( name ) {
self.showModal( '<form id="deleteFile">\
<div class="modal-body">\
<label>Do you really want to delete the file '+name+'?\
</div><div class="modal-footer">\
<button type="button" class="btn btn-danger" onclick="ifm.deleteFile(\''+ifm.JSEncode(name)+'\');ifm.hideModal();return false;">Yes</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">No</button>\
</div>\
</form>' );
};
this.deleteFile = function( name ) {
$.ajax({
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "deleteFile",
dir: self.currentDir,
filename: name
}),
dataType: "json",
success: function(data) {
if(data.status == "OK") {
self.showMessage("File successfully deleted", "s");
self.refreshFileTable();
} else self.showMessage("File could not be deleted", "e");
},
error: function() { self.showMessage("General error occured", "e"); }
});
};
this.createDir = function() { this.createDir = function() {
$.ajax({ $.ajax({
url: self.IFM_SCFN, url: self.api,
type: "POST", type: "POST",
data: ({ data: ({
api: "createDir", api: "createDir",
@@ -354,7 +306,107 @@ function IFM() {
}); });
}; };
this.renameFileDialog = function(name) {
/**
* Saves a file
*/
this.saveFile = function() {
$.ajax({
url: self.api,
type: "POST",
data: ({
api: "saveFile",
dir: self.currentDir,
filename: $("#showFile input[name^=filename]").val(),
content: ifm.editor.getValue()
}),
dataType: "json",
success: function( data ) {
if( data.status == "OK" ) {
self.showMessage( "File successfully edited/created.", "s" );
self.refreshFileTable();
} else self.showMessage( "File could not be edited/created:" + data.message, "e" );
},
error: function() { self.showMessage( "General error occured", "e" ); }
});
self.fileChanged = false;
};
/**
* Edit a file
*
* @params string name - name of the file
*/
this.editFile = function( name ) {
$.ajax({
url: self.api,
type: "POST",
dataType: "json",
data: ({
api: "getContent",
dir: self.currentDir,
filename: name
}),
success: function( data ) {
if( data.status == "OK" && data.data.content != null ) {
self.showFileForm( data.data.filename, data.data.content );
}
else if( data.status == "OK" && data.data.content == null ) {
self.showMessage( "The content of this file cannot be fetched.", "e" );
}
else self.showMessage( "Error: "+data.message, "e" );
},
error: function() { self.showMessage( "This file can not be displayed or edited.", "e" ); }
});
};
/**
* Shows the delete file dialog
*
* @param string name - name of the file
*/
this.deleteFileDialog = function( name ) {
self.showModal( '<form id="deleteFile">\
<div class="modal-body">\
<label>Do you really want to delete the file '+name+'?\
</div><div class="modal-footer">\
<button type="button" class="btn btn-danger" onclick="ifm.deleteFile(\''+ifm.JSEncode(name)+'\');ifm.hideModal();return false;">Yes</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">No</button>\
</div>\
</form>' );
};
/**
* Deletes a file
*
* @params string name - name of the file
*/
this.deleteFile = function( name ) {
$.ajax({
url: self.api,
type: "POST",
data: ({
api: "deleteFile",
dir: self.currentDir,
filename: name
}),
dataType: "json",
success: function(data) {
if(data.status == "OK") {
self.showMessage("File successfully deleted", "s");
self.refreshFileTable();
} else self.showMessage("File could not be deleted", "e");
},
error: function() { self.showMessage("General error occured", "e"); }
});
};
/**
* Show the rename file dialog
*
* @params string name - name of the file
*/
this.renameFileDialog = function( name ) {
self.showModal( '<div class="modal-body">\ self.showModal( '<div class="modal-body">\
<form id="renameFile">\ <form id="renameFile">\
<fieldset>\ <fieldset>\
@@ -366,9 +418,14 @@ function IFM() {
</div>' ); </div>' );
}; };
this.renameFile = function(name) { /**
* Renames a file
*
* @params string name - name of the file
*/
this.renameFile = function( name ) {
$.ajax({ $.ajax({
url: ifm.IFM_SCFN, url: ifm.api,
type: "POST", type: "POST",
data: ({ data: ({
api: "renameFile", api: "renameFile",
@@ -387,38 +444,12 @@ function IFM() {
}); });
}; };
this.copyMove = function( source, destination, action ) { /**
var id=self.generateGuid(); * Show the copy/move dialog
self.task_add(action.charAt(0).toUpperCase()+action.slice(1)+" "+source+" to "+destination, id); *
$.ajax({ * @params string name - name of the file
url: self.IFM_SCFN, */
type: "POST", this.copyMoveDialog = function( name ) {
data: ({
dir: self.currentDir,
api: "copyMove",
action: action,
filename: source,
destination: destination
}),
dataType: "json",
success: function(data) {
if( data.status == "OK" ) {
self.showMessage( data.message, "s" );
} else {
self.showMessage( data.message, "e" );
}
self.refreshFileTable();
},
error: function() {
self.showMessage( "General error occured.", "e" );
},
complete: function() {
self.task_done(id);
}
});
};
this.copyMoveDialog = function(name) {
self.showModal( '<form id="copyMoveFile"><fieldset>\ self.showModal( '<form id="copyMoveFile"><fieldset>\
<div class="modal-body">\ <div class="modal-body">\
<label>Select destination:</label>\ <label>Select destination:</label>\
@@ -431,7 +462,7 @@ function IFM() {
</div>\ </div>\
</fieldset></form>'); </fieldset></form>');
$.ajax({ $.ajax({
url: ifm.IFM_SCFN, url: ifm.api,
type: "POST", type: "POST",
data: ({ data: ({
api: "getFolderTree", api: "getFolderTree",
@@ -459,10 +490,51 @@ function IFM() {
}); });
}; };
this.extractFileDialog = function(name) { /**
var targetDirSuggestion=""; * Copy or moves a file
if(name.lastIndexOf(".") > 1) *
targetDirSuggestion = name.substr(0,name.length-4); * @params string name - name of the file
*/
this.copyMove = function( source, destination, action ) {
var id=self.generateGuid();
self.task_add( action.charAt(0).toUpperCase() + action.slice(1) + " " + source + " to " + destination, id );
$.ajax({
url: self.api,
type: "POST",
data: {
dir: self.currentDir,
api: "copyMove",
action: action,
filename: source,
destination: destination
},
dataType: "json",
success: function(data) {
if( data.status == "OK" ) {
self.showMessage( data.message, "s" );
} else {
self.showMessage( data.message, "e" );
}
self.refreshFileTable();
},
error: function() {
self.showMessage( "General error occured.", "e" );
},
complete: function() {
self.task_done( id );
}
});
};
/**
* Shows the extract file dialog
*
* @param string name - name of the file
*/
this.extractFileDialog = function( name ) {
var targetDirSuggestion = "";
if( name.lastIndexOf( "." ) > 1 )
targetDirSuggestion = name.substr( 0, name.length - 4 );
else targetDirSuggestion = name; else targetDirSuggestion = name;
self.showModal( '<form id="extractFile"><fieldset>\ self.showModal( '<form id="extractFile"><fieldset>\
<div class="modal-body">\ <div class="modal-body">\
@@ -492,27 +564,36 @@ function IFM() {
}); });
}; };
this.extractFile = function(name, t) { /**
* Extracts a file
*
* @param string name - name of the file
* @param string t - name of the target directory
*/
this.extractFile = function( name, t ) {
$.ajax({ $.ajax({
url: self.IFM_SCFN, url: self.api,
type: "POST", type: "POST",
data: ({ data: {
api: "extractFile", api: "extractFile",
dir: self.currentDir, dir: self.currentDir,
filename: name, filename: name,
targetdir: t targetdir: t
}), },
dataType: "json", dataType: "json",
success: function(data) { success: function( data ) {
if(data.status == "OK") { if( data.status == "OK" ) {
self.showMessage("File successfully extracted", "s"); self.showMessage( "File successfully extracted", "s" );
self.refreshFileTable(); self.refreshFileTable();
} else self.showMessage("File could not be extracted. Error: "+data.message, "e"); } else self.showMessage( "File could not be extracted. Error: " + data.message, "e" );
}, },
error: function() { self.showMessage("General error occured", "e"); } error: function() { self.showMessage( "General error occured", "e" ); }
}); });
}; };
/**
* Shows the upload file dialog
*/
this.uploadFileDialog = function() { this.uploadFileDialog = function() {
self.showModal( '<form id="uploadFile">\ self.showModal( '<form id="uploadFile">\
<div class="modal-body">\ <div class="modal-body">\
@@ -526,11 +607,14 @@ function IFM() {
<button class="btn btn-default" onclick="ifm.uploadFile();ifm.hideModal();return false;">Upload</button>\ <button class="btn btn-default" onclick="ifm.uploadFile();ifm.hideModal();return false;">Upload</button>\
<button class="btn btn-default" onclick="ifm.hideModal();return false;">Cancel</button>\ <button class="btn btn-default" onclick="ifm.hideModal();return false;">Cancel</button>\
</div>\ </div>\
</form>'); </form>' );
}; };
/**
* Uploads a file
*/
this.uploadFile = function() { this.uploadFile = function() {
var ufile = document.getElementById('ufile').files[0]; var ufile = document.getElementById( 'ufile' ).files[0];
var data = new FormData(); var data = new FormData();
var newfilename = $("#uploadFile input[name^=newfilename]").val(); var newfilename = $("#uploadFile input[name^=newfilename]").val();
data.append('api', 'uploadFile'); data.append('api', 'uploadFile');
@@ -539,7 +623,7 @@ function IFM() {
data.append('newfilename', newfilename); data.append('newfilename', newfilename);
var id = self.generateGuid(); var id = self.generateGuid();
$.ajax({ $.ajax({
url: self.IFM_SCFN, url: self.api,
type: "POST", type: "POST",
data: data, data: data,
processData: false, processData: false,
@@ -563,10 +647,16 @@ function IFM() {
self.task_add("Upload "+ufile.name, id); self.task_add("Upload "+ufile.name, id);
}; };
/**
* Change the permissions of a file
*
* @params object e - event object
* @params string name - name of the file
*/
this.changePermissions = function(e, name) { this.changePermissions = function(e, name) {
if(e.keyCode == '13') if(e.keyCode == '13')
$.ajax({ $.ajax({
url: self.IFM_SCFN, url: self.api,
type: "POST", type: "POST",
data: ({ data: ({
api: "changePermissions", api: "changePermissions",
@@ -588,6 +678,9 @@ function IFM() {
}); });
}; };
/**
* Show the remote upload dialog
*/
this.remoteUploadDialog = function() { this.remoteUploadDialog = function() {
self.showModal( '<form id="uploadFile">\ self.showModal( '<form id="uploadFile">\
<div class="modal-body">\ <div class="modal-body">\
@@ -612,11 +705,14 @@ function IFM() {
$("#filename").on("keyup", function() { $("#url").off(); }); $("#filename").on("keyup", function() { $("#url").off(); });
}; };
/**
* Remote uploads a file
*/
this.remoteUpload = function() { this.remoteUpload = function() {
var filename = $("#filename").val(); var filename = $("#filename").val();
var id = ifm.generateGuid(); var id = ifm.generateGuid();
$.ajax({ $.ajax({
url: ifm.IFM_SCFN, url: ifm.api,
type: "POST", type: "POST",
data: ({ data: ({
api: "remoteUpload", api: "remoteUpload",
@@ -638,68 +734,78 @@ function IFM() {
ifm.task_add("Remote upload: "+filename, id); ifm.task_add("Remote upload: "+filename, id);
}; };
// -------------------- /**
// additional functions * Shows the ajax request dialog
// -------------------- */
this.showMessage = function(m, t) { this.ajaxRequestDialog = function() {
var msgType = (t == "e")?"danger":(t == "s")?"success":"info"; self.showModal( '<form id="ajaxrequest">\
$.notify( <div class="modal-body">\
{ message: m }, <fieldset>\
{ type: msgType, delay: 5000, mouse_over: 'pause', offset: { x: 15, y: 65 } } <label>URL</label><br>\
); <input onkeypress="return ifm.preventEnter(event);" class="form-control" type="text" id="ajaxurl" required><br>\
<label>Data</label><br>\
<textarea class="form-control" id="ajaxdata"></textarea><br>\
<label>Method</label><br>\
<input type="radio" name="arMethod" value="GET">GET</input><input type="radio" name="arMethod" value="POST" checked="checked">POST</input><br>\
<button type="button" class="btn btn-success" onclick="ifm.ajaxRequest();return false;">Request</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">Close</button><br>\
<label>Response</label><br>\
<textarea class="form-control" id="ajaxresponse"></textarea>\
</fieldset>\
</form>\
</div>');
}; };
this.pathCombine = function(a, b) {
if(a == "" && b == "") return ""; /**
if(b[0] == "/") b = b.substring(1); * Performs an ajax request
if(a == "") return b; */
if(a[a.length-1] == "/") a = a.substring(0, a.length-1); this.ajaxRequest = function() {
if(b == "") return a; $.ajax({
return a+"/"+b; url : $("#ajaxurl").val(),
cache : false,
data : $('#ajaxdata').val().replace(/\n/g,"&"),
type : $('#ajaxrequest input[name=arMethod]:checked').val(),
success : function(response) { $("#ajaxresponse").text(response); },
error : function(e) { self.showMessage("Error: "+e, "e"); console.log(e); }
});
}; };
this.preventEnter = function(e) {
if( e.keyCode == 13 ) return false;
else return true; /**
} * Shows a popup to prevent that the user closes the file editor accidentally
*/
this.showSaveQuestion = function() { this.showSaveQuestion = function() {
var a = '<div id="savequestion"><label>Do you want to save this file?</label><br><button onclick="ifm.saveFile();ifm.closeFileForm(); return false;">Save</button><button onclick="ifm.closeFileForm();return false;">Dismiss</button>'; var a = '<div id="savequestion"><label>Do you want to save this file?</label><br><button onclick="ifm.saveFile();ifm.closeFileForm(); return false;">Save</button><button onclick="ifm.closeFileForm();return false;">Dismiss</button>';
$(document.body).prepend(a); $(document.body).prepend(a);
self.bindOverlayClickEvent(); self.bindOverlayClickEvent();
}; };
/**
* Hides the save question
*/
this.hideSaveQuestion = function() { this.hideSaveQuestion = function() {
$("#savequestion").remove(); $("#savequestion").remove();
}; };
this.handleMultiselect = function() {
var amount = $("#filetable tr.selectedItem").length; /**
if(amount > 0) { * Shows the delete dialog for multiple files
if(document.getElementById("multiseloptions")===null) { */
$(document.body).prepend('<div id="multiseloptions">\
<div style="font-size:0.8em;background-color:#00A3A3;padding:2px;">\
<a style="color:#FFF" onclick="$(\'input[name=multisel]\').attr(\'checked\', false);$(\'#multiseloptions\').remove();">[close]</a>\
</div>\
<ul><li><a onclick="ifm.multiDelete();"><span class="icon icon-trash"></span> delete (<span class="amount"></span>)</a></li></ul></div>\
');
$("#multiseloptions").draggable();
//$("#multiseloptions").resizable({ghost: true, minHeight: 50, minWidth: 100});
}
$("#multiseloptions .amount").text(amount);
}
else {
if(document.getElementById("multiseloptions")!==null)
$("#multiseloptions").remove();
}
};
this.multiDeleteDialog = function() { this.multiDeleteDialog = function() {
var form = '<form id="deleteFile"><div class="modal-body"><label>Do you really want to delete these '+$('#filetable tr.selectedItem').length+' files?</label>'; var form = '<form id="deleteFile"><div class="modal-body"><label>Do you really want to delete these '+$('#filetable tr.selectedItem').length+' files?</label>';
form += '</div><div class="modal-footer"><button type="button" class="btn btn-danger" onclick="ifm.multiDelete();ifm.hideModal();return false;">Yes</button>'; form += '</div><div class="modal-footer"><button type="button" class="btn btn-danger" onclick="ifm.multiDelete();ifm.hideModal();return false;">Yes</button>';
form += '<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">No</button></div></form>'; form += '<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">No</button></div></form>';
self.showModal( form ); self.showModal( form );
}; };
/**
* Deletes multiple files
*/
this.multiDelete = function() { this.multiDelete = function() {
var elements = $('#filetable tr.selectedItem'); var elements = $('#filetable tr.selectedItem');
var filenames = []; var filenames = [];
for(var i=0;typeof(elements[i])!='undefined';filenames.push(elements[i++].getAttribute('data-filename'))); for(var i=0;typeof(elements[i])!='undefined';filenames.push(elements[i++].getAttribute('data-filename')));
$.ajax({ $.ajax({
url: self.IFM_SCFN, url: self.api,
type: "POST", type: "POST",
data: ({ data: ({
api: "deleteMultipleFiles", api: "deleteMultipleFiles",
@@ -721,25 +827,107 @@ function IFM() {
error: function() { ifm.showMessage("General error occured", "e"); } error: function() { ifm.showMessage("General error occured", "e"); }
}); });
}; };
// --------------------
// helper functions
// --------------------
/**
* Shows a notification
*
* @param string m - message text
* @param string t - message type (e: error, s: success)
*/
this.showMessage = function(m, t) {
var msgType = (t == "e")?"danger":(t == "s")?"success":"info";
$.notify(
{ message: m },
{ type: msgType, delay: 5000, mouse_over: 'pause', offset: { x: 15, y: 65 } }
);
};
/**
* Combines two path components
*
* @param string a - component 1
* @param string b - component 2
*/
this.pathCombine = function(a, b) {
if(a == "" && b == "") return "";
if(b[0] == "/") b = b.substring(1);
if(a == "") return b;
if(a[a.length-1] == "/") a = a.substring(0, a.length-1);
if(b == "") return a;
return a+"/"+b;
};
/**
* Prevents a user to submit a form via clicking enter
*/
this.preventEnter = function(e) {
if( e.keyCode == 13 ) return false;
else return true;
}
/**
* Checks if an element is part of an array
*
* @param obj needle - search item
* @param array haystack - array to search
*/
this.inArray = function(needle, haystack) { this.inArray = function(needle, haystack) {
for(var i = 0; i < haystack.length; i++) { if(haystack[i] == needle) return true; } return false; for(var i = 0; i < haystack.length; i++) { if(haystack[i] == needle) return true; } return false;
}; };
this.task_add = function(name,id) { // uFI stands for uploadFileInformation
if(!document.getElementById("waitqueue")) { /**
$(document.body).prepend('<div id="waitqueue"></div>'); * Adds a task to the taskbar.
//$("#waitqueue").on("mouseover", function() { $(this).toggleClass("left"); }); *
* @param string name - description of the task
* @param string id - identifier for the task
*/
this.task_add = function( name, id ) {
if( ! document.getElementById( "waitqueue" ) ) {
$( document.body ).prepend( '<div id="waitqueue"></div>' );
} }
$("#waitqueue").prepend('<div id="'+id+'" class="panel panel-default"><div class="panel-body"><div class="progress"><div class="progress-bar progress-bar-info progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemax="100" style="width:100%"></div><span class="progbarlabel">'+name+'</span></div></div></div>'); $( "#waitqueue" ).prepend('\
<div id="'+id+'" class="panel panel-default">\
<div class="panel-body">\
<div class="progress">\
<div class="progress-bar progress-bar-info progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemax="100" style="width:100%"></div>\
<span class="progbarlabel">'+name+'</span>\
</div>\
</div>\
</div>\
');
}; };
/**
* Removes a task from the taskbar
*
* @param string id - task identifier
*/
this.task_done = function(id) { this.task_done = function(id) {
$("#"+id).remove(); $("#"+id).remove();
if($("#waitqueue>div").length == 0) { if($("#waitqueue>div").length == 0) {
$("#waitqueue").remove(); $("#waitqueue").remove();
} }
}; };
/**
* Updates a task
*
* @param integer progress - percentage of status
* @param string id - task identifier
*/
this.task_update = function(progress, id) { this.task_update = function(progress, id) {
$('#'+id+' .progress-bar').css('width', progress+'%').attr('aria-valuenow', progress); $('#'+id+' .progress-bar').css('width', progress+'%').attr('aria-valuenow', progress);
}; };
/**
* Highlights an item in the file table
*
* @param object param - either an element id or a jQuery object
*/
this.highlightItem = function( param ) { this.highlightItem = function( param ) {
var highlight = function( el ) { var highlight = function( el ) {
el.addClass( 'highlightedItem' ).siblings().removeClass( 'highlightedItem' ); el.addClass( 'highlightedItem' ).siblings().removeClass( 'highlightedItem' );
@@ -768,7 +956,13 @@ function IFM() {
} }
} }
}; };
this.isElementInViewport = function isElementInViewport (el) {
/**
* Checks if an element is within the viewport
*
* @param object el - element object
*/
this.isElementInViewport = function (el) {
if (typeof jQuery === "function" && el instanceof jQuery) { if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0]; el = el[0];
} }
@@ -780,6 +974,10 @@ function IFM() {
rect.right <= (window.innerWidth || document.documentElement.clientWidth) rect.right <= (window.innerWidth || document.documentElement.clientWidth)
); );
} }
/**
* Generates a GUID
*/
this.generateGuid = function() { this.generateGuid = function() {
var result, i, j; var result, i, j;
result = ''; result = '';
@@ -789,14 +987,43 @@ function IFM() {
} }
return result; return result;
}; };
/**
* Logs a message if debug mode is on
*
* @param string m - message text
*/
this.log = function( m ) {
if( self.debug ) {
console.log( "IFM (debug): " + m );
}
};
/**
* Encodes a string for use within javascript
*
* @param string s - encoding string
*/
this.JSEncode = function(s) { this.JSEncode = function(s) {
return s.replace(/'/g, '\\x27').replace(/"/g, '\\x22'); return s.replace(/'/g, '\\x27').replace(/"/g, '\\x22');
}; };
/**
* Handles the javascript pop states
*
* @param object event - event object
*/
this.historyPopstateHandler = function(event) { this.historyPopstateHandler = function(event) {
var dir = ""; var dir = "";
if( event.state && event.state.dir ) dir = event.state.dir; if( event.state && event.state.dir ) dir = event.state.dir;
self.changeDirectory( dir, { pushState: false, absolute: true } ); self.changeDirectory( dir, { pushState: false, absolute: true } );
}; };
/**
* Handles keystrokes
*
* @param object e - event object
*/
this.handleKeystrokes = function( e ) { this.handleKeystrokes = function( e ) {
// bind 'del' key // bind 'del' key
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] ) { if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] ) {
@@ -895,7 +1122,9 @@ function IFM() {
} }
} }
// initialization /**
* Initializes the application
*/
this.init = function() { this.init = function() {
// bind static buttons // bind static buttons
$("#refresh").click(function(){ $("#refresh").click(function(){
@@ -929,5 +1158,5 @@ function IFM() {
}; };
} }
var ifm = new IFM(); var ifm = new IFM({ api: "ifm.php" });
ifm.init(); ifm.init();

View File

@@ -16,14 +16,21 @@ ini_set( 'display_errors', 'OFF' );
class IFM { class IFM {
const VERSION = '2.4.0'; const VERSION = '2.4.0';
public function __construct() { private $config = array();
public function __construct( $config ) {
session_start(); session_start();
if( ! is_array( $config ) ) {
trigger_error( "IFM: could not load config" );
exit( 1 );
} else {
$this->config = $config;
}
} }
/* /**
this function contains the client-side application * This function contains the client-side application
*/ */
public function getApplication() { public function getApplication() {
print '<!DOCTYPE HTML> print '<!DOCTYPE HTML>
<html> <html>
@@ -115,6 +122,7 @@ class IFM {
<script>';?> @@@src/includes/bootstrap-notify.min.js@@@ <?php print '</script> <script>';?> @@@src/includes/bootstrap-notify.min.js@@@ <?php print '</script>
<script>';?> @@@src/includes/ekko-lightbox.min.js@@@ <?php print '</script> <script>';?> @@@src/includes/ekko-lightbox.min.js@@@ <?php print '</script>
<script>';?> @@@src/includes/bootstrap-treeview.min.js@@@ <?php print '</script> <script>';?> @@@src/includes/bootstrap-treeview.min.js@@@ <?php print '</script>
<script>';?> @@@src/includes/mustache.min.js@@@ <?php print '</script>
<script>';?> @@@src/ifm.js@@@ <?php print '</script> <script>';?> @@@src/ifm.js@@@ <?php print '</script>
</body> </body>
</html> </html>
@@ -137,6 +145,9 @@ class IFM {
$this->getFiles( $_REQUEST["dir"] ); $this->getFiles( $_REQUEST["dir"] );
else else
$this->getFiles( "" ); $this->getFiles( "" );
}
elseif( $_REQUEST["api"] == "getConfig" ) {
echo json_encode( IFMConfig::getConstants() );
} else { } else {
if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) ) { if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) ) {
switch( $_REQUEST["api"] ) { switch( $_REQUEST["api"] ) {
@@ -956,5 +967,5 @@ class IFM {
start program start program
*/ */
$ifm = new IFM(); $ifm = new IFM( IFMConfig::getConstants() );
$ifm->run(); $ifm->run();