mirror of
https://github.com/xevidos/codiad.git
synced 2024-11-14 07:41: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" ) {
|
public static function decompress( $file, $output = "default" ) {
|
||||||
|
|
||||||
$type = filetype( $file );
|
|
||||||
$response = array();
|
$response = array();
|
||||||
|
$path_info = pathinfo( $file );
|
||||||
|
$type = isset( $path_info["extension"] ) ? $path_info["extension"] : null;
|
||||||
$supported = self::supports( $type );
|
$supported = self::supports( $type );
|
||||||
$archive = self::get_instance();
|
$archive = self::get_instance();
|
||||||
|
|
||||||
|
if( $output == "default" ) {
|
||||||
|
|
||||||
|
$output = $path_info["dirname"] . "/" . $path_info["filename"];
|
||||||
|
}
|
||||||
|
|
||||||
if( $supported["status"] === "success" ) {
|
if( $supported["status"] === "success" ) {
|
||||||
|
|
||||||
if( extension_loaded( self::EXTENSIONS["{$type}"] ) ) {
|
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 {
|
} else {
|
||||||
|
|
||||||
$response = $archive->execute( $type, "decompress" );
|
$response = $archive->execute( $type, "decompress" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( $response === true ) {
|
||||||
|
|
||||||
|
$response = array(
|
||||||
|
"status" => "success",
|
||||||
|
"message" => null,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$response = $supported;
|
$response = $supported;
|
||||||
|
@ -257,11 +271,17 @@ class Archive {
|
||||||
|
|
||||||
function zip_d( $path, $output ) {
|
function zip_d( $path, $output ) {
|
||||||
|
|
||||||
|
if( ! is_dir( $output ) ) {
|
||||||
|
|
||||||
|
mkdir( $output );
|
||||||
|
}
|
||||||
|
|
||||||
$status = false;
|
$status = false;
|
||||||
$output = rtrim( $output, '/' ) . '/';
|
$output = rtrim( $output, '/' ) . '/';
|
||||||
$archive = new ZipArchive();
|
$archive = new ZipArchive();
|
||||||
|
$open = $archive->open( $path );
|
||||||
|
|
||||||
if ( $archive->open( $path ) === true ) {
|
if ( $open === true ) {
|
||||||
|
|
||||||
$archive->extractTo( $output );
|
$archive->extractTo( $output );
|
||||||
$archive->close();
|
$archive->close();
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Filemanager extends Common {
|
||||||
* trying to rename or delete it, allow the actual file name.
|
* 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" ) ) {
|
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" ) ) {
|
} elseif( $invalid_characters && ( $_GET['action'] == "modify" || $_GET['action'] == "delete" ) ) {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$path = preg_replace( '/[^A-Za-z0-9\-\._\/\ ]/', '', $path );
|
$path = preg_replace( '/[^A-Za-z0-9\-\._@\/\(\) ]/', '', $path );
|
||||||
}
|
}
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
@ -315,63 +315,12 @@ class Filemanager extends Common {
|
||||||
|
|
||||||
$index = array();
|
$index = array();
|
||||||
|
|
||||||
if( is_dir( $path ) && $handle = opendir( $path ) ) {
|
if( is_dir( $path ) ) {
|
||||||
|
|
||||||
while( false !== ( $object = readdir( $handle ) ) ) {
|
$files = $this->index_path( $path );
|
||||||
|
|
||||||
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 );
|
|
||||||
|
|
||||||
$response["status"] = "success";
|
$response["status"] = "success";
|
||||||
$response["data"] = array( "index" => $output );
|
$response["data"] = array( "index" => $files );
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$response["status"] = "error";
|
$response["status"] = "error";
|
||||||
|
@ -385,6 +334,52 @@ class Filemanager extends Common {
|
||||||
return $response;
|
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)
|
// MODIFY (Modifies a file name/contents or directory name)
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
"applies-to" : "directory-only non-root",
|
"applies-to" : "directory-only non-root",
|
||||||
"onclick": "codiad.filemanager.archive( $('#context-menu').attr('data-path') );"
|
"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",
|
"title": "Break",
|
||||||
"icon": null,
|
"icon": null,
|
||||||
|
|
|
@ -258,6 +258,33 @@ switch( $action ) {
|
||||||
}
|
}
|
||||||
break;
|
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':
|
case 'upload':
|
||||||
|
|
||||||
$response = $Filemanager->upload( $path );
|
$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 ) {
|
contextCheckMouse: function( e ) {
|
||||||
|
|
||||||
let offset = $( '#context-menu' ).offset();
|
let offset = $( '#context-menu' ).offset();
|
||||||
|
@ -429,7 +445,7 @@
|
||||||
// Loop out all files and folders in directory path
|
// Loop out all files and folders in directory path
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
indexFiles: [],
|
opened_folders: [],
|
||||||
|
|
||||||
index: function( path, rescan ) {
|
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' )
|
node.parent( 'li' )
|
||||||
.children( 'ul' )
|
.children( 'ul' )
|
||||||
.slideUp( 300, function() {
|
.slideUp( 300, function() {
|
||||||
$( this )
|
$( this )
|
||||||
.remove();
|
.remove();
|
||||||
node.removeClass( 'open' );
|
node.removeClass( 'open' );
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
node.addClass( 'loading' );
|
node.addClass( 'loading' );
|
||||||
$.get( this.controller + '?action=index&path=' + encodeURIComponent( path ), function( data ) {
|
$.get( this.controller + '?action=index&path=' + encodeURIComponent( path ), function( data ) {
|
||||||
|
|
||||||
node.addClass( 'open' );
|
node.addClass( 'open' );
|
||||||
let response = codiad.jsend.parse( data );
|
let response = codiad.jsend.parse( data );
|
||||||
|
console.log( response );
|
||||||
|
|
||||||
if( response != 'error' ) {
|
if( response != 'error' ) {
|
||||||
|
|
||||||
/* Notify listener */
|
/* Notify listener */
|
||||||
_this.indexFiles = response.index;
|
files = response.index;
|
||||||
amplify.publish( "filemanager.onIndex", {
|
amplify.publish( "filemanager.onIndex", {
|
||||||
path: path,
|
path: path,
|
||||||
files: _this.indexFiles
|
files: _this.indexFiles
|
||||||
});
|
});
|
||||||
|
|
||||||
let files = _this.indexFiles;
|
if( Object.keys( files ).length > 0 ) {
|
||||||
|
|
||||||
if( files.length > 0 ) {
|
|
||||||
|
|
||||||
let expanded = parentNode.children( 'span' ).hasClass( 'plus' );
|
let expanded = parentNode.children( 'span' ).hasClass( 'plus' );
|
||||||
|
|
||||||
|
@ -495,70 +517,11 @@
|
||||||
if( rescan ) {
|
if( rescan ) {
|
||||||
|
|
||||||
display = '';
|
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();
|
node.parent( 'li' ).children( 'ul' ).remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
container.css( "display", display );
|
||||||
|
_this.createIndexes( files, container );
|
||||||
$( container ).insertAfter( node );
|
$( container ).insertAfter( node );
|
||||||
|
|
||||||
if( ! rescan ) {
|
if( ! rescan ) {
|
||||||
|
@ -567,21 +530,75 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node.removeClass( 'loading' );
|
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
|
// Listen for dbclick events on nodes
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in a new issue