1
0
mirror of https://github.com/misterunknown/ifm.git synced 2025-08-09 09:36:29 +02:00
This commit is contained in:
Jannis Rondorf
2017-07-28 14:29:31 +02:00
8 changed files with 345 additions and 39 deletions

View File

@@ -51,8 +51,10 @@ RUN set -xe; \
php5-zlib \
php5-posix \
php5-soap \
php5-openssl \
php5-pcntl \
php5-xml \
php5-phar \
php5-zip
RUN mkdir -p /run/apache2 \

View File

@@ -13,20 +13,34 @@ The IFM uses the following resources:
* create/edit files and directories
* copy/move files and directories
* download files and directories
* upload files directly or via URL
* extract zip archives
* upload files directly, via URL or per drag & drop
* extract archives (tar, tgz, tar.gz, tar.bz2, zip)
* change permissions
* image preview
## requirements
| Client | Server |
|:--------------------------------- |:------------------------------------------------------------ |
| HTML5 and CSS3 compatible browser | PHP >= 5.5 (only if using auth; if not PHP 5.4 works either) |
| activated JavaScript | optional: cURL extention (for remote upload) |
* Client
* HTML5 and CSS3 compatible browser
* activated javascript
* Server
* PHP >= 5.5
* extensions
* bz2
* curl (for remote upload)
* json
* openssl (for remote uploads from https sources)
* phar (for tar support)
* zip
* zlib
## installation
Just copy the ifm.php to your webspace - thats all :)
## security information
The IFM is usually locked to it's own directory, so you are not able to go above. You can change that by setting the `root_dir` in the scripts [configuration](https://github.com/misterunknown/ifm/wiki/Configuration).
By default, it is not allowed to show or edit the `.htaccess` file. This is because you can configure the IFM via environment variables. Thus if anyone has the ability to edit the `.htaccess` file, he could overwrite the active configuration. [See also](https://github.com/misterunknown/ifm/wiki/Configuration).
## key bindings
* <kbd>e</kbd> - edit / extract current file
* <kbd>h</kbd><kbd>j</kbd><kbd>k</kbd><kbd>l</kbd> - vim-style navigation (alternative to arrow keys)
@@ -37,6 +51,7 @@ Just copy the ifm.php to your webspace - thats all :)
* <kbd>a</kbd> - show ajax request dialog
* <kbd>F</kbd> - new file
* <kbd>D</kbd> - new directory
* <kbd>c</kbd><kbd>m</kbd> - show copy/move dialog
* <kbd>space</kbd> - select a highlighted item
* <kbd>del</kbd> - delete selected files
* <kbd>Enter</kbd> - open a file or change to the directory
@@ -117,6 +132,3 @@ listed below:
## issues
Currently there are no known issues. If you find any flaws please let me know.
## security information
By default, the IFM is locked to it's own directory, so you are not able to go above. You can change that by setting the $root_dir in the scripts configuration.

File diff suppressed because one or more lines are too long

117
ifm.php

File diff suppressed because one or more lines are too long

View File

@@ -486,12 +486,30 @@ function IFM( params ) {
url: self.api,
type: "POST",
data: ({
api: "getFolderTree",
dir: self.currentDir
api: "getFolders"
}),
dataType: "json",
success: function( data ) {
$( '#copyMoveTree' ).treeview( { data: data, levels: 0, expandIcon: "icon icon-folder-empty", collapseIcon: "icon icon-folder-open-empty" } );
$( '#copyMoveTree' ).treeview({
data: data,
levels: 1,
expandIcon: "icon icon-folder-empty",
emptyIcon: "icon icon-folder-empty",
collapseIcon: "icon icon-folder-open-empty",
loadingIcon: "icon icon-spin5",
lazyLoad: function( n, cb ) {
$.ajax({
url: self.api,
type: "POST",
data: {
api: "getFolders",
dir: n.dataAttr.path
},
dataType: "json",
success: cb
});
}
});
},
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
});

View File

@@ -1 +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}
.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon,.treeview span.image{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}.treeview .node-hidden{display:none}.treeview span.image{display:inline-block;height:1.19em;vertical-align:middle;background-size:contain;background-repeat:no-repeat;line-height:1em}

File diff suppressed because one or more lines are too long

View File

@@ -47,7 +47,7 @@ class IFM {
"showowner" => 1,
"showgroup" => 1,
"showpermissions" => 2,
"showhtdocs" => 1,
"showhtdocs" => 0,
"showhiddenfiles" => 1,
"showpath" => 0,
);
@@ -61,7 +61,40 @@ class IFM {
if( session_status() !== PHP_SESSION_ACTIVE )
session_start();
$this->config = array_merge( $this->defaultconfig, $config );
// load the default config
$this->config = $this->defaultconfig;
// load config from environment variables
$this->config['auth'] = getenv('IFM_AUTH') !== false ? getenv('IFM_AUTH') : $this->config['auth'] ;
$this->config['auth_source'] = getenv('IFM_AUTH_SOURCE') !== false ? getenv('IFM_AUTH_SOURCE') : $this->config['auth_source'] ;
$this->config['root_dir'] = getenv('IFM_ROOT_DIR') !== false ? getenv('IFM_ROOT_DIR') : $this->config['root_dir'] ;
$this->config['tmp_dir'] = getenv('IFM_TMP_DIR') !== false ? getenv('IFM_TMP_DIR') : $this->config['tmp_dir'] ;
$this->config['defaulttimezone'] = getenv('IFM_DEFAULTTIMEZONE') !== false ? getenv('IFM_DEFAULTTIMEZONE') : $this->config['defaulttimezone'] ;
$this->config['forbiddenChars'] = getenv('IFM_FORBIDDENCHARS') !== false ? str_split( getenv('IFM_FORBIDDENCHARS') ) : $this->config['forbiddenChars'] ;
$this->config['ajaxrequest'] = getenv('IFM_API_AJAXREQUEST') !== false ? getenv('IFM_API_AJAXREQUEST') : $this->config['ajaxrequest'] ;
$this->config['chmod'] = getenv('IFM_API_CHMOD') !== false ? getenv('IFM_API_CHMOD') : $this->config['chmod'] ;
$this->config['copymove'] = getenv('IFM_API_COPYMOVE') !== false ? getenv('IFM_API_COPYMOVE') : $this->config['copymove'] ;
$this->config['createdir'] = getenv('IFM_API_CREATEDIR') !== false ? getenv('IFM_API_CREATEDIR') : $this->config['createdir'] ;
$this->config['createfile'] = getenv('IFM_API_CREATEFILE') !== false ? getenv('IFM_API_CREATEFILE') : $this->config['createfile'] ;
$this->config['edit'] = getenv('IFM_API_EDIT') !== false ? getenv('IFM_API_EDIT') : $this->config['edit'] ;
$this->config['delete'] = getenv('IFM_API_DELETE') !== false ? getenv('IFM_API_DELETE') : $this->config['delete'] ;
$this->config['download'] = getenv('IFM_API_DOWNLOAD') !== false ? getenv('IFM_API_DOWNLOAD') : $this->config['download'] ;
$this->config['extract'] = getenv('IFM_API_EXTRACT') !== false ? getenv('IFM_API_EXTRACT') : $this->config['extract'] ;
$this->config['upload'] = getenv('IFM_API_UPLOAD') !== false ? getenv('IFM_API_UPLOAD') : $this->config['upload'] ;
$this->config['remoteupload'] = getenv('IFM_API_REMOTEUPLOAD') !== false ? getenv('IFM_API_REMOTEUPLOAD') : $this->config['remoteupload'] ;
$this->config['rename'] = getenv('IFM_API_RENAME') !== false ? getenv('IFM_API_RENAME') : $this->config['rename'] ;
$this->config['zipnload'] = getenv('IFM_API_ZIPNLOAD') !== false ? getenv('IFM_API_ZIPNLOAD') : $this->config['zipnload'] ;
$this->config['showlastmodified'] = getenv('IFM_GUI_SHOWLASTMODIFIED') !== false ? getenv('IFM_GUI_SHOWLASTMODIFIED') : $this->config['showlastmodified'] ;
$this->config['showfilesize'] = getenv('IFM_GUI_SHOWFILESIZE') !== false ? getenv('IFM_GUI_SHOWFILESIZE') : $this->config['showfilesize'] ;
$this->config['showowner'] = getenv('IFM_GUI_SHOWOWNER') !== false ? getenv('IFM_GUI_SHOWOWNER') : $this->config['showowner'] ;
$this->config['showgroup'] = getenv('IFM_GUI_SHOWGROUP') !== false ? getenv('IFM_GUI_SHOWGROUP') : $this->config['showgroup'] ;
$this->config['showpermissions'] = getenv('IFM_GUI_SHOWPERMISSIONS') !== false ? getenv('IFM_GUI_SHOWPERMISSIONS') : $this->config['showpermissions'] ;
$this->config['showhtdocs'] = getenv('IFM_GUI_SHOWHTDOCS') !== false ? getenv('IFM_GUI_SHOWHTDOCS') : $this->config['showhtdocs'] ;
$this->config['showhiddenfiles'] = getenv('IFM_GUI_SHOWHIDDENFILES') !== false ? getenv('IFM_GUI_SHOWHIDDENFILES') : $this->config['showhiddenfiles'] ;
$this->config['showpath'] = getenv('IFM_GUI_SHOWPATH') !== false ? getenv('IFM_GUI_SHOWPATH') : $this->config['showpath'] ;
// load config from passed array
$this->config = array_merge( $this->config, $config );
$templates = array();
$templates['app'] = <<<'f00bar'
@@ -143,6 +176,7 @@ f00bar;
public function getCSS() {
print '
<style type="text/css">';?> @@@src/includes/bootstrap.min.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/includes/bootstrap-treeview.min.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/includes/fontello-embedded.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/includes/animation.css@@@ <?php print '</style>
<style type="text/css">';?> @@@src/style.css@@@ <?php print '</style>
@@ -196,6 +230,9 @@ f00bar;
}
elseif( $_REQUEST["api"] == "getConfig" ) {
$this->getConfig();
}
elseif( $_REQUEST["api"] == "getFolders" ) {
$this->getFolders( $_REQUEST );
} elseif( $_REQUEST["api"] == "getTemplates" ) {
echo json_encode( $this->templates );
} elseif( $_REQUEST["api"] == "getI18N" ) {
@@ -221,9 +258,7 @@ f00bar;
case "zipnload": $this->zipnload( $_REQUEST); break;
case "remoteUpload": $this->remoteUpload( $_REQUEST ); break;
case "multidelete": $this->deleteMultipleFiles( $_REQUEST ); break;
case "getFolderTree":
echo json_encode( array_merge( array( 0 => array( "text" => "/ [root]", "nodes" => array(), "dataAttributes" => array( "path" => $this->getRootDir() ) ) ), $this->getFolderTreeRecursive( $this->getRootDir() ) ) );
break;
case "getFolderTree": $this->getFolderTree( $_REQUEST ); break;
default:
echo json_encode( array( "status" => "ERROR", "message" => "Invalid api action given" ) );
break;
@@ -333,6 +368,50 @@ f00bar;
echo json_encode( $ret );
}
private function getFolders( $d ) {
if( ! isset( $d['dir'] ) )
$d['dir'] = $this->getRootDir();
if( ! $this->isPathValid( $d['dir'] ) )
echo "[]";
else {
$ret = array();
foreach( glob( $this->pathCombine( $d['dir'], "*" ), GLOB_ONLYDIR ) as $dir ) {
array_push( $ret, array(
"text" => htmlspecialchars( basename( $dir ) ),
"lazyLoad" => true,
"dataAttr" => array( "path" => $dir )
));
}
sort( $ret );
if( $this->getScriptRoot() == realpath( $d['dir'] ) )
$ret = array_merge(
array(
0 => array(
"text" => "/ [root]",
"dataAttributes" => array( "path" => $this->getRootDir() )
)
),
$ret
);
echo json_encode( $ret );
}
}
private function getFolderTree( $d ) {
echo json_encode(
array_merge(
array(
0 => array(
"text" => "/ [root]",
"nodes" => array(),
"dataAttributes" => array( "path" => $this->getRootDir() )
)
),
$this->getFolderTreeRecursive( $d['dir'] )
)
);
}
private function getFolderTreeRecursive( $start_dir ) {
$ret = array();
$start_dir = realpath( $start_dir );
@@ -882,6 +961,7 @@ f00bar;
$tmp_i = pathinfo( $tmp_d );
array_push( $tmp_missing_parts, $tmp_i['filename'] );
$tmp_d = dirname( $tmp_d );
if( $tmp_d == dirname( $tmp_d ) ) break;
}
$rpDir = $this->pathCombine( realpath( $tmp_d ), implode( "/", array_reverse( $tmp_missing_parts ) ) );
$rpConfig = $this->getRootDir();