mirror of
https://github.com/misterunknown/ifm.git
synced 2025-08-15 04:23:58 +02:00
merge original project modifications
This commit is contained in:
@@ -10,7 +10,7 @@ chdir( realpath( dirname( __FILE__ ) ) );
|
|||||||
|
|
||||||
// output files and common attrs
|
// output files and common attrs
|
||||||
define( "IFM_CDN", true );
|
define( "IFM_CDN", true );
|
||||||
define( "IFM_VERSION", "<a href='https://github.com/cryol/ifm/tree/2.6.0' target=_blank>v2.6.0</a>" );
|
define( "IFM_VERSION", "<a href='https://github.com/cryol/ifm/tree/2.6.1' target=_blank>v2.6.1</a>" );
|
||||||
define( "IFM_RELEASE_DIR", "dist/");
|
define( "IFM_RELEASE_DIR", "dist/");
|
||||||
define( "IFM_STANDALONE", "ifm.php" );
|
define( "IFM_STANDALONE", "ifm.php" );
|
||||||
define( "IFM_STANDALONE_GZ", "ifm.min.php" );
|
define( "IFM_STANDALONE_GZ", "ifm.min.php" );
|
||||||
|
19
src/ifm.js
19
src/ifm.js
@@ -166,7 +166,7 @@ function IFM(params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
item.download.link = self.api+"?api="+item.download.action+"&dir="+self.hrefEncode(self.currentDir)+"&filename="+self.hrefEncode(item.download.name);
|
item.download.link = self.api+"?api="+item.download.action+"&dir="+self.hrefEncode(self.currentDir)+"&filename="+self.hrefEncode(item.download.name);
|
||||||
if( self.config.isDocroot )
|
if( self.config.isDocroot && !self.config.forceproxy )
|
||||||
item.link = self.hrefEncode( self.pathCombine( window.location.path, self.currentDir, item.name ) );
|
item.link = self.hrefEncode( self.pathCombine( window.location.path, self.currentDir, item.name ) );
|
||||||
else if (self.config.download && self.config.zipnload) {
|
else if (self.config.download && self.config.zipnload) {
|
||||||
if (self.config.root_public_url) {
|
if (self.config.root_public_url) {
|
||||||
@@ -520,8 +520,8 @@ function IFM(params) {
|
|||||||
self.editor.getSession().setMode( e.target.value );
|
self.editor.getSession().setMode( e.target.value );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return $(content);
|
return $(content);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1132,7 +1132,7 @@ function IFM(params) {
|
|||||||
searchresults.tBodies[0].addEventListener( 'click', function( e ) {
|
searchresults.tBodies[0].addEventListener( 'click', function( e ) {
|
||||||
if( e.target.classList.contains( 'searchitem' ) || e.target.parentElement.classList.contains( 'searchitem' ) ) {
|
if( e.target.classList.contains( 'searchitem' ) || e.target.parentElement.classList.contains( 'searchitem' ) ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
self.changeDirectory( self.pathCombine( self.search.data.currentDir, e.target.dataset.folder || e.target.parentElement.dataset.foldera ), { absolute: true } );
|
self.changeDirectory( self.pathCombine( self.search.data.currentDir, e.target.dataset.folder || e.target.parentElement.dataset.folder ), { absolute: true });
|
||||||
self.hideModal();
|
self.hideModal();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1585,8 +1585,10 @@ function IFM(params) {
|
|||||||
// global key events
|
// global key events
|
||||||
switch( e.key ) {
|
switch( e.key ) {
|
||||||
case '/':
|
case '/':
|
||||||
|
if (self.config.search) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
self.showSearchDialog();
|
self.showSearchDialog();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -1594,9 +1596,10 @@ function IFM(params) {
|
|||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
|
if (self.config.showrefresh) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
self.refreshFileTable();
|
self.refreshFileTable();
|
||||||
return;
|
}
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
if( self.config.upload ) {
|
if( self.config.upload ) {
|
||||||
@@ -1823,8 +1826,12 @@ function IFM(params) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// bind static buttons
|
// bind static buttons
|
||||||
document.getElementById( 'refresh' ).onclick = function() { self.refreshFileTable(); };
|
if (el_r = document.getElementById('refresh'))
|
||||||
document.getElementById( 'search' ).onclick = function() { self.showSearchDialog(); };
|
el_r.onclick = function() { self.refreshFileTable(); };
|
||||||
|
if (el_s = document.getElementById('search'))
|
||||||
|
el_s.onclick = function() { self.showSearchDialog(); };
|
||||||
|
//document.getElementById( 'refresh' ).onclick = function() { self.refreshFileTable(); };
|
||||||
|
//document.getElementById( 'search' ).onclick = function() { self.showSearchDialog(); };
|
||||||
if( self.config.createfile )
|
if( self.config.createfile )
|
||||||
document.getElementById( 'createFile' ).onclick = function() { self.showFileDialog(); };
|
document.getElementById( 'createFile' ).onclick = function() { self.showFileDialog(); };
|
||||||
if( self.config.createdir )
|
if( self.config.createdir )
|
||||||
|
@@ -23,7 +23,7 @@ class IFMArchive {
|
|||||||
/**
|
/**
|
||||||
* Add a folder to an archive
|
* Add a folder to an archive
|
||||||
*/
|
*/
|
||||||
private static function addFolder( &$archive, $folder, $offset=0 ) {
|
private static function addFolder(&$archive, $folder, $offset=0, $exclude_callback=null) {
|
||||||
if ($offset == 0)
|
if ($offset == 0)
|
||||||
$offset = strlen(dirname($folder)) + 1;
|
$offset = strlen(dirname($folder)) + 1;
|
||||||
$archive->addEmptyDir(substr($folder, $offset));
|
$archive->addEmptyDir(substr($folder, $offset));
|
||||||
@@ -33,8 +33,12 @@ class IFMArchive {
|
|||||||
$filePath = $folder . '/' . $f;
|
$filePath = $folder . '/' . $f;
|
||||||
if (file_exists($filePath) && is_readable($filePath))
|
if (file_exists($filePath) && is_readable($filePath))
|
||||||
if (is_file($filePath))
|
if (is_file($filePath))
|
||||||
|
if (!is_callable($exclude_callback) || $exclude_callback($f))
|
||||||
$archive->addFile( $filePath, substr( $filePath, $offset ) );
|
$archive->addFile( $filePath, substr( $filePath, $offset ) );
|
||||||
elseif (is_dir($filePath))
|
elseif (is_dir($filePath))
|
||||||
|
if (is_callable($exclude_callback))
|
||||||
|
self::addFolder($archive, $filePath, $offset, $exclude_callback);
|
||||||
|
else
|
||||||
self::addFolder($archive, $filePath, $offset);
|
self::addFolder($archive, $filePath, $offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,18 +48,23 @@ class IFMArchive {
|
|||||||
/**
|
/**
|
||||||
* Create a zip file
|
* Create a zip file
|
||||||
*/
|
*/
|
||||||
public static function createZip( $src, $out )
|
public static function createZip($src, $out, $exclude_callback=null) {
|
||||||
{
|
|
||||||
$a = new ZipArchive();
|
$a = new ZipArchive();
|
||||||
$a->open($out, ZIPARCHIVE::CREATE);
|
$a->open($out, ZIPARCHIVE::CREATE);
|
||||||
|
|
||||||
if (!is_array($src))
|
if (!is_array($src))
|
||||||
$src = array($src);
|
$src = array($src);
|
||||||
|
|
||||||
|
file_put_contents("debug.ifm.log", var_export(is_callable($exclude_callback), true)."\n");
|
||||||
|
|
||||||
foreach ($src as $s)
|
foreach ($src as $s)
|
||||||
if (is_dir($s))
|
if (is_dir($s))
|
||||||
|
if (is_callable($exclude_callback))
|
||||||
|
self::addFolder( $a, $s, null, $exclude_callback );
|
||||||
|
else
|
||||||
self::addFolder( $a, $s );
|
self::addFolder( $a, $s );
|
||||||
elseif (is_file($s))
|
elseif (is_file($s))
|
||||||
|
if (!is_callable($exclude_callback) || $exclude_callback($s))
|
||||||
$a->addFile($s, substr($s, strlen(dirname($s)) + 1));
|
$a->addFile($s, substr($s, strlen(dirname($s)) + 1));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
22
src/main.php
22
src/main.php
@@ -100,6 +100,9 @@ class IFM {
|
|||||||
$this->config['showhiddenfiles'] = getenv('IFM_GUI_SHOWHIDDENFILES') !== false ? intval( getenv('IFM_GUI_SHOWHIDDENFILES') ) : $this->config['showhiddenfiles'] ;
|
$this->config['showhiddenfiles'] = getenv('IFM_GUI_SHOWHIDDENFILES') !== false ? intval( getenv('IFM_GUI_SHOWHIDDENFILES') ) : $this->config['showhiddenfiles'] ;
|
||||||
$this->config['showpath'] = getenv('IFM_GUI_SHOWPATH') !== false ? intval( getenv('IFM_GUI_SHOWPATH') ) : $this->config['showpath'] ;
|
$this->config['showpath'] = getenv('IFM_GUI_SHOWPATH') !== false ? intval( getenv('IFM_GUI_SHOWPATH') ) : $this->config['showpath'] ;
|
||||||
$this->config['contextmenu'] = getenv('IFM_GUI_CONTEXTMENU') !== false ? intval( getenv('IFM_GUI_CONTEXTMENU') ) : $this->config['contextmenu'] ;
|
$this->config['contextmenu'] = getenv('IFM_GUI_CONTEXTMENU') !== false ? intval( getenv('IFM_GUI_CONTEXTMENU') ) : $this->config['contextmenu'] ;
|
||||||
|
$this->config['search'] = getenv('IFM_API_SEARCH') !== false ? intval( getenv('IFM_API_SEARCH') ) : $this->config['search'] ;
|
||||||
|
$this->config['showrefresh'] = getenv('IFM_GUI_REFRESH') !== false ? intval( getenv('IFM_GUI_REFRESH') ) : $this->config['showrefresh'] ;
|
||||||
|
$this->config['forceproxy'] = getenv('IFM_GUI_FORCEPROXY') !== false ? intval( getenv('IFM_GUI_FORCEPROXY') ) : $this->config['forceproxy'] ;
|
||||||
|
|
||||||
// optional settings
|
// optional settings
|
||||||
if( getenv('IFM_SESSION_LIFETIME') !== false )
|
if( getenv('IFM_SESSION_LIFETIME') !== false )
|
||||||
@@ -427,6 +430,11 @@ IFM_ASSETS
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function searchItems( $d ) {
|
private function searchItems( $d ) {
|
||||||
|
if( $this->config['search'] != 1 ) {
|
||||||
|
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( strpos( $d['pattern'], '/' ) !== false ) {
|
if( strpos( $d['pattern'], '/' ) !== false ) {
|
||||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['pattern_error_slashes'] ) );
|
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['pattern_error_slashes'] ) );
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
@@ -653,6 +661,8 @@ IFM_ASSETS
|
|||||||
private function downloadFile( array $d, $forceDL=true ) {
|
private function downloadFile( array $d, $forceDL=true ) {
|
||||||
if( $this->config['download'] != 1 )
|
if( $this->config['download'] != 1 )
|
||||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) );
|
||||||
|
elseif( ! $this->isFilenameValid( $d['filename'] ) )
|
||||||
|
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||||
elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['filename'], 0, 3 ) == ".ht" || substr( $d['filename'],0,3 ) == ".ht" ) )
|
elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['filename'], 0, 3 ) == ".ht" || substr( $d['filename'],0,3 ) == ".ht" ) )
|
||||||
$this->jsonResponse( array( "status" => "ERROR", "message"=> $this->l['nopermissions'] ) );
|
$this->jsonResponse( array( "status" => "ERROR", "message"=> $this->l['nopermissions'] ) );
|
||||||
elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['filename'], 0, 1 ) == "." || substr( $d['filename'],0,1 ) == "." ) )
|
elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['filename'], 0, 1 ) == "." || substr( $d['filename'],0,1 ) == "." ) )
|
||||||
@@ -792,20 +802,22 @@ IFM_ASSETS
|
|||||||
else {
|
else {
|
||||||
if( ! file_exists( $d['filename'] ) )
|
if( ! file_exists( $d['filename'] ) )
|
||||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_not_found'] ) );
|
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_not_found'] ) );
|
||||||
elseif ( ! $this->isFilenameValid( $d['filename'] ) )
|
elseif (!$this->isPathValid($d['filename']))
|
||||||
|
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) );
|
||||||
|
elseif ($d['filename'] != "." && !$this->isFilenameValid($d['filename']))
|
||||||
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
$this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) );
|
||||||
else {
|
else {
|
||||||
unset( $zip );
|
unset( $zip );
|
||||||
$dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename
|
$dfile = $this->pathCombine( __DIR__, $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename
|
||||||
try {
|
try {
|
||||||
IFMArchive::createZip( realpath( $d['filename'] ), $dfile );
|
IFMArchive::createZip(realpath($d['filename']), $dfile, array($this, 'isFilenameValid'));
|
||||||
if( $d['filename'] == "." ) {
|
if( $d['filename'] == "." ) {
|
||||||
if( getcwd() == $this->getScriptRoot() )
|
if( getcwd() == $this->getScriptRoot() )
|
||||||
$d['filename'] = "root";
|
$d['filename'] = "root";
|
||||||
else
|
else
|
||||||
$d['filename'] = basename( getcwd() );
|
$d['filename'] = basename( getcwd() );
|
||||||
}
|
}
|
||||||
$this->fileDownload( array( "file" => $dfile, "name" => $d['filename'] . ".zip" ) );
|
$this->fileDownload( array( "file" => $dfile, "name" => $d['filename'] . ".zip", "forceDL" => true ) );
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
echo $this->l['error'] . " " . $e->getMessage();
|
echo $this->l['error'] . " " . $e->getMessage();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1228,7 +1240,7 @@ IFM_ASSETS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if filename is allowed
|
// check if filename is allowed
|
||||||
private function isFilenameValid( $f ) {
|
public function isFilenameValid( $f ) {
|
||||||
if( ! $this->isFilenameAllowed( $f ) )
|
if( ! $this->isFilenameAllowed( $f ) )
|
||||||
return false;
|
return false;
|
||||||
if( strtoupper( substr( PHP_OS, 0, 3 ) ) == "WIN" ) {
|
if( strtoupper( substr( PHP_OS, 0, 3 ) ) == "WIN" ) {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
body {
|
body {
|
||||||
padding-top: 70px;
|
padding-top: 70px;
|
||||||
|
overflow-y: scroll !important;
|
||||||
}
|
}
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 14pt;
|
font-size: 14pt;
|
||||||
|
@@ -19,12 +19,16 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
|
{{#config.showrefresh}}
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a id="refresh" class="nav-link"><span title="{{i18n.refresh}}" class="icon icon-arrows-cw" href="#"></span> <span class="d-block d-sm-none">{{i18n.refresh}}</span></a>
|
<a id="refresh" class="nav-link"><span title="{{i18n.refresh}}" class="icon icon-arrows-cw" href="#"></span> <span class="d-block d-sm-none">{{i18n.refresh}}</span></a>
|
||||||
</li>
|
</li>
|
||||||
|
{{/config.showrefresh}}
|
||||||
|
{{#config.search}}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a id="search" class="nav-link"><span title="{{i18n.search}}" class="icon icon-search" href="#"></span> <span class="d-block d-sm-none">{{i18n.search}}</span></a>
|
<a id="search" class="nav-link"><span title="{{i18n.search}}" class="icon icon-search" href="#"></span> <span class="d-block d-sm-none">{{i18n.search}}</span></a>
|
||||||
</li>
|
</li>
|
||||||
|
{{/config.search}}
|
||||||
{{#config.upload}}
|
{{#config.upload}}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a id="upload" class="nav-link"><span title="{{i18n.upload}}" class="icon icon-upload" href="#"></span> <span class="d-block d-sm-none">{{i18n.upload}}</span></a>
|
<a id="upload" class="nav-link"><span title="{{i18n.upload}}" class="icon icon-upload" href="#"></span> <span class="d-block d-sm-none">{{i18n.upload}}</span></a>
|
||||||
|
Reference in New Issue
Block a user