Feel free to improve it here, but PLEASE fill the ‘notes’ field below to explain your contribution.
documentation
An url like http://www.your-site.com/index.php/browser/virtual_root/path will allow people to browse directories and files that are under path from absolute_path. You define an absolute_path (in the file system of the server) for a virtual_root with this array
var $roots = array(
'virtual_root' => 'absolute_path',
//...
);
This may allow us to browse files that are outside your web root, forcing the browsing via CI, and allowing us full control on accesses (not provided for the moment).
todo
* stats for directories and files
* links for sorting directories and files
* clever css markup
* several examples of stylesheets
* bells and hooks and whistles and filters to check accesses
* ...
the controller
<?php
// may only work if this controller is not in a subfolder
class Browser extends Controller {
var $roots = array(
'test' => '/home'
);
function Browser()
{
parent::Controller();
// FAL check here
}
function _remap()
{
$segment_array = $this->uri->segment_array();
// first and second segments are our controller and the 'virtual root'
$controller = array_shift( $segment_array );
$virtual_root = array_shift( $segment_array );
if( empty( $this->roots )) exit( 'no roots defined' );
// let's check if a virtual root is choosen
// if this controller is the default controller, first segment is 'index'
if ( $controller == 'index' OR $virtual_root == '' ) show_404();
// let's check if a virtual root matches
if ( ! array_key_exists( $virtual_root, $this->roots )) show_404();
// build absolute path
$path_in_url = '';
foreach ( $segment_array as $segment ) $path_in_url.= $segment.'/';
$absolute_path = $this->roots[ $virtual_root ].'/'.$path_in_url;
$absolute_path = rtrim( $absolute_path ,'/' );
// is it a directory or a file ?
if ( is_dir( $absolute_path ))
{
// we'll need this to build links
$this->load->helper('url');
$dirs = array();
$files = array();
// let's traverse the directory
if ( $handle = @opendir( $absolute_path ))
{
while ( false !== ($file = readdir( $handle )))
{
if (( $file != "." AND $file != ".." ))
{
if ( is_dir( $absolute_path.'/'.$file ))
{
$dirs[]['name'] = $file;
}
else
{
$files[]['name'] = $file;
}
}
}
closedir( $handle );
sort( $dirs );
sort( $files );
}
// parent directory
// here to ensure it's available and the first in the array
if ( $path_in_url != '' )
array_unshift ( $dirs, array( 'name' => '..' ));
// send the view
$data = array(
'controller' => $controller,
'virtual_root' => $virtual_root,
'path_in_url' => $path_in_url,
'dirs' => $dirs,
'files' => $files,
);
$this->load->view( 'browser', $data );
}
else
{
// it's not a directory, but is it a file ?
if ( is_file( $absolute_path ))
{
// let's serve the file
header ('Cache-Control: no-store, no-cache, must-revalidate');
header ('Cache-Control: pre-check=0, post-check=0, max-age=0');
header ('Pragma: no-cache');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize( ".$absolute_path." ));
header('Content-Disposition: attachment; filename=' . basename( $absolute_path ));
@readfile( $absolute_path );
}
else
{
show_404();
}
}
}
}
the view
<h1><?=$virtual_root?></h1>
<h2><?='/'.$path_in_url?></h2>
<?php
$prefix = $controller.'/'.$virtual_root.'/'.$path_in_url;
if (!empty($dirs)) foreach( $dirs as $dir )
echo 'd '.anchor($prefix.$dir['name'], $dir['name']).'<br>';
if (!empty($files)) foreach( $files as $file )
echo anchor($prefix.$file['name'], $file['name']).'<br>';
?>
