corz.org uses cookies to remember that you've seen this notice explaining that corz.org uses cookies, okay!
<?php // ۞// text { encoding:utf-8 ; bom:no ; linebreaks:unix ; tabs:4sp ; }
$indexer['version'] = '0.6.3.1';
// find: (.*)//distro(\t)?(.*)\n //distro
// replace: \3\n //distro
/*
corz indexer
like an Apache Index (but better looking!)..
This script outputs a nice Apache-like file index. It's HTML5 compliant and
can be easily styled to suit your site or mood.
The included style sheet, you will note, adapts to the screen, progressively
removing columns as the viewport narrows, as well as a few other tricks.
File indexes on a phone? Hell yeas!
Indexer also shows you the number of items /inside/ directories, as well as
the size they occupy, /before/ you enter them.
Of course you can speciy custom icons and descriptions for your files, or
better let corz indexer read your .htaccess (or any similarly-formatted
configuration file) and use /those/. That's right, you can switch from
Apache indexes to corz indexer with almost zero configuration! (a few
optional prefs below)
If you don't use Apache indexing, I hope you find the supplied sample
configuration file (indexer.conf) helpful. You can also use it as-is.
Usage:
There a lot of ways you can use this. The best is probably to drop an
index.php into whatever directory you wish to display indexed. Inside
that file put simply..
require $_SERVER['DOCUMENT_ROOT'].'/inc/indexer.php';
Enclosed in php tags, of course, and with the correct path to wherever
you keep this script. indexer will use the header and footer files from
that same directory, and optionally create a comments facility (if an
index.php.comment file is found in the directory)
Make Big Fun Now!
;o)
(c) 2006->tomorrow! ~ cor + corz.org ;o)
Please view the license for this free software, here:
https://corz.org/free-scripts-licence.nfo
2do..
php files (and/or special files) at the top
(so we don't have to use ---thumbs---.php, etc)
Optionally hide file extensions
*/
/*
prefs.. */
// I put all my prefs in one place.. //distro
require_once $_SERVER['DOCUMENT_ROOT'].'/inc/init.php'; //distro
//:debug:
//:debug:
/*
CSS File..
Styles for indexer. Go nuts!
Separate multiple stylesheets with commas, e.g.
$indexer['styles'] = '/inc/css/main.css,/inc/css/index.css'; // or whatever
They will be imported in the order you list them.
(though with <link>s, so most likely concurrently)
*/
$indexer['styles'] = $site_config['indexer']['styles']; //distro $indexer['styles'] = '/indexer/index.css';
/*
.htaccess file..
corz indexer will read descriptions and (optionally) icon paths from this configuration file.
Specify the path (from site root) to a file containing descriptions, in standard .htaccess
format. NOTE: it's perfectly safe to point it at an actual .htacess file.
*/
$indexer['htaccess_file'] = $site_config['indexer']['htaccess_file'];//distro $indexer['htaccess_file'] = '/indexer/indexer.conf'; // '/.htaccess' = your root .htaccess file.;
/*
This file can have any name and be anywhere accessible by the server process. If you
don't already use Apache's file indexing capabilities, it makes sense to create a whole
new config file, perhaps "/inc/indexer.conf". Everything will work exactly as expected, so
long as you follow the Apache indexing directives format, documented extensively online:
https://corz.org/server/resources/file_view.htaccess.txt
See below these prefs for notes about description and icon path mapping.
*/
/*
Header file..
Exactly the same format of header file Apache uses, will be fine.
Which is to say, a regular HTML page with everything up to where the index begins.
*/
$indexer['header'] = $site_config['indexer']['header'];//distro $indexer['header'] = 'header.php';
// this file lives in whatever directory you are indexing. If it does not exist,
// indexer will use its own built-in (HTML5) page header.
/*
Readme file..
Again, exactly the same format of readme file Apache uses, is fine.
Which is to say, a regular HTML page from where the index ends to the absolute end of the page.
*/
$indexer['readme'] = $site_config['indexer']['readme'];//distro $indexer['readme'] = 'readme.php';
//2do.. fallback options, or specify only basename (no extension) and order, or read .htaccess!!!
// NOTE: The above two named files will not display in the file listings. They are
// automatically ignored. You can ignore other files and folders, too..
// ALSO NOTE: These are "included", so you can put php tags in them, run code. You can
// name them something.php or something.html - it won't make any difference to indexer.
// Either way, php will be parsed, variables available, all that good stuff.
/*
Ignore Files/Folders..
A simple list of files and folders to ignore, separate multiple entries with commas..
Note: indexer will first read the IndexIgnore directive from your .htaccess (specified above)
and parse that. You can add more here..
Note: Shell patterns are allowed.
*/
$indexer['ignore'] = $site_config['indexer']['ignore']; //distro $indexer['ignore'] = 'index.*,thumbs,default-exhibit.txt';
/*
AddIcon Mapping..
This is a good idea. You can map multiple file extensions to a single "icon" file, just
like Apache does. Indexer will grab these mappings from the above named .htaccess file.
*/
$indexer['use_AddIcon'] = $site_config['indexer']['use_AddIcon']; //distro $indexer['use_AddIcon'] = true;
/*
If you are using .htaccess-style icons and descriptions, you are done with prefs now.
Enjoy!
*/
/*
The second icon mapping system is "Extension-Based Icon Mappings".
When using extension-based icon mappings, you don't need a configuration file at all,
simply place corresponding icons files into the icon directory.
The icons are expected to be in the 'img_dir' directory, set here..
*/
/*
Path to custom icons directory..
*/
$indexer['img_dir'] = $site_config['indexer']['img_dir']; //distro $indexer['img_dir'] = '/img/icons/';
/*
"icon" extension.
Traditionally, the "icon" files are not icons at all, but gifs. Here you can specify
the file extension used for your "icons" when using custom (NON-AddIcon) icons.
GIF is no longer proprietry and is actually a handy format for small icons (it stores
transparency values). PNG is probably better these days, though..
*/
$indexer['ico_ext'] = $site_config['indexer']['ico_ext']; //distro $indexer['ico_ext'] = 'gif';
/*
Comments Script
Enter the path to the comments script, from site root.
Leave blank to have the page close automatically..
*/
$indexer['comments_script'] = $site_config['indexer']['comments_script']; //distro $indexer['comments_script'] = '/inc/comments.php';
// NOTE: comments will only load if there is a file.ext.comment file next to the calling file.
// so you can leave enabled and it will only kick-in in places where you have actual comment files.
// a little message to place above the comments (if applicable)..
$indexer['comments_intro_msg'] = $site_config['indexer']['comments_intro_msg']; //distro $indexer['comments_intro_msg'] = '<h2>Comments..</h2>';
/*
Footer Script
Location of siter footer, from site root - leave blank to have the page close automatically..
*/
$indexer['footer'] = $site_config['indexer']['footer']; //distro $indexer['footer'] = '/inc/footer.php';
/*
end prefs */
// add the slash now..
$indexer['img_dir'] .= '/';
/*
A note about icons..
You have a choice of two icon systems. Use whichever you prefer.
* The first ($indexer['use_AddIcon'] = true;) maps the icon paths from an Apache-formatted config file. Basically,
indexer reads your .htaccess (or similarly formatted file) and looks for lines like this..
AddIcon /img/icons/small/text.gif .txt .comment
..and plucks out the path (/img/icons/small/text.gif), and assigns it to the named extensions ('.txt' and
'.comment'). If you run actual Apache indexes on the same site as this indexer, they can share the same icons.
* The second ($indexer['use_AddIcon'] = false;) system assigns icons by their extension.
This is simple to implement - icons are named like so (assuming you have 'gif' as your expension)..
foobar.doc => uses icon => doc.gif
foobar.txt => uses icon => txt.gif
The downside is that you need an actual icon (or symlink to an actual icon) for each file extension.
You will also need to ensure you have 'generic.gif', 'blank.gif' and 'dir.gif' in the same directory.
Of course you can use mapped /or/ extension-based custom icons in the same or different locations.
The best of both worlds!
*/
/*
FYI, a complete .htaccess-style file type (description AND icon directives) would look something like this:
AddIcon /img/icons/text.png .txt .comment
AddDescription "plain text" .txt .comment
You can specify multiple extensions for a single description (as above) or else supply separate descriptions for
each individual extension, e.g..
AddIcon /img/icons/text.png .txt .comment
AddDescription "plain text" .txt
AddDescription "comment file" .comment
It's the same for icons, you could do:
AddIcon /img/icons/text.png .txt
AddIcon /img/icons/commnt.png .comment
AddDescription "plain text" .txt .comment
Or any combination thereof. Indexer will also query your DefaultIcon directive, which is mapped to any unknown file
types, usually "generic.gif" or "unknown.gif"..
DefaultIcon /img/icons/generic.gif
A complete working sample configuration is supplied inside the corz indexer package.
*/
// Let's go..
//
// no site init here, so start session now
// (we will need it for comments, or whatever also you slot into the pages)
//
@session_start();
$version_app = ''; // you can request version information, do ?version
if (isset($_GET['version'])) { $version_app = 'v'.$indexer['version']; }
if (file_exists($indexer['header'])) {
include $indexer['header'];
if ($version_app) {
// using custom header (with title), place in a comment, instead..
echo '
<!--corz indexer ',$version_app,' -->
';
}
} else {
echo '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<title>Index of.. ',dirname($_SERVER['PHP_SELF']),' ..by corz indexer ',$version_app,'</title>';
echo '
<!-- (c) copyright 2000-'.date('Y').' cor + corz.org, some rights reserved -->
<meta name="generator" content="indexer - automated Apache-like-but-better indexing - hand made by cor @ corz.org" />
<meta name="author" content="cor" />
<meta name="publisher" content="corz.org" />
<link rel="shortcut icon" href="/favicon.ico" />';
$style_sheets = explode(',', $indexer['styles']);
foreach ($style_sheets as $my_sheet) {
echo '
<link rel="stylesheet" href="',$my_sheet,'" type="text/css" media="screen" />';
}
echo '
</head>
<body>
<div id="Indexer">
<h3>Index of.. ',dirname($_SERVER['PHP_SELF']),'</h3>';
}
$files = scan_dir_with_style('./');
$mefile = basename($_SERVER['SCRIPT_FILENAME']);
$ht_directives = array();
$icon_paths = array();
if (substr($indexer['htaccess_file'], 0, 1) == '/') { $indexer['htaccess_file'] = substr($indexer['htaccess_file'], 1); }
$raw_directives = file($_SERVER['DOCUMENT_ROOT'].'/'.$indexer['htaccess_file']);
//IndexIgnore..
$ignore_directive = array_keys_partial($raw_directives, 'IndexIgnore');
$ignored = preg_split('/\s+/', trim($ignore_directive[0]));
$ignored = array_merge($ignored, explode(',', trim($indexer['ignore'])));
foreach ($raw_directives as $key=>$value) {
$value = trim($value);
// ignore comments..
if (substr($value, 0, 1) == '#') { continue; }
// grab descriptions..
//
if (stristr($value, 'AddDescription')) {
$elems = explode('"', $value);
$exts = explode(' ', $elems[2]);
foreach ($exts as $thisext) {
if ($thisext) {
$ht_directives[trim($thisext)] = $elems[1];
}
}
}
// Grab Icon paths..
//
if ($indexer['use_AddIcon'] and stristr($value, 'AddIcon')) {
$elems = preg_split('/\s+/', $value);
for ($i=2; $i < count($elems); $i++) {
switch (true) {
case substr($elems[$i], 0, 1) == '.': // regular files
$icon_paths[substr($elems[$i], 1)] = $elems[1];
break;
default :
$icon_paths[$elems[$i]] = $elems[1];
}
}
}
if (stristr($value, 'DefaultIcon')) {
$elems = preg_split('/\s+/', $value);
$icon_paths['unknown'] = $elems[1];
}
}
//echo '<pre>raw_directives:',print_r($raw_directives,true),'</pre>';//:debug
//echo '<pre>ht_directives:',print_r($ht_directives,true),'</pre>';//:debug
//echo '<pre>icon_paths:',print_r($icon_paths,true),'</pre>';//:debug
//
// special icons..
//
if (!$indexer['use_AddIcon']) {
$icon_paths['.'] = $indexer['img_dir'].'back.'.$indexer['ico_ext'];
$icon_paths['^^BLANKICON^^'] = $indexer['img_dir'].'blank.'.$indexer['ico_ext'];
$icon_paths['^^DIRECTORY^^'] = $indexer['img_dir'].'dir.'.$indexer['ico_ext'];
$icon_paths['unknown'] = $indexer['img_dir'].'generic.'.$indexer['ico_ext'];
}
// then the files ..
echo '
<div class="Index">
<div id="IconsTitles" class="Icons Titles"><img src="',$icon_paths['^^BLANKICON^^'],'" alt="Blank-Icon" width="16" height="16"></div>
<div id="Name" class="Name Titles">Name</div>
<div id="LastMod" class="LastMod Titles">Last modified</div>
<div id="Size" class="Size Titles">Size</div>
<div id="Description" class="Description Titles">Description</div>
<hr class="index-top">
<div id="parentIcons" class="Icons Titles"><img src="',$icon_paths['.'],'" alt="ParentIconTitle" width="16" height="16"></div><div class="Name Titles"><a
href="../">Parent Directory</a></div><div class="clear"></div>';
foreach ($files as $file) {
// ignored files..
if ((substr($file, 0, 1) == '.')
or (in_array($file, $ignored))
or ($file == $indexer['header'])
or ($file == $indexer['readme'])
or ($file == $mefile)
) { continue; }
foreach ($ignored as $igfile) {
if (fnmatch($igfile, $file, FNM_CASEFOLD)) { continue 2; }
}
// Icon Column..
//
// reset..
$my_icon = '';
$file_ext = '^^DIRECTORY^^';
$this_description = '';
// regular files..
if (strstr($file, '.')) {
$file_ext = substr($file, strrpos($file, '.') + 1); // "jpg"
// AddIcon-mapped icons..
if ($indexer['use_AddIcon']) {
if (array_key_exists($file_ext, $icon_paths) and file_exists($_SERVER['DOCUMENT_ROOT'].$icon_paths[$file_ext])) {
$my_icon = $icon_paths[$file_ext];
}
} else {
// extension-based custom icons..
if (file_exists($_SERVER['DOCUMENT_ROOT'].$indexer['img_dir'].$file_ext.'.'.$indexer['ico_ext'])) {
$my_icon = $indexer['img_dir'].$file_ext.'.'.$indexer['ico_ext'];
}
}
} elseif (is_dir($file)) {
$my_icon = $icon_paths[$file_ext]; // still '^^DIRECTORY^^'
}
// output the icon, or not..
if (file_exists($_SERVER['DOCUMENT_ROOT'].$my_icon) and !is_dir($_SERVER['DOCUMENT_ROOT'].$my_icon)) {
$my_icon_link = '<img src="'.$my_icon.'" alt="'.$file_ext.'-Icon" width="16" height="16">';
} else { // still not mapped - must be unknown..
$my_icon_link = '<img src="'.$icon_paths['unknown'].'" alt="'.$file_ext.'-Icon" width="16" height="16">';
}
echo '<div class="Icons">',$my_icon_link,'</div>';
// Name Column..
//
echo '<div class="Name"><a href="',$file,'" title="',$file,'">',$file;
if (is_dir($file)) {
echo '/ <span class="smaller">(';
$fsize = foldersize($file);
echo $fsize[1],' items)</span>'; } echo '</a></div>';
// Last Modified column..
//
echo '<div class="LastMod">',date('j-M-y h:i A', filemtime($file)),'</div>';
// Size Column..
//
$this_size = do_nice_filesize($file);
if (is_dir($file)) { $this_size = do_nice_size($fsize[0]); }
echo '<div class="Size">',$this_size,'</div>';
// Description Column..
//
switch (true) {
case is_dir($file):
$this_description = 'directory (folder)';
break;
// known filetype..
case array_key_exists('.'.$file_ext, $ht_directives):
$this_description = $ht_directives['.'.$file_ext];
break;
default :
$this_description = 'unknown file type';
}
echo '<div class="Description">',$this_description,'</div><div class="clear"></div>'."\n";
// need a break, to prevent HUUUUUUUGE lines - some browsers rightly don't like that.
}
// close up the index section..
echo '
<hr class="index-bottom">
</div>';
$foot_str = '';
if (file_exists($_SERVER['DOCUMENT_ROOT'].$indexer['footer'])) {
ob_start();
include $_SERVER['DOCUMENT_ROOT'].$indexer['footer'];
$foot_str = ob_get_clean();
}
// spit out any user readme file..
// we use include so we can parse php tags in readme file.
//
if (file_exists($indexer['readme'])) {
// use a buffer, in case your readme has page closing tags..
ob_start();
include $indexer['readme'];
$readme = ob_get_contents();
ob_end_clean();
// remove those page closing tags..
$end_page = array('</body>', '</html>',);
$readme = str_replace($end_page, '', $readme).'</div>';
echo '
<div class="readme">
'.$readme.'
</div>';
}
if (file_exists($_SERVER['SCRIPT_FILENAME'].'.comment')) {
$intro_msg = $indexer['comments_intro_msg'];
include $_SERVER['DOCUMENT_ROOT'].$indexer['comments_script'];
echo $foot_str.'
</body>
</html>';
exit;
} elseif (!file_exists($indexer['readme'])) {
echo'
</div>';
}
echo $foot_str.'
</body>
</html>';
/*
fin!
*/
// get the size and item count of a dir..
// (including all subdirectories)
//
function foldersize($dir) {
$dir_size = 0;
$count = 0;
$dir_array = scandir($dir);
foreach($dir_array as $key=>$filename) {
if ($filename!=".." and $filename!=".") {
if (is_dir($dir."/".$filename)) {
$new_foldersize = foldersize($dir."/".$filename);
$dir_size = $dir_size + $new_foldersize[0];
$count = $count + $new_foldersize[1];
} else if (is_file($dir."/".$filename)) {
$dir_size = $dir_size + filesize($dir."/".$filename);
$count++;
}
}
}
return array($dir_size, $count);
}
function do_nice_filesize($file) {
$nice_size = 0;
if (file_exists($file)) {
$size = filesize($file);
$nice_size = do_nice_size($size);
}
return $nice_size;
}
function do_nice_size($size) {
if ($size < 1024) {
$nice_size = $size.' Bytes';
} elseif (($size >= 1024) and ($size < 1024000)) {
$nice_size = round($size/1024,2).' KB';
} elseif ($size >= 1024000) {
$nice_size=round(($size/1024)/1024,2).' MB';
}
return $nice_size;
}
// Will sort the dirs and files "naturally", putting dirs before files..
// Also, Upper-Case files & dirs go before lower-case files & dirs.
function scan_dir_with_style($path) {
$sortedDirs = $sortedFiles = array();
$dir_scanned = scandir($path);
natsort($dir_scanned);
foreach($dir_scanned as $file) {
if (is_file($path.$file)) {
array_push($sortedFiles, $file);
} else {
array_push($sortedDirs, $file);
}
}
return array_merge($sortedDirs, $sortedFiles);
}
// like array_keys, but with partial matching..
function array_keys_partial($input, $search_value, $strict=false) {
$foundkeys = array();
foreach ($input as $k=>$v) {
if (substr(trim($v), 0, 1) == '#') { continue; }
if ($strict and strpos($v, $search_value) !== false) {
$foundkeys[] = $v;
} elseif (!$strict and stripos($v, $search_value) !== false) {
$foundkeys[] = $v;
}
}
return $foundkeys;
}
?>