mirror of
https://github.com/xevidos/codiad.git
synced 2024-11-13 07:11:14 +01:00
Continued work on new archive system, Improved file indexing performance, Added unarchive to context menu
This commit is contained in:
parent
7700671b1d
commit
a377b4dddd
5 changed files with 208 additions and 143 deletions
|
@ -127,20 +127,34 @@ class Archive {
|
|||
|
||||
public static function decompress( $file, $output = "default" ) {
|
||||
|
||||
$type = filetype( $file );
|
||||
$response = array();
|
||||
$path_info = pathinfo( $file );
|
||||
$type = isset( $path_info["extension"] ) ? $path_info["extension"] : null;
|
||||
$supported = self::supports( $type );
|
||||
$archive = self::get_instance();
|
||||
|
||||
if( $output == "default" ) {
|
||||
|
||||
$output = $path_info["dirname"] . "/" . $path_info["filename"];
|
||||
}
|
||||
|
||||
if( $supported["status"] === "success" ) {
|
||||
|
||||
if( extension_loaded( self::EXTENSIONS["{$type}"] ) ) {
|
||||
|
||||
$response = call_user_func( array( $archive, "{$type}_d" ), $path );
|
||||
$response = call_user_func( array( $archive, "{$type}_d" ), $file, $output );
|
||||
} else {
|
||||
|
||||
$response = $archive->execute( $type, "decompress" );
|
||||
}
|
||||
|
||||
if( $response === true ) {
|
||||
|
||||
$response = array(
|
||||
"status" => "success",
|
||||
"message" => null,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
$response = $supported;
|
||||
|
@ -257,11 +271,17 @@ class Archive {
|
|||
|
||||
function zip_d( $path, $output ) {
|
||||
|
||||
if( ! is_dir( $output ) ) {
|
||||
|
||||
mkdir( $output );
|
||||
}
|
||||
|
||||
$status = false;
|
||||
$output = rtrim( $output, '/' ) . '/';
|
||||
$archive = new ZipArchive();
|
||||
$open = $archive->open( $path );
|
||||
|
||||
if ( $archive->open( $path ) === true ) {
|
||||
if ( $open === true ) {
|
||||
|
||||
$archive->extractTo( $output );
|
||||
$archive->close();
|
||||
|
|
|
@ -53,7 +53,7 @@ class Filemanager extends Common {
|
|||
* trying to rename or delete it, allow the actual file name.
|
||||
*/
|
||||
|
||||
$invalid_characters = preg_match( '/[^A-Za-z0-9\-\._@\/\ ]/', $path );
|
||||
$invalid_characters = preg_match( '/[^A-Za-z0-9\-\._@\/\(\) ]/', $path );
|
||||
|
||||
if( $invalid_characters && ! ( $_GET['action'] == "modify" || $_GET['action'] == "delete" ) ) {
|
||||
|
||||
|
@ -61,7 +61,7 @@ class Filemanager extends Common {
|
|||
} elseif( $invalid_characters && ( $_GET['action'] == "modify" || $_GET['action'] == "delete" ) ) {
|
||||
} else {
|
||||
|
||||
$path = preg_replace( '/[^A-Za-z0-9\-\._\/\ ]/', '', $path );
|
||||
$path = preg_replace( '/[^A-Za-z0-9\-\._@\/\(\) ]/', '', $path );
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
@ -315,63 +315,12 @@ class Filemanager extends Common {
|
|||
|
||||
$index = array();
|
||||
|
||||
if( is_dir( $path ) && $handle = opendir( $path ) ) {
|
||||
if( is_dir( $path ) ) {
|
||||
|
||||
while( false !== ( $object = readdir( $handle ) ) ) {
|
||||
|
||||
if( $object != "." && $object != ".." && $object != "" ) {
|
||||
|
||||
$full_path = $path . '/' . $object;
|
||||
|
||||
if( is_link( $full_path ) ) {
|
||||
|
||||
$full_path = readlink( $full_path );
|
||||
}
|
||||
|
||||
if ( is_dir( $full_path ) ) {
|
||||
|
||||
$type = "directory";
|
||||
$size = count( glob( $path . '/' . $object . '/*' ) );
|
||||
} else {
|
||||
|
||||
$type = "file";
|
||||
$size = @filesize( $path . '/' . $object );
|
||||
}
|
||||
$index[] = array(
|
||||
|
||||
"name" => $relative_path . $object,
|
||||
"type" => $type,
|
||||
"size" => $size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$folders = array();
|
||||
$files = array();
|
||||
foreach( $index as $item => $data ) {
|
||||
|
||||
if ( $data['type'] == 'directory' ) {
|
||||
|
||||
$folders[] = array( "name" => htmlentities( $data['name'], ENT_QUOTES ), "type" => $data['type'], "size" => $data['size'] );
|
||||
}
|
||||
if ( $data['type'] == 'file' ) {
|
||||
|
||||
$files[] = array( "name" => htmlentities( $data['name'], ENT_QUOTES ), "type" => $data['type'], "size" => $data['size'] );
|
||||
}
|
||||
}
|
||||
|
||||
function sorter( $a, $b, $key = 'name' ) {
|
||||
|
||||
return strnatcmp( $a[$key], $b[$key] );
|
||||
}
|
||||
|
||||
usort( $folders, "sorter" );
|
||||
usort( $files, "sorter" );
|
||||
|
||||
$output = array_merge( $folders, $files );
|
||||
$files = $this->index_path( $path );
|
||||
|
||||
$response["status"] = "success";
|
||||
$response["data"] = array( "index" => $output );
|
||||
$response["data"] = array( "index" => $files );
|
||||
} else {
|
||||
|
||||
$response["status"] = "error";
|
||||
|
@ -385,6 +334,52 @@ class Filemanager extends Common {
|
|||
return $response;
|
||||
}
|
||||
|
||||
function index_path( $path ) {
|
||||
|
||||
$paths = array();
|
||||
|
||||
if( is_dir( $path ) && $handle = opendir( $path ) ) {
|
||||
|
||||
while( false !== ( $f = readdir( $handle ) ) ) {
|
||||
|
||||
if ( "$f" != '.' && "$f" != '..' ) {
|
||||
|
||||
$p = "$path" . DIRECTORY_SEPARATOR . "$f";
|
||||
$p = str_replace( "//", "/", $p );
|
||||
$rp = realpath( $p );
|
||||
$path_info = pathinfo( $p );
|
||||
|
||||
if( is_dir( $p ) ) {
|
||||
|
||||
$paths[] = array(
|
||||
|
||||
"basename" => $path_info["basename"],
|
||||
"children" => $this->index_path( $p ),
|
||||
"dirname" => str_replace( WORKSPACE . "/", "", $p ),
|
||||
"extension" => null,
|
||||
"filename" => $path_info["filename"],
|
||||
"full_dirname" => $path_info["dirname"],
|
||||
"full_path" => $p,
|
||||
"path" => str_replace( WORKSPACE . "/", "", $p ),
|
||||
);
|
||||
} else {
|
||||
|
||||
$paths[] = array(
|
||||
"basename" => $path_info["basename"],
|
||||
"dirname" => str_replace( WORKSPACE . "/", "", $p ),
|
||||
"extension" => isset( $path_info["extension"] ) ? $path_info["extension"] : null,
|
||||
"filename" => $path_info["filename"],
|
||||
"path" => str_replace( WORKSPACE . "/", "", $p ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir( $handle );
|
||||
return $paths;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// MODIFY (Modifies a file name/contents or directory name)
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
"applies-to" : "directory-only non-root",
|
||||
"onclick": "codiad.filemanager.archive( $('#context-menu').attr('data-path') );"
|
||||
},
|
||||
{
|
||||
"title": "Unarchive",
|
||||
"icon": "icon-archive",
|
||||
"applies-to" : "file-only non-root",
|
||||
"onclick": "codiad.filemanager.unarchive( $('#context-menu').attr('data-path') );"
|
||||
},
|
||||
{
|
||||
"title": "Break",
|
||||
"icon": null,
|
||||
|
|
|
@ -258,6 +258,33 @@ switch( $action ) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'unarchive':
|
||||
|
||||
if( ! isset( $path ) ) {
|
||||
|
||||
exit( formatJSEND( "error", "No path specified." ) );
|
||||
}
|
||||
|
||||
if( ! Permissions::check_access( "create", $access ) ) {
|
||||
|
||||
exit( formatJSEND( "error", "Invalid access to unzip archive." ) );
|
||||
}
|
||||
|
||||
$Archive = new Archive();
|
||||
$path = $Filemanager->formatPath( $path );
|
||||
$result = $Archive->decompress( $path );
|
||||
|
||||
if( $result && $result["status"] == "success" ) {
|
||||
|
||||
$response = formatJSEND( "success", $result );
|
||||
} else {
|
||||
|
||||
$response = formatJSEND( "error", $result["message"] );
|
||||
}
|
||||
|
||||
exit( $response );
|
||||
break;
|
||||
|
||||
case 'upload':
|
||||
|
||||
$response = $Filemanager->upload( $path );
|
||||
|
|
|
@ -184,6 +184,22 @@
|
|||
});
|
||||
},
|
||||
|
||||
unarchive: function( path ) {
|
||||
|
||||
let _this = this;
|
||||
|
||||
$.get( _this.controller + '?action=unarchive&path=' + encodeURIComponent( path ), function( data ) {
|
||||
|
||||
console.log( data );
|
||||
let response = codiad.jsend.parse( data );
|
||||
console.log( response );
|
||||
/*parent = path.split( '/' );
|
||||
parent.pop();
|
||||
_this.rescan( parent.join( '/' ) );
|
||||
*/
|
||||
});
|
||||
},
|
||||
|
||||
contextCheckMouse: function( e ) {
|
||||
|
||||
let offset = $( '#context-menu' ).offset();
|
||||
|
@ -429,7 +445,7 @@
|
|||
// Loop out all files and folders in directory path
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
indexFiles: [],
|
||||
opened_folders: [],
|
||||
|
||||
index: function( path, rescan ) {
|
||||
|
||||
|
@ -452,35 +468,41 @@
|
|||
});
|
||||
}
|
||||
|
||||
if( node.hasClass( 'open' ) && ! rescan ) {
|
||||
let open = node.hasClass( 'open' );
|
||||
|
||||
if( open ) {
|
||||
|
||||
_this.opened_folders.push( path );
|
||||
}
|
||||
|
||||
if( open && ! rescan ) {
|
||||
|
||||
node.parent( 'li' )
|
||||
.children( 'ul' )
|
||||
.slideUp( 300, function() {
|
||||
$( this )
|
||||
.remove();
|
||||
node.removeClass( 'open' );
|
||||
});
|
||||
.children( 'ul' )
|
||||
.slideUp( 300, function() {
|
||||
$( this )
|
||||
.remove();
|
||||
node.removeClass( 'open' );
|
||||
});
|
||||
} else {
|
||||
|
||||
node.addClass( 'loading' );
|
||||
$.get( this.controller + '?action=index&path=' + encodeURIComponent( path ), function( data ) {
|
||||
|
||||
node.addClass( 'open' );
|
||||
let response = codiad.jsend.parse( data );
|
||||
let response = codiad.jsend.parse( data );
|
||||
console.log( response );
|
||||
|
||||
if( response != 'error' ) {
|
||||
|
||||
/* Notify listener */
|
||||
_this.indexFiles = response.index;
|
||||
files = response.index;
|
||||
amplify.publish( "filemanager.onIndex", {
|
||||
path: path,
|
||||
files: _this.indexFiles
|
||||
});
|
||||
|
||||
let files = _this.indexFiles;
|
||||
|
||||
if( files.length > 0 ) {
|
||||
if( Object.keys( files ).length > 0 ) {
|
||||
|
||||
let expanded = parentNode.children( 'span' ).hasClass( 'plus' );
|
||||
|
||||
|
@ -495,70 +517,11 @@
|
|||
if( rescan ) {
|
||||
|
||||
display = '';
|
||||
}
|
||||
|
||||
container.css( "display", display );
|
||||
|
||||
$.each( files, function( index ) {
|
||||
|
||||
let ext = '';
|
||||
let name = files[index].name.replace( path, '' );
|
||||
let nodeClass = 'none';
|
||||
let entry = $( "<li></li>" );
|
||||
let span = $( "<span></span>" );
|
||||
let link = $( "<a></a>" );
|
||||
|
||||
entry.draggable({
|
||||
|
||||
opacity: 0.85,
|
||||
revert: true,
|
||||
start: _this.object_start,
|
||||
stop: _this.object_stop,
|
||||
zIndex: 100
|
||||
});
|
||||
name = name.split( '/' ).join( ' ' );
|
||||
|
||||
if( files[index].type == 'file' ) {
|
||||
|
||||
ext = 'ext-' + name.split( '.' ).pop();
|
||||
} else {
|
||||
|
||||
link.droppable({
|
||||
accept: _this.object_accept,
|
||||
drop: _this.object_drop,
|
||||
over: _this.object_over,
|
||||
out: _this.object_out
|
||||
});
|
||||
}
|
||||
|
||||
if( files[index].type == 'directory' && files[index].size > 0 ) {
|
||||
|
||||
if( expanded ) {
|
||||
|
||||
nodeClass = 'minus';
|
||||
} else {
|
||||
|
||||
nodeClass = 'plus';
|
||||
}
|
||||
}
|
||||
|
||||
span.addClass( nodeClass );
|
||||
|
||||
link.addClass( files[index].type );
|
||||
link.addClass( ext );
|
||||
link.attr( "data-type", files[index].type );
|
||||
link.attr( "data-path", files[index].name );
|
||||
link.text( name );
|
||||
|
||||
entry.append( span, link );
|
||||
container.append( entry );
|
||||
});
|
||||
|
||||
if( rescan ) {
|
||||
|
||||
node.parent( 'li' ).children( 'ul' ).remove();
|
||||
}
|
||||
|
||||
container.css( "display", display );
|
||||
_this.createIndexes( files, container );
|
||||
$( container ).insertAfter( node );
|
||||
|
||||
if( ! rescan ) {
|
||||
|
@ -567,21 +530,75 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
node.removeClass( 'loading' );
|
||||
|
||||
if( rescan && _this.rescanChildren.length > _this.rescanCounter ) {
|
||||
|
||||
_this.rescan( _this.rescanChildren[_this.rescanCounter++] );
|
||||
} else {
|
||||
|
||||
_this.rescanChildren = [];
|
||||
_this.rescanCounter = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
createIndexes: function( files, container = null ) {
|
||||
|
||||
let _this = this;
|
||||
|
||||
$.each( files, function( key, value ) {
|
||||
|
||||
console.log( key, value );
|
||||
|
||||
let expanded = _this.opened_folders.includes( value.path );
|
||||
let ext = '';
|
||||
let name = '';
|
||||
let nodeClass = 'none';
|
||||
let entry = $( "<li></li>" );
|
||||
let span = $( "<span></span>" );
|
||||
let link = $( "<a></a>" );
|
||||
let type = null;
|
||||
|
||||
entry.draggable({
|
||||
|
||||
opacity: 0.85,
|
||||
revert: true,
|
||||
start: _this.object_start,
|
||||
stop: _this.object_stop,
|
||||
zIndex: 100
|
||||
});
|
||||
|
||||
if( value.children == undefined ) {
|
||||
|
||||
ext = "ext-" + value.extension;
|
||||
name = value.basename;
|
||||
type = 'file';
|
||||
link.addClass( ext );
|
||||
} else {
|
||||
|
||||
link.droppable({
|
||||
accept: _this.object_accept,
|
||||
drop: _this.object_drop,
|
||||
over: _this.object_over,
|
||||
out: _this.object_out
|
||||
});
|
||||
|
||||
if( expanded ) {
|
||||
|
||||
nodeClass = 'minus';
|
||||
} else {
|
||||
|
||||
nodeClass = 'plus';
|
||||
}
|
||||
|
||||
name = value.basename;
|
||||
type = 'directory';
|
||||
}
|
||||
|
||||
span.addClass( nodeClass );
|
||||
link.addClass( type );
|
||||
link.attr( "data-type", type );
|
||||
link.attr( "data-path", value.path );
|
||||
link.text( name );
|
||||
|
||||
entry.append( span, link );
|
||||
container.append( entry );
|
||||
});
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Listen for dbclick events on nodes
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue