From e720bce160ba1bae73ccd5c8de76e307025867b3 Mon Sep 17 00:00:00 2001 From: Marco Dickert Date: Fri, 28 Jul 2017 15:36:33 +0200 Subject: [PATCH 1/3] added server-side search function --- build/libifm.php | 120 +++++++++++++++++++++++++++------------------ ifm.php | 120 +++++++++++++++++++++++++++------------------ src/main.php | 124 +++++++++++++++++++++++++++++------------------ 3 files changed, 226 insertions(+), 138 deletions(-) diff --git a/build/libifm.php b/build/libifm.php index 26010dd..8aafba3 100644 --- a/build/libifm.php +++ b/build/libifm.php @@ -2206,6 +2206,7 @@ function IFM( params ) { case "zipnload": $this->zipnload( $_REQUEST); break; case "remoteUpload": $this->remoteUpload( $_REQUEST ); break; case "multidelete": $this->deleteMultipleFiles( $_REQUEST ); break; + case "searchItems": $this->searchItems( $_REQUEST ); break; case "getFolderTree": $this->getFolderTree( $_REQUEST ); break; default: echo json_encode( array( "status" => "ERROR", "message" => "Invalid api action given" ) ); @@ -2253,52 +2254,8 @@ function IFM( params ) { elseif( $result == "." ) {} elseif( $result != ".." && substr( $result, 0, 1 ) == "." && $this->config['showhiddenfiles'] != 1 ) {} else { - $item = array(); - $item["name"] = $result; - if( is_dir( $result ) ) { - $item["type"] = "dir"; - if( $result == ".." ) - $item["icon"] = "icon icon-up-open"; - else - $item["icon"] = "icon icon-folder-empty"; - } else { - $item["type"] = "file"; - if( in_array( substr( $result, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) - $type = substr( $result, -6 ); - elseif( substr( $result, -8 ) == ".tar.bz2" ) - $type = "tar.bz2"; - else - $type = substr( strrchr( $result, "." ), 1 ); - $item["icon"] = $this->getTypeIcon( $type ); - $item["ext"] = strtolower($type); - } - if( $this->config['showlastmodified'] == 1 ) { $item["lastmodified"] = date( "d.m.Y, G:i e", filemtime( $result ) ); } - if( $this->config['showfilesize'] == 1 ) { - $item["size"] = filesize( $result ); - if( $item["size"] > 1073741824 ) $item["size"] = round( ( $item["size"]/1073741824 ), 2 ) . " GB"; - elseif($item["size"]>1048576)$item["size"] = round( ( $item["size"]/1048576 ), 2 ) . " MB"; - elseif($item["size"]>1024)$item["size"] = round( ( $item["size"]/1024 ), 2 ) . " KB"; - else $item["size"] = $item["size"] . " Byte"; - } - if( $this->config['showpermissions'] > 0 ) { - if( $this->config['showpermissions'] == 1 ) $item["fileperms"] = substr( decoct( fileperms( $result ) ), -3 ); - elseif( $this->config['showpermissions'] == 2 ) $item["fileperms"] = $this->filePermsDecode( fileperms( $result ) ); - if( $item["fileperms"] == "" ) $item["fileperms"] = " "; - $item["filepermmode"] = ( $this->config['showpermissions'] == 1 ) ? "short" : "long"; - } - if( $this->config['showowner'] == 1 ) { - if ( function_exists( "posix_getpwuid" ) && fileowner($result) !== false ) { - $ownerarr = posix_getpwuid( fileowner( $result ) ); - $item["owner"] = $ownerarr['name']; - } else $item["owner"] = false; - } - if( $this->config['showgroup'] == 1 ) { - if( function_exists( "posix_getgrgid" ) && filegroup( $result ) !== false ) { - $grouparr = posix_getgrgid( filegroup( $result ) ); - $item["group"] = $grouparr['name']; - } else $item["group"] = false; - } - if( is_dir( $result ) ) $dirs[] = $item; + $item = $this->getItemInformation( $result ); + if( $item['type'] == "dir" ) $dirs[] = $item; else $files[] = $item; } } @@ -2309,6 +2266,55 @@ function IFM( params ) { echo json_encode( array_merge( $dirs, $files ) ); } + private function getItemInformation( $name ) { + $item = array(); + $item["name"] = $name; + if( is_dir( $name ) ) { + $item["type"] = "dir"; + if( $name == ".." ) + $item["icon"] = "icon icon-up-open"; + else + $item["icon"] = "icon icon-folder-empty"; + } else { + $item["type"] = "file"; + if( in_array( substr( $name, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) + $type = substr( $name, -6 ); + elseif( substr( $name, -8 ) == ".tar.bz2" ) + $type = "tar.bz2"; + else + $type = substr( strrchr( $name, "." ), 1 ); + $item["icon"] = $this->getTypeIcon( $type ); + $item["ext"] = strtolower($type); + } + if( $this->config['showlastmodified'] == 1 ) { $item["lastmodified"] = date( "d.m.Y, G:i e", filemtime( $name ) ); } + if( $this->config['showfilesize'] == 1 ) { + $item["size"] = filesize( $name ); + if( $item["size"] > 1073741824 ) $item["size"] = round( ( $item["size"]/1073741824 ), 2 ) . " GB"; + elseif($item["size"]>1048576)$item["size"] = round( ( $item["size"]/1048576 ), 2 ) . " MB"; + elseif($item["size"]>1024)$item["size"] = round( ( $item["size"]/1024 ), 2 ) . " KB"; + else $item["size"] = $item["size"] . " Byte"; + } + if( $this->config['showpermissions'] > 0 ) { + if( $this->config['showpermissions'] == 1 ) $item["fileperms"] = substr( decoct( fileperms( $name ) ), -3 ); + elseif( $this->config['showpermissions'] == 2 ) $item["fileperms"] = $this->filePermsDecode( fileperms( $name ) ); + if( $item["fileperms"] == "" ) $item["fileperms"] = " "; + $item["filepermmode"] = ( $this->config['showpermissions'] == 1 ) ? "short" : "long"; + } + if( $this->config['showowner'] == 1 ) { + if ( function_exists( "posix_getpwuid" ) && fileowner($name) !== false ) { + $ownerarr = posix_getpwuid( fileowner( $name ) ); + $item["owner"] = $ownerarr['name']; + } else $item["owner"] = false; + } + if( $this->config['showgroup'] == 1 ) { + if( function_exists( "posix_getgrgid" ) && filegroup( $name ) !== false ) { + $grouparr = posix_getgrgid( filegroup( $name ) ); + $item["group"] = $grouparr['name']; + } else $item["group"] = false; + } + return $item; + } + private function getConfig() { $ret = $this->config; $ret['inline'] = ( $this->mode == "inline" ) ? true : false; @@ -2345,6 +2351,28 @@ function IFM( params ) { } } + private function searchItems( $d ) { + $this->chDirIfNecessary( $d['dir'] ); + try { + $results = $this->searchItemsRecursive( $d['pattern'] ); + echo json_encode( $results ); + } catch( Exception $e ) { + echo json_encode( array( "status" => "ERROR", "message" => $e->getMessage() ) ); + } + } + + private function searchItemsRecursive( $pattern, $dir="" ) { + $items = array(); + $dir = $dir ? $dir : '.'; + foreach( glob( $this->pathCombine( $dir, $pattern ) ) as $result ) { + array_push( $items, $this->getItemInformation( $result ) ); + } + foreach( glob( $this->pathCombine( $dir, '*') , GLOB_ONLYDIR ) as $subdir ) { + $items = array_merge( $items, $this->searchItemsRecursive( $pattern, $subdir ) ); + } + return $items; + } + private function getFolderTree( $d ) { echo json_encode( array_merge( diff --git a/ifm.php b/ifm.php index fac3357..6d390d2 100644 --- a/ifm.php +++ b/ifm.php @@ -2206,6 +2206,7 @@ function IFM( params ) { case "zipnload": $this->zipnload( $_REQUEST); break; case "remoteUpload": $this->remoteUpload( $_REQUEST ); break; case "multidelete": $this->deleteMultipleFiles( $_REQUEST ); break; + case "searchItems": $this->searchItems( $_REQUEST ); break; case "getFolderTree": $this->getFolderTree( $_REQUEST ); break; default: echo json_encode( array( "status" => "ERROR", "message" => "Invalid api action given" ) ); @@ -2253,52 +2254,8 @@ function IFM( params ) { elseif( $result == "." ) {} elseif( $result != ".." && substr( $result, 0, 1 ) == "." && $this->config['showhiddenfiles'] != 1 ) {} else { - $item = array(); - $item["name"] = $result; - if( is_dir( $result ) ) { - $item["type"] = "dir"; - if( $result == ".." ) - $item["icon"] = "icon icon-up-open"; - else - $item["icon"] = "icon icon-folder-empty"; - } else { - $item["type"] = "file"; - if( in_array( substr( $result, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) - $type = substr( $result, -6 ); - elseif( substr( $result, -8 ) == ".tar.bz2" ) - $type = "tar.bz2"; - else - $type = substr( strrchr( $result, "." ), 1 ); - $item["icon"] = $this->getTypeIcon( $type ); - $item["ext"] = strtolower($type); - } - if( $this->config['showlastmodified'] == 1 ) { $item["lastmodified"] = date( "d.m.Y, G:i e", filemtime( $result ) ); } - if( $this->config['showfilesize'] == 1 ) { - $item["size"] = filesize( $result ); - if( $item["size"] > 1073741824 ) $item["size"] = round( ( $item["size"]/1073741824 ), 2 ) . " GB"; - elseif($item["size"]>1048576)$item["size"] = round( ( $item["size"]/1048576 ), 2 ) . " MB"; - elseif($item["size"]>1024)$item["size"] = round( ( $item["size"]/1024 ), 2 ) . " KB"; - else $item["size"] = $item["size"] . " Byte"; - } - if( $this->config['showpermissions'] > 0 ) { - if( $this->config['showpermissions'] == 1 ) $item["fileperms"] = substr( decoct( fileperms( $result ) ), -3 ); - elseif( $this->config['showpermissions'] == 2 ) $item["fileperms"] = $this->filePermsDecode( fileperms( $result ) ); - if( $item["fileperms"] == "" ) $item["fileperms"] = " "; - $item["filepermmode"] = ( $this->config['showpermissions'] == 1 ) ? "short" : "long"; - } - if( $this->config['showowner'] == 1 ) { - if ( function_exists( "posix_getpwuid" ) && fileowner($result) !== false ) { - $ownerarr = posix_getpwuid( fileowner( $result ) ); - $item["owner"] = $ownerarr['name']; - } else $item["owner"] = false; - } - if( $this->config['showgroup'] == 1 ) { - if( function_exists( "posix_getgrgid" ) && filegroup( $result ) !== false ) { - $grouparr = posix_getgrgid( filegroup( $result ) ); - $item["group"] = $grouparr['name']; - } else $item["group"] = false; - } - if( is_dir( $result ) ) $dirs[] = $item; + $item = $this->getItemInformation( $result ); + if( $item['type'] == "dir" ) $dirs[] = $item; else $files[] = $item; } } @@ -2309,6 +2266,55 @@ function IFM( params ) { echo json_encode( array_merge( $dirs, $files ) ); } + private function getItemInformation( $name ) { + $item = array(); + $item["name"] = $name; + if( is_dir( $name ) ) { + $item["type"] = "dir"; + if( $name == ".." ) + $item["icon"] = "icon icon-up-open"; + else + $item["icon"] = "icon icon-folder-empty"; + } else { + $item["type"] = "file"; + if( in_array( substr( $name, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) + $type = substr( $name, -6 ); + elseif( substr( $name, -8 ) == ".tar.bz2" ) + $type = "tar.bz2"; + else + $type = substr( strrchr( $name, "." ), 1 ); + $item["icon"] = $this->getTypeIcon( $type ); + $item["ext"] = strtolower($type); + } + if( $this->config['showlastmodified'] == 1 ) { $item["lastmodified"] = date( "d.m.Y, G:i e", filemtime( $name ) ); } + if( $this->config['showfilesize'] == 1 ) { + $item["size"] = filesize( $name ); + if( $item["size"] > 1073741824 ) $item["size"] = round( ( $item["size"]/1073741824 ), 2 ) . " GB"; + elseif($item["size"]>1048576)$item["size"] = round( ( $item["size"]/1048576 ), 2 ) . " MB"; + elseif($item["size"]>1024)$item["size"] = round( ( $item["size"]/1024 ), 2 ) . " KB"; + else $item["size"] = $item["size"] . " Byte"; + } + if( $this->config['showpermissions'] > 0 ) { + if( $this->config['showpermissions'] == 1 ) $item["fileperms"] = substr( decoct( fileperms( $name ) ), -3 ); + elseif( $this->config['showpermissions'] == 2 ) $item["fileperms"] = $this->filePermsDecode( fileperms( $name ) ); + if( $item["fileperms"] == "" ) $item["fileperms"] = " "; + $item["filepermmode"] = ( $this->config['showpermissions'] == 1 ) ? "short" : "long"; + } + if( $this->config['showowner'] == 1 ) { + if ( function_exists( "posix_getpwuid" ) && fileowner($name) !== false ) { + $ownerarr = posix_getpwuid( fileowner( $name ) ); + $item["owner"] = $ownerarr['name']; + } else $item["owner"] = false; + } + if( $this->config['showgroup'] == 1 ) { + if( function_exists( "posix_getgrgid" ) && filegroup( $name ) !== false ) { + $grouparr = posix_getgrgid( filegroup( $name ) ); + $item["group"] = $grouparr['name']; + } else $item["group"] = false; + } + return $item; + } + private function getConfig() { $ret = $this->config; $ret['inline'] = ( $this->mode == "inline" ) ? true : false; @@ -2345,6 +2351,28 @@ function IFM( params ) { } } + private function searchItems( $d ) { + $this->chDirIfNecessary( $d['dir'] ); + try { + $results = $this->searchItemsRecursive( $d['pattern'] ); + echo json_encode( $results ); + } catch( Exception $e ) { + echo json_encode( array( "status" => "ERROR", "message" => $e->getMessage() ) ); + } + } + + private function searchItemsRecursive( $pattern, $dir="" ) { + $items = array(); + $dir = $dir ? $dir : '.'; + foreach( glob( $this->pathCombine( $dir, $pattern ) ) as $result ) { + array_push( $items, $this->getItemInformation( $result ) ); + } + foreach( glob( $this->pathCombine( $dir, '*') , GLOB_ONLYDIR ) as $subdir ) { + $items = array_merge( $items, $this->searchItemsRecursive( $pattern, $subdir ) ); + } + return $items; + } + private function getFolderTree( $d ) { echo json_encode( array_merge( diff --git a/src/main.php b/src/main.php index 68e2f32..58b3c99 100644 --- a/src/main.php +++ b/src/main.php @@ -243,6 +243,7 @@ f00bar; case "zipnload": $this->zipnload( $_REQUEST); break; case "remoteUpload": $this->remoteUpload( $_REQUEST ); break; case "multidelete": $this->deleteMultipleFiles( $_REQUEST ); break; + case "searchItems": $this->searchItems( $_REQUEST ); break; case "getFolderTree": $this->getFolderTree( $_REQUEST ); break; default: echo json_encode( array( "status" => "ERROR", "message" => "Invalid api action given" ) ); @@ -290,52 +291,8 @@ f00bar; elseif( $result == "." ) {} elseif( $result != ".." && substr( $result, 0, 1 ) == "." && $this->config['showhiddenfiles'] != 1 ) {} else { - $item = array(); - $item["name"] = $result; - if( is_dir( $result ) ) { - $item["type"] = "dir"; - if( $result == ".." ) - $item["icon"] = "icon icon-up-open"; - else - $item["icon"] = "icon icon-folder-empty"; - } else { - $item["type"] = "file"; - if( in_array( substr( $result, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) - $type = substr( $result, -6 ); - elseif( substr( $result, -8 ) == ".tar.bz2" ) - $type = "tar.bz2"; - else - $type = substr( strrchr( $result, "." ), 1 ); - $item["icon"] = $this->getTypeIcon( $type ); - $item["ext"] = strtolower($type); - } - if( $this->config['showlastmodified'] == 1 ) { $item["lastmodified"] = date( "d.m.Y, G:i e", filemtime( $result ) ); } - if( $this->config['showfilesize'] == 1 ) { - $item["size"] = filesize( $result ); - if( $item["size"] > 1073741824 ) $item["size"] = round( ( $item["size"]/1073741824 ), 2 ) . " GB"; - elseif($item["size"]>1048576)$item["size"] = round( ( $item["size"]/1048576 ), 2 ) . " MB"; - elseif($item["size"]>1024)$item["size"] = round( ( $item["size"]/1024 ), 2 ) . " KB"; - else $item["size"] = $item["size"] . " Byte"; - } - if( $this->config['showpermissions'] > 0 ) { - if( $this->config['showpermissions'] == 1 ) $item["fileperms"] = substr( decoct( fileperms( $result ) ), -3 ); - elseif( $this->config['showpermissions'] == 2 ) $item["fileperms"] = $this->filePermsDecode( fileperms( $result ) ); - if( $item["fileperms"] == "" ) $item["fileperms"] = " "; - $item["filepermmode"] = ( $this->config['showpermissions'] == 1 ) ? "short" : "long"; - } - if( $this->config['showowner'] == 1 ) { - if ( function_exists( "posix_getpwuid" ) && fileowner($result) !== false ) { - $ownerarr = posix_getpwuid( fileowner( $result ) ); - $item["owner"] = $ownerarr['name']; - } else $item["owner"] = false; - } - if( $this->config['showgroup'] == 1 ) { - if( function_exists( "posix_getgrgid" ) && filegroup( $result ) !== false ) { - $grouparr = posix_getgrgid( filegroup( $result ) ); - $item["group"] = $grouparr['name']; - } else $item["group"] = false; - } - if( is_dir( $result ) ) $dirs[] = $item; + $item = $this->getItemInformation( $result ); + if( $item['type'] == "dir" ) $dirs[] = $item; else $files[] = $item; } } @@ -346,6 +303,55 @@ f00bar; echo json_encode( array_merge( $dirs, $files ) ); } + private function getItemInformation( $name ) { + $item = array(); + $item["name"] = $name; + if( is_dir( $name ) ) { + $item["type"] = "dir"; + if( $name == ".." ) + $item["icon"] = "icon icon-up-open"; + else + $item["icon"] = "icon icon-folder-empty"; + } else { + $item["type"] = "file"; + if( in_array( substr( $name, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) + $type = substr( $name, -6 ); + elseif( substr( $name, -8 ) == ".tar.bz2" ) + $type = "tar.bz2"; + else + $type = substr( strrchr( $name, "." ), 1 ); + $item["icon"] = $this->getTypeIcon( $type ); + $item["ext"] = strtolower($type); + } + if( $this->config['showlastmodified'] == 1 ) { $item["lastmodified"] = date( "d.m.Y, G:i e", filemtime( $name ) ); } + if( $this->config['showfilesize'] == 1 ) { + $item["size"] = filesize( $name ); + if( $item["size"] > 1073741824 ) $item["size"] = round( ( $item["size"]/1073741824 ), 2 ) . " GB"; + elseif($item["size"]>1048576)$item["size"] = round( ( $item["size"]/1048576 ), 2 ) . " MB"; + elseif($item["size"]>1024)$item["size"] = round( ( $item["size"]/1024 ), 2 ) . " KB"; + else $item["size"] = $item["size"] . " Byte"; + } + if( $this->config['showpermissions'] > 0 ) { + if( $this->config['showpermissions'] == 1 ) $item["fileperms"] = substr( decoct( fileperms( $name ) ), -3 ); + elseif( $this->config['showpermissions'] == 2 ) $item["fileperms"] = $this->filePermsDecode( fileperms( $name ) ); + if( $item["fileperms"] == "" ) $item["fileperms"] = " "; + $item["filepermmode"] = ( $this->config['showpermissions'] == 1 ) ? "short" : "long"; + } + if( $this->config['showowner'] == 1 ) { + if ( function_exists( "posix_getpwuid" ) && fileowner($name) !== false ) { + $ownerarr = posix_getpwuid( fileowner( $name ) ); + $item["owner"] = $ownerarr['name']; + } else $item["owner"] = false; + } + if( $this->config['showgroup'] == 1 ) { + if( function_exists( "posix_getgrgid" ) && filegroup( $name ) !== false ) { + $grouparr = posix_getgrgid( filegroup( $name ) ); + $item["group"] = $grouparr['name']; + } else $item["group"] = false; + } + return $item; + } + private function getConfig() { $ret = $this->config; $ret['inline'] = ( $this->mode == "inline" ) ? true : false; @@ -382,6 +388,32 @@ f00bar; } } + 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" ) ); + exit( 1 ); + } + try { + $results = $this->searchItemsRecursive( $d['pattern'] ); + echo json_encode( $results ); + } catch( Exception $e ) { + echo json_encode( array( "status" => "ERROR", "message" => $e->getMessage() ) ); + } + } + + private function searchItemsRecursive( $pattern, $dir="" ) { + $items = array(); + $dir = $dir ? $dir : '.'; + foreach( glob( $this->pathCombine( $dir, $pattern ) ) as $result ) { + array_push( $items, $this->getItemInformation( $result ) ); + } + foreach( glob( $this->pathCombine( $dir, '*') , GLOB_ONLYDIR ) as $subdir ) { + $items = array_merge( $items, $this->searchItemsRecursive( $pattern, $subdir ) ); + } + return $items; + } + private function getFolderTree( $d ) { echo json_encode( array_merge( From 18c48c806bd38b72a4736367f309fcde289bc926 Mon Sep 17 00:00:00 2001 From: Marco Dickert Date: Sun, 30 Jul 2017 05:20:07 +0200 Subject: [PATCH 2/3] added search function to the frontend; fixed some bugs --- build/libifm.php | 148 ++++++++++++++++++++++++- ifm.php | 148 ++++++++++++++++++++++++- src/ifm.js | 56 ++++++++++ src/main.php | 60 +++++++++- src/templates/modal.search.html | 10 ++ src/templates/modal.searchresults.html | 11 ++ 6 files changed, 419 insertions(+), 14 deletions(-) create mode 100644 src/templates/modal.search.html create mode 100644 src/templates/modal.searchresults.html diff --git a/build/libifm.php b/build/libifm.php index 8aafba3..facc4d1 100644 --- a/build/libifm.php +++ b/build/libifm.php @@ -478,6 +478,33 @@ f00bar; +f00bar; + $templates['search'] = <<<'f00bar' +
+ +
+ +f00bar; + $templates['searchresults'] = <<<'f00bar' + +{{#items}} + + + + {{linkname}} ({{folder}}) + + + +{{/items}} + + f00bar; $templates['uploadfile'] = <<<'f00bar'
@@ -786,6 +813,7 @@ function IFM( params ) { this.fileChanged = false; // flag for check if file was changed already this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests this.rootElement = ""; + this.search = {}; /** * Shows a bootstrap modal @@ -840,7 +868,9 @@ function IFM( params ) { dir: self.currentDir }, dataType: "json", - success: self.rebuildFileTable, + success: function( data ) { + self.rebuildFileTable( data ); + }, error: function( response ) { self.showMessage( "General error occured: No or broken response", "e" ); }, complete: function() { self.task_done( id ); } }); @@ -852,6 +882,13 @@ function IFM( params ) { * @param object data - object with items */ this.rebuildFileTable = function( data ) { + if( data.status == "ERROR" ) { + this.showMessage( data.message, "e" ); + return; + } else if ( ! Array.isArray( data ) ) { + this.showMessage( "Invalid data from server", "e" ); + return; + } data.forEach( function( item ) { item.guid = self.generateGuid(); item.linkname = ( item.name == ".." ) ? "[ up ]" : item.name; @@ -1622,6 +1659,50 @@ function IFM( params ) { }); }; + this.showSearchDialog = function() { + self.showModal( Mustache.render( self.templates.search, { lastSearch: self.search.lastSearch } ) ); + $( '#searchResults tbody' ).remove(); + $( '#searchResults' ).append( Mustache.render( self.templates.searchresults, { items: self.search.data } ) ); + $( '#searchPattern' ).on( 'keypress', function( e ) { + if( e.keyCode == 13 ) { + e.preventDefault(); + e.stopPropagation(); + self.search.lastSearch = e.target.value; + $.ajax({ + url: self.api, + type: "POST", + data: { + api: "searchItems", + dir: self.currentDir, + pattern: e.target.value + }, + 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 ); + }); + self.search.data = data; + $('#searchResults').html( Mustache.render( self.templates.searchresults, { items: data } ) ); + } + }); + } + }); + $( document ).on( 'click', 'a.searchitem', function( e ) { + console.log( e ); + e.preventDefault(); + e.stopPropagation(); + self.changeDirectory( e.target.dataset.folder || e.target.parentNode.dataset.folder, { absolute: true } ); + self.hideModal(); + }); + $( document ).on( 'keypress', 'a.searchitem', function( e ) { + console.log( e ); + e.preventDefault(); + if( e.key == "Enter" ) + e.target.click(); + }); + } + // -------------------- // helper functions // -------------------- @@ -1871,6 +1952,10 @@ function IFM( params ) { return; switch( e.key ) { + case '/': + e.preventDefault(); + self.showSearchDialog(); + break; case 'g': e.preventDefault(); $('#currentDir').focus(); @@ -2242,7 +2327,7 @@ function IFM( params ) { */ private function getFiles( $dir ) { - $dir = $this->getValidDir( $dir ); + $this->log( '$dir: '.$dir ); $this->chDirIfNecessary( $dir ); unset( $files ); unset( $dirs ); $files = array(); $dirs = array(); @@ -2263,7 +2348,10 @@ function IFM( params ) { } usort( $dirs, array( $this, "sortByName" ) ); usort( $files, array( $this, "sortByName" ) ); - echo json_encode( array_merge( $dirs, $files ) ); + + $this->log( '$files: '.print_r($files, true ) ); + $this->log( '$dirs: '.print_r($dirs, true ) ); + $this->jsonResponse( array_merge( $dirs, $files ) ); } private function getItemInformation( $name ) { @@ -2353,6 +2441,10 @@ function IFM( params ) { 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" ) ); + exit( 1 ); + } try { $results = $this->searchItemsRecursive( $d['pattern'] ); echo json_encode( $results ); @@ -2788,12 +2880,58 @@ function IFM( params ) { echo json_encode( array( "status" => "error", "message" => "Corrupt parameter data" ) ); } - //apis - /* help functions */ + private function log( $string ) { + file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), $string, FILE_APPEND ); + } + + private function jsonResponse( $array ) { + $this->convertToUTF8( $array ); + $json = json_encode( $array ); + if( $json === false ) { + switch(json_last_error()) { + case JSON_ERROR_NONE: + $err = ' - Keine Fehler'; + break; + case JSON_ERROR_DEPTH: + $err = ' - Maximale Stacktiefe überschritten'; + break; + case JSON_ERROR_STATE_MISMATCH: + $err = ' - Unterlauf oder Nichtübereinstimmung der Modi'; + break; + case JSON_ERROR_CTRL_CHAR: + $err = ' - Unerwartetes Steuerzeichen gefunden'; + break; + case JSON_ERROR_SYNTAX: + $err = ' - Syntaxfehler, ungültiges JSON'; + break; + case JSON_ERROR_UTF8: + $err = ' - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'; + break; + default: + $err = ' - Unbekannter Fehler'; + break; + } + + $this->jsonResponse( array( "status" => "ERROR", "message" => $err ) ); + } else { + echo $json; + } + } + + private function convertToUTF8( &$item ) { + if( is_array( $item ) ) + array_walk( + $item, + array( $this, 'convertToUTF8' ) + ); + else + $item = utf8_encode( $item ); + } + public function checkAuth() { if( $this->config['auth'] == 1 && ( ! isset( $_SESSION['auth'] ) || $_SESSION['auth'] !== true ) ) { $login_failed = false; diff --git a/ifm.php b/ifm.php index 6d390d2..ffeb78f 100644 --- a/ifm.php +++ b/ifm.php @@ -478,6 +478,33 @@ f00bar;
+f00bar; + $templates['search'] = <<<'f00bar' +
+ +
+ +f00bar; + $templates['searchresults'] = <<<'f00bar' + +{{#items}} + + + + {{linkname}} ({{folder}}) + + + +{{/items}} + + f00bar; $templates['uploadfile'] = <<<'f00bar'
@@ -786,6 +813,7 @@ function IFM( params ) { this.fileChanged = false; // flag for check if file was changed already this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests this.rootElement = ""; + this.search = {}; /** * Shows a bootstrap modal @@ -840,7 +868,9 @@ function IFM( params ) { dir: self.currentDir }, dataType: "json", - success: self.rebuildFileTable, + success: function( data ) { + self.rebuildFileTable( data ); + }, error: function( response ) { self.showMessage( "General error occured: No or broken response", "e" ); }, complete: function() { self.task_done( id ); } }); @@ -852,6 +882,13 @@ function IFM( params ) { * @param object data - object with items */ this.rebuildFileTable = function( data ) { + if( data.status == "ERROR" ) { + this.showMessage( data.message, "e" ); + return; + } else if ( ! Array.isArray( data ) ) { + this.showMessage( "Invalid data from server", "e" ); + return; + } data.forEach( function( item ) { item.guid = self.generateGuid(); item.linkname = ( item.name == ".." ) ? "[ up ]" : item.name; @@ -1622,6 +1659,50 @@ function IFM( params ) { }); }; + this.showSearchDialog = function() { + self.showModal( Mustache.render( self.templates.search, { lastSearch: self.search.lastSearch } ) ); + $( '#searchResults tbody' ).remove(); + $( '#searchResults' ).append( Mustache.render( self.templates.searchresults, { items: self.search.data } ) ); + $( '#searchPattern' ).on( 'keypress', function( e ) { + if( e.keyCode == 13 ) { + e.preventDefault(); + e.stopPropagation(); + self.search.lastSearch = e.target.value; + $.ajax({ + url: self.api, + type: "POST", + data: { + api: "searchItems", + dir: self.currentDir, + pattern: e.target.value + }, + 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 ); + }); + self.search.data = data; + $('#searchResults').html( Mustache.render( self.templates.searchresults, { items: data } ) ); + } + }); + } + }); + $( document ).on( 'click', 'a.searchitem', function( e ) { + console.log( e ); + e.preventDefault(); + e.stopPropagation(); + self.changeDirectory( e.target.dataset.folder || e.target.parentNode.dataset.folder, { absolute: true } ); + self.hideModal(); + }); + $( document ).on( 'keypress', 'a.searchitem', function( e ) { + console.log( e ); + e.preventDefault(); + if( e.key == "Enter" ) + e.target.click(); + }); + } + // -------------------- // helper functions // -------------------- @@ -1871,6 +1952,10 @@ function IFM( params ) { return; switch( e.key ) { + case '/': + e.preventDefault(); + self.showSearchDialog(); + break; case 'g': e.preventDefault(); $('#currentDir').focus(); @@ -2242,7 +2327,7 @@ function IFM( params ) { */ private function getFiles( $dir ) { - $dir = $this->getValidDir( $dir ); + $this->log( '$dir: '.$dir ); $this->chDirIfNecessary( $dir ); unset( $files ); unset( $dirs ); $files = array(); $dirs = array(); @@ -2263,7 +2348,10 @@ function IFM( params ) { } usort( $dirs, array( $this, "sortByName" ) ); usort( $files, array( $this, "sortByName" ) ); - echo json_encode( array_merge( $dirs, $files ) ); + + $this->log( '$files: '.print_r($files, true ) ); + $this->log( '$dirs: '.print_r($dirs, true ) ); + $this->jsonResponse( array_merge( $dirs, $files ) ); } private function getItemInformation( $name ) { @@ -2353,6 +2441,10 @@ function IFM( params ) { 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" ) ); + exit( 1 ); + } try { $results = $this->searchItemsRecursive( $d['pattern'] ); echo json_encode( $results ); @@ -2788,12 +2880,58 @@ function IFM( params ) { echo json_encode( array( "status" => "error", "message" => "Corrupt parameter data" ) ); } - //apis - /* help functions */ + private function log( $string ) { + file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), $string, FILE_APPEND ); + } + + private function jsonResponse( $array ) { + $this->convertToUTF8( $array ); + $json = json_encode( $array ); + if( $json === false ) { + switch(json_last_error()) { + case JSON_ERROR_NONE: + $err = ' - Keine Fehler'; + break; + case JSON_ERROR_DEPTH: + $err = ' - Maximale Stacktiefe überschritten'; + break; + case JSON_ERROR_STATE_MISMATCH: + $err = ' - Unterlauf oder Nichtübereinstimmung der Modi'; + break; + case JSON_ERROR_CTRL_CHAR: + $err = ' - Unerwartetes Steuerzeichen gefunden'; + break; + case JSON_ERROR_SYNTAX: + $err = ' - Syntaxfehler, ungültiges JSON'; + break; + case JSON_ERROR_UTF8: + $err = ' - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'; + break; + default: + $err = ' - Unbekannter Fehler'; + break; + } + + $this->jsonResponse( array( "status" => "ERROR", "message" => $err ) ); + } else { + echo $json; + } + } + + private function convertToUTF8( &$item ) { + if( is_array( $item ) ) + array_walk( + $item, + array( $this, 'convertToUTF8' ) + ); + else + $item = utf8_encode( $item ); + } + public function checkAuth() { if( $this->config['auth'] == 1 && ( ! isset( $_SESSION['auth'] ) || $_SESSION['auth'] !== true ) ) { $login_failed = false; diff --git a/src/ifm.js b/src/ifm.js index 4dddb86..041b532 100644 --- a/src/ifm.js +++ b/src/ifm.js @@ -14,6 +14,7 @@ function IFM( params ) { this.fileChanged = false; // flag for check if file was changed already this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests this.rootElement = ""; + this.search = {}; /** * Shows a bootstrap modal @@ -80,6 +81,13 @@ function IFM( params ) { * @param object data - object with items */ this.rebuildFileTable = function( data ) { + if( data.status == "ERROR" ) { + this.showMessage( data.message, "e" ); + return; + } else if ( ! Array.isArray( data ) ) { + this.showMessage( "Invalid data from server", "e" ); + return; + } data.forEach( function( item ) { item.guid = self.generateGuid(); item.linkname = ( item.name == ".." ) ? "[ up ]" : item.name; @@ -850,6 +858,50 @@ function IFM( params ) { }); }; + this.showSearchDialog = function() { + self.showModal( Mustache.render( self.templates.search, { lastSearch: self.search.lastSearch } ) ); + $( '#searchResults tbody' ).remove(); + $( '#searchResults' ).append( Mustache.render( self.templates.searchresults, { items: self.search.data } ) ); + $( '#searchPattern' ).on( 'keypress', function( e ) { + if( e.keyCode == 13 ) { + e.preventDefault(); + e.stopPropagation(); + self.search.lastSearch = e.target.value; + $.ajax({ + url: self.api, + type: "POST", + data: { + api: "searchItems", + dir: self.currentDir, + pattern: e.target.value + }, + 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 ); + }); + self.search.data = data; + $('#searchResults').html( Mustache.render( self.templates.searchresults, { items: data } ) ); + } + }); + } + }); + $( document ).on( 'click', 'a.searchitem', function( e ) { + console.log( e ); + e.preventDefault(); + e.stopPropagation(); + self.changeDirectory( e.target.dataset.folder || e.target.parentNode.dataset.folder, { absolute: true } ); + self.hideModal(); + }); + $( document ).on( 'keypress', 'a.searchitem', function( e ) { + console.log( e ); + e.preventDefault(); + if( e.key == "Enter" ) + e.target.click(); + }); + } + // -------------------- // helper functions // -------------------- @@ -1099,6 +1151,10 @@ function IFM( params ) { return; switch( e.key ) { + case '/': + e.preventDefault(); + self.showSearchDialog(); + break; case 'g': e.preventDefault(); $('#currentDir').focus(); diff --git a/src/main.php b/src/main.php index 58b3c99..3364a0a 100644 --- a/src/main.php +++ b/src/main.php @@ -136,6 +136,12 @@ f00bar; f00bar; $templates['renamefile'] = <<<'f00bar' @@@src/templates/modal.renamefile.html@@@ +f00bar; + $templates['search'] = <<<'f00bar' +@@@src/templates/modal.search.html@@@ +f00bar; + $templates['searchresults'] = <<<'f00bar' +@@@src/templates/modal.searchresults.html@@@ f00bar; $templates['uploadfile'] = <<<'f00bar' @@@src/templates/modal.uploadfile.html@@@ @@ -279,7 +285,6 @@ f00bar; */ private function getFiles( $dir ) { - $dir = $this->getValidDir( $dir ); $this->chDirIfNecessary( $dir ); unset( $files ); unset( $dirs ); $files = array(); $dirs = array(); @@ -300,7 +305,8 @@ f00bar; } usort( $dirs, array( $this, "sortByName" ) ); usort( $files, array( $this, "sortByName" ) ); - echo json_encode( array_merge( $dirs, $files ) ); + + $this->jsonResponse( array_merge( $dirs, $files ) ); } private function getItemInformation( $name ) { @@ -829,12 +835,58 @@ f00bar; echo json_encode( array( "status" => "error", "message" => "Corrupt parameter data" ) ); } - //apis - /* help functions */ + private function log( $d ) { + file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), ( is_array( $d ) ? print_r( $d, true ) : $d ), FILE_APPEND ); + } + + private function jsonResponse( $array ) { + $this->convertToUTF8( $array ); + $json = json_encode( $array ); + if( $json === false ) { + switch(json_last_error()) { + case JSON_ERROR_NONE: + echo ' - No errors'; + break; + case JSON_ERROR_DEPTH: + echo ' - Maximum stack depth exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + echo ' - Underflow or the modes mismatch'; + break; + case JSON_ERROR_CTRL_CHAR: + echo ' - Unexpected control character found'; + break; + case JSON_ERROR_SYNTAX: + echo ' - Syntax error, malformed JSON'; + break; + case JSON_ERROR_UTF8: + echo ' - Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + echo ' - Unknown error'; + break; + } + + $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not encode json: " . $err ) ); + } else { + echo $json; + } + } + + private function convertToUTF8( &$item ) { + if( is_array( $item ) ) + array_walk( + $item, + array( $this, 'convertToUTF8' ) + ); + else + $item = utf8_encode( $item ); + } + public function checkAuth() { if( $this->config['auth'] == 1 && ( ! isset( $_SESSION['auth'] ) || $_SESSION['auth'] !== true ) ) { $login_failed = false; diff --git a/src/templates/modal.search.html b/src/templates/modal.search.html new file mode 100644 index 0000000..469ffda --- /dev/null +++ b/src/templates/modal.search.html @@ -0,0 +1,10 @@ + + +
diff --git a/src/templates/modal.searchresults.html b/src/templates/modal.searchresults.html new file mode 100644 index 0000000..486d9dd --- /dev/null +++ b/src/templates/modal.searchresults.html @@ -0,0 +1,11 @@ + +{{#items}} + + + + {{linkname}} ({{folder}}) + + + +{{/items}} + From bfbee57fee8c9772d74e9a3ab6915a3d09a19beb Mon Sep 17 00:00:00 2001 From: Marco Dickert Date: Sun, 30 Jul 2017 05:24:34 +0200 Subject: [PATCH 3/3] new builds --- build/libifm.php | 29 ++++++++++++----------------- ifm.php | 29 ++++++++++++----------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/build/libifm.php b/build/libifm.php index facc4d1..ee23154 100644 --- a/build/libifm.php +++ b/build/libifm.php @@ -868,9 +868,7 @@ function IFM( params ) { dir: self.currentDir }, dataType: "json", - success: function( data ) { - self.rebuildFileTable( data ); - }, + success: self.rebuildFileTable, error: function( response ) { self.showMessage( "General error occured: No or broken response", "e" ); }, complete: function() { self.task_done( id ); } }); @@ -2327,7 +2325,6 @@ function IFM( params ) { */ private function getFiles( $dir ) { - $this->log( '$dir: '.$dir ); $this->chDirIfNecessary( $dir ); unset( $files ); unset( $dirs ); $files = array(); $dirs = array(); @@ -2349,8 +2346,6 @@ function IFM( params ) { usort( $dirs, array( $this, "sortByName" ) ); usort( $files, array( $this, "sortByName" ) ); - $this->log( '$files: '.print_r($files, true ) ); - $this->log( '$dirs: '.print_r($dirs, true ) ); $this->jsonResponse( array_merge( $dirs, $files ) ); } @@ -2884,8 +2879,8 @@ function IFM( params ) { help functions */ - private function log( $string ) { - file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), $string, FILE_APPEND ); + private function log( $d ) { + file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), ( is_array( $d ) ? print_r( $d, true ) : $d ), FILE_APPEND ); } private function jsonResponse( $array ) { @@ -2894,29 +2889,29 @@ function IFM( params ) { if( $json === false ) { switch(json_last_error()) { case JSON_ERROR_NONE: - $err = ' - Keine Fehler'; + echo ' - No errors'; break; case JSON_ERROR_DEPTH: - $err = ' - Maximale Stacktiefe überschritten'; + echo ' - Maximum stack depth exceeded'; break; case JSON_ERROR_STATE_MISMATCH: - $err = ' - Unterlauf oder Nichtübereinstimmung der Modi'; + echo ' - Underflow or the modes mismatch'; break; case JSON_ERROR_CTRL_CHAR: - $err = ' - Unerwartetes Steuerzeichen gefunden'; + echo ' - Unexpected control character found'; break; case JSON_ERROR_SYNTAX: - $err = ' - Syntaxfehler, ungültiges JSON'; + echo ' - Syntax error, malformed JSON'; break; case JSON_ERROR_UTF8: - $err = ' - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'; + echo ' - Malformed UTF-8 characters, possibly incorrectly encoded'; break; default: - $err = ' - Unbekannter Fehler'; + echo ' - Unknown error'; break; } - - $this->jsonResponse( array( "status" => "ERROR", "message" => $err ) ); + + $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not encode json: " . $err ) ); } else { echo $json; } diff --git a/ifm.php b/ifm.php index ffeb78f..62a82b9 100644 --- a/ifm.php +++ b/ifm.php @@ -868,9 +868,7 @@ function IFM( params ) { dir: self.currentDir }, dataType: "json", - success: function( data ) { - self.rebuildFileTable( data ); - }, + success: self.rebuildFileTable, error: function( response ) { self.showMessage( "General error occured: No or broken response", "e" ); }, complete: function() { self.task_done( id ); } }); @@ -2327,7 +2325,6 @@ function IFM( params ) { */ private function getFiles( $dir ) { - $this->log( '$dir: '.$dir ); $this->chDirIfNecessary( $dir ); unset( $files ); unset( $dirs ); $files = array(); $dirs = array(); @@ -2349,8 +2346,6 @@ function IFM( params ) { usort( $dirs, array( $this, "sortByName" ) ); usort( $files, array( $this, "sortByName" ) ); - $this->log( '$files: '.print_r($files, true ) ); - $this->log( '$dirs: '.print_r($dirs, true ) ); $this->jsonResponse( array_merge( $dirs, $files ) ); } @@ -2884,8 +2879,8 @@ function IFM( params ) { help functions */ - private function log( $string ) { - file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), $string, FILE_APPEND ); + private function log( $d ) { + file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), ( is_array( $d ) ? print_r( $d, true ) : $d ), FILE_APPEND ); } private function jsonResponse( $array ) { @@ -2894,29 +2889,29 @@ function IFM( params ) { if( $json === false ) { switch(json_last_error()) { case JSON_ERROR_NONE: - $err = ' - Keine Fehler'; + echo ' - No errors'; break; case JSON_ERROR_DEPTH: - $err = ' - Maximale Stacktiefe überschritten'; + echo ' - Maximum stack depth exceeded'; break; case JSON_ERROR_STATE_MISMATCH: - $err = ' - Unterlauf oder Nichtübereinstimmung der Modi'; + echo ' - Underflow or the modes mismatch'; break; case JSON_ERROR_CTRL_CHAR: - $err = ' - Unerwartetes Steuerzeichen gefunden'; + echo ' - Unexpected control character found'; break; case JSON_ERROR_SYNTAX: - $err = ' - Syntaxfehler, ungültiges JSON'; + echo ' - Syntax error, malformed JSON'; break; case JSON_ERROR_UTF8: - $err = ' - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'; + echo ' - Malformed UTF-8 characters, possibly incorrectly encoded'; break; default: - $err = ' - Unbekannter Fehler'; + echo ' - Unknown error'; break; } - - $this->jsonResponse( array( "status" => "ERROR", "message" => $err ) ); + + $this->jsonResponse( array( "status" => "ERROR", "message" => "Could not encode json: " . $err ) ); } else { echo $json; }