|
// +----------------------------------------------------------------+
//---------------------------------------------------
//------------------- Changes -----------------------
//---------------------------------------------------
//
// Patches
//
// Sept 09, 2001 => v 1.0
// Tim Waugh (tim@cyberelk.net, http://www.cyberelk.net/tim/)
// Added support for multi-dot file names
// (ex. stuff.under.mytoenail.foo as opposed to single-dot
// file names like stuff.foo)
//
// Jan 05, 2002 => v 1.5
// Added more flexibility to file listing inclusion/exclusion
// - can now choose to include only files with specific extensions
// in listings or to list all files, excluding those with specific
// extensions. Added option to block listing of all subdirectories.
// Changed var names to make variable types more obvious (ie
// $arrSomeArray instead of $someArray).
//
// July 13, 2002 => 1.5.1
// Fixed sorting. There was a typo in isortMultiD that
// shortcircuted sorting.
//
// Sept 20, 2002 => 1.5.2
// Fixed sorting (again). Sorting of dirs now works in the same
// fashion as sorting of files. Thanks to Tom/Dphekt for reporting
// the bug.
//
// Feb 16, 2003 => 2.0
// Pulled the guts of the script out into a class.
// Fixed sorting (really).
//
// March 10, 2003 => 2.0.2
// Minor improvements. Added breadcrumbs.
//
// April 15, 2003 => 2.0.5
// Added urldecode calls to get rid of ugly %20's when directory
// being sorted is the current directory and the current directory
// has spaces in its name.
//
// May 2, 2003 => 2.0.6
// Added handling for filenames without extensions, bug reported by
// Jaco Bongers
//
// May 21, 2003 => 2.0.7
// Case-insensitive sorting of file names (but not extensions)
//
// Oct 02, 2003 => 2.0.8
// Groups of files of the same type grouped within the HTML source
// apart from groups of files of other types. Added at the suggestion
// of Michael Stewart.
//---------------------------------------------------
class lophty_directory_indexer
{
var $strIndexerVersion;
var $strThisServerName;
var $strThisFileName;
var $strSystemPathToCallerScriptDir;
var $strUriPathToCallerScriptDir;
var $strIndexerClassFileName;
var $strIndexerCssFilePath;
var $arrIndexerFileImgProps;
var $arrDirImageProps;
var $arrBulletImgs;
var $arrFileExtSpecificBulletImgs;
var $arrFileDescrs;
var $arrDirDescrs;
var $arrDontListFiles;
var $arrDontListDirs;
var $arrDontListFilesExts;
var $arrListOnlyFilesExts;
var $intShowSubdirs;
var $strDirectoryToIndexSystemPath;
var $strDirectoryToIndexUriPath;
var $strDirectoryToIndexName;
var $arrIndexedDirs;
var $arrIndexedFiles;
var $arrSortedIndexedDirs;
var $arrSortedIndexedFiles;
var $intShowBreadCrumbs;
var $intGroupFileExts;
function lophty_directory_indexer($strRequestUri,
$strServerName,
$strSystemPathToCallerScript,
$strThisPageFilesDirPath = "lophtyindexerfiles/",
$strThisFileName='index.php')
{
//---------------------------------------------------
// lophty_directory_indexer : constructor, initialize params.
//---------------------------------------------------
//
// $strThisFileName : the name of this file
//
// $strThisScriptPath : the path to the directory in which
// this page sits. For Apache-served sites, you can use the
// predefined $REQUEST_URI variable. Note that you can also
// specify a string, like a full url, but this will not affect
// the directory that's actually indexed. :D
//
// $strThisPageFilesDirPath : the name of a directory in which
// we'll put the css file and gifs that we need to beautify
// this page Note that you don't have to put those files into
// a directory separate from this file. I just do it to make
// global changes for all of these indexing pages possible -
// by putting the css file and gifs into a folder and then
// giving $strThisPageFilesDirPath the value of the path to
// that folder, you can update the bullets or the general
// appearance of the page by changing a few files in one
// location. If you want to put these files into the same
// directory as this page, that's fine - just give
// $strThisPageFilesDirPath a value of ""
//
// $arrBulletImgs : holds the filenames of the images used
// as bullets.
//
// Finally, remember to change the permissions on subdirectories
// that will be listed by this script if you would like visiors
// to be able to drill down into them.
//
//---------------------------------------------------
$this->strIndexerVersion = 'lophty directory indexer 2.0.8';
$this->strThisScriptPath = $strRequestUri;
$this->strThisServerName = $strServerName;
$this->strSystemPathToCallerScriptDir = $this->getPathToDir($strSystemPathToCallerScript);
$this->strUriPathToCallerScriptDir = 'http://'.$strServerName.$this->getPathToDir($strRequestUri);
//---------------------------------------------------
$this->strThisPageFilesDirPath = $strThisPageFilesDirPath;
$this->strThisFileName = $this->getFileNameFromCompletePath($strRequestUri);
if (empty($this->strThisFileName)) {
$this->strThisFileName = $strThisFileName;
}
$this->strIndexerClassFileName = 'lophty_directory_indexer.php';
$this->strIndexerCssFilePath = $this->strThisPageFilesDirPath."dirindexer.css";
//---------------------------------------------------
$this->arrIndexerFileImgProps = array('filepath' => $this->strThisPageFilesDirPath."file.gif", 'height' => '13', 'width' => '13');
$this->arrDirImageProps = array('filepath' => $this->strThisPageFilesDirPath."dir.gif", 'height' => '13', 'width' => '13');
$this->arrBulletImgs = array('fileImg' => $this->arrIndexerFileImgProps, 'dirImg' => $this->arrDirImageProps);
//---------------------------------------------------
$this->arrFileExtSpecificBulletImgs = array();
//---------------------------------------------------
$this->arrFileDescrs = array();
$this->arrDirDescrs = array();
//---------------------------------------------------
// Add the name of this file and the namess of the files and
// dirs used with it to arrays. When the files and directories
// are read in, files and dirs in these 2 arrays will not by
// listed or counted when this page is viewed. If there are any
// other files other than those actually used by this page that
// you'd rather not have so readily available to others through
// this page, you can add them into these arrays.
//---------------------------------------------------
$this->arrDontListFiles = array($this->strThisFileName, $this->strIndexerClassFileName, $arrBulletImgs['dirImg']['filepath'], $arrBulletImgs['fileImg']['filepath'], $strIndexerCssFilePath);
$this->arrDontListDirs = array($this->strThisPageFilesDirPath, "cgi-bin", "lophtyindexerfiles");
//---------------------------------------------------
// Below are two array declarations. These array declarations
// should contain only string values corresponding to file
// extensions.
//
// Ex. $arrDontListFilesExts = array("jpeg", "jpg", "gif");
//
// Files with extensions listed in the $arrDontListFilesExts array
// will not be shown. If you include any extension strings in the
// $arrListOnlyFilesExts array, then *ONLY* files with those
// extensions will be shown.
//
// Note : use lower case extensions, i.e. txt, not TXT
//
// Ex. (1.)
//
// $arrDontListFilesExts = array();
// $arrListOnlyFilesExts = array();
//
// result : all files (other than any listed in $arrDontListFiles)
// will be shown and counted.
//
//
// Ex. (2.)
//
// $arrDontListFilesExts = array("php");
// $arrListOnlyFilesExts = array();
//
// result : all files (other than any listed in $arrDontListFiles)
// EXCEPT php files will be shown and counted.
//
//
// Ex. (3.)
//
// $arrDontListFilesExts = array();
// $arrListOnlyFilesExts = array("zip");
//
// result : only zip files not listed in $arrDontListFiles
// will be shown and counted.
//
//
// Ex. (4.)
//
// $arrDontListFilesExts = array("txt");
// $arrListOnlyFilesExts = array("zip", "php", "txt");
//
// result : only zip and php files not listed in $arrDontListFiles
// will be shown and counted. Obviously this is a dumb thing to do,
// but it illustrates the precedence between consideration of
// $arrDontListFilesExts and $arrListOnlyFilesExts
//---------------------------------------------------
$this->arrDontListFilesExts = array();
$this->arrListOnlyFilesExts = array();
//---------------------------------------------------
// $intShowSubdirs <= set this to 0 and no directories will be shown.
//---------------------------------------------------
$this->intShowSubdirs = 1;
$this->strDirectoryToIndexSystemPath = '';
$this->strDirectoryToIndexUriPath = '';
$this->strDirectoryToIndexName = '';
$this->intShowBreadCrumbs = 1;
//---------------------------------------------------
// $blnGroupFileExts <= set this to true to have groups of files with
// the same file extension separated by empty spacer tr/td's.
//---------------------------------------------------
$this->blnGroupFileExts = false;
}
function getThisDirName($strUrl)
{
//---------------------------------------------------
// getThisDirName : Accepts the path to the directory either in the
// form of $REQUEST_URI or a string value and pulls out the directory
// name
//---------------------------------------------------
$strAfterCutOne = substr($strUrl, 0, strrpos($strUrl, "/"));
$strAfterCutTwo = substr($strAfterCutOne, strrpos($strAfterCutOne, "/") - strlen($strAfterCutOne) + 1);
return $strAfterCutTwo;
}
function getPathToDir($strPathToFile)
{
//---------------------------------------------------
// getPathToDir : Accepts the path to a file and trims
// away the file name to give the path to the dir.
//---------------------------------------------------
$strPathToDir = substr($strPathToFile, 0, (strrpos($strPathToFile, "/") + 1));
return $strPathToDir;
}
function getFileNameFromCompletePath($strPathToFile)
{
//---------------------------------------------------
// getFileNameFromCompletePath : Accepts the path to a
// file and trims away everything but the filename.
//---------------------------------------------------
$strFileName = substr($strPathToFile, (strrpos($strPathToFile, "/") + 1), (strlen($strPathToFile) +1));
return $strFileName;
}
function constructDirToIndexUriPath()
{
$strDirToIndexUriPath = 'http://'.$this->strThisServerName.$this->strThisScriptPath;
$intPosLastBackSlash = strrpos($strDirToIndexUriPath, '/') + 1;
$strDirToIndexUriPath = substr($strDirToIndexUriPath, 0, $intPosLastBackSlash);
return $strDirToIndexUriPath;
}
function sortDirNames($arrDirNames)
{
//---------------------------------------------------
// sortDirNames :
//
// This function sorts the directory names array
//
//---------------------------------------------------
sort($arrDirNames);
return $arrDirNames;
}
function sortFileNames($arrFileNames)
{
//---------------------------------------------------
// sortFileNames : This function sorts the array of
// arrays of filename fragments (exploded filename on ".").
//---------------------------------------------------
$arrFileExtensions = array(); //holds all file extensions
$arrFilesByExtension = array(); //holds arrays of file name fragments as elements of arrays that are keyed to file extensions
$arrFileNamesSortedReturn = array(); //final array of sorted file names returned
for ($i = 0; $i < count($arrFileNames); $i++) {
$strFileExtension = array_pop($arrFileNames[$i]);
$arrFilesByExtension[$strFileExtension][] = implode('.', $arrFileNames[$i]);
if (!in_array($strFileExtension, $arrFileExtensions)) {
$arrFileExtensions[] = $strFileExtension;
}
}
sort($arrFileExtensions);
for ($i=0; $i < count($arrFileExtensions); $i++) {
$strThisExtension = $arrFileExtensions[$i];
usort($arrFilesByExtension[$strThisExtension], create_function('$a,$b','return strcasecmp($a,$b);'));
for ($j = 0; $j < count($arrFilesByExtension[$strThisExtension]); $j++) {
$arrFilesByExtension[$strThisExtension][$j] = array('filename'=>$arrFilesByExtension[$strThisExtension][$j], 'ext'=>$strThisExtension);
}
$arrFileNamesSortedReturn = array_merge($arrFileNamesSortedReturn, $arrFilesByExtension[$strThisExtension]);
}
return $arrFileNamesSortedReturn;
}
function indexDir($strDirectoryToIndexSystemPath = '.', $strDirectoryToIndexUriPath = '', $strDirectoryToIndexName = '')
{
//---------------------------------------------------
// indexdirThisDir : This function scours through the current
// directory (regardless of which directory u specify via the
// getThisDirName call) and makes a list of directories and
// does the same for files, first by their extensions and
// then by their names. Remember that since it's only
// alphabetical on the first char php and phtml or php3 and
// php files will be jumbled together, as will html and htm
// (the same logic holds for file names).
//---------------------------------------------------
$arrBulletImgs = $this->arrBulletImgs;
$arrDontListFiles = $this->arrDontListFiles;
$arrDontListDirs = $this->arrDontListDirs;
$arrListOnlyFilesExts = $this->arrListOnlyFilesExts;
$arrDontListFilesExts = $this->arrDontListFilesExts;
$intShowSubdirs = $this->intShowSubdirs;
//---------------------------------------------------
$intNumHiddenDirs = 0;
$intNumHiddenFiles = 0;
//---------------------------------------------------
$arrDirs = array();
$arrFiles = array();
$this->arrIndexedDirs = &$arrDirs;
$this->arrIndexedFiles = &$arrFiles;
//---------------------------------------------------
$arrSortedDirs = array();
$arrSortedFiles = array();
$this->arrSortedIndexedDirs = &$arrSortedDirs;
$this->arrSortedIndexedFiles = &$arrSortedFiles;
//---------------------------------------------------
if (empty($strDirectoryToIndexUriPath)) {
$this->strDirectoryToIndexUriPath = $this->constructDirToIndexUriPath();
}
//---------------------------------------------------
// Drop path to and name of directory being indexed
// into class properties.
//---------------------------------------------------
$this->strDirectoryToIndexSystemPath = $strDirectoryToIndexSystemPath;
if (!empty($strDirectoryToIndexName)) {
//---------------------------------------------------
// They've provided a dir name
//---------------------------------------------------
$this->strDirectoryToIndexName = $strDirectoryToIndexName;
} elseif ($strDirectoryToIndexSystemPath != '.') {
//---------------------------------------------------
// They haven't provided a dir name, but they don't seem
// to be indexing the current dir
//---------------------------------------------------
$this->strDirectoryToIndexName = $this->getThisDirName($strDirectoryToIndexSystemPath);
} elseif ($strDirectoryToIndexSystemPath == '.') {
//---------------------------------------------------
// Indexing the current dir
//---------------------------------------------------
$this->strDirectoryToIndexName = $this->getThisDirName($this->strThisScriptPath);
} else {
$this->strDirectoryToIndexName = 'unnamed directory';
}
$this->strDirectoryToIndexName = urldecode($this->strDirectoryToIndexName);
//---------------------------------------------------
$strPathToFileDirForStat = '';
if ($strDirectoryToIndexSystemPath != '.') {
$strPathToFileDirForStat = $strDirectoryToIndexSystemPath;
}
//---------------------------------------------------
// Get a handle on the directory.
//---------------------------------------------------
$handleThisDir=opendir($strDirectoryToIndexSystemPath);
while (false !== ($handleFileORdir = readdir($handleThisDir))) {
if ($handleFileORdir != "." && $handleFileORdir != "..") {
if (is_dir($strPathToFileDirForStat.$handleFileORdir)== false) {
//---------------------------------------------------
// It's a file
//---------------------------------------------------
$thisFileNoShow = 1;
//---------------------------------------------------
// (1.) explode file name on '.'
//---------------------------------------------------
$arrFileNameAndExtension = explode(".", $handleFileORdir);
//---------------------------------------------------
$arrFileExtBits = $arrFileNameAndExtension;
$strFirstBit = array_shift($arrFileExtBits);
//---------------------------------------------------
// (2.) does this file posess an extension included in a list of "only show" extensions or a list of "don't show" extensions ?
//---------------------------------------------------
if ((count($arrListOnlyFilesExts) > 0) || (count($arrDontListFilesExts) > 0)) {
$intExtensionOK = 0;
$intIndexFileExtension = count($arrFileExtBits);
if (count($arrListOnlyFilesExts) > 0) {
if (in_array(strtolower($arrFileNameAndExtension[$intIndexFileExtension]), $arrListOnlyFilesExts)) {
$intExtensionOK = 1;
}
} elseif (count($arrListOnlyFilesExts) == 0) {
$intExtensionOK = 1;
}
//---------------------------------------------------
if (in_array(strtolower($arrFileNameAndExtension[$intIndexFileExtension]), $arrDontListFilesExts)) {
$intExtensionOK = 0;
}
//---------------------------------------------------
// (Act on whether or not the extension was found in that list
//---------------------------------------------------
if ($intExtensionOK == 1) {
$thisFileNoShow = 0;
}
} else {
$thisFileNoShow = 0;
}
//---------------------------------------------------
// is this file in a list of files designated as not to be shown?
//---------------------------------------------------
if (in_array($handleFileORdir, $arrDontListFiles)) {
$thisFileNoShow = 1;
}
//---------------------------------------------------
if($thisFileNoShow == 0) {
array_push ($arrFiles, $arrFileNameAndExtension);
}
} else {
//---------------------------------------------------
// It's a directory
//---------------------------------------------------
$intThisDirNoShow = 0;
if ($this->intShowSubdirs > 0) {
for ($i = 0; $i < count($arrDontListDirs); $i++) {
if($handleFileORdir == $arrDontListDirs[$i]) {
$intThisDirNoShow = 1;
break;
}
}
if($intThisDirNoShow == 0) {
array_push ($arrDirs, $handleFileORdir);
}
}
}
}
}
//---------------------------------------------------
closedir($handleThisDir);
//---------------------------------------------------
$arrSortedDirs = $this->sortDirNames($arrDirs);
$arrSortedFiles = $this->sortFileNames($arrFiles);
//---------------------------------------------------
$arrFilesDirs = array('dirs'=>$arrSortedDirs, 'files'=>$arrSortedFiles);
return $arrFilesDirs;
}
function returnDirsListHTMLChunk($arrDirs = '', $strDirectoryToIndexUriPath='')
{
//---------------------------------------------------
// returnDirsListHTMLChunk : accepts an array of dir names
// and uri to the directory. Returns dir listing HTML chunk.
//---------------------------------------------------
$arrBulletImgs = $this->arrBulletImgs;
$arrDontListFiles = $this->arrDontListFiles;
$arrDontListDirs = $this->arrDontListDirs;
$arrListOnlyFilesExts = $this->arrListOnlyFilesExts;
$arrDontListFilesExts = $this->arrDontListFilesExts;
$intShowSubdirs = $this->intShowSubdirs;
$arrDirDescrs = $this->arrDirDescrs;
//---------------------------------------------------
if (!empty($strDirectoryToIndexUriPath)) {
$this->strDirectoryToIndexUriPath = $strDirectoryToIndexUriPath;
}
//---------------------------------------------------
$strListingHTML = '';
if (empty($arrDirs)) {
$arrDirs = $this->arrIndexedDirs;
}
//---------------------------------------------------
if (($intShowSubdirs != 0) && (count($arrDirs) > 0)) {
$arrDirDescrsKeys = array_keys($arrDirDescrs);
$strListingHTML .="\n".'
';
//---------------------------------------------------
// Is there a description for this directory? If so,
// show it beneath the directory listing itself
//---------------------------------------------------
if (in_array($arrDirs[$i], $arrDirDescrsKeys)) {
$strListingHTML .= '
';
//---------------------------------------------------
// Is there a description for this file? If so,
// show it beneath the file listing itself
//---------------------------------------------------
if (in_array($strFileName, $arrFileDescrsKeys)) {
$strThisFileTrs .= '
'.$arrFileDescrs[$strFileName].'
';
}
return $strThisFileTrs;
}
function returnFilesListHTMLChunk($arrFileNames='', $strDirectoryToIndexSystemPath='', $strDirectoryToIndexUriPath='')
{
//---------------------------------------------------
// returnFilesListHTMLChunk : accepts an array of file names
// and the system path and uri to the directory. Returns
// file listing HTML chunk.
//---------------------------------------------------
$strListingHTML = '';
if (count($arrFileNames) > 0) {
$intNumLastFileIndex = count($arrFileNames) - 1;
$strListingHTML .='
file
size (kb)
last modified
';
//---------------------------------------------------
for ($i = 0; $i < count($arrFileNames); $i++) {
//---------------------------------------------------
// Open table if this is the first file OR close table and open
// a new one if this is the first file in a set of files with a
// different file extension than the previous set.
//---------------------------------------------------
$intPrevFileIndex = $i - 1;
if (($intPrevFileIndex >= 0) && ($this->blnGroupFileExts) && ($arrFileNames[$i]['ext'] != $arrFileNames[$intPrevFileIndex]['ext'])) {
$strListingHTML .= '