mirror of
https://github.com/misterunknown/ifm.git
synced 2025-08-12 19:13:57 +02:00
@@ -66,13 +66,11 @@ See [authentication](https://github.com/misterunknown/ifm/wiki/Authentication).
|
||||
The docker image is based on alpine 3.5 for a small image footprint, with necessary apache, php and supporting packages installed and exposes port 80
|
||||
|
||||
### build image
|
||||
|
||||
Run the following command from the top source dir:
|
||||
|
||||
`docker build -t ifm .`
|
||||
|
||||
### run image
|
||||
|
||||
The script is installed inside the image at `/var/www/html/index.php`. Its default configuration is unchanged, thus it will display the contents of the document root (`/var/www/html`)
|
||||
|
||||
Here is an example of how to start up a container with this image:
|
||||
|
1240
build/ifm.js
1240
build/ifm.js
File diff suppressed because it is too large
Load Diff
962
build/libifm.php
962
build/libifm.php
File diff suppressed because it is too large
Load Diff
28
compiler.php
28
compiler.php
@@ -18,6 +18,21 @@ $IFM_BUILD_STANDALONE = "ifm.php";
|
||||
$IFM_BUILD_STANDALONE_COMPRESSED = "build/ifm.min.php";
|
||||
$IFM_BUILD_LIB_PHP = "build/libifm.php";
|
||||
|
||||
$options = getopt( null, array( "language::" ) );
|
||||
$vars['languages'] = isset( $options['language'] ) ? explode( ',', $options['language'] ) : array( "en" );
|
||||
$vars['defaultlanguage'] = $vars['languages'][0];
|
||||
$vars['languageincludes'] = "";
|
||||
foreach( $vars['languages'] as $l ) {
|
||||
if( file_exists( "src/i18n/".$l.".json" ) )
|
||||
$vars['languageincludes'] .=
|
||||
'$i18n["'.$l.'"] = <<<\'f00bar\'' . "\n"
|
||||
. file_get_contents( "src/i18n/".$l.".json" ) . "\n"
|
||||
. 'f00bar;' . "\n"
|
||||
. '$i18n["'.$l.'"] = json_decode( $i18n["'.$l.'"], true );' . "\n" ;
|
||||
else
|
||||
print "WARNING: Language file src/i18n/".$l.".json not found.\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Concat PHP Files
|
||||
*/
|
||||
@@ -30,13 +45,20 @@ foreach( $IFM_SRC_PHP as $phpfile ) {
|
||||
$compiled = join( $compiled );
|
||||
|
||||
/**
|
||||
* Process includes
|
||||
* Process file includes
|
||||
*/
|
||||
$includes = NULL;
|
||||
preg_match_all( "/\@\@\@file:([^\@]+)\@\@\@/", $compiled, $includes, PREG_SET_ORDER );
|
||||
foreach( $includes as $file ) {
|
||||
foreach( $includes as $file )
|
||||
$compiled = str_replace( $file[0], file_get_contents( $file[1] ), $compiled );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process variable includes
|
||||
*/
|
||||
$includes = NULL;
|
||||
preg_match_all( "/\@\@\@vars:([^\@]+)\@\@\@/", $compiled, $includes, PREG_SET_ORDER );
|
||||
foreach( $includes as $var )
|
||||
$compiled = str_replace( $var[0], $vars[$var[1]], $compiled );
|
||||
|
||||
/**
|
||||
* Build standalone script
|
||||
|
@@ -1,34 +1,86 @@
|
||||
{
|
||||
"ajax_request": "AJAX Request",
|
||||
"archivename": "Name des Archivs",
|
||||
"archive_create_success": "Das Archiv wurde erfolgreich erstellt.",
|
||||
"archive_create_error": "Das Archiv konnte nicht erstellt werden.",
|
||||
"archive_invalid_format": "Ungültiges Archivformat angegeben.",
|
||||
"cancel": "Abbrechen",
|
||||
"close": "Schließen",
|
||||
"copy": "Kopieren",
|
||||
"copy_error": "Folgende Dateien konnten nicht kopiert werden:",
|
||||
"copy_success": "Datei(en) erfolgreich kopiert.",
|
||||
"create_archive": "Archiv erstellen",
|
||||
"data": "Daten",
|
||||
"delete": "Löschen",
|
||||
"directoryname": "Ordner Name",
|
||||
"download": "Download",
|
||||
"edit": "Bearbeiten",
|
||||
"editor_options": "Editor Optionen",
|
||||
"extract": "Auspacken",
|
||||
"extract_filename": "Folgende Datei auspacken -",
|
||||
"file_delete_confirm": "Soll die folgende Datei wirklich gelöscht werden -",
|
||||
"file_edit_success": "Datei erfolgreich geändert / angelegt.",
|
||||
"file_multi_delete_confirm": "Sollen diese Dateien wirklich gelöscht werden -",
|
||||
"error": "Fehler:",
|
||||
"extract": "Entpacken",
|
||||
"extract_error": "Das Archiv konnte nicht entpackt werden.",
|
||||
"extract_filename": "Folgende Datei entpacken -",
|
||||
"extract_success": "Das Archiv wurde erfolgreich entpackt.",
|
||||
"file_copy_to": "nach",
|
||||
"file_delete_confirm": "Soll die folgende Datei wirklich gelöscht werden:",
|
||||
"file_delete_error": "Folgende Dateien konnten nicht gelöscht werden:",
|
||||
"file_delete_success": "Datei(en) erfolgreich gelöscht",
|
||||
"file_display_error": "Die Datei kann nicht angezeigt oder geändert werden",
|
||||
"file_new": "Neue Datei",
|
||||
"file_save_confirm": "Soll diese Datei wirklich gelöscht werden -",
|
||||
"file_load_error": "Der Inhalt der Datei konnte nicht geladen werden",
|
||||
"file_open_error": "Die Datei konnte nicht geöffnet werden.",
|
||||
"file_new": "Neue Datei",
|
||||
"file_no_permission": "Sie haben keine Berechtigung diese Datei zu erstellen/bearbeiten.",
|
||||
"file_not_found": "Die Datei wurde nicht gefunden, oder kann nicht geöffnet werden.",
|
||||
"file_rename": "Datei umbenennen",
|
||||
"file_rename_error": "Datei konnte nicht umbenannt werden: ",
|
||||
"file_rename_success": "Datei erfolgreich umbenannt.",
|
||||
"file_save_error": "Datei konnte nicht gespeichert werden.",
|
||||
"file_save_success": "Datei erfolgreich gespeichert.",
|
||||
"file_save_confirm": "Soll diese Datei wirklich gespeichert werden -",
|
||||
"file_save_error": "Datei konnte nicht geändert oder angelegt werden: ",
|
||||
"file_upload_error": "Datei konnte nicht hochgeladen werden.",
|
||||
"file_upload_success": "Datei erfolgreich hochgeladen",
|
||||
"filename": "Dateiname",
|
||||
"filename_new": "Neuer Dateiname",
|
||||
"filename_slashes": "Der Dateiname darf keine Schrägstriche enthalten.",
|
||||
"folder_create_error": "Verzeichnis konnte nicht angelegt werden.",
|
||||
"folder_create_success": "Verzeichnis erfolgreich angelegt.",
|
||||
"folder_new": "Neue Ordner",
|
||||
"folder_not_found": "Das Verzeichnis wurde nicht gefunden.",
|
||||
"folder_tree_load_error": "Fehler bei Laden des Verzeichnisbaums.",
|
||||
"footer": "IFM - verbesserter file manager | ifm.php versteckt |",
|
||||
"general_error": "Genereller Fehler aufgetreten: Keine oder unvollständige Antwort vom Server",
|
||||
"github": "Besuche das Projekt auf GitHub",
|
||||
"group": "Gruppe",
|
||||
"invalid_action": "Fehlerhafte Aktion übergeben.",
|
||||
"invalid_archive_format": "Ungültiges Archiv-Format. Möglich sind zip, tar, tar.gz oder tar.bz2.",
|
||||
"invalid_data": "Fehlerhafte Daten vom Server erhalten.",
|
||||
"invalid_dir": "Ungültiges Verzeichnis übergegeben.",
|
||||
"invalid_filename": "Ungültiger Dateiname übergegeben.",
|
||||
"invalid_params": "Ungültige Parameter übergegeben.",
|
||||
"invalid_url": "Ungültige URL übergegeben.",
|
||||
"json_encode_error": "Konnte die Antwort nicht als JSON formatieren:",
|
||||
"last_modified": "Zuletzt geändert",
|
||||
"load_config_error": "Konfiguration konnte nicht geladen werden.",
|
||||
"load_template_error": "Vorlagen konnten nicht geladen werden.",
|
||||
"load_text_error": "Texte konnten nicht geladen werden.",
|
||||
"login": "Anmeldung",
|
||||
"login_failed": "Anmeldung fehlgeschlagen.",
|
||||
"logout": "Abmelden",
|
||||
"method": "Methode",
|
||||
"move": "Verschieben",
|
||||
"move_error": "Folgende Dateien konnten nicht verschoben werden:",
|
||||
"move_success": "Datei(en) erfolgreich verschoben.",
|
||||
"nopermissions": "Sie haben nicht die nötige Berechtigung dafür.",
|
||||
"options": "Optionen",
|
||||
"owner": "Besitzer",
|
||||
"password": "Passwort",
|
||||
"path_content": "Inhalt von",
|
||||
"pattern_error_slashes": "Das Muster darf keine Slashes enthalten.",
|
||||
"permission_change_error": "Berechtigungen konnten nicht geändert werden.",
|
||||
"permission_change_success": "Berechtigungen erfolgreich geändert.",
|
||||
"permission_parse_error": "Berechtigungen konnten nicht geparst werden.",
|
||||
"permissions": "Berechtigungen",
|
||||
"refresh": "Auffrischen",
|
||||
"rename": "Umbenennen",
|
||||
@@ -36,7 +88,7 @@
|
||||
"request": "Anfrage",
|
||||
"response": "Antwort",
|
||||
"save": "Speichen",
|
||||
"save_wo_close": "Speichen ohne Schließen",
|
||||
"save_wo_close": "Speichen ohne schließen",
|
||||
"search": "Suchen",
|
||||
"search_pattern": "Muster",
|
||||
"select_destination": "Zielort auswählen",
|
||||
@@ -46,7 +98,7 @@
|
||||
"tasks": "Aufgaben",
|
||||
"toggle_nav": "Navigation umschalten",
|
||||
"upload": "Hochladen",
|
||||
"upload_drop": "Dateien zum hochladen hier hinziehen",
|
||||
"upload_drop": "Dateien zum hochladen hier ablegen",
|
||||
"upload_file": "Datei hochladen",
|
||||
"upload_remote": "Hochladen von ausserhalb",
|
||||
"upload_remote_url": "Entfernte URL zum hochladen",
|
||||
|
@@ -1,34 +1,86 @@
|
||||
{
|
||||
"ajax_request": "AJAX Request",
|
||||
"ajax_request": "AJAX request",
|
||||
"archivename": "Name of the archive",
|
||||
"archive_create_success": "Archive successfully created.",
|
||||
"archive_create_error": "Could not create archive.",
|
||||
"archive_invalid_format": "Invalid archive format given.",
|
||||
"cancel": "Cancel",
|
||||
"close": "Close",
|
||||
"copy": "Copy",
|
||||
"copy_error": "The following files could not be copied:",
|
||||
"copy_success": "File(s) copied successfully.",
|
||||
"create_archive": "Create archive",
|
||||
"data": "Data",
|
||||
"delete": "Delete",
|
||||
"directoryname": "Directory Name",
|
||||
"download": "Download",
|
||||
"edit": "Edit",
|
||||
"editor_options": "Editor Options",
|
||||
"extract": "Extract",
|
||||
"error": "Error:",
|
||||
"extract": "extract",
|
||||
"extract_error": "Could not extract archive.",
|
||||
"extract_filename": "Extract file - ",
|
||||
"extract_success": "Archive extracted successfully.",
|
||||
"file_copy_to": "to",
|
||||
"file_delete_confirm": "Do you really want to delete the following file -",
|
||||
"file_edit_success": "File successfully edited / created.",
|
||||
"file_multi_delete_confirm": "Do you really want to delete these files -",
|
||||
"file_delete_error": "File(s) could not be deleted.",
|
||||
"file_delete_success": "File(s) successfully deleted.",
|
||||
"file_display_error": "This file can not be displayed or edited.",
|
||||
"file_new": "New File",
|
||||
"file_load_error": "Content could not be loaded.",
|
||||
"file_open_error": "Could not open the file.",
|
||||
"file_new": "New file",
|
||||
"file_no_permission": "No permission to edit/create file.",
|
||||
"file_not_found": "File was not found or could not be opened.",
|
||||
"file_rename": "Rename File",
|
||||
"file_rename_error": "File could not be renamed: ",
|
||||
"file_rename_success": "File successfully renamed.",
|
||||
"file_save_error": "File could not be saved.",
|
||||
"file_save_success": "File was saved successfully.",
|
||||
"file_save_confirm": "Do you want to save the following file -",
|
||||
"file_save_error": "File could not be edited or created: ",
|
||||
"file_upload_error": "File could not be uploaded.",
|
||||
"file_upload_success": "File successfully uploaded.",
|
||||
"filename": "Filename",
|
||||
"filename_new": "New Filename",
|
||||
"filename_slashes": "The filename must not contain slashes.",
|
||||
"folder_create_error": "Directory could not be created: ",
|
||||
"folder_create_success": "Directory sucessfully created.",
|
||||
"folder_new": "New Folder",
|
||||
"folder_not_found": "The directory could not be found.",
|
||||
"folder_tree_load_error": "Error while fetching the folder tree.",
|
||||
"footer": "IFM - improved file manager | ifm.php hidden |",
|
||||
"general_error": "General error occured: No or broken response.",
|
||||
"github": "Visit the project on GitHub",
|
||||
"group": "Group",
|
||||
"invalid_action": "Invalid action given.",
|
||||
"invalid_archive_format": "Invalid archive format given. Possible formats are zip, tar, tar.gz or tar.bz2.",
|
||||
"invalid_data": "Invalid data from server.",
|
||||
"invalid_dir": "Invalid directory given.",
|
||||
"invalid_filename": "Invalid filename given.",
|
||||
"invalid_params": "Invalid parameter given.",
|
||||
"invalid_url": "Invalid URL given.",
|
||||
"json_encode_error": "Could not format the response as JSON:",
|
||||
"last_modified": "Last Modified",
|
||||
"load_config_error": "Could not load configuration.",
|
||||
"load_template_error": "Could not load templates.",
|
||||
"load_text_error": "Could not load texts.",
|
||||
"login": "Login",
|
||||
"login_failed": "Login failed.",
|
||||
"logout": "Log Off",
|
||||
"method": "Method",
|
||||
"move": "Move",
|
||||
"move_error": "The following files could not be moved:",
|
||||
"move_success": "File(s) successfully moved.",
|
||||
"nopermissions": "You don't have the permission to do that.",
|
||||
"options": "Options",
|
||||
"owner": "Owner",
|
||||
"password": "Password",
|
||||
"path_content": "Content of",
|
||||
"pattern_error_slashes": "Pattern must not contain slashes.",
|
||||
"permission_change_error": "Permissions could not be changed: ",
|
||||
"permission_change_success": "Permissions successfully changed.",
|
||||
"permission_parse_error": "Permissions could not be parsed correctly.",
|
||||
"permissions": "Permissions",
|
||||
"refresh": "Refresh",
|
||||
"rename": "Rename",
|
||||
@@ -37,6 +89,7 @@
|
||||
"response": "Response",
|
||||
"save": "Save",
|
||||
"save_wo_close": "Save w/o Close",
|
||||
"search": "Search",
|
||||
"search_pattern": "Pattern",
|
||||
"select_destination": "Select Destination",
|
||||
"size": "Size",
|
||||
|
381
src/ifm.js
381
src/ifm.js
@@ -67,7 +67,7 @@ function IFM( params ) {
|
||||
*/
|
||||
this.refreshFileTable = function () {
|
||||
var taskid = self.generateGuid();
|
||||
self.task_add( { id: taskid, name: "Refresh" } );
|
||||
self.task_add( { id: taskid, name: self.i18n.refresh } );
|
||||
$.ajax({
|
||||
url: self.api,
|
||||
type: "POST",
|
||||
@@ -77,7 +77,7 @@ function IFM( params ) {
|
||||
},
|
||||
dataType: "json",
|
||||
success: self.rebuildFileTable,
|
||||
error: function() { self.showMessage( "General error occured: No or broken response", "e" ); },
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e" ); },
|
||||
complete: function() { self.task_done( taskid ); }
|
||||
});
|
||||
};
|
||||
@@ -92,7 +92,7 @@ function IFM( params ) {
|
||||
this.showMessage( data.message, "e" );
|
||||
return;
|
||||
} else if ( ! Array.isArray( data ) ) {
|
||||
this.showMessage( "Invalid data from server", "e" );
|
||||
this.showMessage( self.i18n.invalid_data, "e" );
|
||||
return;
|
||||
}
|
||||
data.forEach( function( item ) {
|
||||
@@ -140,6 +140,7 @@ function IFM( params ) {
|
||||
}
|
||||
}
|
||||
if( ! self.inArray( item.name, [".", ".."] ) ) {
|
||||
item.dragdrop = 'draggable="true"';
|
||||
if( self.config.copymove )
|
||||
item.button.push({
|
||||
action: "copymove",
|
||||
@@ -179,16 +180,17 @@ function IFM( params ) {
|
||||
filetable.tBodies[0].addEventListener( 'click', function( e ) {
|
||||
if( e.target.tagName == "TD" && e.target.parentElement.classList.contains( 'clickable-row' ) && e.target.parentElement.dataset.filename !== ".." && e.ctrlKey )
|
||||
e.target.parentElement.classList.toggle( 'selectedItem' );
|
||||
else if( e.target.classList.contains( 'ifmitem' ) ) {
|
||||
else if( e.target.classList.contains( 'ifmitem' ) || e.target.parentElement.classList.contains( 'ifmitem' ) ) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if( e.target.dataset.type == "dir" )
|
||||
self.changeDirectory( e.target.parentElement.parentElement.dataset.filename );
|
||||
ifmitem = ( e.target.classList.contains( 'ifmitem' ) ? e.target : e.target.parentElement );
|
||||
if( ifmitem.dataset.type == "dir" )
|
||||
self.changeDirectory( ifmitem.parentElement.parentElement.dataset.filename );
|
||||
else
|
||||
if( self.config.isDocroot )
|
||||
window.location.href = self.hrefEncode( self.pathCombine( self.currentDir, e.target.parentElement.parentElement.dataset.filename ) );
|
||||
window.location.href = self.hrefEncode( self.pathCombine( self.currentDir, ifmitem.parentElement.parentElement.dataset.filename ) );
|
||||
else
|
||||
document.forms["d_"+e.target.id].submit();
|
||||
document.forms["d_"+ifmitem.id].submit();
|
||||
} else if( e.target.parentElement.name == 'start_download' ) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
@@ -196,7 +198,7 @@ function IFM( params ) {
|
||||
} else if( e.target.parentElement.name && e.target.parentElement.name.substring(0, 3) == "do-" ) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
var item = self.fileCache.find( x => x.guid === e.target.parentElement.dataset.id );
|
||||
var item = self.fileCache.find( function( x ) { if( x.guid === e.target.parentElement.dataset.id ) return x; } );
|
||||
switch( e.target.parentElement.name.substr( 3 ) ) {
|
||||
case "rename":
|
||||
self.showRenameFileDialog( item.name );
|
||||
@@ -243,11 +245,11 @@ function IFM( params ) {
|
||||
},
|
||||
actionsGroups:[
|
||||
['edit', 'extract', 'rename'],
|
||||
['copymove', 'download', 'delete']
|
||||
['copymove', 'download', 'createarchive', 'delete']
|
||||
],
|
||||
actions: {
|
||||
edit: {
|
||||
name: "edit",
|
||||
name: self.i18n.edit,
|
||||
onClick: function( data ) {
|
||||
self.editFile( data.clicked.name );
|
||||
},
|
||||
@@ -257,7 +259,7 @@ function IFM( params ) {
|
||||
}
|
||||
},
|
||||
extract: {
|
||||
name: "extract",
|
||||
name: self.i18n.extract,
|
||||
onClick: function( data ) {
|
||||
self.showExtractFileDialog( data.clicked.name );
|
||||
},
|
||||
@@ -267,7 +269,7 @@ function IFM( params ) {
|
||||
}
|
||||
},
|
||||
rename: {
|
||||
name: "rename",
|
||||
name: self.i18n.rename,
|
||||
onClick: function( data ) {
|
||||
self.showRenameFileDialog( data.clicked.name );
|
||||
},
|
||||
@@ -277,9 +279,9 @@ function IFM( params ) {
|
||||
copymove: {
|
||||
name: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
return 'copy/move <span class="badge">'+data.selected.length+'</span>';
|
||||
return self.i18n.copy+'/'+self.i18n.move+' <span class="badge">'+data.selected.length+'</span>';
|
||||
else
|
||||
return 'copy/move';
|
||||
return self.i18n.copy+'/'+self.i18n.move;
|
||||
},
|
||||
onClick: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
@@ -293,9 +295,9 @@ function IFM( params ) {
|
||||
download: {
|
||||
name: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
return 'download <span class="badge">'+data.selected.length+'</span>';
|
||||
return self.i18n.download+' <span class="badge">'+data.selected.length+'</span>';
|
||||
else
|
||||
return 'download';
|
||||
return self.i18n.download;
|
||||
},
|
||||
onClick: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
@@ -306,12 +308,28 @@ function IFM( params ) {
|
||||
iconClass: "icon icon-download",
|
||||
isShown: function() { return !!self.config.download; }
|
||||
},
|
||||
createarchive: {
|
||||
name: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
return self.i18n.create_archive+' <span class="badge">'+data.selected.length+'</span>';
|
||||
else
|
||||
return self.i18n.create_archive;
|
||||
},
|
||||
onClick: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
self.showCreateArchiveDialog( data.selected );
|
||||
else
|
||||
self.showCreateArchiveDialog( data.clicked );
|
||||
},
|
||||
iconClass: "icon icon-archive",
|
||||
isShown: function( data ) { return !!( self.config.createarchive && data.clicked.name != ".." ); }
|
||||
},
|
||||
'delete': {
|
||||
name: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
return 'delete <span class="badge">'+data.selected.length+'</span>';
|
||||
return self.i18n.delete+' <span class="badge">'+data.selected.length+'</span>';
|
||||
else
|
||||
return 'delete';
|
||||
return self.i18n.delete;
|
||||
},
|
||||
onClick: function( data ) {
|
||||
if( data.selected.length > 0 )
|
||||
@@ -352,7 +370,7 @@ function IFM( params ) {
|
||||
$( "#currentDir" ).val( self.currentDir );
|
||||
if( config.pushState ) history.pushState( { dir: self.currentDir }, self.currentDir, "#"+encodeURIComponent( self.currentDir ) );
|
||||
},
|
||||
error: function() { self.showMessage( "General error occured: No or broken response", "e" ); }
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e" ); }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -445,11 +463,11 @@ function IFM( params ) {
|
||||
dataType: "json",
|
||||
success: function( data ) {
|
||||
if( data.status == "OK" ) {
|
||||
self.showMessage( self.i18n.file_edit_success, "s" );
|
||||
self.showMessage( self.i18n.file_save_success, "s" );
|
||||
self.refreshFileTable();
|
||||
} else self.showMessage( "File could not be edited/created:" + data.message, "e" );
|
||||
} else self.showMessage( self.i18n.file_save_error + data.message, "e" );
|
||||
},
|
||||
error: function() { self.showMessage( "General error occured", "e" ); }
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e" ); }
|
||||
});
|
||||
self.fileChanged = false;
|
||||
};
|
||||
@@ -474,11 +492,11 @@ function IFM( params ) {
|
||||
self.showFileDialog( 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" );
|
||||
self.showMessage( self.i18n.file_load_error, "e" );
|
||||
}
|
||||
else self.showMessage( "Error: "+data.message, "e" );
|
||||
else self.showMessage( self.i18n.error +data.message, "e" );
|
||||
},
|
||||
error: function() { self.showMessage( "This file can not be displayed or edited.", "e" ); }
|
||||
error: function() { self.showMessage( self.i18n.file_display_error, "e" ); }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -522,14 +540,14 @@ function IFM( params ) {
|
||||
dataType: "json",
|
||||
success: function( data ){
|
||||
if( data.status == "OK" ) {
|
||||
self.showMessage( "Directory sucessfully created.", "s" );
|
||||
self.showMessage( self.i18n.folder_create_success, "s" );
|
||||
self.refreshFileTable();
|
||||
}
|
||||
else {
|
||||
self.showMessage( "Directory could not be created: "+data.message, "e" );
|
||||
self.showMessage( self.i18n.folder_create_error +data.message, "e" );
|
||||
}
|
||||
},
|
||||
error: function() { self.showMessage( "General error occured.", "e" ); }
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e" ); }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -575,11 +593,11 @@ function IFM( params ) {
|
||||
dataType: "json",
|
||||
success: function( data ) {
|
||||
if( data.status == "OK" ) {
|
||||
self.showMessage( "File(s) successfully deleted", "s" );
|
||||
self.showMessage( self.i18n.file_delete_success, "s" );
|
||||
self.refreshFileTable();
|
||||
} else self.showMessage( "File(s) could not be deleted", "e" );
|
||||
} else self.showMessage( self.i18n.file_delete_error, "e" );
|
||||
},
|
||||
error: function() { self.showMessage( "General error occured", "e" ); }
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e" ); }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -628,11 +646,11 @@ function IFM( params ) {
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if(data.status == "OK") {
|
||||
ifm.showMessage("File successfully renamed", "s");
|
||||
ifm.showMessage( self.i18n.file_rename_success, "s");
|
||||
ifm.refreshFileTable();
|
||||
} else ifm.showMessage("File could not be renamed: "+data.message, "e");
|
||||
} else ifm.showMessage( self.i18n.file_rename_error +data.message, "e");
|
||||
},
|
||||
error: function() { ifm.showMessage("General error occured", "e"); }
|
||||
error: function() { ifm.showMessage( self.i18n.general_error, "e"); }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -672,7 +690,7 @@ function IFM( params ) {
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
||||
error: function() { self.hideModal(); self.showMessage( self.i18n.folder_tree_load_error, "e" ) }
|
||||
});
|
||||
var form = document.forms.formCopyMove;
|
||||
form.addEventListener( 'click', function( e ) {
|
||||
@@ -694,42 +712,40 @@ function IFM( params ) {
|
||||
/**
|
||||
* Copy or moves a file
|
||||
*
|
||||
* @params {string} source - name of the file
|
||||
* @params {string} sources - array of fileCache items
|
||||
* @params {string} destination - target directory
|
||||
* @params {string} action - action (copy|move)
|
||||
*/
|
||||
this.copyMove = function( sources, destination, action ) {
|
||||
if( ! Array.isArray( sources ) )
|
||||
sources = [sources];
|
||||
sources.forEach( function( source ) {
|
||||
var id = self.generateGuid();
|
||||
self.task_add( { id: id, name: action.charAt(0).toUpperCase() + action.slice(1) + " " + source.name + " to " + destination } );
|
||||
$.ajax({
|
||||
url: self.api,
|
||||
type: "POST",
|
||||
data: {
|
||||
dir: self.currentDir,
|
||||
api: "copyMove",
|
||||
action: action,
|
||||
filename: source.name,
|
||||
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 );
|
||||
var id = self.generateGuid();
|
||||
self.task_add( { id: id, name: self.i18n[action] + " " + ( sources.length > 1 ? sources.length : sources[0].name ) + " " + self.i18n.file_copy_to + " " + destination } );
|
||||
$.ajax({
|
||||
url: self.api,
|
||||
type: "POST",
|
||||
data: {
|
||||
dir: self.currentDir,
|
||||
api: "copyMove",
|
||||
action: action,
|
||||
filenames: sources.map( function( e ) { return e.name } ),
|
||||
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( self.i18n.general_error, "e" );
|
||||
},
|
||||
complete: function() {
|
||||
self.task_done( id );
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -787,11 +803,11 @@ function IFM( params ) {
|
||||
dataType: "json",
|
||||
success: function( data ) {
|
||||
if( data.status == "OK" ) {
|
||||
self.showMessage( "File successfully extracted", "s" );
|
||||
self.showMessage( data.message, "s" );
|
||||
self.refreshFileTable();
|
||||
} else self.showMessage( "File could not be extracted. Error: " + data.message, "e" );
|
||||
} else self.showMessage( data.message, "e" );
|
||||
},
|
||||
error: function() { self.showMessage( "General error occured", "e" ); },
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e" ); },
|
||||
complete: function() { self.task_done( id ); }
|
||||
});
|
||||
};
|
||||
@@ -852,11 +868,11 @@ function IFM( params ) {
|
||||
},
|
||||
success: function(data) {
|
||||
if(data.status == "OK") {
|
||||
self.showMessage("File successfully uploaded", "s");
|
||||
self.showMessage( self.i18n.file_upload_success, "s");
|
||||
if(data.cd == self.currentDir) self.refreshFileTable();
|
||||
} else self.showMessage("File could not be uploaded: "+data.message, "e");
|
||||
} else self.showMessage( data.message, "e");
|
||||
},
|
||||
error: function() { self.showMessage("General error occured", "e"); },
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e"); },
|
||||
complete: function() { self.task_done(id); }
|
||||
});
|
||||
self.task_add( { id: id, name: "Upload " + file.name } );
|
||||
@@ -881,14 +897,14 @@ function IFM( params ) {
|
||||
dataType: "json",
|
||||
success: function( data ){
|
||||
if( data.status == "OK" ) {
|
||||
self.showMessage( "Permissions successfully changed.", "s" );
|
||||
self.showMessage( self.i18n.permission_change_success, "s" );
|
||||
self.refreshFileTable();
|
||||
}
|
||||
else {
|
||||
self.showMessage( "Permissions could not be changed: "+data.message, "e");
|
||||
self.showMessage( data.message, "e");
|
||||
}
|
||||
},
|
||||
error: function() { self.showMessage("General error occured.", "e"); }
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e"); }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -939,15 +955,15 @@ function IFM( params ) {
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if(data.status == "OK") {
|
||||
self.showMessage( "File successfully uploaded", "s" );
|
||||
self.showMessage( self.i18n.file_upload_success, "s" );
|
||||
self.refreshFileTable();
|
||||
} else
|
||||
self.showMessage( "File could not be uploaded:<br />" + data.message, "e" );
|
||||
self.showMessage( self.i18n.file_upload_error + data.message, "e" );
|
||||
},
|
||||
error: function() { self.showMessage("General error occured", "e"); },
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e"); },
|
||||
complete: function() { self.task_done(id); }
|
||||
});
|
||||
self.task_add( { id: id, name: "Remote upload: "+filename } );
|
||||
self.task_add( { id: id, name: self.i18n.upload_remote+" "+filename } );
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1016,6 +1032,7 @@ function IFM( params ) {
|
||||
if( e.key == 'Enter' ) {
|
||||
e.preventDefault();
|
||||
if( e.target.value.trim() === '' ) return;
|
||||
document.getElementById( 'searchResults' ).tBodies[0].innerHTML = '<tr><td style="text-align:center;"><span class="icon icon-spin5 animate-spin"></span></td></tr>';
|
||||
self.search.lastSearch = e.target.value;
|
||||
$.ajax({
|
||||
url: self.api,
|
||||
@@ -1027,17 +1044,89 @@ function IFM( params ) {
|
||||
},
|
||||
dataType: "json",
|
||||
success: function( data ) {
|
||||
data.forEach( function(e) {
|
||||
e.folder = e.name.substr( 0, e.name.lastIndexOf( '/' ) );
|
||||
e.linkname = e.name.substr( e.name.lastIndexOf( '/' ) + 1 );
|
||||
});
|
||||
updateResults( data );
|
||||
if( data.status == 'ERROR' ) {
|
||||
self.hideModal();
|
||||
self.showMessage( data.message, "e" );
|
||||
} else {
|
||||
data.forEach( function(e) {
|
||||
e.folder = e.name.substr( 0, e.name.lastIndexOf( '/' ) );
|
||||
e.linkname = e.name.substr( e.name.lastIndexOf( '/' ) + 1 );
|
||||
});
|
||||
updateResults( data );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the create archive dialog
|
||||
*/
|
||||
this.showCreateArchiveDialog = function( items ) {
|
||||
self.showModal( Mustache.render( self.templates.createarchive, { i18n: self.i18n } ) );
|
||||
|
||||
var form = document.forms.formCreateArchive;
|
||||
form.elements.archivename.addEventListener( 'keypress', function( e ) {
|
||||
if( e.key == 'Enter' ) {
|
||||
e.preventDefault();
|
||||
self.createArchive( items, e.target.value );
|
||||
self.hideModal();
|
||||
}
|
||||
});
|
||||
form.addEventListener( 'click', function( e ) {
|
||||
if( e.target.id == 'buttonSave' ) {
|
||||
e.preventDefault();
|
||||
self.createArchive( items, form.elements.archivename.value );
|
||||
self.hideModal();
|
||||
} else if( e.target.id == 'buttonCancel' ) {
|
||||
e.preventDefault();
|
||||
self.hideModal();
|
||||
}
|
||||
}, false );
|
||||
};
|
||||
|
||||
this.createArchive = function( items, archivename ) {
|
||||
var type = "";
|
||||
if( archivename.substr( -3 ).toLowerCase() == "zip" )
|
||||
type = "zip";
|
||||
else if( archivename.substr( -3 ).toLowerCase() == "tar" )
|
||||
type = "tar";
|
||||
else if( archivename.substr( -6 ).toLowerCase() == "tar.gz" )
|
||||
type = "tar.gz";
|
||||
else if( archivename.substr( -7 ).toLowerCase() == "tar.bz2" )
|
||||
type = "tar.bz2";
|
||||
else {
|
||||
self.showMessage( self.i18n.invalid_archive_format, "e" );
|
||||
return;
|
||||
}
|
||||
var id = self.generateGuid();
|
||||
self.task_add( { id: id, name: self.i18n.create_archive+" "+archivename } );
|
||||
|
||||
$.ajax({
|
||||
url: self.api,
|
||||
type: "POST",
|
||||
data: {
|
||||
api: "createArchive",
|
||||
dir: self.currentDir,
|
||||
archivename: archivename,
|
||||
filenames: items.map( function( e ) { return e.name; } ),
|
||||
format: type
|
||||
},
|
||||
dataType: "json",
|
||||
success: function( data ) {
|
||||
console.log( data );
|
||||
if( data.status == "OK" ) {
|
||||
self.showMessage( data.message, "s" );
|
||||
self.refreshFileTable();
|
||||
} else
|
||||
self.showMessage( data.message, "e" );
|
||||
},
|
||||
error: function() { self.showMessage( self.i18n.general_error, "e" ); },
|
||||
complete: function() { self.task_done( id ); }
|
||||
});
|
||||
};
|
||||
|
||||
// --------------------
|
||||
// helper functions
|
||||
// --------------------
|
||||
@@ -1194,7 +1283,10 @@ function IFM( params ) {
|
||||
|
||||
var highlightedItem = document.getElementsByClassName( 'highlightedItem' )[0];
|
||||
if( ! highlightedItem ) {
|
||||
highlight( document.getElementById( 'filetable' ).tBodies[0].firstElementChild );
|
||||
if( document.activeElement.classList.contains( 'ifmitem' ) )
|
||||
highlight( document.activeElement.parentElement.parentElement );
|
||||
else
|
||||
highlight( document.getElementById( 'filetable' ).tBodies[0].firstElementChild );
|
||||
} else {
|
||||
var newItem = ( direction=="next" ? highlightedItem.nextElementSibling : highlightedItem.previousElementSibling );
|
||||
if( newItem != null )
|
||||
@@ -1477,7 +1569,7 @@ function IFM( params ) {
|
||||
self.initLoadTemplates();
|
||||
},
|
||||
error: function() {
|
||||
throw new Error( "IFM: could not load configuration" );
|
||||
throw new Error( self.i18n.load_config_error );
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1497,7 +1589,7 @@ function IFM( params ) {
|
||||
self.initLoadI18N();
|
||||
},
|
||||
error: function() {
|
||||
throw new Error( "IFM: could not load templates" );
|
||||
throw new Error( self.i18n.load_template_error );
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1517,7 +1609,7 @@ function IFM( params ) {
|
||||
self.initApplication();
|
||||
},
|
||||
error: function() {
|
||||
throw new Error( "IFM: could not load I18N" );
|
||||
throw new Error( self.i18n.load_text_error );
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1555,34 +1647,101 @@ function IFM( params ) {
|
||||
document.getElementById( 'buttonAjaxRequest' ).onclick = function() { self.showAjaxRequestDialog(); };
|
||||
if( self.config.upload )
|
||||
document.addEventListener( 'dragover', function( e ) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var div = document.getElementById( 'filedropoverlay' );
|
||||
div.style.display = 'block';
|
||||
div.ondrop = function( e ) {
|
||||
if( Array.prototype.indexOf.call(e.dataTransfer.types, "Files") != -1 ) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var files = e.dataTransfer.files;
|
||||
for( var i = 0; i < files.length; i++ ) {
|
||||
self.uploadFile( files[i] );
|
||||
}
|
||||
if( e.target.id == 'filedropoverlay' )
|
||||
e.target.style.display = 'none';
|
||||
else if( e.target.parentElement.id == 'filedropoverlay' ) {
|
||||
e.target.parentElement.style.display = 'none';
|
||||
}
|
||||
};
|
||||
div.ondragleave = function( e ) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if( e.target.id == 'filedropoverlay' )
|
||||
e.target.style.display = 'none';
|
||||
else if( e.target.parentElement.id == 'filedropoverlay' ) {
|
||||
e.target.parentElement.style.display = 'none';
|
||||
}
|
||||
};
|
||||
var div = document.getElementById( 'filedropoverlay' );
|
||||
div.style.display = 'block';
|
||||
div.ondrop = function( e ) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var files = e.dataTransfer.files;
|
||||
for( var i = 0; i < files.length; i++ ) {
|
||||
self.uploadFile( files[i] );
|
||||
}
|
||||
if( e.target.id == 'filedropoverlay' )
|
||||
e.target.style.display = 'none';
|
||||
else if( e.target.parentElement.id == 'filedropoverlay' ) {
|
||||
e.target.parentElement.style.display = 'none';
|
||||
}
|
||||
};
|
||||
div.ondragleave = function( e ) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if( e.target.id == 'filedropoverlay' )
|
||||
e.target.style.display = 'none';
|
||||
else if( e.target.parentElement.id == 'filedropoverlay' ) {
|
||||
e.target.parentElement.style.display = 'none';
|
||||
}
|
||||
};
|
||||
} else {
|
||||
var div = document.getElementById( 'filedropoverlay' );
|
||||
if( div.style.display == 'block' )
|
||||
div.stye.display == 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// drag and drop of filetable items
|
||||
if( self.config.copymove ) {
|
||||
var isFile = function(e) { return Array.prototype.indexOf.call(e.dataTransfer.types, "Files") != -1 };
|
||||
document.addEventListener( 'dragstart', function( e ) {
|
||||
var selectedItems = document.getElementsByClassName( 'selectedItem' );
|
||||
var data;
|
||||
if( selectedItems.length > 0 )
|
||||
data = self.fileCache.filter(
|
||||
x => self.inArray(
|
||||
x.guid,
|
||||
[].slice.call( selectedItems ).map( function( e ) { return e.dataset.id; } )
|
||||
)
|
||||
);
|
||||
else
|
||||
data = self.fileCache.find( x => x.guid === e.target.dataset.id );
|
||||
e.dataTransfer.setData( 'text/plain', JSON.stringify( data ) );
|
||||
var dragImage = document.createElement( 'div' );
|
||||
dragImage.style.display = 'inline';
|
||||
dragImage.style.padding = '10px';
|
||||
dragImage.innerHTML = '<span class="icon icon-folder-open-empty"></span> '+self.i18n.move+' '+( data.length || data.name );
|
||||
document.body.appendChild( dragImage );
|
||||
setTimeout(function() {
|
||||
dragImage.remove();
|
||||
});
|
||||
e.dataTransfer.setDragImage( dragImage, 0, 0 );
|
||||
});
|
||||
document.addEventListener( 'dragover', function( e ) { if( ! isFile( e ) && e.target.parentElement.classList.contains( 'isDir' ) ) e.preventDefault(); } );
|
||||
document.addEventListener( 'dragenter', function( e ) {
|
||||
if( ! isFile( e ) && e.target.tagName == "TD" && e.target.parentElement.classList.contains( 'isDir' ) )
|
||||
e.target.parentElement.classList.add( 'highlightedItem' );
|
||||
});
|
||||
document.addEventListener( 'dragleave', function( e ) {
|
||||
if( ! isFile( e ) && e.target.tagName == "TD" && e.target.parentElement.classList.contains( 'isDir' ) )
|
||||
e.target.parentElement.classList.remove( 'highlightedItem' );
|
||||
});
|
||||
document.addEventListener( 'drop', function( e ) {
|
||||
if( ! isFile( e ) && e.target.tagName == "TD" && e.target.parentElement.classList.contains( 'isDir' ) ) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
try {
|
||||
var source = JSON.parse( e.dataTransfer.getData( 'text' ) );
|
||||
self.log( "source:" );
|
||||
self.log( source );
|
||||
var destination = self.fileCache.find( x => x.guid === e.target.firstElementChild.id );
|
||||
if( ! Array.isArray( source ) )
|
||||
source = [source];
|
||||
if( source.find( x => x.name === destination.name ) )
|
||||
self.showMessage( "Source and destination are equal." );
|
||||
else
|
||||
self.copyMove( source, destination.name, "move" );
|
||||
} catch( e ) {
|
||||
console.log( e );
|
||||
} finally {
|
||||
[].slice.call( document.getElementsByClassName( 'highlightedItem' ) ).forEach( function( e ) {
|
||||
e.classList.remove( 'highlightedItem' );
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// handle keystrokes
|
||||
document.onkeydown = self.handleKeystrokes;
|
||||
|
||||
|
@@ -1,37 +1,41 @@
|
||||
<?php
|
||||
|
||||
/* =======================================================================
|
||||
/**
|
||||
* =======================================================================
|
||||
* Improved File Manager
|
||||
* ---------------------
|
||||
* License: This project is provided under the terms of the MIT LICENSE
|
||||
* http://github.com/misterunknown/ifm/blob/master/LICENSE
|
||||
* =======================================================================
|
||||
*
|
||||
* zip class
|
||||
* archive class
|
||||
*
|
||||
* this was adapted from http://php.net/manual/de/class.ziparchive.php#110719
|
||||
* This class provides support for various archive types for the IFM. It can
|
||||
* create and extract the following formats:
|
||||
* * zip
|
||||
* * tar
|
||||
* * tar.gz
|
||||
* * tar.bz2
|
||||
*/
|
||||
|
||||
class IFMArchive {
|
||||
|
||||
/**
|
||||
* Add a folder to the zip file
|
||||
* Add a folder to an archive
|
||||
*/
|
||||
private static function folderToZip($folder, &$zipFile, $exclusiveLength) {
|
||||
private static function addFolder( &$archive, $folder, $offset=0 ) {
|
||||
if( $offset == 0 )
|
||||
$offset = strlen( dirname( $folder ) ) + 1;
|
||||
$archive->addEmptyDir( substr( $folder, $offset ) );
|
||||
$handle = opendir( $folder );
|
||||
while( false !== $f = readdir( $handle ) ) {
|
||||
if( $f != '.' && $f != '..' ) {
|
||||
$filePath = "$folder/$f";
|
||||
if( file_exists( $filePath ) && is_readable( $filePath ) ) {
|
||||
// Remove prefix from file path before add to zip.
|
||||
$localPath = substr($filePath, $exclusiveLength);
|
||||
if( is_file( $filePath ) ) {
|
||||
$zipFile->addFile( $filePath, $localPath );
|
||||
} elseif( is_dir( $filePath ) ) {
|
||||
// Add sub-directory.
|
||||
$zipFile->addEmptyDir( $localPath );
|
||||
self::folderToZip( $filePath, $zipFile, $exclusiveLength );
|
||||
}
|
||||
}
|
||||
$filePath = $folder . '/' . $f;
|
||||
if( file_exists( $filePath ) && is_readable( $filePath ) )
|
||||
if( is_file( $filePath ) )
|
||||
$archive->addFile( $filePath, substr( $filePath, $offset ) );
|
||||
elseif( is_dir( $filePath ) )
|
||||
self::addFolder( $archive, $filePath, $offset );
|
||||
}
|
||||
}
|
||||
closedir( $handle );
|
||||
@@ -40,22 +44,24 @@ class IFMArchive {
|
||||
/**
|
||||
* Create a zip file
|
||||
*/
|
||||
public static function createZip( $src, $out, $root=false )
|
||||
public static function createZip( $src, $out )
|
||||
{
|
||||
$z = new ZipArchive();
|
||||
$z->open( $out, ZIPARCHIVE::CREATE);
|
||||
if( $root ) {
|
||||
self::folderToZip( realpath( $src ), $z, strlen( realpath( $src ) . '/' ) );
|
||||
} else {
|
||||
$z->addEmptyDir( basename( $src ) );
|
||||
self::folderToZip( realpath( $src ), $z, strlen( dirname( $src ) . '/' ) );
|
||||
}
|
||||
$a = new ZipArchive();
|
||||
$a->open( $out, ZIPARCHIVE::CREATE);
|
||||
|
||||
if( ! is_array( $src ) )
|
||||
$src = array( $src );
|
||||
|
||||
foreach( $src as $s )
|
||||
if( is_dir( $s ) )
|
||||
self::addFolder( $a, $s );
|
||||
elseif( is_file( $s ) )
|
||||
$a->addFile( $s, substr( $s, strlen( dirname( $s ) ) + 1 ) );
|
||||
|
||||
try {
|
||||
if( ( $res = $z->close() ) !== true ) {
|
||||
throw new Exception("Error while creating zip archive: ". $z->getStatusString());
|
||||
}
|
||||
return $a->close();
|
||||
} catch ( Exception $e ) {
|
||||
throw $e;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,17 +69,54 @@ class IFMArchive {
|
||||
* Unzip a zip file
|
||||
*/
|
||||
public static function extractZip( $file, $destination="./" ) {
|
||||
if( ! file_exists( $file ) )
|
||||
return false;
|
||||
$zip = new ZipArchive;
|
||||
$res = $zip->open( $file );
|
||||
if( $res === true ) {
|
||||
$zip->extractTo( $destination );
|
||||
$zip->close();
|
||||
return true;
|
||||
} else {
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tar archive
|
||||
*/
|
||||
public static function createTar( $src, $out, $t ) {
|
||||
$tmpf = substr( $out, 0, strlen( $out ) - strlen( $t ) ) . "tar";
|
||||
$a = new PharData( $tmpf );
|
||||
|
||||
try {
|
||||
if( ! is_array( $src ) )
|
||||
$src = array( $src );
|
||||
|
||||
foreach( $src as $s )
|
||||
if( is_dir( $s ) )
|
||||
self::addFolder( $a, $s );
|
||||
elseif( is_file( $s ) )
|
||||
$a->addFile( $s, substr( $s, strlen( dirname( $s ) ) +1 ) );
|
||||
switch( $t ) {
|
||||
case "tar.gz":
|
||||
$a->compress( Phar::GZ );
|
||||
@unlink( $tmpf );
|
||||
break;
|
||||
case "tar.bz2":
|
||||
$a->compress( Phar::BZ2 );
|
||||
@unlink( $tmpf );
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} catch( Exception $e ) {
|
||||
@unlink( $tmpf );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a tar archive
|
||||
*/
|
||||
public static function extractTar( $file, $destination="./" ) {
|
||||
if( ! file_exists( $file ) )
|
||||
return false;
|
||||
@@ -81,13 +124,8 @@ class IFMArchive {
|
||||
try {
|
||||
$tar->extractTo( $destination, null, true );
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
} catch( Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function createTar( $src, $out, $root=false ) {
|
||||
$tar = new PharData( $out );
|
||||
$tar->buildFromDirectory( $src );
|
||||
}
|
||||
}
|
||||
|
296
src/main.php
296
src/main.php
@@ -14,8 +14,6 @@ error_reporting( E_ALL );
|
||||
ini_set( 'display_errors', 'OFF' );
|
||||
|
||||
class IFM {
|
||||
const VERSION = '2.4.2';
|
||||
|
||||
private $defaultconfig = array(
|
||||
// general config
|
||||
"auth" => 0,
|
||||
@@ -24,7 +22,7 @@ class IFM {
|
||||
"tmp_dir" => "",
|
||||
"defaulttimezone" => "Europe/Berlin",
|
||||
"forbiddenChars" => array(),
|
||||
"language" => "en",
|
||||
"language" => "@@@vars:defaultlanguage@@@",
|
||||
|
||||
// api controls
|
||||
"ajaxrequest" => 1,
|
||||
@@ -40,6 +38,7 @@ class IFM {
|
||||
"remoteupload" => 1,
|
||||
"rename" => 1,
|
||||
"zipnload" => 1,
|
||||
"createarchive" => 1,
|
||||
|
||||
// gui controls
|
||||
"showlastmodified" => 0,
|
||||
@@ -86,6 +85,7 @@ class IFM {
|
||||
$this->config['remoteupload'] = getenv('IFM_API_REMOTEUPLOAD') !== false ? intval( getenv('IFM_API_REMOTEUPLOAD') ) : $this->config['remoteupload'] ;
|
||||
$this->config['rename'] = getenv('IFM_API_RENAME') !== false ? intval( getenv('IFM_API_RENAME') ) : $this->config['rename'] ;
|
||||
$this->config['zipnload'] = getenv('IFM_API_ZIPNLOAD') !== false ? intval( getenv('IFM_API_ZIPNLOAD') ) : $this->config['zipnload'] ;
|
||||
$this->config['createarchive'] = getenv('IFM_API_CREATEARCHIVE') !== false ? intval( getenv('IFM_API_CREATEARCHIVE') ) : $this->config['createarchive'] ;
|
||||
$this->config['showlastmodified'] = getenv('IFM_GUI_SHOWLASTMODIFIED') !== false ? intval( getenv('IFM_GUI_SHOWLASTMODIFIED') ) : $this->config['showlastmodified'] ;
|
||||
$this->config['showfilesize'] = getenv('IFM_GUI_SHOWFILESIZE') !== false ? intval( getenv('IFM_GUI_SHOWFILESIZE') ) : $this->config['showfilesize'] ;
|
||||
$this->config['showowner'] = getenv('IFM_GUI_SHOWOWNER') !== false ? intval( getenv('IFM_GUI_SHOWOWNER') ) : $this->config['showowner'] ;
|
||||
@@ -123,6 +123,9 @@ f00bar;
|
||||
f00bar;
|
||||
$templates['createdir'] = <<<'f00bar'
|
||||
@@@file:src/templates/modal.createdir.html@@@
|
||||
f00bar;
|
||||
$templates['createarchive'] = <<<'f00bar'
|
||||
@@@file:src/templates/modal.createarchive.html@@@
|
||||
f00bar;
|
||||
$templates['deletefile'] = <<<'f00bar'
|
||||
@@@file:src/templates/modal.deletefile.html@@@
|
||||
@@ -154,15 +157,13 @@ f00bar;
|
||||
$this->templates = $templates;
|
||||
|
||||
$i18n = array();
|
||||
$i18n['en'] = <<<'f00bar'
|
||||
@@@file:src/i18n/en.json@@@
|
||||
f00bar;
|
||||
$i18n['en'] = json_decode($i18n['en'], true);
|
||||
$i18n['de'] = <<<'f00bar'
|
||||
@@@file:src/i18n/de.json@@@
|
||||
f00bar;
|
||||
$i18n['de'] = json_decode($i18n['de'], true);
|
||||
@@@vars:languageincludes@@@
|
||||
$this->i18n = $i18n;
|
||||
|
||||
if( in_array( $this->config['language'], array_keys( $this->i18n ) ) )
|
||||
$this->l = $this->i18n[$this->config['language']];
|
||||
else
|
||||
$this->l = $this->i18n[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,9 +229,9 @@ f00bar;
|
||||
private function handleRequest() {
|
||||
if( $_REQUEST["api"] == "getRealpath" ) {
|
||||
if( isset( $_REQUEST["dir"] ) && $_REQUEST["dir"] != "" )
|
||||
echo $this->jsonResponse( array( "realpath" => $this->getValidDir( $_REQUEST["dir"] ) ) );
|
||||
$this->jsonResponse( array( "realpath" => $this->getValidDir( $_REQUEST["dir"] ) ) );
|
||||
else
|
||||
echo $this->jsonResponse( array( "realpath" => "" ) );
|
||||
$this->jsonResponse( array( "realpath" => "" ) );
|
||||
}
|
||||
elseif( $_REQUEST["api"] == "getFiles" ) {
|
||||
if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) )
|
||||
@@ -244,9 +245,9 @@ f00bar;
|
||||
elseif( $_REQUEST["api"] == "getFolders" ) {
|
||||
$this->getFolders( $_REQUEST );
|
||||
} elseif( $_REQUEST["api"] == "getTemplates" ) {
|
||||
echo $this->jsonResponse( $this->templates );
|
||||
$this->jsonResponse( $this->templates );
|
||||
} elseif( $_REQUEST["api"] == "getI18N" ) {
|
||||
echo $this->jsonResponse( $this->i18n[$this->config['language']] );
|
||||
$this->jsonResponse( $this->l );
|
||||
} elseif( $_REQUEST["api"] == "logout" ) {
|
||||
unset( $_SESSION );
|
||||
session_destroy();
|
||||
@@ -271,7 +272,7 @@ f00bar;
|
||||
case "getFolderTree": $this->getFolderTree( $_REQUEST ); break;
|
||||
case "createArchive": $this->createArchive( $_REQUEST ); break;
|
||||
default:
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid api action given" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid api action given" ) );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -303,6 +304,7 @@ f00bar;
|
||||
api functions
|
||||
*/
|
||||
|
||||
|
||||
private function getFiles( $dir ) {
|
||||
$this->chDirIfNecessary( $dir );
|
||||
|
||||
@@ -381,7 +383,7 @@ f00bar;
|
||||
$ret = $this->config;
|
||||
$ret['inline'] = ( $this->mode == "inline" ) ? true : false;
|
||||
$ret['isDocroot'] = ( $this->getRootDir() == $this->getScriptRoot() ) ? true : false;
|
||||
echo $this->jsonResponse( $ret );
|
||||
$this->jsonResponse( $ret );
|
||||
}
|
||||
|
||||
private function getFolders( $d ) {
|
||||
@@ -409,21 +411,21 @@ f00bar;
|
||||
),
|
||||
$ret
|
||||
);
|
||||
echo $this->jsonResponse( $ret );
|
||||
$this->jsonResponse( $ret );
|
||||
}
|
||||
}
|
||||
|
||||
private function searchItems( $d ) {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
if( strpos( $d['pattern'], '/' ) !== false ) {
|
||||
echo json_decode( array( "status" => "ERROR", "message" => "Pattern must not contain slashes" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['pattern_error_slashes'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
try {
|
||||
$results = $this->searchItemsRecursive( $d['pattern'] );
|
||||
echo $this->jsonResponse( $results );
|
||||
$this->jsonResponse( $results );
|
||||
} catch( Exception $e ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => $e->getMessage() ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error'] . " " . $e->getMessage() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +442,7 @@ f00bar;
|
||||
}
|
||||
|
||||
private function getFolderTree( $d ) {
|
||||
echo $this->jsonResponse(
|
||||
$this->jsonResponse(
|
||||
array_merge(
|
||||
array(
|
||||
0 => array(
|
||||
@@ -479,65 +481,75 @@ f00bar;
|
||||
|
||||
private function copyMove( $d ) {
|
||||
if( $this->config['copymove'] != 1 ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to copy or move files." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
if( ! isset( $d['destination'] ) || ! $this->isPathValid( realpath( $d['destination'] ) ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid destination directory given." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
if( ! file_exists( $d['filename'] ) || $d['filename'] == ".." ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid filename given." ) );
|
||||
if( ! is_array( $d['filenames'] ) ) {
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_params'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
if( $d['action'] == "copy" ) {
|
||||
if( $this->xcopy( $d['filename'], $d['destination'] ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "File(s) were successfully copied." ) );
|
||||
exit( 0 );
|
||||
} else {
|
||||
$err = error_get_last();
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => $err['message'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
} elseif( $d['action'] == "move" ) {
|
||||
if( rename( $d['filename'], $this->pathCombine( $d['destination'], basename( $d['filename'] ) ) ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "File(s) were successfully moved." ) );
|
||||
exit( 0 );
|
||||
} else {
|
||||
$err = error_get_last();
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => $err['message'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
} else {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid action given." ) );
|
||||
if( ! in_array( $d['action'], array( 'copy', 'move' ) ) ) {
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_action'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
$err = array(); $errFlag = -1; // -1 -> all errors; 0 -> at least some errors; 1 -> no errors
|
||||
foreach( $d['filenames'] as $file ) {
|
||||
if( ! file_exists( $file ) || $file == ".." || ! $this->isFilenameValid( $file ) ) {
|
||||
array_push( $err, $file );
|
||||
}
|
||||
if( $d['action'] == "copy" ) {
|
||||
if( $this->xcopy( $file, $d['destination'] ) )
|
||||
$errFlag = 0;
|
||||
else
|
||||
array_push( $err, $file );
|
||||
} elseif( $d['action'] == "move" ) {
|
||||
if( rename( $file, $this->pathCombine( $d['destination'], basename( $file ) ) ) )
|
||||
$errFlag = 0;
|
||||
else
|
||||
array_push( $err, $file );
|
||||
}
|
||||
}
|
||||
$action = ( $d['action'] == "copy" ? "copied" : "moved" );
|
||||
if( empty( $err ) ) {
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => ( $d['action'] == "copy" ? $this->l['copy_success'] : $this->l['move_success'] ), "errflag" => "1" ) );
|
||||
}
|
||||
else {
|
||||
$errmsg = ( $d['action'] == "copy" ? $this->l['copy_error'] : $this->l['move_error'] ) . "<ul>";
|
||||
foreach( $err as $item )
|
||||
$errmsg .= "<li>".$item."</li>";
|
||||
$errmsg .= "</ul>";
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $errmsg, "flag" => $errFlag ) );
|
||||
}
|
||||
}
|
||||
|
||||
// creates a directory
|
||||
private function createDir($w, $dn) {
|
||||
if( $this->config['createdir'] != 1 ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to create directories.") );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
if( $dn == "" )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid directory name") );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) );
|
||||
elseif( ! $this->isFilenameValid( $dn ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid directory name" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $w );
|
||||
if( @mkdir( $dn ) )
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "Directory successful created" ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['folder_create_success'] ) );
|
||||
else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not create directory" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_create_error'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
// save a file
|
||||
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 ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "You are not allowed to edit/create this file." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
if( isset( $d['filename'] ) && $this->isFilenameValid( $d['filename'] ) ) {
|
||||
@@ -546,34 +558,34 @@ f00bar;
|
||||
// work around magic quotes
|
||||
$content = get_magic_quotes_gpc() == 1 ? stripslashes( $d['content'] ) : $d['content'];
|
||||
if( @file_put_contents( $d['filename'], $content ) !== false ) {
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "File successfully saved" ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_save_success'] ) );
|
||||
} else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not write content" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_save_error'] ) );
|
||||
} else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Got no content" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_save_error'] ) );
|
||||
} else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid filename given" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
}
|
||||
|
||||
// gets the content of a file
|
||||
// notice: if the content is not JSON encodable it returns an error
|
||||
private function getContent( array $d ) {
|
||||
if( $this->config['edit'] != 1 )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "You are not allowed to edit files." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['npermissions'] ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
if( isset( $d['filename'] ) && $this->isFilenameAllowed( $d['filename'] ) && file_exists( $d['filename'] ) && is_readable( $d['filename'] ) ) {
|
||||
$content = @file_get_contents( $d['filename'] );
|
||||
if( function_exists( "mb_check_encoding" ) && ! mb_check_encoding( $content, "UTF-8" ) )
|
||||
$content = utf8_encode( $content );
|
||||
echo $this->jsonResponse( array( "status" => "OK", "data" => array( "filename" => $d['filename'], "content" => $content ) ) );
|
||||
} else echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File not found or not readable." ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "data" => array( "filename" => $d['filename'], "content" => $content ) ) );
|
||||
} else $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_not_found'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
// deletes a bunch of files or directories
|
||||
private function deleteFiles( array $d ) {
|
||||
if( $this->config['delete'] != 1 ) $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to delete files" ) );
|
||||
if( $this->config['delete'] != 1 ) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
$err = array(); $errFLAG = -1; // -1 -> no files deleted; 0 -> at least some files deleted; 1 -> all files deleted
|
||||
@@ -596,14 +608,14 @@ f00bar;
|
||||
}
|
||||
}
|
||||
if( empty( $err ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "Files deleted successfully", "errflag" => "1" ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_delete_success'], "errflag" => "1" ) );
|
||||
}
|
||||
else {
|
||||
$errmsg = "The following files could not be deleted:<ul>";
|
||||
$errmsg = $this->l['file_delete_error'] . "<ul>";
|
||||
foreach($err as $item)
|
||||
$errmsg .= "<li>".$item."</li>";
|
||||
$errmsg .= "</ul>";
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => $errmsg, "flag" => $errFLAG ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $errmsg, "flag" => $errFLAG ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,22 +623,22 @@ f00bar;
|
||||
// renames a file
|
||||
private function renameFile( array $d ) {
|
||||
if( $this->config['rename'] != 1 ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to rename files" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
} elseif( ! $this->isFilenameValid( $d['filename'] ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid file name given" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
} else {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
if( strpos( $d['newname'], '/' ) !== false )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No slashes allowed in filenames" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['filename_slashes'] ) );
|
||||
elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['newname'], 0, 3) == ".ht" || substr( $d['filename'], 0, 3 ) == ".ht" ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to rename this file" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['newname'], 0, 1) == "." || substr( $d['filename'], 0, 1 ) == "." ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to rename file" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
else {
|
||||
if( @rename( $d['filename'], $d['newname'] ) )
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "File successful renamed" ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_rename_success'] ) );
|
||||
else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File could not be renamed" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_rename_error'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,11 +646,11 @@ f00bar;
|
||||
// provides a file for downloading
|
||||
private function downloadFile( array $d ) {
|
||||
if( $this->config['download'] != 1 )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to download files" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['filename'], 0, 3 ) == ".ht" || substr( $d['filename'],0,3 ) == ".ht" ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message"=>"Not allowed to download htdocs" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message"=> $this->l['nopermissions'] ) );
|
||||
elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['filename'], 0, 1 ) == "." || substr( $d['filename'],0,1 ) == "." ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to download hidden files" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $d["dir"] );
|
||||
$this->fileDownload( $d['filename'] );
|
||||
@@ -648,34 +660,34 @@ f00bar;
|
||||
// extracts a zip-archive
|
||||
private function extractFile( array $d ) {
|
||||
if( $this->config['extract'] != 1 )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to extract files" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
if( ! file_exists( $d['filename'] ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR","message" => "No valid archive found" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR","message" => $this->l['invalid_filename'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
if( ! isset( $d['targetdir'] ) || trim( $d['targetdir'] ) == "" )
|
||||
$d['targetdir'] = "./";
|
||||
if( ! $this->isPathValid( $d['targetdir'] ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR","message" => "Target directory is not valid." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR","message" => $this->l['invalid_dir'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
if( ! is_dir( $d['targetdir'] ) && ! mkdir( $d['targetdir'], 0777, true ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR","message" => "Could not create target directory." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR","message" => $this->l['folder_create_error'] ) );
|
||||
exit( 1 );
|
||||
}
|
||||
if( substr( strtolower( $d['filename'] ), -4 ) == ".zip" ) {
|
||||
if( ! IFMArchive::extractZip( $d['filename'], $d['targetdir'] ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR","message" => "File could not be extracted" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR","message" => $this->l['extract_error'] ) );
|
||||
} else {
|
||||
echo $this->jsonResponse( array( "status" => "OK","message" => "File successfully extracted." ) );
|
||||
$this->jsonResponse( array( "status" => "OK","message" => $this->l['extract_success'] ) );
|
||||
}
|
||||
} else {
|
||||
if( ! IFMArchive::extractTar( $d['filename'], $d['targetdir'] ) ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR","message" => "File could not be extracted" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR","message" => $this->l['extract_error'] ) );
|
||||
} else {
|
||||
echo $this->jsonResponse( array( "status" => "OK","message" => "File successfully extracted." ) );
|
||||
$this->jsonResponse( array( "status" => "OK","message" => $this->l['extract_success'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -684,35 +696,35 @@ f00bar;
|
||||
// uploads a file
|
||||
private function uploadFile( array $d ) {
|
||||
if( $this->config['upload'] != 1 )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to upload files" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
elseif( !isset( $_FILES['file'] ) )
|
||||
echo $this->jsonResponse( array( "file" => $_FILE,"files" => $_FILES ) );
|
||||
$this->jsonResponse( array( "file" => $_FILE,"files" => $_FILES ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
$newfilename = ( isset( $d["newfilename"] ) && $d["newfilename"]!="" ) ? $d["newfilename"] : $_FILES['file']['name'];
|
||||
if( ! $this->isFilenameValid( $newfilename ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid filename given" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
else {
|
||||
if( $_FILES['file']['tmp_name'] ) {
|
||||
if( is_writable( getcwd( ) ) ) {
|
||||
if( move_uploaded_file( $_FILES['file']['tmp_name'], $newfilename ) )
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "The file ".$_FILES['file']['name']." was uploaded successfully", "cd" => $d['dir'] ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_upload_success'], "cd" => $d['dir'] ) );
|
||||
else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File could not be uploaded" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_upload_error'] ) );
|
||||
}
|
||||
else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "File could not be uploaded since it has no permissions to write in this directory" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_upload_success'] ) );
|
||||
} else
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No file found" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_not_found'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// change permissions of a file
|
||||
private function changePermissions( array $d ) {
|
||||
if( $this->config['chmod'] != 1 ) echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No rights to change 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 $this->jsonResponse( array( "status" => "ERROR", "message" => "Not allowed to change the permissions" ) ); }
|
||||
if( $this->config['chmod'] != 1 ) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
elseif( ! isset( $d["chmod"] )||$d['chmod']=="" ) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['permission_parse_error'] ) );
|
||||
elseif( ! $this->isPathValid( $this->pathCombine( $d['dir'],$d['filename'] ) ) ) { $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); }
|
||||
else {
|
||||
$this->chDirIfNecessary( $d['dir'] ); $chmod = $d["chmod"]; $cmi = true;
|
||||
if( ! is_numeric( $chmod ) ) {
|
||||
@@ -737,12 +749,12 @@ f00bar;
|
||||
if( $cmi ) {
|
||||
try {
|
||||
chmod( $d["filename"], (int)octdec( $chmod ) );
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "Permissions changed successfully" ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['permission_change_success'] ) );
|
||||
} catch ( Exception $e ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Error while changing permissions" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['permission_change_error'] ) );
|
||||
}
|
||||
}
|
||||
else echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not determine permission format" ) );
|
||||
else $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['permission_parse_error'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,18 +762,18 @@ 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
|
||||
private function zipnload( array $d ) {
|
||||
if( $this->config['zipnload'] != 1 )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to download directories" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermission'] ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
if( ! file_exists( $d['filename'] ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Directory not found" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_not_found'] ) );
|
||||
elseif ( ! $this->isFilenameValid( $d['filename'] ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Filename not valid" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
else {
|
||||
unset( $zip );
|
||||
$dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename
|
||||
try {
|
||||
IFMArchive::createZip( realpath( $d['filename'] ), $dfile, ( $d['filename'] == "." ) );
|
||||
IFMArchive::createZip( realpath( $d['filename'] ), $dfile );
|
||||
if( $d['filename'] == "." ) {
|
||||
if( getcwd() == $this->getScriptRoot() )
|
||||
$d['filename'] = "root";
|
||||
@@ -770,7 +782,7 @@ f00bar;
|
||||
}
|
||||
$this->fileDownload( $dfile, $d['filename'] . ".zip" );
|
||||
} catch ( Exception $e ) {
|
||||
echo "An error occured: " . $e->getMessage();
|
||||
echo $this->l['error'] . " " . $e->getMessage();
|
||||
} finally {
|
||||
if( file_exists( $dfile ) ) @unlink( $dfile );
|
||||
}
|
||||
@@ -781,65 +793,92 @@ f00bar;
|
||||
// uploads a file from an other server using the curl extention
|
||||
private function remoteUpload( array $d ) {
|
||||
if( $this->config['remoteupload'] != 1 )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to remote upload files" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
elseif( !isset( $d['method'] ) || !in_array( $d['method'], array( "curl", "file" ) ) )
|
||||
echo $this->jsonResponse( array( "status" => "error", "message" => "Invalid method given. Valid methods: ['curl', 'file']" ) );
|
||||
$this->jsonResponse( array( "status" => "error", "message" => $this->l['invalid_params'] ) );
|
||||
elseif( $d['method']=="curl" && $this->checkCurl( ) == false )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "cURL extention not installed. Please install the cURL extention to use remote file upload." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error']." cURL extention not installed." ) );
|
||||
elseif( $d['method']=="curl" && $this->checkCurl( ) == true ) {
|
||||
$filename = ( isset( $d['filename'] )&&$d['filename']!="" )?$d['filename']:"curl_".uniqid( );
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
$ch = curl_init( );
|
||||
if( $ch ) {
|
||||
if( $this->isFilenameValid( $filename ) == false )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "This filename is not valid." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
elseif( filter_var( $d['url'], FILTER_VALIDATE_URL ) === false )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "The passed URL is not valid" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_url'] ) );
|
||||
else {
|
||||
$fp = fopen( $filename, "w" );
|
||||
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 ) )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Failed to set options and execute cURL" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error']." ".curl_error( $ch ) ) );
|
||||
else {
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "File sucessfully uploaded" ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_upload_success'] ) );
|
||||
}
|
||||
curl_close( $ch );
|
||||
fclose( $fp );
|
||||
} else {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Failed to open file" ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_open_error'] ) );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "Failed to init cURL." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error']." curl init" ) );
|
||||
}
|
||||
}
|
||||
elseif( $d['method']=='file' ) {
|
||||
$filename = ( isset( $d['filename'] ) && $d['filename']!="" ) ? $d['filename'] : "curl_".uniqid( );
|
||||
if( $this->isFilenameValid( $filename ) == false )
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => "This filename is not valid." ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
else {
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
try {
|
||||
file_put_contents( $filename, file_get_contents( $d['url'] ) );
|
||||
echo $this->jsonResponse( array( "status" => "OK", "message" => "File successfully uploaded" ) );
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_upload_success'] ) );
|
||||
} catch( Exception $e ) {
|
||||
echo $this->jsonResponse( array( "status" => "ERROR", "message" => $e->getMessage() ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error'] . " " . $e->getMessage() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
echo $this->jsonResponse( array( "status" => "error", "message" => "Corrupt parameter data" ) );
|
||||
$this->jsonResponse( array( "status" => "error", "message" => $this->l['invalid_params'] ) );
|
||||
}
|
||||
|
||||
private function createArchive( $d ) {
|
||||
// if( $config['createarchive'] != 1 ) {
|
||||
// echo $this->jsonResponse( array( "status" => "ERROR", "message" => "No permission to create archives" ) );
|
||||
// return false;
|
||||
// }
|
||||
// $this->chDirIfNecessary( $d['dir'] );
|
||||
// switch( $d['format'] ) {
|
||||
// case "zip":
|
||||
//
|
||||
if( $this->config['createarchive'] != 1 ) {
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||
return false;
|
||||
}
|
||||
if( ! $this->isFilenameValid( $d['archivename'] ) ) {
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
return false;
|
||||
}
|
||||
$this->chDirIfNecessary( $d['dir'] );
|
||||
$filenames = array();
|
||||
foreach( $d['filenames'] as $file )
|
||||
if( ! $this->isFilenameValid( $file ) ) {
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||
exit( 1 );
|
||||
} else
|
||||
array_push( $filenames, realpath( $file ) );
|
||||
switch( $d['format'] ) {
|
||||
case "zip":
|
||||
if( IFMArchive::createZip( $filenames, $d['archivename'] ) )
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['archive_create_success'] ) );
|
||||
else
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['archive_create_error'] ) );
|
||||
break;
|
||||
case "tar":
|
||||
case "tar.gz":
|
||||
case "tar.bz2":
|
||||
if( IFMArchive::createTar( $filenames, $d['archivename'], $d['format'] ) )
|
||||
$this->jsonResponse( array( "status" => "OK", "message" => $this->l['archive_create_success'] ) );
|
||||
else
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['archive_create_error'] ) );
|
||||
break;
|
||||
default:
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['archive_invalid_format'] ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -878,7 +917,7 @@ f00bar;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => "Could not encode json: " . $err ) );
|
||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['json_encode_error'] . " " . $err ) );
|
||||
} else {
|
||||
echo $json;
|
||||
}
|
||||
@@ -913,9 +952,9 @@ f00bar;
|
||||
} else {
|
||||
if( isset( $_POST["api"] ) ) {
|
||||
if( $login_failed === true )
|
||||
echo $this->jsonResponse( array( "status"=>"ERROR", "message"=>"authentication failed" ) );
|
||||
$this->jsonResponse( array( "status"=>"ERROR", "message"=>"authentication failed" ) );
|
||||
else
|
||||
echo $this->jsonResponse( array( "status"=>"ERROR", "message"=>"not authenticated" ) );
|
||||
$this->jsonResponse( array( "status"=>"ERROR", "message"=>"not authenticated" ) );
|
||||
} else {
|
||||
$this->loginForm($login_failed);
|
||||
}
|
||||
@@ -962,9 +1001,8 @@ f00bar;
|
||||
$authenticated = false;
|
||||
}
|
||||
ldap_unbind( $ds );
|
||||
} else {
|
||||
} else
|
||||
$authenticated = false;
|
||||
}
|
||||
return $authenticated;
|
||||
break;
|
||||
}
|
||||
@@ -974,12 +1012,12 @@ f00bar;
|
||||
private function loginForm($loginFailed=false) {
|
||||
$err = "";
|
||||
if( $loginFailed )
|
||||
$err = '<div class="alert alert-danger">Login failed.</div>';
|
||||
$err = '<div class="alert alert-danger">'.$this->l['login_failed'].'</div>';
|
||||
$this->getHTMLHeader();
|
||||
$html = str_replace( "{{error}}", $err, $this->templates['login'] );
|
||||
$html = str_replace( "{{i18n.username}}", $this->i18n[$this->config['language']]['username'], $html );
|
||||
$html = str_replace( "{{i18n.password}}", $this->i18n[$this->config['language']]['password'], $html );
|
||||
$html = str_replace( "{{i18n.login}}", $this->i18n[$this->config['language']]['login'], $html );
|
||||
$html = str_replace( "{{i18n.username}}", $this->l['username'], $html );
|
||||
$html = str_replace( "{{i18n.password}}", $this->l['password'], $html );
|
||||
$html = str_replace( "{{i18n.login}}", $this->l['login'], $html );
|
||||
print $html;
|
||||
$this->getHTMLFooter();
|
||||
}
|
||||
|
@@ -1,6 +1,13 @@
|
||||
body {
|
||||
padding-top: 70px;
|
||||
overflow-y: scroll;
|
||||
overflow-y: scroll !important;
|
||||
}
|
||||
|
||||
/*
|
||||
* This prevents the content from moving when opening a modal
|
||||
*/
|
||||
.modal-open {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@@ -27,7 +34,7 @@ img.imgpreview { max-width: 100%; }
|
||||
|
||||
div#content { width: 100%; height: 350px; }
|
||||
|
||||
input[name=newperms] { width: 7em; }
|
||||
input[name=newpermissions] { padding: 6px 8px; }
|
||||
|
||||
#filetable tr th.buttons { min-width: 95px; }
|
||||
#filetable tbody tr.highlightedItem { box-shadow: 0px 0px 10px 2px #337ab7; }
|
||||
@@ -76,17 +83,19 @@ footer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
background-color: #FFF;
|
||||
filter: alpha(opacity=50);
|
||||
-moz-opacity: 0.5;
|
||||
opacity: 0.5;
|
||||
color: #FFF;
|
||||
background-color: lightblue;
|
||||
filter: alpha(opacity=70);
|
||||
-moz-opacity: 0.7;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#filedropoverlay div {
|
||||
border-radius: 5px;
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
position:relative;
|
||||
top:50%;
|
||||
font-size: 6em;
|
||||
}
|
||||
|
||||
.td-permissions { width: 1px; }
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{{#items}}
|
||||
<tr class="clickable-row {{rowclasses}}" data-filename="{{name}}" data-eaction="{{eaction}}">
|
||||
<tr class="clickable-row {{rowclasses}}" {{{dragdrop}}} data-id="{{guid}}" data-filename="{{name}}" data-eaction="{{eaction}}">
|
||||
<td>
|
||||
<a {{{href}}} tabindex="0" id="{{guid}}" class="ifmitem" {{{tooltip}}} data-type="{{type}}">
|
||||
<span class="{{icon}}"></span>
|
||||
@@ -25,8 +25,8 @@
|
||||
<td>{{size}}</td>
|
||||
{{/config.showfilesize}}
|
||||
{{#config.showpermissions}}
|
||||
<td class="hidden-xs">
|
||||
<input type="text" name="newpermissions" class="form-control {{filepermmode}}" value="{{fileperms}}" data-filename="{{name}}" {{readonly}}>
|
||||
<td class="hidden-xs td-permissions">
|
||||
<input type="text" size="11" name="newpermissions" class="form-control {{filepermmode}}" value="{{fileperms}}" data-filename="{{name}}" {{readonly}}>
|
||||
</td>
|
||||
{{/config.showpermissions}}
|
||||
{{#config.showowner}}
|
||||
|
12
src/templates/modal.createarchive.html
Normal file
12
src/templates/modal.createarchive.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<form id="formCreateArchive">
|
||||
<div class="modal-body">
|
||||
<fieldset>
|
||||
<label>{{i18n.archivename}}:</label>
|
||||
<input class="form-control" type="text" name="archivename" value="" />
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" id="buttonSave">{{i18n.save}}</button>
|
||||
<button type="button" class="btn btn-default" id="buttonCancel">{{i18n.cancel}}</button>
|
||||
</div>
|
||||
</form>
|
@@ -6,7 +6,7 @@
|
||||
</fieldset>
|
||||
</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="buttonRename">{{i18n.file_rename}}</button>
|
||||
<button type="button" class="btn btn-default" id="buttonCancel">{{i18n.cancel}} </button>
|
||||
</div>
|
||||
</form>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<div class="modal-body">
|
||||
<fieldset>
|
||||
<label>{{i18n.search_pattern}}:</label>
|
||||
<input type="text" class="form-control" id="searchPattern" name="pattern" value="{{lastSearch}}"><br>
|
||||
<input type="text" class="form-control" id="searchPattern" name="pattern" autocomplete="off" value="{{lastSearch}}"><br>
|
||||
<table id="searchResults" class="table">
|
||||
</table>
|
||||
</fieldset>
|
||||
|
Reference in New Issue
Block a user