1
0
mirror of https://github.com/misterunknown/ifm.git synced 2025-09-01 19:52:33 +02:00

added copy and move functionality for files and directories, disable logging for every keystroke

This commit is contained in:
Marco Dickert
2017-07-03 17:55:44 +02:00
parent 8ba3f99e8f
commit c8df517b2b
6 changed files with 375 additions and 11 deletions

194
ifm.php

File diff suppressed because one or more lines are too long

View File

@@ -27,6 +27,7 @@ class IFMConfig {
const createdir = 1; // allow to create directorys const createdir = 1; // allow to create directorys
const createfile = 1; // allow to create files const createfile = 1; // allow to create files
const zipnload = 1; // allow to zip and download directorys const zipnload = 1; // allow to zip and download directorys
const copymove = 1; // allow to copy and move files and directories
// view controls // view controls
const multiselect = 1; // implement multiselect of files and directories const multiselect = 1; // implement multiselect of files and directories

View File

@@ -104,7 +104,7 @@ function IFM() {
if( self.config.showgroup > 0 ) if( self.config.showgroup > 0 )
newRow += '<td class="hidden-xs hidden-sm hidden-md">' + data[i].group + '</td>'; newRow += '<td class="hidden-xs hidden-sm hidden-md">' + data[i].group + '</td>';
// actions // actions
if( self.inArray( 1, [self.config.edit, self.config.rename, self.config.delete, self.config.extract] ) ) { if( self.inArray( 1, [self.config.edit, self.config.rename, self.config.delete, self.config.extract, self.config.copymove] ) ) {
newRow += '<td>'; newRow += '<td>';
if( data[i].name.toLowerCase().substr(-4) == ".zip" && self.config.extract == 1 ) { if( data[i].name.toLowerCase().substr(-4) == ".zip" && self.config.extract == 1 ) {
newRow += '<a tabindex="0" onclick="ifm.extractFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-archive" title="extract"></span></a>'; newRow += '<a tabindex="0" onclick="ifm.extractFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-archive" title="extract"></span></a>';
@@ -112,6 +112,9 @@ function IFM() {
newRow += '<a tabindex="0" onclick="ifm.editFile(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-pencil" title="edit"></span></a>'; newRow += '<a tabindex="0" onclick="ifm.editFile(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-pencil" title="edit"></span></a>';
} }
if( data[i].name != ".." && data[i].name != "." ) { if( data[i].name != ".." && data[i].name != "." ) {
if( self.config.copymove == 1 ) {
newRow += '<a tabindex="0" onclick="ifm.copyMoveDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-folder-open-empty" title="copy/move"></span></a>';
}
if( self.config.rename == 1 ) if( self.config.rename == 1 )
newRow += '<a tabindex="0" onclick="ifm.renameFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-terminal" title="rename"></span></a>'; newRow += '<a tabindex="0" onclick="ifm.renameFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-terminal" title="rename"></span></a>';
if( self.config.delete == 1 ) if( self.config.delete == 1 )
@@ -140,7 +143,6 @@ function IFM() {
}; };
this.changeDirectory = function( newdir, options={} ) { this.changeDirectory = function( newdir, options={} ) {
console.log( "changeDirectory, newdir="+newdir );
config = { absolute: false, pushState: true }; config = { absolute: false, pushState: true };
jQuery.extend( config, options ); jQuery.extend( config, options );
if( ! config.absolute ) newdir = self.pathCombine( self.currentDir, newdir ); if( ! config.absolute ) newdir = self.pathCombine( self.currentDir, newdir );
@@ -385,6 +387,78 @@ function IFM() {
}); });
}; };
this.copyMove = function( source, destination, action ) {
var id=self.generateGuid();
self.task_add(action.charAt(0).toUpperCase()+action.slice(1)+" "+source+" to "+destination, id);
$.ajax({
url: self.IFM_SCFN,
type: "POST",
data: ({
dir: self.currentDir,
api: "copyMove",
action: action,
filename: source,
destination: destination
}),
dataType: "json",
success: function(data) {
if( data.status == "OK" ) {
self.showMessage( data.message, "s" );
} else {
self.showMessage( data.message, "e" );
}
self.refreshFileTable();
},
error: function() {
self.showMessage( "General error occured.", "e" );
},
complete: function() {
self.task_done(id);
}
});
};
this.copyMoveDialog = function(name) {
self.showModal( '<form id="copyMoveFile"><fieldset>\
<div class="modal-body">\
<label>Select destination:</label>\
<div id="copyMoveTree"><span class="icon icon-spin5"></span></div>\
</div>\
<div class="modal-footer">\
<button type="button" class="btn btn-default" id="copyButton">copy</button>\
<button type="button" class="btn btn-default" id="moveButton">move</button>\
<button type="button" class="btn btn-default" id="cancelButton">cancel</button>\
</div>\
</fieldset></form>');
$.ajax({
url: ifm.IFM_SCFN,
type: "POST",
data: ({
api: "getFolderTree",
dir: ifm.currentDir
}),
dataType: "json",
success: function(data) {
$('#copyMoveTree').treeview({data: data, levels: 0, expandIcon: "icon icon-folder-empty", collapseIcon: "icon icon-folder-open-empty"});
},
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
});
$('#copyButton').on( 'click', function(e) {
self.copyMove( name, $('#copyMoveTree .node-selected').data('path'), 'copy' );
self.hideModal();
return false;
});
$('#moveButton').on( 'click', function(e) {
self.copyMove( name, $('#copyMoveTree .node-selected').data('path'), 'move' );
self.hideModal();
return false;
});
$('#cancelButton').on( 'click', function(e) {
self.hideModal();
return false;
});
};
this.extractFileDialog = function(name) { this.extractFileDialog = function(name) {
var targetDirSuggestion=""; var targetDirSuggestion="";
if(name.lastIndexOf(".") > 1) if(name.lastIndexOf(".") > 1)
@@ -819,8 +893,6 @@ function IFM() {
} }
break; break;
} }
console.log( "key: "+e.key );
} }
// initialization // initialization

View File

@@ -0,0 +1 @@
.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}

File diff suppressed because one or more lines are too long

View File

@@ -35,6 +35,7 @@ class IFM {
<style type="text/css">';?> @@@src/includes/bootstrap.min.css@@@ <?php print '</style> <style type="text/css">';?> @@@src/includes/bootstrap.min.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/includes/ekko-lightbox.min.css@@@ <?php print '</style> <style type="text/css">';?> @@@src/includes/ekko-lightbox.min.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/includes/fontello-embedded.css@@@ <?php print '</style> <style type="text/css">';?> @@@src/includes/fontello-embedded.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/includes/bootstrap-treeview.min.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/style.css@@@ <?php print '</style> <style type="text/css">';?> @@@src/style.css@@@ <?php print '</style>
</head> </head>
<body> <body>
@@ -113,6 +114,7 @@ class IFM {
<script>';?> @@@src/includes/bootstrap.min.js@@@ <?php print '</script> <script>';?> @@@src/includes/bootstrap.min.js@@@ <?php print '</script>
<script>';?> @@@src/includes/bootstrap-notify.min.js@@@ <?php print '</script> <script>';?> @@@src/includes/bootstrap-notify.min.js@@@ <?php print '</script>
<script>';?> @@@src/includes/ekko-lightbox.min.js@@@ <?php print '</script> <script>';?> @@@src/includes/ekko-lightbox.min.js@@@ <?php print '</script>
<script>';?> @@@src/includes/bootstrap-treeview.min.js@@@ <?php print '</script>
<script>';?> @@@src/ifm.js@@@ <?php print '</script> <script>';?> @@@src/ifm.js@@@ <?php print '</script>
</body> </body>
</html> </html>
@@ -146,11 +148,17 @@ class IFM {
case "downloadFile": $this->downloadFile( $_REQUEST ); break; case "downloadFile": $this->downloadFile( $_REQUEST ); break;
case "extractFile": $this->extractFile( $_REQUEST ); break; case "extractFile": $this->extractFile( $_REQUEST ); break;
case "uploadFile": $this->uploadFile( $_REQUEST ); break; case "uploadFile": $this->uploadFile( $_REQUEST ); break;
case "copyMove": $this->copyMove( $_REQUEST ); break;
case "changePermissions": $this->changePermissions( $_REQUEST ); break; case "changePermissions": $this->changePermissions( $_REQUEST ); break;
case "zipnload": $this->zipnload( $_REQUEST); break; case "zipnload": $this->zipnload( $_REQUEST); break;
case "remoteUpload": $this->remoteUpload( $_REQUEST ); break; case "remoteUpload": $this->remoteUpload( $_REQUEST ); break;
case "deleteMultipleFiles": $this->deleteMultipleFiles( $_REQUEST ); break; case "deleteMultipleFiles": $this->deleteMultipleFiles( $_REQUEST ); break;
default: echo json_encode(array("status"=>"ERROR", "message"=>"No valid api action given")); break; case "getFolderTree":
echo json_encode( array_merge( array( 0 => array( "text" => "/ [root]", "nodes" => array(), "dataAttributes" => array( "path" => realpath( IFMConfig::root_dir ) ) ) ), $this->getFolderTreeRecursive( IFMConfig::root_dir ) ) );
break;
default:
echo json_encode( array( "status" => "ERROR", "message" => "No valid api action given" ) );
break;
} }
} else { } else {
print json_encode(array("status"=>"ERROR", "message"=>"No valid working directory")); print json_encode(array("status"=>"ERROR", "message"=>"No valid working directory"));
@@ -248,6 +256,58 @@ class IFM {
echo json_encode( array_merge( $dirs, $files ) ); echo json_encode( array_merge( $dirs, $files ) );
} }
private function getFolderTreeRecursive( $start_dir ) {
$ret = array();
$start_dir = realpath( $start_dir );
if( $handle = opendir( $start_dir ) ) {
while (false !== ( $result = readdir( $handle ) ) ) {
if( is_dir( $this->pathCombine( $start_dir, $result ) ) && $result != "." && $result != ".." ) {
array_push( $ret, array( "text" => $result, "dataAttributes" => array( "path" => $this->pathCombine( $start_dir, $result ) ), "nodes" => $this->getFolderTreeRecursive( $this->pathCombine( $start_dir, $result ) ) ) );
}
}
}
sort( $ret );
return $ret;
}
private function copyMove( $d ) {
if( IFMConfig::copymove != 1 ) {
echo json_encode( array( "status" => "ERROR", "message" => "No permission to copy or move files." ) );
exit( 1 );
}
$this->chDirIfNecessary( $d['dir'] );
if( ! isset( $d['destination'] ) || ! $this->isPathValid( realpath( $d['destination'] ) ) ) {
echo json_encode( array( "status" => "ERROR", "message" => "No valid destination directory given." ) );
exit( 1 );
}
if( ! file_exists( $d['filename'] ) ) {
echo json_encode( array( "status" => "ERROR", "message" => "No valid filename given." ) );
exit( 1 );
}
if( $d['action'] == "copy" ) {
if( $this->copyr( $d['filename'], $d['destination'] ) ) {
echo json_encode( array( "status" => "OK", "message" => "File(s) were successfully copied." ) );
exit( 0 );
} else {
$err = error_get_last();
echo json_encode( array( "status" => "ERROR", "message" => $err['message'] ) );
exit( 1 );
}
} elseif( $d['action'] == "move" ) {
if( rename( $d['filename'], $this->pathCombine( $d['destination'], basename( $d['filename'] ) ) ) ) {
echo json_encode( array( "status" => "OK", "message" => "File(s) were successfully moved." ) );
exit( 0 );
} else {
$err = error_get_last();
echo json_encode( array( "status" => "ERROR", "message" => $err['message'] ) );
exit( 1 );
}
} else {
echo json_encode( array( "status" => "ERROR", "message" => "No valid action given." ) );
exit( 1 );
}
}
// creates a directory // creates a directory
private function createDir($w, $dn) { private function createDir($w, $dn) {
if( $dn == "" ) { if( $dn == "" ) {
@@ -788,6 +848,53 @@ class IFM {
return 0; return 0;
} }
/**
* Copy a file, or recursively copy a folder and its contents
*
* @author Aidan Lister <aidan@php.net>
* @version 1.0.1
* @link http://aidanlister.com/2004/04/recursively-copying-directories-in-php/
* @param string $source Source path
* @param string $dest Destination path
* @return bool Returns TRUE on success, FALSE on failure
*/
private function copyr( $source, $dest )
{
// Check for symlinks
if (is_link($source)) {
return symlink(readlink($source), $dest);
}
// Simple copy for a file
if (is_file($source)) {
$dest = ( is_dir( $dest ) ) ? $this->pathCombine( $dest, basename( $source ) ) : $dest;
return copy($source, $dest);
} else {
$dest = $this->pathCombine( $dest, basename( $source ) );
}
// Make destination directory
if (!is_dir($dest)) {
mkdir($dest);
}
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Deep copy directories
$this->copyr("$source/$entry", "$dest/$entry");
}
// Clean up
$dir->close();
return true;
}
// combines two parts to a valid path // combines two parts to a valid path
private function pathCombine( $a, $b ) { private function pathCombine( $a, $b ) {
if( trim( $a ) == "" && trim( $b ) == "" ) if( trim( $a ) == "" && trim( $b ) == "" )