mirror of
https://github.com/misterunknown/ifm.git
synced 2025-08-16 21:13:59 +02:00
Merge branch 'master' of https://github.com/misterunknown/ifm
This commit is contained in:
@@ -51,8 +51,10 @@ RUN set -xe; \
|
|||||||
php5-zlib \
|
php5-zlib \
|
||||||
php5-posix \
|
php5-posix \
|
||||||
php5-soap \
|
php5-soap \
|
||||||
|
php5-openssl \
|
||||||
php5-pcntl \
|
php5-pcntl \
|
||||||
php5-xml \
|
php5-xml \
|
||||||
|
php5-phar \
|
||||||
php5-zip
|
php5-zip
|
||||||
|
|
||||||
RUN mkdir -p /run/apache2 \
|
RUN mkdir -p /run/apache2 \
|
||||||
|
30
README.md
30
README.md
@@ -13,20 +13,34 @@ The IFM uses the following resources:
|
|||||||
* create/edit files and directories
|
* create/edit files and directories
|
||||||
* copy/move files and directories
|
* copy/move files and directories
|
||||||
* download files and directories
|
* download files and directories
|
||||||
* upload files directly or via URL
|
* upload files directly, via URL or per drag & drop
|
||||||
* extract zip archives
|
* extract archives (tar, tgz, tar.gz, tar.bz2, zip)
|
||||||
* change permissions
|
* change permissions
|
||||||
* image preview
|
* image preview
|
||||||
|
|
||||||
## requirements
|
## requirements
|
||||||
| Client | Server |
|
* Client
|
||||||
|:--------------------------------- |:------------------------------------------------------------ |
|
* HTML5 and CSS3 compatible browser
|
||||||
| HTML5 and CSS3 compatible browser | PHP >= 5.5 (only if using auth; if not PHP 5.4 works either) |
|
* activated javascript
|
||||||
| activated JavaScript | optional: cURL extention (for remote upload) |
|
* 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
|
## installation
|
||||||
Just copy the ifm.php to your webspace - thats all :)
|
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
|
## key bindings
|
||||||
* <kbd>e</kbd> - edit / extract current file
|
* <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)
|
* <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>a</kbd> - show ajax request dialog
|
||||||
* <kbd>F</kbd> - new file
|
* <kbd>F</kbd> - new file
|
||||||
* <kbd>D</kbd> - new directory
|
* <kbd>D</kbd> - new directory
|
||||||
|
* <kbd>c</kbd><kbd>m</kbd> - show copy/move dialog
|
||||||
* <kbd>space</kbd> - select a highlighted item
|
* <kbd>space</kbd> - select a highlighted item
|
||||||
* <kbd>del</kbd> - delete selected files
|
* <kbd>del</kbd> - delete selected files
|
||||||
* <kbd>Enter</kbd> - open a file or change to the directory
|
* <kbd>Enter</kbd> - open a file or change to the directory
|
||||||
@@ -117,6 +132,3 @@ listed below:
|
|||||||
|
|
||||||
## issues
|
## issues
|
||||||
Currently there are no known issues. If you find any flaws please let me know.
|
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.
|
|
||||||
|
117
build/libifm.php
117
build/libifm.php
File diff suppressed because one or more lines are too long
24
src/ifm.js
24
src/ifm.js
@@ -486,12 +486,30 @@ function IFM( params ) {
|
|||||||
url: self.api,
|
url: self.api,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: ({
|
data: ({
|
||||||
api: "getFolderTree",
|
api: "getFolders"
|
||||||
dir: self.currentDir
|
|
||||||
}),
|
}),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function( data ) {
|
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" ) }
|
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
||||||
});
|
});
|
||||||
|
2
src/includes/bootstrap-treeview.min.css
vendored
2
src/includes/bootstrap-treeview.min.css
vendored
@@ -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}
|
2
src/includes/bootstrap-treeview.min.js
vendored
2
src/includes/bootstrap-treeview.min.js
vendored
File diff suppressed because one or more lines are too long
90
src/main.php
90
src/main.php
@@ -47,7 +47,7 @@ class IFM {
|
|||||||
"showowner" => 1,
|
"showowner" => 1,
|
||||||
"showgroup" => 1,
|
"showgroup" => 1,
|
||||||
"showpermissions" => 2,
|
"showpermissions" => 2,
|
||||||
"showhtdocs" => 1,
|
"showhtdocs" => 0,
|
||||||
"showhiddenfiles" => 1,
|
"showhiddenfiles" => 1,
|
||||||
"showpath" => 0,
|
"showpath" => 0,
|
||||||
);
|
);
|
||||||
@@ -61,7 +61,40 @@ class IFM {
|
|||||||
if( session_status() !== PHP_SESSION_ACTIVE )
|
if( session_status() !== PHP_SESSION_ACTIVE )
|
||||||
session_start();
|
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 = array();
|
||||||
$templates['app'] = <<<'f00bar'
|
$templates['app'] = <<<'f00bar'
|
||||||
@@ -143,6 +176,7 @@ f00bar;
|
|||||||
public function getCSS() {
|
public function getCSS() {
|
||||||
print '
|
print '
|
||||||
<style type="text/css">';?> @@@src/includes/bootstrap.min.css@@@ <?php print '</style>
|
<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/fontello-embedded.css@@@ <?php print '</style>
|
||||||
<style type="text/css">';?> @@@src/includes/animation.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>
|
<style type="text/css">';?> @@@src/style.css@@@ <?php print '</style>
|
||||||
@@ -196,6 +230,9 @@ f00bar;
|
|||||||
}
|
}
|
||||||
elseif( $_REQUEST["api"] == "getConfig" ) {
|
elseif( $_REQUEST["api"] == "getConfig" ) {
|
||||||
$this->getConfig();
|
$this->getConfig();
|
||||||
|
}
|
||||||
|
elseif( $_REQUEST["api"] == "getFolders" ) {
|
||||||
|
$this->getFolders( $_REQUEST );
|
||||||
} elseif( $_REQUEST["api"] == "getTemplates" ) {
|
} elseif( $_REQUEST["api"] == "getTemplates" ) {
|
||||||
echo json_encode( $this->templates );
|
echo json_encode( $this->templates );
|
||||||
} elseif( $_REQUEST["api"] == "getI18N" ) {
|
} elseif( $_REQUEST["api"] == "getI18N" ) {
|
||||||
@@ -221,9 +258,7 @@ f00bar;
|
|||||||
case "zipnload": $this->zipnload( $_REQUEST); break;
|
case "zipnload": $this->zipnload( $_REQUEST); break;
|
||||||
case "remoteUpload": $this->remoteUpload( $_REQUEST ); break;
|
case "remoteUpload": $this->remoteUpload( $_REQUEST ); break;
|
||||||
case "multidelete": $this->deleteMultipleFiles( $_REQUEST ); break;
|
case "multidelete": $this->deleteMultipleFiles( $_REQUEST ); break;
|
||||||
case "getFolderTree":
|
case "getFolderTree": $this->getFolderTree( $_REQUEST ); break;
|
||||||
echo json_encode( array_merge( array( 0 => array( "text" => "/ [root]", "nodes" => array(), "dataAttributes" => array( "path" => $this->getRootDir() ) ) ), $this->getFolderTreeRecursive( $this->getRootDir() ) ) );
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
echo json_encode( array( "status" => "ERROR", "message" => "Invalid api action given" ) );
|
echo json_encode( array( "status" => "ERROR", "message" => "Invalid api action given" ) );
|
||||||
break;
|
break;
|
||||||
@@ -333,6 +368,50 @@ f00bar;
|
|||||||
echo json_encode( $ret );
|
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 ) {
|
private function getFolderTreeRecursive( $start_dir ) {
|
||||||
$ret = array();
|
$ret = array();
|
||||||
$start_dir = realpath( $start_dir );
|
$start_dir = realpath( $start_dir );
|
||||||
@@ -882,6 +961,7 @@ f00bar;
|
|||||||
$tmp_i = pathinfo( $tmp_d );
|
$tmp_i = pathinfo( $tmp_d );
|
||||||
array_push( $tmp_missing_parts, $tmp_i['filename'] );
|
array_push( $tmp_missing_parts, $tmp_i['filename'] );
|
||||||
$tmp_d = dirname( $tmp_d );
|
$tmp_d = dirname( $tmp_d );
|
||||||
|
if( $tmp_d == dirname( $tmp_d ) ) break;
|
||||||
}
|
}
|
||||||
$rpDir = $this->pathCombine( realpath( $tmp_d ), implode( "/", array_reverse( $tmp_missing_parts ) ) );
|
$rpDir = $this->pathCombine( realpath( $tmp_d ), implode( "/", array_reverse( $tmp_missing_parts ) ) );
|
||||||
$rpConfig = $this->getRootDir();
|
$rpConfig = $this->getRootDir();
|
||||||
|
Reference in New Issue
Block a user