1
0
mirror of https://github.com/misterunknown/ifm.git synced 2025-08-10 10:04:01 +02:00

This commit finishes the js-rewrite and contains all changes as a consequence thereof

This commit is contained in:
Marco Dickert
2017-08-04 17:17:32 +02:00
parent 71527a47f3
commit 5b8c1a9ad4
10 changed files with 1416 additions and 1170 deletions

File diff suppressed because it is too large Load Diff

862
ifm.php

File diff suppressed because it is too large Load Diff

View File

@@ -7,8 +7,8 @@ function IFM( params ) {
// reference to ourself, because "this" does not work within callbacks // reference to ourself, because "this" does not work within callbacks
var self = this; var self = this;
// set the backend for the application
params = params || {}; params = params || {};
// set the backend for the application
self.api = params.api || window.location.pathname; self.api = params.api || window.location.pathname;
this.editor = null; // global ace editor this.editor = null; // global ace editor
@@ -21,8 +21,8 @@ function IFM( params ) {
/** /**
* Shows a bootstrap modal * Shows a bootstrap modal
* *
* @param {string} content - content of the modal * @param {string} content - HTML content of the modal
* @param {object} options - options for the modal * @param {object} options - options for the modal ({ large: false })
*/ */
this.showModal = function( content, options ) { this.showModal = function( content, options ) {
options = options || {}; options = options || {};
@@ -55,7 +55,7 @@ function IFM( params ) {
}; };
/** /**
* Hides a bootstrap modal * Hides a the current bootstrap modal
*/ */
this.hideModal = function() { this.hideModal = function() {
// Hide the modal via jquery to get the hide.bs.modal event triggered // Hide the modal via jquery to get the hide.bs.modal event triggered
@@ -63,11 +63,11 @@ function IFM( params ) {
}; };
/** /**
* Reloads the file table * Refreshes the file table
*/ */
this.refreshFileTable = function () { this.refreshFileTable = function () {
var id = self.generateGuid(); var taskid = self.generateGuid();
self.task_add( { id: id, name: "Refresh" } ); self.task_add( { id: taskid, name: "Refresh" } );
$.ajax({ $.ajax({
url: self.api, url: self.api,
type: "POST", type: "POST",
@@ -77,8 +77,8 @@ function IFM( params ) {
}, },
dataType: "json", dataType: "json",
success: self.rebuildFileTable, success: self.rebuildFileTable,
error: function( response ) { self.showMessage( "General error occured: No or broken response", "e" ); }, error: function() { self.showMessage( "General error occured: No or broken response", "e" ); },
complete: function() { self.task_done( id ); } complete: function() { self.task_done( taskid ); }
}); });
}; };
@@ -100,7 +100,6 @@ function IFM( params ) {
item.linkname = ( item.name == ".." ) ? "[ up ]" : item.name; item.linkname = ( item.name == ".." ) ? "[ up ]" : item.name;
item.download = {}; item.download = {};
item.download.name = ( item.name == ".." ) ? "." : item.name; item.download.name = ( item.name == ".." ) ? "." : item.name;
item.download.allowed = self.config.download;
item.download.currentDir = self.currentDir; item.download.currentDir = self.currentDir;
if( ! self.config.chmod ) if( ! self.config.chmod )
item.readonly = "readonly"; item.readonly = "readonly";
@@ -128,7 +127,7 @@ function IFM( params ) {
icon: "icon icon-archive", icon: "icon icon-archive",
title: "extract" title: "extract"
}); });
} else if( self.config.edit && item.icon.indexOf( 'file-image' ) == -1) { } else if( self.config.edit && item.icon.indexOf( 'file-image' ) == -1 && ! self.inArray( item.ext, ["zip","tar","tgz","tar.gz","tar.xz","tar.bz2"] ) ) {
item.eaction = "edit"; item.eaction = "edit";
item.button.push({ item.button.push({
action: "edit", action: "edit",
@@ -158,12 +157,18 @@ function IFM( params ) {
}); });
} }
}); });
// save items to file cache
self.fileCache = data; self.fileCache = data;
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config } );
// build new tbody and replace the old one with the new
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config, i18n: self.i18n } );
var filetable = document.getElementById( 'filetable' ); var filetable = document.getElementById( 'filetable' );
filetable.tBodies[0].remove(); filetable.tBodies[0].remove();
filetable.append( document.createElement( 'tbody' ) ); filetable.append( document.createElement( 'tbody' ) );
filetable.tBodies[0].innerHTML = newTBody; filetable.tBodies[0].innerHTML = newTBody;
// add event listeners
filetable.tBodies[0].addEventListener( 'keypress', function( e ) { filetable.tBodies[0].addEventListener( 'keypress', function( e ) {
if( e.target.name == 'newpermissions' && !!self.config.chmod && e.key == 'Enter' ) if( e.target.name == 'newpermissions' && !!self.config.chmod && e.key == 'Enter' )
self.changePermissions( e.target.dataset.filename, e.target.value ); self.changePermissions( e.target.dataset.filename, e.target.value );
@@ -208,12 +213,15 @@ function IFM( params ) {
} }
} }
}); });
// has to be jquery, since this is a bootstrap feature
$( 'a[data-toggle="tooltip"]' ).tooltip({ $( 'a[data-toggle="tooltip"]' ).tooltip({
animated: 'fade', animated: 'fade',
placement: 'right', placement: 'right',
html: true html: true
}); });
if( self.config.contextmenu && !!( self.config.edit || self.config.extract || self.config.rename || self.config.copymove || self.config.download || self.config.delete ) ) { if( self.config.contextmenu && !!( self.config.edit || self.config.extract || self.config.rename || self.config.copymove || self.config.download || self.config.delete ) ) {
// create the context menu, this also uses jquery, AFAIK
var contextMenu = new BootstrapMenu( '.clickable-row', { var contextMenu = new BootstrapMenu( '.clickable-row', {
fetchElementData: function( row ) { fetchElementData: function( row ) {
var data = {}; var data = {};
@@ -225,8 +233,7 @@ function IFM( params ) {
}, },
actionsGroups:[ actionsGroups:[
['edit', 'extract', 'rename'], ['edit', 'extract', 'rename'],
['copymove', 'download'], ['copymove', 'download', 'delete']
['delete']
], ],
actions: { actions: {
edit: { edit: {
@@ -271,7 +278,7 @@ function IFM( params ) {
self.showCopyMoveDialog( data.clicked ); self.showCopyMoveDialog( data.clicked );
}, },
iconClass: "icon icon-folder-empty", iconClass: "icon icon-folder-empty",
isShown: function() { return !!self.config.copymove; } isShown: function( data ) { return !!( self.config.copymove && data.clicked.name != ".." ); }
}, },
download: { download: {
name: function( data ) { name: function( data ) {
@@ -303,7 +310,7 @@ function IFM( params ) {
self.showDeleteDialog( data.clicked ); self.showDeleteDialog( data.clicked );
}, },
iconClass: "icon icon-trash", iconClass: "icon icon-trash",
isShown: function() { return !!self.config.delete; } isShown: function( data ) { return !!( self.config.delete && data.clicked.name != ".." ); }
} }
} }
}); });
@@ -346,51 +353,71 @@ function IFM( params ) {
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] : "";
self.showModal( Mustache.render( self.templates.file, { filename: filename, i18n: self.i18n } ), { large: true } ); self.showModal( Mustache.render( self.templates.file, { filename: filename, i18n: self.i18n } ), { large: true } );
var form = $('#formFile');
form.find('input[name="filename"]').on( 'keypress', self.preventEnter ); var form = document.getElementById( 'formFile' );
form.find('#buttonSave').on( 'click', function() { form.addEventListener( 'keypress', function( e ) {
self.saveFile( form.find('input[name=filename]').val(), self.editor.getValue() ); if( e.target.name == 'filename' && e.key == 'Enter' )
self.hideModal(); e.preventDefault();
return false;
}); });
form.find('#buttonSaveNotClose').on( 'click', function() { form.addEventListener( 'click', function( e ) {
self.saveFile( form.find('input[name=filename]').val(), self.editor.getValue() ); if( e.target.id == "buttonSave" ) {
return false; e.preventDefault();
self.saveFile( document.querySelector( '#formFile input[name=filename]' ).value, self.editor.getValue() );
self.hideModal();
} else if( e.target.id == "buttonSaveNotClose" ) {
e.preventDefault();
self.saveFile( document.querySelector( '#formFile input[name=filename]' ).value, self.editor.getValue() );
} else if( e.target.id == "buttonClose" ) {
e.preventDefault();
self.hideModal();
}
}); });
form.find('#buttonClose').on( 'click', function() {
self.hideModal(); $('#editoroptions').popover({
return false;
});
form.find('#editoroptions').popover({
html: true, html: true,
title: function() { return $('#editoroptions-head').html(); }, title: self.i18n.options,
content: function() { content: function() {
var content = $('#editoroptions-content').clone() // see https://github.com/twbs/bootstrap/issues/12571
var ihatethisfuckingpopoverworkaround = $('#editoroptions').data('bs.popover');
ihatethisfuckingpopoverworkaround.$tip.find( '.popover-content' ).empty();
var aceSession = self.editor.getSession(); var aceSession = self.editor.getSession();
content.removeClass( 'hide' ); var template = document.createElement( 'template');
content.find( '#editor-wordwrap' ) template.innerHTML = Mustache.render( self.templates.file_editoroptions, {
.prop( 'checked', ( aceSession.getOption( 'wrap' ) == 'off' ? false : true ) ) wordwrap: ( aceSession.getOption( 'wrap' ) == 'off' ? false : true ),
.on( 'change', function() { self.editor.setOption( 'wrap', $( this ).is( ':checked' ) ); }); softtabs: aceSession.getOption( 'useSoftTabs' ),
content.find( '#editor-softtabs' ) tabsize: aceSession.getOption( 'tabSize' ),
.prop( 'checked', aceSession.getOption( 'useSoftTabs' ) ) i18n: self.i18n
.on( 'change', function() { self.editor.setOption( 'useSoftTabs', $( this ).is( ':checked' ) ); }); });
content.find( '#editor-tabsize' ) var content = template.content.childNodes;
.val( aceSession.getOption( 'tabSize' ) ) content.forEach( function( el ) {
.on( 'keydown', function( e ) { if( e.key == 'Enter' ) { self.editor.setOption( 'tabSize', $( this ).val() ); } }); if( el.id == "editor-wordwrap" )
el.addEventListener( 'change', function( e ) {
self.editor.setOption( 'wrap', e.srcElement.checked );
});
else if( el.id == "editor-softtabs" )
el.addEventListener( 'change', function( e ) {
self.editor.setOption( 'useSoftTabs', e.srcElement.checked );
});
else if( el.lastChild && el.lastChild.id == "editor-tabsize" )
el.lastChild.addEventListener( 'keydown', function( e ) {
if( e.key == 'Enter' ) {
e.preventDefault();
self.editor.setOption( 'tabSize', e.srcElement.value );
}
});
});
console.log( content );
return content; return content;
} }
}); });
form.on( 'remove', function () { self.editor = null; self.fileChanged = false; });
// Start ACE // Start ACE
self.editor = ace.edit("content"); self.editor = ace.edit("content");
self.editor.$blockScrolling = 'Infinity'; self.editor.$blockScrolling = 'Infinity';
self.editor.getSession().setValue(content); self.editor.getSession().setValue(content);
self.editor.focus(); self.editor.focus();
self.editor.on("change", function() { self.fileChanged = true; }); self.editor.on("change", function() { self.fileChanged = true; });
// word wrap checkbox
$('#aceWordWrap').on( 'change', function (event) {
self.editor.getSession().setUseWrapMode( $(this).is(':checked') );
});
}; };
/** /**
@@ -451,17 +478,24 @@ function IFM( params ) {
*/ */
this.showCreateDirDialog = function() { this.showCreateDirDialog = function() {
self.showModal( Mustache.render( self.templates.createdir, { i18n: self.i18n } ) ); self.showModal( Mustache.render( self.templates.createdir, { i18n: self.i18n } ) );
var form = $( '#formCreateDir' ); var form = document.forms.formCreateDir;
form.find( 'input[name=dirname]' ).on( 'keypress', self.preventEnter ); form.elements.dirname.addEventListener( 'keypress', function( e ) {
form.find( '#buttonSave' ).on( 'click', function() { if(e.key == 'Enter' ) {
self.createDir( form.find( 'input[name=dirname] ').val() ); e.preventDefault();
self.hideModal(); self.createDir( e.target.value );
return false; self.hideModal();
}); }
form.find( '#buttonCancel' ).on( 'click', function() {
self.hideModal();
return false;
}); });
form.addEventListener( 'click', function( e ) {
if( e.target.id == 'buttonSave' ) {
e.preventDefault();
self.createDir( form.elements.dirname.value );
self.hideModal();
} else if( e.target.id == 'buttonCancel' ) {
e.preventDefault();
self.hideModal();
}
}, false );
}; };
/** /**
@@ -495,21 +529,22 @@ function IFM( params ) {
*/ */
this.showDeleteDialog = function( items ) { this.showDeleteDialog = function( items ) {
self.showModal( Mustache.render( self.templates.deletefile, { self.showModal( Mustache.render( self.templates.deletefile, {
multiple: Array.isArray( items ), multiple: ( items.length > 1 ),
count: items.length, count: items.length,
filename: ( Array.isArray( items ) ? items[0].name : items.name ), filename: ( Array.isArray( items ) ? items[0].name : items.name ),
i18n: self.i18n i18n: self.i18n
})); }));
var form = document.getElementById('formDeleteFiles'); var form = document.forms.formDeleteFiles;
document.getElementById( 'buttonYes' ).onclick = function() { form.addEventListener( 'click', function( e ) {
self.deleteFiles( items ); if( e.target.id == 'buttonYes' ) {
self.hideModal(); e.preventDefault();
return false; self.deleteFiles( items );
}; self.hideModal();
document.getElementById( 'buttonNo' ).onclick = function() { } else if( e.target.id == 'buttonNo' ) {
self.hideModal(); e.preventDefault();
return false; self.hideModal();
}; }
});
}; };
/** /**
@@ -546,16 +581,23 @@ function IFM( params ) {
*/ */
this.showRenameFileDialog = function( filename ) { this.showRenameFileDialog = function( filename ) {
self.showModal( Mustache.render( self.templates.renamefile, { filename: filename, i18n: self.i18n } ) ); self.showModal( Mustache.render( self.templates.renamefile, { filename: filename, i18n: self.i18n } ) );
var form = $( '#formRenameFile' ); var form = document.forms.formRenameFile;
form.find( 'input[name=newname]' ).on( 'keypress', self.preventEnter ); form.elements.newname.addEventListener( 'keypress', function( e ) {
form.find( '#buttonRename' ).on( 'click', function() { if( e.key == 'Enter' ) {
self.renameFile( filename, form.find( 'input[name=newname]' ).val() ); e.preventDefault();
self.hideModal(); self.renameFile( filename, e.target.value );
return false; self.hideModal();
}
}); });
form.find( '#buttonCancel' ).on( 'click', function() { form.addEventListener( 'click', function( e ) {
self.hideModal(); if( e.target.id == 'buttonRename' ) {
return false; e.preventDefault();
self.renameFile( filename, form.elements.newname.value );
self.hideModal();
} else if( e.target.id == 'buttonCancel' ) {
e.preventDefault();
self.hideModal();
}
}); });
}; };
@@ -623,19 +665,20 @@ function IFM( params ) {
}, },
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) } error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
}); });
$( '#copyButton' ).on( 'click', function() { var form = document.forms.formCopyMove;
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'copy' ); form.addEventListener( 'click', function( e ) {
self.hideModal(); if( e.target.id == 'copyButton' ) {
return false; e.preventDefault();
}); self.copyMove( items, form.getElementsByClassName( 'node-selected' )[0].dataset.path, 'copy' );
$( '#moveButton' ).on( 'click', function() { self.hideModal();
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'move' ); } else if( e.target.id == 'moveButton' ) {
self.hideModal(); e.preventDefault();
return false; self.copyMove( items, form.getElementsByClassName( 'node-selected' )[0].dataset.path, 'move' );
}); self.hideModal();
$( '#cancelButton' ).on( 'click', function() { } else if( e.target.id == 'cancelButton' ) {
self.hideModal(); e.preventDefault();
return false; self.hideModal();
}
}); });
}; };
@@ -687,28 +730,31 @@ function IFM( params ) {
* @param {string} filename - name of the file * @param {string} filename - name of the file
*/ */
this.showExtractFileDialog = function( filename ) { this.showExtractFileDialog = function( filename ) {
var targetDirSuggestion = ''; var targetDirSuggestion = ( filename.lastIndexOf( '.' ) > 1 ) ? filename.substr( 0, filename.lastIndexOf( '.' ) ) : filename;
if( filename.lastIndexOf( '.' ) > 1 )
targetDirSuggestion = filename.substr( 0, filename.lastIndexOf( '.' ) );
else targetDirSuggestion = filename;
self.showModal( Mustache.render( self.templates.extractfile, { filename: filename, destination: targetDirSuggestion, i18n: self.i18n } ) ); self.showModal( Mustache.render( self.templates.extractfile, { filename: filename, destination: targetDirSuggestion, i18n: self.i18n } ) );
var form = $('#formExtractFile'); var form = document.forms.formExtractFile;
form.find('#buttonExtract').on( 'click', function() { form.addEventListener( 'click', function( e ) {
var t = form.find('input[name=extractTargetLocation]:checked').val(); if( e.target.id == 'buttonExtract' ) {
if( t == "custom" ) t = form.find('#extractCustomLocation').val(); e.preventDefault();
self.extractFile( filename, t ); var loc = form.elements.extractTargetLocation.value;
self.hideModal(); self.extractFile( filename, ( loc == "custom" ? form.elements.extractCustomLocation.value : loc ) );
return false; self.hideModal();
} else if( e.target.id == 'buttonCancel' ) {
e.preventDefault();
self.hideModal();
}
}); });
form.find('#buttonCancel').on( 'click', function() { form.elements.extractCustomLocation.addEventListener( 'keypress', function( e ) {
self.hideModal(); var loc = form.elements.extractTargetLocation.value;
return false; if( e.key == 'Enter' ) {
e.preventDefault();
self.extractFile( filename, ( loc == "custom" ? form.elements.extractCustomLocation.value : loc ) );
self.hideModal();
}
});
form.elements.extractCustomLocation.addEventListener( 'focus', function( e ) {
form.elements.extractTargetLocation.value = 'custom';
}); });
form.find('#extractCustomLocation')
.on( 'click', function(e) {
$(e.target).prev().children().first().prop( 'checked', true );
})
.on( 'keypress', self.preventEnter );
}; };
/** /**
@@ -743,29 +789,28 @@ function IFM( params ) {
*/ */
this.showUploadFileDialog = function() { this.showUploadFileDialog = function() {
self.showModal( Mustache.render( self.templates.uploadfile, { i18n: self.i18n } ) ); self.showModal( Mustache.render( self.templates.uploadfile, { i18n: self.i18n } ) );
var form = $('#formUploadFile'); var form = document.forms.formUploadFile;
form.find( 'input[name=newfilename]' ).on( 'keypress', self.preventEnter ); form.elements.files.addEventListener( 'change', function( e ) {
form.find( 'input[name=files]' ).on( 'change', function( e ) {
if( e.target.files.length > 1 ) if( e.target.files.length > 1 )
form.find( 'input[name=newfilename]' ).attr( 'readonly', true ); form.elements.newfilename.readOnly = true;
else else
form.find( 'input[name=newfilename]' ).attr( 'readonly', false ); form.elements.newfilename.readOnly = false;
}); });
form.find( '#buttonUpload' ).on( 'click', function( e ) { form.addEventListener( 'click', function( e ) {
e.preventDefault(); if( e.target.id == 'buttonUpload' ) {
var files = form.find( 'input[name=files]' )[0].files; e.preventDefault();
if( files.length > 1 ) var files = Array.prototype.slice.call( form.elements.files.files );
for( var i = 0; i < files.length; i++ ) { if( files.length > 1 )
self.uploadFile( files[i] ); files.forEach( function( file ) {
} self.uploadFile( file );
else });
self.uploadFile( files[0], form.find( 'input[name=newfilename]' ).val() ); else
self.hideModal(); self.uploadFile( files[0], form.elements.newfilename.value );
return false; self.hideModal();
}); } else if( e.target.id == 'buttonCancel' ) {
form.find( '#buttonCancel' ).on( 'click', function() { e.preventDefault();
self.hideModal(); self.hideModal();
return false; }
}); });
}; };
@@ -811,7 +856,7 @@ function IFM( params ) {
* @params object e - event object * @params object e - event object
* @params string name - name of the file * @params string name - name of the file
*/ */
this.changePermissions = function( filename, newperms) { this.changePermissions = function( filename, newperms ) {
$.ajax({ $.ajax({
url: self.api, url: self.api,
type: "POST", type: "POST",
@@ -840,31 +885,34 @@ function IFM( params ) {
*/ */
this.showRemoteUploadDialog = function() { this.showRemoteUploadDialog = function() {
self.showModal( Mustache.render( self.templates.remoteupload, { i18n: self.i18n } ) ); self.showModal( Mustache.render( self.templates.remoteupload, { i18n: self.i18n } ) );
var form = $('#formRemoteUpload'); var form = document.forms.formRemoteUpload;
form.find( '#url' ) var urlChangeHandler = function( e ) {
.on( 'keypress', self.preventEnter ) form.elements.filename.value = e.target.value.substr( e.target.value.lastIndexOf( '/' ) + 1 );
.on( 'change keyup', function() { };
$("#filename").val($(this).val().substr($(this).val().lastIndexOf("/")+1)); form.elements.url.addEventListener( 'keypress', self.preventEnter );
}); form.elements.url.addEventListener( 'change', urlChangeHandler );
form.find( '#filename' ) form.elements.url.addEventListener( 'keyup', urlChangeHandler );
.on( 'keypress', self.preventEnter ) form.elements.filename.addEventListener( 'keypress', self.preventEnter );
.on( 'keyup', function() { $("#url").off( 'change keyup' ); }); form.elements.filename.addEventListener( 'keyup', function( e ) {
form.find( '#buttonUpload' ).on( 'click', function() { form.elements.url.removeEventListener( 'change', urlChangeHandler );
self.remoteUpload(); form.elements.url.removeEventListener( 'keyup', urlChangeHandler );
self.hideModal();
return false;
}); });
form.find( '#buttonCancel' ).on( 'click', function() { form.addEventListener( 'click', function( e ) {
self.hideModal(); if( e.target.id == 'buttonUpload' ) {
return false; e.preventDefault();
self.remoteUpload( form.elements.url.value, form.elements.filename.value, form.elements.method.value );
self.hideModal();
} else if( e.target.id == 'buttonCancel' ) {
e.preventDefault();
self.hideModal();
}
}); });
}; };
/** /**
* Remote uploads a file * Remote uploads a file
*/ */
this.remoteUpload = function() { this.remoteUpload = function( url, filename, method ) {
var filename = $("#formRemoteUpload #filename").val();
var id = ifm.generateGuid(); var id = ifm.generateGuid();
$.ajax({ $.ajax({
url: ifm.api, url: ifm.api,
@@ -873,20 +921,21 @@ function IFM( params ) {
api: "remoteUpload", api: "remoteUpload",
dir: ifm.currentDir, dir: ifm.currentDir,
filename: filename, filename: filename,
method: $("#formRemoteUpload input[name=method]:checked").val(), method: method,
url: encodeURI($("#url").val()) url: encodeURI( url )
}), }),
dataType: "json", dataType: "json",
success: function(data) { success: function(data) {
if(data.status == "OK") { if(data.status == "OK") {
ifm.showMessage("File successfully uploaded", "s"); self.showMessage( "File successfully uploaded", "s" );
ifm.refreshFileTable(); self.refreshFileTable();
} else ifm.showMessage("File could not be uploaded:<br />"+data.message, "e"); } else
}, self.showMessage( "File could not be uploaded:<br />" + data.message, "e" );
error: function() { ifm.showMessage("General error occured", "e"); }, },
complete: function() { ifm.task_done(id); } error: function() { self.showMessage("General error occured", "e"); },
complete: function() { self.task_done(id); }
}); });
ifm.task_add( { id: id, name: "Remote upload: "+filename } ); self.task_add( { id: id, name: "Remote upload: "+filename } );
}; };
/** /**
@@ -894,71 +943,68 @@ function IFM( params ) {
*/ */
this.showAjaxRequestDialog = function() { this.showAjaxRequestDialog = function() {
self.showModal( Mustache.render( self.templates.ajaxrequest, { i18n: self.i18n } ) ); self.showModal( Mustache.render( self.templates.ajaxrequest, { i18n: self.i18n } ) );
var form = $('#formAjaxRequest'); var form = document.forms.formAjaxRequest;
form.find( '#ajaxurl' ).on( 'keypress', self.preventEnter ); form.elements.ajaxurl.addEventListener( 'keypress', self.preventEnter );
form.find( '#buttonRequest' ).on( 'click', function() { form.addEventListener( 'click', function( e ) {
self.ajaxRequest(); if( e.target.id == 'buttonRequest' ) {
return false; e.preventDefault();
}); self.ajaxRequest( form.elements.ajaxurl.value, form.elements.ajaxdata.value.replace( /\n/g, '&' ), form.elements.arMethod.value );
form.find( '#buttonClose' ).on( 'click', function() { } else if( e.target.id == 'buttonClose' ) {
self.hideModal(); e.preventDefault();
return false; self.hideModal();
}
}); });
}; };
/** /**
* Performs an ajax request * Performs an ajax request
*/ */
this.ajaxRequest = function() { this.ajaxRequest = function( url, data, method ) {
$.ajax({ $.ajax({
url : $("#ajaxurl").val(), url : url,
cache : false, cache : false,
data : $('#ajaxdata').val().replace(/\n/g,"&"), data : data,
type : $('#ajaxrequest input[name=arMethod]:checked').val(), type : method,
success : function(response) { $("#ajaxresponse").text(response); }, success : function( response ) { document.getElementById( 'ajaxresponse' ).innerText = response; },
error : function(e) { self.showMessage("Error: "+e, "e"); console.log(e); } error : function(e) { self.showMessage("Error: "+e, "e"); console.log(e); }
}); });
}; };
/** /**
* Deletes multiple files * Shows the search dialog
*/ */
this.multiDelete = function() {
var elements = $('#filetable tr.selectedItem');
var filenames = [];
for( var i=0; typeof(elements[i])!='undefined';filenames.push(elements[i++].getAttribute('data-filename')));
$.ajax({
url: self.api,
type: "POST",
data: ({
api: "multidelete",
dir: self.currentDir,
filenames: filenames
}),
dataType: "json",
success: function(data) {
if(data.status == "OK") {
if(data.errflag == 1)
ifm.showMessage("All files successfully deleted.", "s");
else if(data.errflag == 0)
ifm.showMessage("Some files successfully deleted. "+data.message);
else
ifm.showMessage("Files could not be deleted. "+data.message, "e");
ifm.refreshFileTable();
} else ifm.showMessage("Files could not be deleted:<br />"+data.message, "e");
},
error: function() { ifm.showMessage("General error occured", "e"); }
});
};
this.showSearchDialog = function() { this.showSearchDialog = function() {
self.showModal( Mustache.render( self.templates.search, { lastSearch: self.search.lastSearch, i18n: self.i18n } ) ); self.showModal( Mustache.render( self.templates.search, { lastSearch: self.search.lastSearch, i18n: self.i18n } ) );
$( '#searchResults tbody' ).remove();
$( '#searchResults' ).append( Mustache.render( self.templates.searchresults, { items: self.search.data } ) ); var updateResults = function( data ) {
$( '#searchPattern' ).on( 'keypress', function( e ) { console.log( 'update results' );
if( e.keyCode == 13 ) { self.search.data = data;
var searchresults = document.getElementById( 'searchResults' );
if( searchresults.tBodies[0] ) searchresults.tBodies[0].remove();
searchresults.appendChild( document.createElement( 'tbody' ) );
searchresults.tBodies[0].innerHTML = Mustache.render( self.templates.searchresults, { items: self.search.data } );
searchresults.tBodies[0].addEventListener( 'click', function( e ) {
if( e.target.classList.contains( 'searchitem' ) ) {
e.preventDefault();
self.changeDirectory( e.target.dataset.folder || e.target.parentNode.dataset.folder, { absolute: true } );
self.hideModal();
}
});
searchresults.tBodies[0].addEventListener( 'keypress', function( e ) {
if( e.target.classList.contains( 'searchitem' ) ) {
e.preventDefault();
e.target.click();
}
});
};
updateResults( self.search.data );
document.getElementById( 'searchPattern' ).addEventListener( 'keypress', function( e ) {
if( e.key == 'Enter' ) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); console.log( e );
if( e.target.value.trim() === '' ) return;
self.search.lastSearch = e.target.value; self.search.lastSearch = e.target.value;
$.ajax({ $.ajax({
url: self.api, url: self.api,
@@ -974,24 +1020,12 @@ function IFM( params ) {
e.folder = e.name.substr( 0, e.name.lastIndexOf( '/' ) ); e.folder = e.name.substr( 0, e.name.lastIndexOf( '/' ) );
e.linkname = e.name.substr( e.name.lastIndexOf( '/' ) + 1 ); e.linkname = e.name.substr( e.name.lastIndexOf( '/' ) + 1 );
}); });
self.search.data = data; updateResults( data );
$('#searchResults').html( Mustache.render( self.templates.searchresults, { items: data } ) );
} }
}); });
} }
}); });
$( document ).on( 'click', 'a.searchitem', function( e ) { };
e.preventDefault();
e.stopPropagation();
self.changeDirectory( e.target.dataset.folder || e.target.parentNode.dataset.folder, { absolute: true } );
self.hideModal();
});
$( document ).on( 'keypress', 'a.searchitem', function( e ) {
e.preventDefault();
if( e.key == "Enter" )
e.target.click();
});
}
// -------------------- // --------------------
// helper functions // helper functions
@@ -1004,26 +1038,32 @@ function IFM( params ) {
* @param string t - message type (e: error, s: success) * @param string t - message type (e: error, s: success)
*/ */
this.showMessage = function(m, t) { this.showMessage = function(m, t) {
var msgType = (t == "e")?"danger":(t == "s")?"success":"info"; var msgType = ( t == "e" ) ? "danger" : ( t == "s" ) ? "success" : "info";
var element = ( self.config.inline ) ? self.rootElement : "body"; var element = ( self.config.inline ) ? self.rootElement : "body";
$.notify( $.notify(
{ message: m }, { message: m },
{ type: msgType, delay: 5000, mouse_over: 'pause', offset: { x: 15, y: 65 }, element: element } { type: msgType, delay: 3000, mouse_over: 'pause', offset: { x: 15, y: 65 }, element: element }
); );
}; };
/** /**
* Combines two path components * Combines two path components
* *
* @param string a - component 1 * @param {string} a - component 1
* @param string b - component 2 * @param {string} b - component 2
* @returns {string} - combined path
*/ */
this.pathCombine = function(a, b) { this.pathCombine = function(a, b) {
if(a == "" && b == "") return ""; if ( a == "" && b == "" )
if(b[0] == "/") b = b.substring(1); return "";
if(a == "") return b; if( b[0] == "/" )
if(a[a.length-1] == "/") a = a.substring(0, a.length-1); b = b.substring(1);
if(b == "") return a; if( a == "" )
return b;
if( a[a.length-1] == "/" )
a = a.substring(0, a.length-1);
if( b == "" )
return a;
return a+"/"+b; return a+"/"+b;
}; };
@@ -1033,18 +1073,28 @@ function IFM( params ) {
* @param object e - click event * @param object e - click event
*/ */
this.preventEnter = function(e) { this.preventEnter = function(e) {
if( e.keyCode == 13 ) return false; if( e.key == 'Enter' )
else return true; e.preventDefault();
} };
/** /**
* Checks if an element is part of an array * Checks if an element is part of an array
* *
* @param obj needle - search item * @param {object} needle - search item
* @param array haystack - array to search * @param {array} haystack - array to search
* @returns {boolean}
*/ */
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.getNodesFromString = function( s ) {
var template = document.createElement( 'template');
template.innerHTML = s;
return template.content.childNodes[0];
}; };
/** /**
@@ -1058,24 +1108,26 @@ function IFM( params ) {
return false; return false;
} }
if( ! document.querySelector( "footer" ) ) { if( ! document.querySelector( "footer" ) ) {
$( document.body ).append( Mustache.render( self.templates.footer ) ); var newFooter = self.getNodesFromString( Mustache.render( self.templates.footer, { i18n: self.i18n } ) );
$( 'a[name=showAll]' ).on( 'click', function( e ) { newFooter.addEventListener( 'click', function( e ) {
var f = $( 'footer' ); if( e.target.name == 'showAll' ) {
if( f.css( 'maxHeight' ) == '80%' ) { if( newFooter.style.maxHeight == '80%' ) {
f.css( 'maxHeight', '6em' ); newFooter.style.maxHeight = '6em';
f.css( 'overflow', 'hidden' ); newFooter.style.overflow = 'hidden';
} else { } else {
f.css( 'maxHeight', '80%' ); newFooter.style.maxHeight = '80%';
f.css( 'overflow', 'scroll' ); newFooter.style.overflow = 'scroll';
}
} }
}); });
$(document.body).css( 'padding-bottom', '6em' ); document.body.appendChild( newFooter );
document.body.style.paddingBottom = '6em';
} }
task.id = "wq-"+task.id; task.id = "wq-"+task.id;
task.type = task.type || "info"; task.type = task.type || "info";
var wq = $( "#waitqueue" ); var wq = document.getElementById( 'waitqueue' );
wq.prepend( Mustache.render( self.templates.task, task ) ); wq.prepend( self.getNodesFromString( Mustache.render( self.templates.task, task ) ) );
$( 'span[name=taskCount]' ).text( wq.find( '>div' ).length ); document.getElementsByName( 'taskCount' )[0].innerText = wq.children.length;
}; };
/** /**
@@ -1084,12 +1136,14 @@ function IFM( params ) {
* @param string id - task identifier * @param string id - task identifier
*/ */
this.task_done = function( id ) { this.task_done = function( id ) {
$( '#wq-'+id ).remove(); document.getElementById( 'wq-' + id ).remove();
if( $( '#waitqueue>div' ).length == 0) { var wq = document.getElementById( 'waitqueue' );
$( 'footer' ).remove(); if( wq.children.length == 0 ) {
$( document.body ).css( 'padding-bottom', '0' ); document.getElementsByTagName( 'footer' )[0].remove();
document.body.style.paddingBottom = 0;
} else {
document.getElementsByName( 'taskCount' )[0].innerText = wq.children.length;
} }
$( 'span[name=taskCount]' ).text( $('#waitqueue>div').length );
}; };
/** /**
@@ -1099,7 +1153,9 @@ function IFM( params ) {
* @param string id - task identifier * @param string id - task identifier
*/ */
this.task_update = function( progress, id ) { this.task_update = function( progress, id ) {
$('#wq-'+id+' .progress-bar').css( 'width', progress+'%' ).attr( 'aria-valuenow', progress ); var progbar = document.getElementById( 'wq-'+id ).getElementsByClassName( 'progress-bar' )[0];
progbar.style.width = progress+'%';
progbar.setAttribute( 'aria-valuenow', progress );
}; };
/** /**
@@ -1107,32 +1163,31 @@ function IFM( params ) {
* *
* @param object param - either an element id or a jQuery object * @param object param - either an element id or a jQuery object
*/ */
this.highlightItem = function( param ) { this.highlightItem = function( direction ) {
var highlight = function( el ) { var highlight = function( el ) {
el.addClass( 'highlightedItem' ).siblings().removeClass( 'highlightedItem' ); [].slice.call( el.parentElement.children ).forEach( function( e ) {
el.find( 'a' ).first().focus(); e.classList.remove( 'highlightedItem' );
});
el.classList.add( 'highlightedItem' );
el.firstElementChild.firstElementChild.focus();
if( ! self.isElementInViewport( el ) ) { if( ! self.isElementInViewport( el ) ) {
var scrollOffset = 0; var scrollOffset = 0;
if( param=="prev" ) if( direction=="prev" )
scrollOffset = el.offset().top - ( window.innerHeight || document.documentElement.clientHeight ) + el.height() + 15; scrollOffset = el.offset().top - ( window.innerHeight || document.documentElement.clientHeight ) + el.height() + 15;
else else
scrollOffset = el.offset().top - 55; scrollOffset = el.offset().top - 55;
$('html, body').animate( { scrollTop: scrollOffset }, 200 ); $('html, body').animate( { scrollTop: scrollOffset }, 200 );
} }
}; };
if( param.jquery ) {
highlight( param );
} else {
var highlightedItem = $('.highlightedItem');
if( ! highlightedItem.length ) {
highlight( $('#filetable tbody tr:first-child') );
} else {
var newItem = ( param=="next" ? highlightedItem.next() : highlightedItem.prev() );
if( newItem.is( 'tr' ) ) {
highlight( newItem ); var highlightedItem = document.getElementsByClassName( 'highlightedItem' )[0];
} if( ! highlightedItem ) {
} highlight( document.getElementById( 'filetable' ).tBodies[0].firstElementChild );
} else {
var newItem = ( direction=="next" ? highlightedItem.nextElementSibling : highlightedItem.previousElementSibling );
if( newItem != null )
highlight( newItem );
} }
}; };
@@ -1142,17 +1197,14 @@ function IFM( params ) {
* @param object el - element object * @param object el - element object
*/ */
this.isElementInViewport = function( el ) { this.isElementInViewport = function( el ) {
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect(); var rect = el.getBoundingClientRect();
return ( return (
rect.top >= 60 && rect.top >= 80 &&
rect.left >= 0 && rect.left >= 0 &&
rect.bottom <= ( ( window.innerHeight || document.documentElement.clientHeight ) ) && rect.bottom <= ( ( window.innerHeight || document.documentElement.clientHeight ) ) &&
rect.right <= ( window.innerWidth || document.documentElement.clientWidth ) rect.right <= ( window.innerWidth || document.documentElement.clientWidth )
); );
} };
/** /**
* Generates a GUID * Generates a GUID
@@ -1185,7 +1237,7 @@ function IFM( params ) {
*/ */
this.HTMLEncode = function( s ) { this.HTMLEncode = function( s ) {
return s.replace( /'/g, '&#39;').replace( /"/g, '&#43;'); return s.replace( /'/g, '&#39;').replace( /"/g, '&#43;');
} };
/** /**
* Encodes a string for use in the href attribute of an anchor. * Encodes a string for use in the href attribute of an anchor.
@@ -1217,17 +1269,17 @@ function IFM( params ) {
.replace( '`', '%60' ) .replace( '`', '%60' )
.replace( '\\', '%5C' ) .replace( '\\', '%5C' )
; ;
} };
/** /**
* Handles the javascript pop states * Handles the javascript pop states
* *
* @param object event - event object * @param object event - event object
*/ */
this.historyPopstateHandler = function(event) { this.historyPopstateHandler = function( e ) {
var dir = ""; var dir = "";
if( event.state && event.state.dir ) if( e.state && e.state.dir )
dir = event.state.dir; dir = e.state.dir;
self.changeDirectory( dir, { pushState: false, absolute: true } ); self.changeDirectory( dir, { pushState: false, absolute: true } );
}; };
@@ -1237,9 +1289,16 @@ function IFM( params ) {
* @param object e - event object * @param object e - event object
*/ */
this.handleKeystrokes = function( e ) { this.handleKeystrokes = function( e ) {
// bind 'del' key var isFormElement = function( el ) {
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] ) do {
return; if( self.inArray( el.tagName, ['INPUT', 'TEXTAREA'] ) ) {
return true;
}
} while( ( el == el.parentElement ) !== false );
return false;
}
if( isFormElement( e.target ) ) return;
// global key events // global key events
switch( e.key ) { switch( e.key ) {
@@ -1364,7 +1423,7 @@ function IFM( params ) {
} }
return; return;
break; break;
case ' ': // todo: make it work only when noting other is focused case ' ':
case 'Enter': case 'Enter':
if( element.children[0].children[0] == document.activeElement ) { if( element.children[0].children[0] == document.activeElement ) {
if( e.key == 'Enter' && element.classList.contains( 'isDir' ) ) { if( e.key == 'Enter' && element.classList.contains( 'isDir' ) ) {
@@ -1389,8 +1448,15 @@ function IFM( params ) {
} }
return; return;
break; break;
case 'n':
e.preventDefault();
if( self.config.rename ) {
self.showRenameFileDialog( item.name );
}
return;
break;
} }
} };
/** /**
* Initializes the application * Initializes the application

View File

@@ -132,6 +132,9 @@ f00bar;
f00bar; f00bar;
$templates['file'] = <<<'f00bar' $templates['file'] = <<<'f00bar'
@@@file:src/templates/modal.file.html@@@ @@@file:src/templates/modal.file.html@@@
f00bar;
$templates['file_editoroptions'] = <<<'f00bar'
@@@file:src/templates/modal.file_editoroptions.html@@@
f00bar; f00bar;
$templates['remoteupload'] = <<<'f00bar' $templates['remoteupload'] = <<<'f00bar'
@@@file:src/templates/modal.remoteupload.html@@@ @@@file:src/templates/modal.remoteupload.html@@@
@@ -225,9 +228,9 @@ f00bar;
private function handleRequest() { private function handleRequest() {
if( $_REQUEST["api"] == "getRealpath" ) { if( $_REQUEST["api"] == "getRealpath" ) {
if( isset( $_REQUEST["dir"] ) && $_REQUEST["dir"] != "" ) if( isset( $_REQUEST["dir"] ) && $_REQUEST["dir"] != "" )
echo json_encode( array( "realpath" => $this->getValidDir( $_REQUEST["dir"] ) ) ); echo $this->jsonResponse( array( "realpath" => $this->getValidDir( $_REQUEST["dir"] ) ) );
else else
echo json_encode( array( "realpath" => "" ) ); echo $this->jsonResponse( array( "realpath" => "" ) );
} }
elseif( $_REQUEST["api"] == "getFiles" ) { elseif( $_REQUEST["api"] == "getFiles" ) {
if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) ) if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) )
@@ -241,9 +244,9 @@ f00bar;
elseif( $_REQUEST["api"] == "getFolders" ) { elseif( $_REQUEST["api"] == "getFolders" ) {
$this->getFolders( $_REQUEST ); $this->getFolders( $_REQUEST );
} elseif( $_REQUEST["api"] == "getTemplates" ) { } elseif( $_REQUEST["api"] == "getTemplates" ) {
echo json_encode( $this->templates ); echo $this->jsonResponse( $this->templates );
} elseif( $_REQUEST["api"] == "getI18N" ) { } elseif( $_REQUEST["api"] == "getI18N" ) {
echo json_encode( $this->i18n[$this->config['language']] ); echo $this->jsonResponse( $this->i18n[$this->config['language']] );
} elseif( $_REQUEST["api"] == "logout" ) { } elseif( $_REQUEST["api"] == "logout" ) {
unset( $_SESSION ); unset( $_SESSION );
session_destroy(); session_destroy();
@@ -267,11 +270,11 @@ f00bar;
case "searchItems": $this->searchItems( $_REQUEST ); break; case "searchItems": $this->searchItems( $_REQUEST ); break;
case "getFolderTree": $this->getFolderTree( $_REQUEST ); break; case "getFolderTree": $this->getFolderTree( $_REQUEST ); break;
default: default:
echo json_encode( array( "status" => "ERROR", "message" => "Invalid api action given" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid api action given" ) );
break; break;
} }
} else { } else {
print json_encode( array( "status" => "ERROR", "message" => "Invalid working directory" ) ); print $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid working directory" ) );
} }
} }
exit( 0 ); exit( 0 );
@@ -377,7 +380,7 @@ f00bar;
$ret = $this->config; $ret = $this->config;
$ret['inline'] = ( $this->mode == "inline" ) ? true : false; $ret['inline'] = ( $this->mode == "inline" ) ? true : false;
$ret['isDocroot'] = ( $this->getRootDir() == $this->getScriptRoot() ) ? "true" : "false"; $ret['isDocroot'] = ( $this->getRootDir() == $this->getScriptRoot() ) ? "true" : "false";
echo json_encode( $ret ); echo $this->jsonResponse( $ret );
} }
private function getFolders( $d ) { private function getFolders( $d ) {
@@ -405,7 +408,7 @@ f00bar;
), ),
$ret $ret
); );
echo json_encode( $ret ); echo $this->jsonResponse( $ret );
} }
} }
@@ -417,9 +420,9 @@ f00bar;
} }
try { try {
$results = $this->searchItemsRecursive( $d['pattern'] ); $results = $this->searchItemsRecursive( $d['pattern'] );
echo json_encode( $results ); echo $this->jsonResponse( $results );
} catch( Exception $e ) { } catch( Exception $e ) {
echo json_encode( array( "status" => "ERROR", "message" => $e->getMessage() ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => $e->getMessage() ) );
} }
} }
@@ -436,7 +439,7 @@ f00bar;
} }
private function getFolderTree( $d ) { private function getFolderTree( $d ) {
echo json_encode( echo $this->jsonResponse(
array_merge( array_merge(
array( array(
0 => array( 0 => array(
@@ -475,38 +478,38 @@ f00bar;
private function copyMove( $d ) { private function copyMove( $d ) {
if( $this->config['copymove'] != 1 ) { if( $this->config['copymove'] != 1 ) {
echo json_encode( array( "status" => "ERROR", "message" => "No permission to copy or move files." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to copy or move files." ) );
exit( 1 ); exit( 1 );
} }
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
if( ! isset( $d['destination'] ) || ! $this->isPathValid( realpath( $d['destination'] ) ) ) { if( ! isset( $d['destination'] ) || ! $this->isPathValid( realpath( $d['destination'] ) ) ) {
echo json_encode( array( "status" => "ERROR", "message" => "Invalid destination directory given." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid destination directory given." ) );
exit( 1 ); exit( 1 );
} }
if( ! file_exists( $d['filename'] ) || $d['filename'] == ".." ) { if( ! file_exists( $d['filename'] ) || $d['filename'] == ".." ) {
echo json_encode( array( "status" => "ERROR", "message" => "Invalid filename given." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid filename given." ) );
exit( 1 ); exit( 1 );
} }
if( $d['action'] == "copy" ) { if( $d['action'] == "copy" ) {
if( $this->xcopy( $d['filename'], $d['destination'] ) ) { if( $this->xcopy( $d['filename'], $d['destination'] ) ) {
echo json_encode( array( "status" => "OK", "message" => "File(s) were successfully copied." ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "File(s) were successfully copied." ) );
exit( 0 ); exit( 0 );
} else { } else {
$err = error_get_last(); $err = error_get_last();
echo json_encode( array( "status" => "ERROR", "message" => $err['message'] ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => $err['message'] ) );
exit( 1 ); exit( 1 );
} }
} elseif( $d['action'] == "move" ) { } elseif( $d['action'] == "move" ) {
if( rename( $d['filename'], $this->pathCombine( $d['destination'], basename( $d['filename'] ) ) ) ) { if( rename( $d['filename'], $this->pathCombine( $d['destination'], basename( $d['filename'] ) ) ) ) {
echo json_encode( array( "status" => "OK", "message" => "File(s) were successfully moved." ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "File(s) were successfully moved." ) );
exit( 0 ); exit( 0 );
} else { } else {
$err = error_get_last(); $err = error_get_last();
echo json_encode( array( "status" => "ERROR", "message" => $err['message'] ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => $err['message'] ) );
exit( 1 ); exit( 1 );
} }
} else { } else {
echo json_encode( array( "status" => "ERROR", "message" => "Invalid action given." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid action given." ) );
exit( 1 ); exit( 1 );
} }
} }
@@ -514,26 +517,26 @@ f00bar;
// creates a directory // creates a directory
private function createDir($w, $dn) { private function createDir($w, $dn) {
if( $this->config['createdir'] != 1 ) { if( $this->config['createdir'] != 1 ) {
echo json_encode( array( "status" => "ERROR", "message" => "No permission to create directories.") ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to create directories.") );
exit( 1 ); exit( 1 );
} }
if( $dn == "" ) if( $dn == "" )
echo json_encode( array( "status" => "ERROR", "message" => "Invalid directory name") ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid directory name") );
elseif( ! $this->isFilenameValid( $dn ) ) elseif( ! $this->isFilenameValid( $dn ) )
echo json_encode( array( "status" => "ERROR", "message" => "Invalid directory name" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid directory name" ) );
else { else {
$this->chDirIfNecessary( $w ); $this->chDirIfNecessary( $w );
if( @mkdir( $dn ) ) if( @mkdir( $dn ) )
echo json_encode( array( "status" => "OK", "message" => "Directory successful created" ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "Directory successful created" ) );
else else
echo json_encode( array( "status" => "ERROR", "message" => "Could not create directory" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not create directory" ) );
} }
} }
// save a file // save a file
private function saveFile( $d ) { private function saveFile( $d ) {
if( ( file_exists( $this->pathCombine( $d['dir'], $d['filename'] ) ) && $this->config['edit'] != 1 ) || ( ! file_exists( $this->pathCombine( $d['dir'], $d['filename'] ) ) && $this->config['createfile'] != 1 ) ) { if( ( file_exists( $this->pathCombine( $d['dir'], $d['filename'] ) ) && $this->config['edit'] != 1 ) || ( ! file_exists( $this->pathCombine( $d['dir'], $d['filename'] ) ) && $this->config['createfile'] != 1 ) ) {
echo json_encode( array( "status" => "ERROR", "message" => "You are not allowed to edit/create this file." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "You are not allowed to edit/create this file." ) );
exit( 1 ); exit( 1 );
} }
if( isset( $d['filename'] ) && $this->isFilenameValid( $d['filename'] ) ) { if( isset( $d['filename'] ) && $this->isFilenameValid( $d['filename'] ) ) {
@@ -542,28 +545,28 @@ f00bar;
// work around magic quotes // work around magic quotes
$content = get_magic_quotes_gpc() == 1 ? stripslashes( $d['content'] ) : $d['content']; $content = get_magic_quotes_gpc() == 1 ? stripslashes( $d['content'] ) : $d['content'];
if( @file_put_contents( $d['filename'], $content ) !== false ) { if( @file_put_contents( $d['filename'], $content ) !== false ) {
echo json_encode( array( "status" => "OK", "message" => "File successfully saved" ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "File successfully saved" ) );
} else } else
echo json_encode( array( "status" => "ERROR", "message" => "Could not write content" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not write content" ) );
} else } else
echo json_encode( array( "status" => "ERROR", "message" => "Got no content" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Got no content" ) );
} else } else
echo json_encode( array( "status" => "ERROR", "message" => "Invalid filename given" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid filename given" ) );
} }
// gets the content of a file // gets the content of a file
// notice: if the content is not JSON encodable it returns an error // notice: if the content is not JSON encodable it returns an error
private function getContent( array $d ) { private function getContent( array $d ) {
if( $this->config['edit'] != 1 ) if( $this->config['edit'] != 1 )
echo json_encode( array( "status" => "ERROR", "message" => "You are not allowed to edit files." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "You are not allowed to edit files." ) );
else { else {
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
if( isset( $d['filename'] ) && $this->isFilenameAllowed( $d['filename'] ) && file_exists( $d['filename'] ) && is_readable( $d['filename'] ) ) { if( isset( $d['filename'] ) && $this->isFilenameAllowed( $d['filename'] ) && file_exists( $d['filename'] ) && is_readable( $d['filename'] ) ) {
$content = @file_get_contents( $d['filename'] ); $content = @file_get_contents( $d['filename'] );
if( function_exists( "mb_check_encoding" ) && ! mb_check_encoding( $content, "UTF-8" ) ) if( function_exists( "mb_check_encoding" ) && ! mb_check_encoding( $content, "UTF-8" ) )
$content = utf8_encode( $content ); $content = utf8_encode( $content );
echo json_encode( array( "status" => "OK", "data" => array( "filename" => $d['filename'], "content" => $content ) ) ); echo $this->jsonResponse( array( "status" => "OK", "data" => array( "filename" => $d['filename'], "content" => $content ) ) );
} else echo json_encode( array( "status" => "ERROR", "message" => "File not found or not readable." ) ); } else echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File not found or not readable." ) );
} }
} }
@@ -592,14 +595,14 @@ f00bar;
} }
} }
if( empty( $err ) ) { if( empty( $err ) ) {
echo json_encode( array( "status" => "OK", "message" => "Files deleted successfully", "errflag" => "1" ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "Files deleted successfully", "errflag" => "1" ) );
} }
else { else {
$errmsg = "The following files could not be deleted:<ul>"; $errmsg = "The following files could not be deleted:<ul>";
foreach($err as $item) foreach($err as $item)
$errmsg .= "<li>".$item."</li>"; $errmsg .= "<li>".$item."</li>";
$errmsg .= "</ul>"; $errmsg .= "</ul>";
echo json_encode( array( "status" => "OK", "message" => $errmsg, "flag" => $errFLAG ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => $errmsg, "flag" => $errFLAG ) );
} }
} }
} }
@@ -607,22 +610,22 @@ f00bar;
// renames a file // renames a file
private function renameFile( array $d ) { private function renameFile( array $d ) {
if( $this->config['rename'] != 1 ) { if( $this->config['rename'] != 1 ) {
echo json_encode( array( "status" => "ERROR", "message" => "No permission to rename files" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to rename files" ) );
} elseif( ! $this->isFilenameValid( $d['filename'] ) ) { } elseif( ! $this->isFilenameValid( $d['filename'] ) ) {
echo json_encode( array( "status" => "ERROR", "message" => "Invalid file name given" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid file name given" ) );
} else { } else {
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
if( strpos( $d['newname'], '/' ) !== false ) if( strpos( $d['newname'], '/' ) !== false )
echo json_encode( array( "status" => "ERROR", "message" => "No slashes allowed in filenames" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No slashes allowed in filenames" ) );
elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['newname'], 0, 3) == ".ht" || substr( $d['filename'], 0, 3 ) == ".ht" ) ) elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['newname'], 0, 3) == ".ht" || substr( $d['filename'], 0, 3 ) == ".ht" ) )
echo json_encode( array( "status" => "ERROR", "message" => "Not allowed to rename this file" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to rename this file" ) );
elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['newname'], 0, 1) == "." || substr( $d['filename'], 0, 1 ) == "." ) ) elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['newname'], 0, 1) == "." || substr( $d['filename'], 0, 1 ) == "." ) )
echo json_encode( array( "status" => "ERROR", "message" => "Not allowed to rename file" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to rename file" ) );
else { else {
if( @rename( $d['filename'], $d['newname'] ) ) if( @rename( $d['filename'], $d['newname'] ) )
echo json_encode( array( "status" => "OK", "message" => "File successful renamed" ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "File successful renamed" ) );
else else
echo json_encode( array( "status" => "ERROR", "message" => "File could not be renamed" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File could not be renamed" ) );
} }
} }
} }
@@ -630,11 +633,11 @@ f00bar;
// provides a file for downloading // provides a file for downloading
private function downloadFile( array $d ) { private function downloadFile( array $d ) {
if( $this->config['download'] != 1 ) if( $this->config['download'] != 1 )
echo json_encode( array( "status" => "ERROR", "message" => "Not allowed to download files" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to download files" ) );
elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['filename'], 0, 3 ) == ".ht" || substr( $d['filename'],0,3 ) == ".ht" ) ) elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['filename'], 0, 3 ) == ".ht" || substr( $d['filename'],0,3 ) == ".ht" ) )
echo json_encode( array( "status" => "ERROR", "message"=>"Not allowed to download htdocs" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message"=>"Not allowed to download htdocs" ) );
elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['filename'], 0, 1 ) == "." || substr( $d['filename'],0,1 ) == "." ) ) elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['filename'], 0, 1 ) == "." || substr( $d['filename'],0,1 ) == "." ) )
echo json_encode( array( "status" => "ERROR", "message" => "Not allowed to download hidden files" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to download hidden files" ) );
else { else {
$this->chDirIfNecessary( $d["dir"] ); $this->chDirIfNecessary( $d["dir"] );
$this->fileDownload( $d['filename'] ); $this->fileDownload( $d['filename'] );
@@ -644,34 +647,34 @@ f00bar;
// extracts a zip-archive // extracts a zip-archive
private function extractFile( array $d ) { private function extractFile( array $d ) {
if( $this->config['extract'] != 1 ) if( $this->config['extract'] != 1 )
echo json_encode( array( "status" => "ERROR", "message" => "No permission to extract files" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to extract files" ) );
else { else {
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
if( ! file_exists( $d['filename'] ) ) { if( ! file_exists( $d['filename'] ) ) {
echo json_encode( array( "status" => "ERROR","message" => "No valid archive found" ) ); echo $this->jsonResponse( array( "status" => "ERROR","message" => "No valid archive found" ) );
exit( 1 ); exit( 1 );
} }
if( ! isset( $d['targetdir'] ) || trim( $d['targetdir'] ) == "" ) if( ! isset( $d['targetdir'] ) || trim( $d['targetdir'] ) == "" )
$d['targetdir'] = "./"; $d['targetdir'] = "./";
if( ! $this->isPathValid( $d['targetdir'] ) ) { if( ! $this->isPathValid( $d['targetdir'] ) ) {
echo json_encode( array( "status" => "ERROR","message" => "Target directory is not valid." ) ); echo $this->jsonResponse( array( "status" => "ERROR","message" => "Target directory is not valid." ) );
exit( 1 ); exit( 1 );
} }
if( ! is_dir( $d['targetdir'] ) && ! mkdir( $d['targetdir'], 0777, true ) ) { if( ! is_dir( $d['targetdir'] ) && ! mkdir( $d['targetdir'], 0777, true ) ) {
echo json_encode( array( "status" => "ERROR","message" => "Could not create target directory." ) ); echo $this->jsonResponse( array( "status" => "ERROR","message" => "Could not create target directory." ) );
exit( 1 ); exit( 1 );
} }
if( substr( strtolower( $d['filename'] ), -4 ) == ".zip" ) { if( substr( strtolower( $d['filename'] ), -4 ) == ".zip" ) {
if( ! IFMArchive::extractZip( $d['filename'], $d['targetdir'] ) ) { if( ! IFMArchive::extractZip( $d['filename'], $d['targetdir'] ) ) {
echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); echo $this->jsonResponse( array( "status" => "ERROR","message" => "File could not be extracted" ) );
} else { } else {
echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); echo $this->jsonResponse( array( "status" => "OK","message" => "File successfully extracted." ) );
} }
} else { } else {
if( ! IFMArchive::extractTar( $d['filename'], $d['targetdir'] ) ) { if( ! IFMArchive::extractTar( $d['filename'], $d['targetdir'] ) ) {
echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); echo $this->jsonResponse( array( "status" => "ERROR","message" => "File could not be extracted" ) );
} else { } else {
echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); echo $this->jsonResponse( array( "status" => "OK","message" => "File successfully extracted." ) );
} }
} }
} }
@@ -680,35 +683,35 @@ f00bar;
// uploads a file // uploads a file
private function uploadFile( array $d ) { private function uploadFile( array $d ) {
if( $this->config['upload'] != 1 ) if( $this->config['upload'] != 1 )
echo json_encode( array( "status" => "ERROR", "message" => "No permission to upload files" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to upload files" ) );
elseif( !isset( $_FILES['file'] ) ) elseif( !isset( $_FILES['file'] ) )
echo json_encode( array( "file" => $_FILE,"files" => $_FILES ) ); echo $this->jsonResponse( array( "file" => $_FILE,"files" => $_FILES ) );
else { else {
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
$newfilename = ( isset( $d["newfilename"] ) && $d["newfilename"]!="" ) ? $d["newfilename"] : $_FILES['file']['name']; $newfilename = ( isset( $d["newfilename"] ) && $d["newfilename"]!="" ) ? $d["newfilename"] : $_FILES['file']['name'];
if( ! $this->isFilenameValid( $newfilename ) ) if( ! $this->isFilenameValid( $newfilename ) )
echo json_encode( array( "status" => "ERROR", "message" => "Invalid filename given" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid filename given" ) );
else { else {
if( $_FILES['file']['tmp_name'] ) { if( $_FILES['file']['tmp_name'] ) {
if( is_writable( getcwd( ) ) ) { if( is_writable( getcwd( ) ) ) {
if( move_uploaded_file( $_FILES['file']['tmp_name'], $newfilename ) ) if( move_uploaded_file( $_FILES['file']['tmp_name'], $newfilename ) )
echo json_encode( array( "status" => "OK", "message" => "The file ".$_FILES['file']['name']." was uploaded successfully", "cd" => $d['dir'] ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "The file ".$_FILES['file']['name']." was uploaded successfully", "cd" => $d['dir'] ) );
else else
echo json_encode( array( "status" => "ERROR", "message" => "File could not be uploaded" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File could not be uploaded" ) );
} }
else else
echo json_encode( array( "status" => "ERROR", "message" => "File could not be uploaded since it has no permissions to write in this directory" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File could not be uploaded since it has no permissions to write in this directory" ) );
} else } else
echo json_encode( array( "status" => "ERROR", "message" => "No file found" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No file found" ) );
} }
} }
} }
// change permissions of a file // change permissions of a file
private function changePermissions( array $d ) { private function changePermissions( array $d ) {
if( $this->config['chmod'] != 1 ) echo json_encode( array( "status" => "ERROR", "message" => "No rights to change permissions" ) ); if( $this->config['chmod'] != 1 ) echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No rights to change permissions" ) );
elseif( ! isset( $d["chmod"] )||$d['chmod']=="" ) echo json_encode( array( "status" => "ERROR", "message" => "Could not identify new permissions" ) ); elseif( ! isset( $d["chmod"] )||$d['chmod']=="" ) echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not identify new permissions" ) );
elseif( ! $this->isPathValid( $this->pathCombine( $d['dir'],$d['filename'] ) ) ) { echo json_encode( array( "status" => "ERROR", "message" => "Not allowed to change the permissions" ) ); } elseif( ! $this->isPathValid( $this->pathCombine( $d['dir'],$d['filename'] ) ) ) { echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to change the permissions" ) ); }
else { else {
$this->chDirIfNecessary( $d['dir'] ); $chmod = $d["chmod"]; $cmi = true; $this->chDirIfNecessary( $d['dir'] ); $chmod = $d["chmod"]; $cmi = true;
if( ! is_numeric( $chmod ) ) { if( ! is_numeric( $chmod ) ) {
@@ -733,12 +736,12 @@ f00bar;
if( $cmi ) { if( $cmi ) {
try { try {
chmod( $d["filename"], (int)octdec( $chmod ) ); chmod( $d["filename"], (int)octdec( $chmod ) );
echo json_encode( array( "status" => "OK", "message" => "Permissions changed successfully" ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "Permissions changed successfully" ) );
} catch ( Exception $e ) { } catch ( Exception $e ) {
echo json_encode( array( "status" => "ERROR", "message" => "Error while changing permissions" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Error while changing permissions" ) );
} }
} }
else echo json_encode( array( "status" => "ERROR", "message" => "Could not determine permission format" ) ); else echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not determine permission format" ) );
} }
} }
@@ -746,13 +749,13 @@ f00bar;
// it creates a temporary zip file in the current directory, so it has to be as much space free as the file size is // it creates a temporary zip file in the current directory, so it has to be as much space free as the file size is
private function zipnload( array $d ) { private function zipnload( array $d ) {
if( $this->config['zipnload'] != 1 ) if( $this->config['zipnload'] != 1 )
echo json_encode( array( "status" => "ERROR", "message" => "No permission to download directories" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to download directories" ) );
else { else {
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
if( ! file_exists( $d['filename'] ) ) if( ! file_exists( $d['filename'] ) )
echo json_encode( array( "status" => "ERROR", "message" => "Directory not found" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Directory not found" ) );
elseif ( ! $this->isFilenameValid( $d['filename'] ) ) elseif ( ! $this->isFilenameValid( $d['filename'] ) )
echo json_encode( array( "status" => "ERROR", "message" => "Filename not valid" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Filename not valid" ) );
else { else {
unset( $zip ); unset( $zip );
$dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename $dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename
@@ -777,54 +780,54 @@ f00bar;
// uploads a file from an other server using the curl extention // uploads a file from an other server using the curl extention
private function remoteUpload( array $d ) { private function remoteUpload( array $d ) {
if( $this->config['remoteupload'] != 1 ) if( $this->config['remoteupload'] != 1 )
echo json_encode( array( "status" => "ERROR", "message" => "No permission to remote upload files" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to remote upload files" ) );
elseif( !isset( $d['method'] ) || !in_array( $d['method'], array( "curl", "file" ) ) ) elseif( !isset( $d['method'] ) || !in_array( $d['method'], array( "curl", "file" ) ) )
echo json_encode( array( "status" => "error", "message" => "Invalid method given. Valid methods: ['curl', 'file']" ) ); echo $this->jsonResponse( array( "status" => "error", "message" => "Invalid method given. Valid methods: ['curl', 'file']" ) );
elseif( $d['method']=="curl" && $this->checkCurl( ) == false ) elseif( $d['method']=="curl" && $this->checkCurl( ) == false )
echo json_encode( array( "status" => "ERROR", "message" => "cURL extention not installed. Please install the cURL extention to use remote file upload." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "cURL extention not installed. Please install the cURL extention to use remote file upload." ) );
elseif( $d['method']=="curl" && $this->checkCurl( ) == true ) { elseif( $d['method']=="curl" && $this->checkCurl( ) == true ) {
$filename = ( isset( $d['filename'] )&&$d['filename']!="" )?$d['filename']:"curl_".uniqid( ); $filename = ( isset( $d['filename'] )&&$d['filename']!="" )?$d['filename']:"curl_".uniqid( );
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
$ch = curl_init( ); $ch = curl_init( );
if( $ch ) { if( $ch ) {
if( $this->isFilenameValid( $filename ) == false ) if( $this->isFilenameValid( $filename ) == false )
echo json_encode( array( "status" => "ERROR", "message" => "This filename is not valid." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "This filename is not valid." ) );
elseif( filter_var( $d['url'], FILTER_VALIDATE_URL ) === false ) elseif( filter_var( $d['url'], FILTER_VALIDATE_URL ) === false )
echo json_encode( array( "status" => "ERROR", "message" => "The passed URL is not valid" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "The passed URL is not valid" ) );
else { else {
$fp = fopen( $filename, "w" ); $fp = fopen( $filename, "w" );
if( $fp ) { if( $fp ) {
if( !curl_setopt( $ch, CURLOPT_URL, $d['url'] ) || !curl_setopt( $ch, CURLOPT_FILE, $fp ) || !curl_setopt( $ch, CURLOPT_HEADER, 0 ) || !curl_exec( $ch ) ) if( !curl_setopt( $ch, CURLOPT_URL, $d['url'] ) || !curl_setopt( $ch, CURLOPT_FILE, $fp ) || !curl_setopt( $ch, CURLOPT_HEADER, 0 ) || !curl_exec( $ch ) )
echo json_encode( array( "status" => "ERROR", "message" => "Failed to set options and execute cURL" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Failed to set options and execute cURL" ) );
else { else {
echo json_encode( array( "status" => "OK", "message" => "File sucessfully uploaded" ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "File sucessfully uploaded" ) );
} }
curl_close( $ch ); curl_close( $ch );
fclose( $fp ); fclose( $fp );
} else { } else {
echo json_encode( array( "status" => "ERROR", "message" => "Failed to open file" ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Failed to open file" ) );
} }
} }
} else { } else {
echo json_encode( array( "status" => "ERROR", "message" => "Failed to init cURL." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Failed to init cURL." ) );
} }
} }
elseif( $d['method']=='file' ) { elseif( $d['method']=='file' ) {
$filename = ( isset( $d['filename'] ) && $d['filename']!="" ) ? $d['filename'] : "curl_".uniqid( ); $filename = ( isset( $d['filename'] ) && $d['filename']!="" ) ? $d['filename'] : "curl_".uniqid( );
if( $this->isFilenameValid( $filename ) == false ) if( $this->isFilenameValid( $filename ) == false )
echo json_encode( array( "status" => "ERROR", "message" => "This filename is not valid." ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => "This filename is not valid." ) );
else { else {
$this->chDirIfNecessary( $d['dir'] ); $this->chDirIfNecessary( $d['dir'] );
try { try {
file_put_contents( $filename, file_get_contents( $d['url'] ) ); file_put_contents( $filename, file_get_contents( $d['url'] ) );
echo json_encode( array( "status" => "OK", "message" => "File successfully uploaded" ) ); echo $this->jsonResponse( array( "status" => "OK", "message" => "File successfully uploaded" ) );
} catch( Exception $e ) { } catch( Exception $e ) {
echo json_encode( array( "status" => "ERROR", "message" => $e->getMessage() ) ); echo $this->jsonResponse( array( "status" => "ERROR", "message" => $e->getMessage() ) );
} }
} }
} }
else else
echo json_encode( array( "status" => "error", "message" => "Corrupt parameter data" ) ); echo $this->jsonResponse( array( "status" => "error", "message" => "Corrupt parameter data" ) );
} }
/* /*
@@ -898,9 +901,9 @@ f00bar;
} else { } else {
if( isset( $_POST["api"] ) ) { if( isset( $_POST["api"] ) ) {
if( $login_failed === true ) if( $login_failed === true )
echo json_encode( array( "status"=>"ERROR", "message"=>"authentication failed" ) ); echo $this->jsonResponse( array( "status"=>"ERROR", "message"=>"authentication failed" ) );
else else
echo json_encode( array( "status"=>"ERROR", "message"=>"not authenticated" ) ); echo $this->jsonResponse( array( "status"=>"ERROR", "message"=>"not authenticated" ) );
} else { } else {
$this->loginForm($login_failed); $this->loginForm($login_failed);
} }

View File

@@ -21,6 +21,7 @@ body {
} }
a { cursor: pointer !important; } a { cursor: pointer !important; }
a.ifmitem:focus { outline: 0 }
img.imgpreview { max-width: 100%; } img.imgpreview { max-width: 100%; }

View File

@@ -1,6 +1,6 @@
<form id="formExtractFile"> <form id="formExtractFile">
<fieldset> <div class="modal-body">
<div class="modal-body"> <fieldset>
<label>{{i18n.extract_filename}} {{filename}}:</label> <label>{{i18n.extract_filename}} {{filename}}:</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><input type="radio" name="extractTargetLocation" value="./" checked="checked"></span> <span class="input-group-addon"><input type="radio" name="extractTargetLocation" value="./" checked="checked"></span>
@@ -14,10 +14,10 @@
<span class="input-group-addon"><input type="radio" name="extractTargetLocation" value="custom"></span> <span class="input-group-addon"><input type="radio" name="extractTargetLocation" value="custom"></span>
<input id="extractCustomLocation" type="text" class="form-control" placeholder="custom location" value=""> <input id="extractCustomLocation" type="text" class="form-control" placeholder="custom location" value="">
</div> </div>
</div> </fieldset>
<div class="modal-footer"> </div>
<button type="button" class="btn btn-default" id="buttonExtract">{{i18n.extract}}</button> <div class="modal-footer">
<button type="button" class="btn btn-default" id="buttonCancel">{{i18n.cancel}}</button> <button type="button" class="btn btn-default" id="buttonExtract">{{i18n.extract}}</button>
</div> <button type="button" class="btn btn-default" id="buttonCancel">{{i18n.cancel}}</button>
</fieldset> </div>
</form> </form>

View File

@@ -5,12 +5,6 @@
<input type="text" class="form-control" name="filename" value="{{filename}}"><br> <input type="text" class="form-control" name="filename" value="{{filename}}"><br>
<div id="content" name="content"></div><br> <div id="content" name="content"></div><br>
<button type="button" class="btn btn-default" id="editoroptions">{{i18n.editor_options}}</button> <button type="button" class="btn btn-default" id="editoroptions">{{i18n.editor_options}}</button>
<div class="hide" id="editoroptions-head">{{i18n.options}}</div>
<div class="hide" id="editoroptions-content">
<input type="checkbox" id="editor-wordwrap"> {{i18n.word_wrap}}</input><br>
<input type="checkbox" id="editor-softtabs"> {{i18n.soft_tabs}}</input>
<div class="input-group"><span class="input-group-addon">{{i18n.tab_size}}</span><input class="form-control" type="text" size="2" id="editor-tabsize" title="{{i18n.tab_size}}"></div>
</div>
</fieldset> </fieldset>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View File

@@ -0,0 +1,11 @@
<input type="checkbox" id="editor-wordwrap"
{{#wordwrap}}
checked="checked"
{{/wordwrap}}
> {{i18n.word_wrap}}</input><br>
<input type="checkbox" id="editor-softtabs"
{{#softtabs}}
checked="checked"
{{/softtabs}}
> {{i18n.soft_tabs}}</input>
<div class="input-group"><span class="input-group-addon">{{i18n.tab_size}}</span><input class="form-control" type="text" size="2" id="editor-tabsize" title="{{i18n.tab_size}}" value="{{tabsize}}"></div>

View File

@@ -1,10 +1,12 @@
<div class="modal-body">
<form id="formRenameFile"> <form id="formRenameFile">
<div class="modal-body">
<fieldset> <fieldset>
<label>{{i18n.rename_filename}} {{filename}}:</label> <label>{{i18n.rename_filename}} {{filename}}:</label>
<input class="form-control" type="text" name="newname" /><br> <input class="form-control" type="text" name="newname" value="" /><br>
<button class="btn btn-default" id="buttonRename">{{i18n.rename_filename}}</button>
<button class="btn btn-default" id="buttonCancel">{{i18n.cancel}} </button>
</fieldset> </fieldset>
</form>
</div> </div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="buttonRename">{{i18n.rename_filename}}</button>
<button type="button" class="btn btn-default" id="buttonCancel">{{i18n.cancel}} </button>
</div>
</form>

View File

@@ -1,4 +1,3 @@
<tbody>
{{#items}} {{#items}}
<tr class="{{rowclasses}}" data-filename="{{name}}"> <tr class="{{rowclasses}}" data-filename="{{name}}">
<td> <td>
@@ -8,4 +7,10 @@
</td> </td>
</tr> </tr>
{{/items}} {{/items}}
</tbody> {{^items}}
<tr>
<td>
No results found.
</td>
</tr>
{{/items}}