/*
* Copyright 2003 - 2005 Mark O'Sullivan
* This file is part of the Lussumo Filebrowser.
* The Lussumo Filebrowser is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
* The Lussumo Filebrowser is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with the Lussumo Filebrowser; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* The latest source code is available at www.lussumo.com
* Contact Mark O'Sullivan at mark [at] lussumo [dot] com
*
* Description: The main application file that draws the filebrowser.
*/
error_reporting(E_ALL);
// Global Constants
define("sgLIBRARY", "c:/applications/lussumo/GlobalLibrary/");
// Define XML Node Types
define("XmlNodeTypeContainer", 1);
define("XmlNodeTypeContent", 2);
// Force a boolean value
// Accept a default value if the input value does not represent a boolean value
function ForceBool($InValue, $DefaultBool) {
// If the invalue doesn't exist (ie an array element that doesn't exist) use the default
if (!$InValue) $InValue = $DefaultBool;
$InValue = strtoupper($InValue);
$bReturn = $DefaultBool;
if ($InValue == "TRUE" || $InValue == "FALSE" || $InValue == 1 || $InValue == 0 || $InValue == "Y" || $InValue == "N") {
if ($InValue == "TRUE" || $InValue == 1 || $InValue == "Y") {
$bReturn = 1;
} else {
$bReturn = 0;
}
}
return $bReturn;
}
// Check both the get and post incoming data for a variable
function ForceIncomingBool($VariableName, $DefaultBool) {
// First check the querystring
$bReturn = ForceSet(@$_GET[$VariableName], $DefaultBool);
$bReturn = ForceBool($bReturn, $DefaultBool);
// If the default value was defined, then check the post variables
if ($bReturn == $DefaultBool) {
$bReturn = ForceSet(@$_POST[$VariableName], $DefaultBool);
$bReturn = ForceBool($bReturn, $DefaultBool);
}
return $bReturn;
}
// Check both the get and post incoming data for a variable
// Does not allow integers to be less than 0
function ForceIncomingInt($VariableName, $DefaultValue) {
// First check the querystring
$iReturn = ForceSet(@$_GET[$VariableName], $DefaultValue);
$iReturn = ForceInt($iReturn, $DefaultValue);
// If the default value was defined, then check the form variables
if ($iReturn == $DefaultValue) {
$iReturn = ForceSet(@$_POST[$VariableName], $DefaultValue);
$iReturn = ForceInt($iReturn, $DefaultValue);
}
// If the value found was less than 0, set it to the default value
if($iReturn < 0) $iReturn == $DefaultValue;
return $iReturn;
}
// Check both the get and post incoming data for a variable
function ForceIncomingString($VariableName, $DefaultValue) {
// First check the querystring
$sReturn = ForceSet(@$_GET[$VariableName], $DefaultValue);
$sReturn = ForceString($sReturn, $DefaultValue);
// If the default value was defined, then check the post variables
if ($sReturn == $DefaultValue) {
$sReturn = ForceSet(@$_POST[$VariableName], $DefaultValue);
$sReturn = ForceString($sReturn, $DefaultValue);
}
// And strip slashes from the string
$sReturn = stripslashes($sReturn);
return $sReturn;
}
// Take a value and force it to be an integer.
function ForceInt($InValue, $DefaultValue) {
$iReturn = intval($InValue);
if ($iReturn == 0) $iReturn = $DefaultValue;
return $iReturn;
}
// Takes a variable and checks to see if it's set.
// Returns the value if set, or the default value if not set.
function ForceSet($InValue, $DefaultValue) {
if(isset($InValue)) {
$sReturn = $InValue;
} else {
$sReturn = $DefaultValue;
}
return $sReturn;
}
// Take a value and force it to be a string.
function ForceString($InValue, $DefaultValue) {
if (is_string($InValue)) {
$sReturn = trim($InValue);
$length = strlen($sReturn);
if($length == 0) $sReturn = $DefaultValue;
} else {
$sReturn = $DefaultValue;
}
return $sReturn;
}
function SaveAsDialogue($FolderPath, $FileName, $DeleteFile = "0") {
$DeleteFile = ForceBool($DeleteFile, 0);
$FolderPath = ($FolderPath != "")?$FolderPath."/".$FileName:$FileName;
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename=$FileName");
header("Content-Transfer-Encoding: binary");
readfile($FolderPath);
if ($DeleteFile) unlink($FolderPath);
die();
}
class Error2 {
var $AffectedElement; // The element (class) that has encountered the error
var $AffectedFunction; // The function or method that has encountered the error
var $Message; // Actual error message
var $Code; // Any related code to help identify the error
}
class ErrorManager {
// Public Variables
var $StyleSheet; // A custom stylesheet may be supplied for the error display
// Public, Read Only Variables
var $ErrorCount; // Number of errors encountered
// Private Variables
var $Errors; // Collection of error objects
function AddError(&$Context, $AffectedElement, $AffectedFunction, $Message, $Code = "", $WriteAndKill = 1) {
if ($Context) {
$Error = $Context->ObjectFactory->NewObject($Context, "Error");
} else {
$Error = new Error2();
}
$Error->AffectedElement = $AffectedElement;
$Error->AffectedFunction = $AffectedFunction;
$Error->Message = $Message;
$Error->Code = $Code;
$this->Errors[] = $Error;
$this->ErrorCount += 1;
if ($WriteAndKill == 1) $this->Write($Context);
}
function Clear() {
$this->ErrorCount = 0;
$this->Errors = array();
}
function ErrorManager() {
$this->Clear();
}
function Iif($True = "1", $False = "0") {
if ($this->ErrorCount == 0) {
return $True;
} else {
return $False;
}
}
function Write(&$Context) {
echo("
The page could not be displayed
");
if ($this->StyleSheet == "") {
echo("
");
} else {
echo("StyleSheet."\" />\r\n");
}
echo("
".$Code."
");
}
}
if ($Context) {
if ($Context->Mode == agMODE_DEBUG && $Context->SqlCollector) {
echo("
Database queries run prior to error
");
$Context->SqlCollector->Write();
}
}
echo("
For additional support documentation, visit the Lussumo Software support website at: lussumo.com/support
");
// Cleanup
if ($Context) $Context->Unload();
die();
}
function GetSimple() {
$sReturn = "";
for ($i = 0; $i < count($this->Errors); $i++) {
$sReturn .= ForceString($this->Errors[$i]->Message, "No error message supplied\r\n");
}
return $sReturn;
}
}
class Parameters {
var $aParameters = array();
// Add an element to the collection
function Add($Name, $Value, $EncodeValue = 1) {
if ($EncodeValue && !is_array($Value)) $Value = urlencode($Value);
$this->aParameters[$Name] = $Value;
}
// Completely clear the collection
function Clear() {
$this->aParameters = array();
}
// Return a count of how many elements are in the collection
function Count() {
return count($this->aParameters);
}
// Retrieves all get and post variables
function DefineCollection($Collection, $ParameterPrefix = "", $IncludeByPrefix = "0", $ExcludeByPrefix = "0") {
$ParameterPrefix = ForceString($ParameterPrefix, "");
$IncludeByPrefix = ForceBool($IncludeByPrefix, 0);
$ExcludeByPrefix = ForceBool($ExcludeByPrefix, 0);
$Add = 1;
while (list($key, $value) = each($Collection)) {
$Add = 1;
if ($ParameterPrefix != "") {
$PrefixMatchLocation = strstr($key, $ParameterPrefix);
// If the prefix isn't found or the location is anywhere other than 0 (the start of the variable name)
if ($PrefixMatchLocation === false || $PrefixMatchLocation != 0) {
if ($IncludeByPrefix) $Add = 0;
} else {
if ($ExcludeByPrefix) $Add = 0;
}
}
if ($Add) $this->Add($key, $value);
}
}
function GetHiddenInputs() {
$sReturn = "";
while (list($key, $val) = each($this->aParameters)) {
if(is_array($val)) {
$nmrows = count($val);
for ($i = 0; $i < $nmrows; ++$i) {
$sReturn .= "\r\n";
}
} else {
$sReturn .= "\r\n";
}
}
reset($this->aParameters);
return $sReturn;
}
// Return the collection as a string in querystring name/value pair format
function GetQueryString() {
$sReturn = "";
while (list($key, $val) = each($this->aParameters)) {
if(is_array($val)) {
$nmrows = count($val);
for ($i = 0; $i < $nmrows; ++$i) {
$sReturn .= $key ."[]=" . $val[$i] . "&";
}
} else {
$sReturn .= $key . "=" . $val . "&";
}
}
// remove trailing ampersand
$sReturn = substr($sReturn,0,strlen($sReturn) - 5);
if ($sReturn != "") $sReturn = "?".$sReturn;
reset($this->aParameters);
return $sReturn;
}
// Remove an element from the collection
function Remove($Name) {
$key_index = array_keys(array_keys($this->aParameters), $Name);
if (count($key_index) > 0) array_splice($this->aParameters, $key_index[0], 1);
}
// Set a value. If it already exists, overwrite it.
function Set($Name, $Value, $EncodeValue = 1) {
$this->Remove($Name);
$this->Add($Name, $Value, $EncodeValue);
}
}
class XmlNode {
var $Name; // The name of this element as defined by it's xml tag
var $Type; // Type of node (1. contains other nodes, 2. contains data)
var $Attributes; // Attributes in the current tag element
var $Value; // value of the current element
var $Child; // Array of child elements
}
class XmlManager {
var $ErrorManager; // Error message collector
var $Name; // The name of this class
// Searches through the given node to search for a child node with the supplied name
// returns the node if found, returns false otherwise
function GetNodeByName($NodeToSearch, $NodeName) {
$Node = false;
for ($i = 0; $i < count($NodeToSearch->Child); $i++) {
if ($NodeToSearch->Child[$i]->Name == $NodeName) $Node = $NodeToSearch->Child[$i];
}
return $Node;
}
function GetNodeValueByName($NodeToSearch, $NodeName) {
$Node = $this->GetNodeByName($NodeToSearch, $NodeName);
if ($Node) {
return $Node->Value;
} else {
false;
}
}
// Takes a string of xml and parses it recursively returning a fully descript root node
function ParseNode($XmlString) {
// Retrieve the first xml tag in the file
$XmlString = trim($XmlString);
$RootNodeStartTag = strpos($XmlString, "<");
$RootNodeEndTag = strpos($XmlString, ">");
$RootNodeName = "";
$RootNodeAttributes = array();
$FauxContext = "0";
// If the opening tag exists, parse it out
if ($RootNodeStartTag === false || $RootNodeEndTag === false) {
$this->ErrorManager->AddError($FauxContext,$this->Name, "ParseNode", "A fatal error occurred while attempting to parse xml nodes. Syntax Error: xml not properly defined.");
} else {
$RootNodeName = trim(substr($XmlString, $RootNodeStartTag+1, $RootNodeEndTag-1));
// Evaluate the tag for attributes
$SpacePosition = strpos($RootNodeName, " ");
if ($SpacePosition !== false) {
$sAttributes = trim(substr($RootNodeName,$SpacePosition,strlen($RootNodeName)-$SpacePosition));
$RootNodeName = trim(substr($RootNodeName,0,$SpacePosition));
$tmpArray = explode("=",$sAttributes);
$i = 0;
$ArrayKeys = count($tmpArray)-1;
$Name = "";
while($i < $ArrayKeys) {
if ($i+1 <= $ArrayKeys) {
if ($Name == "") $Name = ForceString($tmpArray[$i],"");
$Value = ForceString($tmpArray[$i+1],"");
if (strpos($Value,"\"") === 0) $Value = substr($Value,1);
$NextQuotePosition = strpos($Value,"\"");
$NextName = "";
if ($NextQuotePosition !== false) {
$NextName = trim(substr($Value,$NextQuotePosition));
$Value = substr($Value,0,$NextQuotePosition);
}
$RootNodeAttributes[$Name] = $Value;
$Name = $NextName;
}
$i += 2;
}
}
}
// Double check to see that the root tag name has been properly defined
if ($RootNodeName == "") $this->ErrorManager->AddError($FauxContext,$this->Name, "ParseNode", "Node name not defined.");
$Node = new XmlNode();
$Node->Name = $RootNodeName;
$Node->Attributes = $RootNodeAttributes;
// Get content from within the root tag
$RootNodeStartCloseTag = strpos($XmlString,"".$RootNodeName.">");
$XmlString = substr($XmlString, $RootNodeEndTag+1, $RootNodeStartCloseTag-$RootNodeEndTag-1);
// Check the inner content to define the current node type
if (strpos($XmlString, "<") !== false && strpos($XmlString, ">") !== false) {
$Node->Type = XmlNodeTypeContainer;
} else {
$Node->Type = XmlNodeTypeContent;
}
if ($Node->Type == XmlNodeTypeContent) {
// If the current node holds content, return it
$Node->Value = $XmlString;
} else {
// If the current node contains more nodes, parse it
// Define nodes until entire xmlstring has been handled at this level
$HandlerComplete = false;
while(!$HandlerComplete) {
// Defind the node name
$NodeStartOpenTag = strpos($XmlString, "<");
$NodeEndOpenTag = strpos($XmlString, ">");
$NodeName = trim(substr($XmlString, $NodeStartOpenTag+1, $NodeEndOpenTag-1-$NodeStartOpenTag));
// Check the Node Name for any spaces and remove anything if it exists
$SpacePosition = strpos($NodeName," ");
if ($SpacePosition !== false) $NodeName = substr($NodeName, 0, $SpacePosition);
// Find the position of the closing tag for this node
$NodeStartCloseTag = strpos($XmlString,"".$NodeName.">");
$NodeEndCloseTag = $NodeStartCloseTag+strlen($NodeName)+3;
// If it wasn't found, throw an error and break the loop
if ($NodeStartCloseTag === false) {
$this->ErrorManager->AddError($FauxContext,$this->Name, "ParseNode", "Closing tag for \"$NodeName\" node not defined.");
break;
// If the tag was found, return everything from the beginning to the end and parse it into a child
} else {
$NewXmlNodeString = substr($XmlString,$NodeStartOpenTag,$NodeEndCloseTag);
$Node->Child[] = $this->ParseNode($NewXmlNodeString);
}
if (strlen($XmlString) > $NodeEndCloseTag) {
$XmlString = trim(substr($XmlString, $NodeEndCloseTag, strlen($XmlString)));
} else {
$XmlString = "";
}
if ($XmlString == "") $HandlerComplete = true;
}
}
return $Node;
}
function XmlManager() {
$this->Name = "XmlManager";
}
}
class File {
var $Name;
var $Extension;
var $Path; // Directory path to the file
var $Body;
var $Size;
}
class FileManager {
var $ErrorManager;
var $Name;
function FileExtension($File) {
if (strstr($File->Name, '.')) {
return substr(strrchr($File->Name, '.'), 1, strlen($File->Name));
} else {
return "";
}
}
function FileManager() {
$this->Name = "FileManager";
}
function FilePath($File) {
if (substr($File->Path, strlen($File->Path) - 1, strlen($File->Path)) != "/") $File->Path .= "/";
return $File->Path.$File->Name;
}
function Get($File) {
// Ensure required properties are set
$FauxContext = 0;
if ($File->Name == "") $this->ErrorManager->AddError($FauxContext, $this->Name, "Get", "You must supply a file name.", "", 0);
if ($File->Path == "") $this->ErrorManager->AddError($FauxContext, $this->Name, "Get", "You must supply a file path.", "", 0);
if ($this->ErrorManager->ErrorCount == 0) {
$File->Extension = $this->FileExtension($File);
$FilePath = $this->FilePath($File);
$FileHandle = @fopen($FilePath, "r");
if (!$FileHandle) {
$this->ErrorManager->AddError($FauxContext, $this->Name, "Get", "The file could not be opened.", $FilePath, 0);
} else {
$File->Size = filesize($FilePath);
$File->Body = @fread($FileHandle, $File->Size);
if (!$File->Body) $this->ErrorManager->AddError($FauxContext, $this->Name, "Get", "The file could not be read.", "", 0);
@fclose($FileHandle);
}
}
return $this->ErrorManager->Iif($File, false);
}
}
function CurrentUrl() {
return basename(ForceString(@$_SERVER["PHP_SELF"], ""));
}
function CurrentWebPath() {
$SelfWebPath = ForceString(@$_SERVER["HTTP_HOST"], "").ForceString(@$_SERVER["PHP_SELF"], "");
// Strip filename from webpath if exists
if (strpos($SelfWebPath, CurrentUrl()) !== false) $SelfWebPath = substr($SelfWebPath,0,strpos($SelfWebPath, CurrentUrl()));
if ($SelfWebPath != "") $SelfWebPath = "http://".$SelfWebPath;
return $SelfWebPath;
}
function FilePath($Path, $File) {
if (substr($Path, strlen($Path) - 1, strlen($Path)) != "/") $Path .= "/";
return $Path.$File;
}
function FormatDisplayedItem($ItemID, $FileName, $FileSize, $HandlerMethod, &$Params, $Config) {
$FolderPath = substr($Config->CurrentBrowsingDirectory, strlen($Config->CurrentWorkingDirectory)+1,(strlen($Config->CurrentBrowsingDirectory)-strlen($Config->CurrentWorkingDirectory)+1));
$FolderPath = ($FolderPath != "")?$FolderPath."/".$FileName:$FileName;
$EncodedPath = EncodeLinkUrl(FilePath(CurrentWebPath(),$FolderPath));
$Params->Add("gid", $ItemID);
$Return = "
\r\n";
return $Return;
}
// Append a folder name to the current browsing directory
function AppendFolder($RootPath, $FolderToAppend) {
if (substr($RootPath, strlen($RootPath)-1, strlen($RootPath)) == "/") $RootPath = substr($RootPath, 0, strlen($RootPath) - 1);
if (substr($FolderToAppend,0,1) == "/") $FolderToAppend = substr($FolderToAppend,1,strlen($FolderToAppend));
return $RootPath."/".$FolderToAppend;
}
// Build the navigation path to the current browsing directory
function BuildPath($FolderNavigator, $FilesPerPage = "10") {
$s = "";
for ($i = 0; $i < count($FolderNavigator); $i++) {
$s .= "/".$FolderNavigator[$i][0]."";
}
return $s;
}
function BuildLiteralPath($FolderNavigator) {
$s = "";
for ($i = 0; $i < count($FolderNavigator); $i++) {
$s .= "/".$FolderNavigator[$i][0];
}
return $s;
}
// returns the complete path to the folder or false if not found
function CheckForFolder($Path, $FolderKey, &$Config) {
$FolderHandle = opendir($Path);
$aCurrentSubFolders = array();
// Only look at folders
while (false !== ($Item = readdir($FolderHandle))) {
if ($Item != '.'
&& $Item != '..'
&& is_dir($Path."/".$Item)
&& !in_array($Path."/".$Item, $Config->FullyQualifiedHideFiles)) $aCurrentSubFolders[] = $Item;
}
closedir($FolderHandle);
// Sort the folders according to the config setting
usort($aCurrentSubFolders, "strcasecmp");
reset($aCurrentSubFolders);
if ($Config->SortDirection == "desc") $aCurrentSubFolders = array_reverse($aCurrentSubFolders);
// If the key supplied is less than the total count of folders found, append the folder name to the path
if ($FolderKey < count($aCurrentSubFolders)) {
$Config->FolderNavigatorLocation = FormatDelimitedString($Config->FolderNavigatorLocation, $FolderKey, $Config->FolderDelimiter);
$Config->FolderNavigator[] = array($aCurrentSubFolders[$FolderKey], $Config->FolderNavigatorLocation);
return AppendFolder($Path, $aCurrentSubFolders[$FolderKey]);
} else {
return false;
}
}
function EncodeLinkUrl($Url) {
return str_replace("'", "%27", $Url);
}
function FormatDelimitedString($String, $Addition, $Delimiter) {
$String = $String."";
$Addition = $Addition."";
$String = trim($String);
$StringLength = strlen($String);
if ($String != "") {
if (substr($String,0,1) == $Delimiter) $String = substr($String, 1, $StringLength-1);
if (substr($String,$StringLength-1,$StringLength) == $Delimiter) $String = substr($String, 0, $StringLength-1);
}
$Addition = ForceString($Addition, "");
$AdditionLength = strlen($Addition);
if ($Addition != "") {
if (substr($Addition,0,1) == $Delimiter) $Addition = substr($Addition, 1, $AdditionLength-1);
if (substr($Addition,$AdditionLength-1,$AdditionLength) == $Delimiter) $Addition = substr($Addition, 0, $AdditionLength-1);
}
$sReturn = "";
if ($String != "" && $Addition != "") {
$sReturn = $String.$Delimiter.$Addition;
} elseif ($String != "" && $Addition == "") {
$sReturn = $String;
} elseif ($String == "" && $Addition != "") {
$sReturn = $Addition;
}
return $sReturn;
}
function FormatFileSize($FileSize) {
if ($FileSize > 1048576) {
return intval((($FileSize / 1048576) * 100) + 0.5) / 100 ."mb";
} elseif ($FileSize > 1024) {
return ceil($FileSize / 1024)."kb";
} else {
return $FileSize."b";
}
}
// strip the file extension from a file name
function GetExtension($FileName) {
if (strstr($FileName, '.')) {
return strtolower(substr(strrchr($FileName, '.'), 1, strlen($FileName)));
} else {
return "";
}
}
class FileCollection {
var $Name; // Name of the current collection
var $FileNames; // Array of file names
var $LowerFileNames;// Array of file names in lowercase (for sorting)
var $FileSizes; // Array of file sizes
var $FileDates; // Array of file dates
var $HandlerMethods;// Array of handler methods
function AddFile($Name, $Size, $Date, $HandlerMethod) {
$this->FileNames[] = $Name;
$this->LowerFileNames[] = strtolower($Name);
$this->FileSizes[] = $Size;
$this->FileDates[] = $Date;
$this->HandlerMethods[] = $HandlerMethod;
}
function BuildAssociativeFileArray($OrderedArray, $ThumbnailArray) {
reset($OrderedArray);
$AssociativeArray = array();
while (list($key, $val) = each($OrderedArray)) {
$AssociativeArray[] = array("Name" => $this->FileNames[$key], "Size" => FormatFileSize($this->FileSizes[$key]), "Date" => $this->FileDates[$key], "HandlerMethod" => $this->HandlerMethods[$key], "ThumbnailPresent" => $this->FindThumbnail($this->FileNames[$key], $ThumbnailArray));
}
return $AssociativeArray;
}
function FileCollection($Name = "") {
$this->Name = $Name;
$this->FileNames = array();
$this->LowerFileNames = array();
$this->FileDates = array();
$this->FileSizes = array();
$this->HandlerMethods = array();
}
function FindThumbnail($FileName, $ThumbnailArray) {
// Take the given filename and look for a thumbnail (thumbnails are prefixed with ".thumb.")
return in_array("_thumb.".$FileName, $ThumbnailArray);
}
// Get all items in this file collection as an associative array in the specified order & direction
function GetFiles($OrderBy = "Size", $Direction = "asc", $ThumbnailArray = "") {
if (!is_array($ThumbnailArray)) $ThumbnailArray = array();
if ($Direction != "asc") $Direction = "desc";
if ($OrderBy != "Size" && $OrderBy != "Name" && $OrderBy != "Date") $OrderBy = "Size";
$SortFunction = "asort";
if ($Direction == "desc") $SortFunction = "arsort";
$ReturnArray = false;
if ($OrderBy == "Date") {
$SortFunction($this->FileDates);
$ReturnArray = $this->BuildAssociativeFileArray($this->FileDates, $ThumbnailArray);
} elseif ($OrderBy == "Name") {
$SortFunction($this->LowerFileNames);
$ReturnArray = $this->BuildAssociativeFileArray($this->LowerFileNames, $ThumbnailArray);
} else {
$SortFunction($this->FileSizes);
$ReturnArray = $this->BuildAssociativeFileArray($this->FileSizes, $ThumbnailArray);
}
return $ReturnArray;
}
}
class Configuration {
// Configuration Settings
var $ConfigFile; // Location of the configuration file
var $FileTypesFile; // Location of the filetypes file
var $ErrorManager; // Handles error messages
var $Version; // FB Version
var $Developer; // FB Developer's name
var $DeveloperEmail; // FB Developer's email address
var $Date; // Date of FB development completion
var $StyleUrl; // URL to the stylesheet
var $PageTitle; // To appear on the page
var $PageIntroduction; // To appear before any images are viewed
var $UsePageIntroductionInSubFolders;
var $DisplayHiddenFiles; // Boolean value indicating if files beginning with underscore should be visible
var $BrowseSubFolders; // Boolean value indicating if subfolders should be browsable/visible
var $SortBy; // Value to sort the files by
var $SortDirection; // Direction to sort the files
var $DateFormat; // The format string that will be used to configure the display format of the date for a file
var $PluginHeight;
var $PluginWidth;
var $DefaultFilesPerPage; // The default number of files to show when someone clicks the >> or << buttons
var $FitImagesToPage; // Boolean value indicating if large images should be shrunk to fit on the page
var $UseThumbnails; // Use thumbnails (if they exist)
// Browsing Properties
var $FileID; // ID of file currently being viewed
var $FolderIDs; // String of comma delimited folder ids
var $aFolderID; // Array of folder id's currently being viewed
var $FilesPerPage; // Number of files to display per page (as defined by the querystring)
var $CurrentWorkingDirectory;
var $CurrentBrowsingDirectory;
var $SelfUrl; // Name of this file
var $SelfWebPath; // path to the filebrowser execution file (ie. http://mydomain.com/images/)
var $FolderDelimiter; // Querystring delimiter to be used between folder ids
var $FolderNavigator; // A holder variable containing a folder navigation array
var $FolderNavigatorLocation; // Another holder variable containing the querystring values for the folder navigator
var $ShowMultipleFiles; // Boolean value indicating if multiple file should be displayed or not
var $GetFileID; // ID of a file to "save as"
var $HideFiles; // An array of files that should remain hidden
var $FullyQualifiedHideFiles; // Same as above, but fully qualified to root
var $Name; // The name of this class
// Default constructor - define default values for class properties
function Configuration() {
// Configuration Settings
$this->ConfigFile = "_config.xml";
$this->FileTypesFile = "_filetypes.xml";
$this->CurrentWorkingDirectory = getcwd();
// Configuration Properties
$this->Version = "1.3.3";
$this->Developer = "Mark O'Sullivan";
$this->Date = "2002-2005";
$this->StyleUrl = "_default.css";
$this->PageTitle = "Lussumo Filebrowser";
$this->PageIntroduction = "";
$this->UsePageIntroductionInSubFolders = false;
$this->DisplayHiddenFiles = false;
$this->BrowseSubFolders = true;
$this->SortBy = "Name";
$this->SortDirection = "asc";
$this->DateFormat = "m-d-y";
$this->PluginHeight = 400;
$this->PluginWidth = 400;
$this->DefaultFilesPerPage = 5;
$this->MaxFilesPerPage = 50;
$this->FitImagesToPage = 1;
$this->UseThumbnails = 0;
$this->HideFiles = array();
$this->FullyQualifiedHideFiles = array();
// Browsing Properties
$this->FolderDelimiter = "-";
$this->FileID = ForceIncomingInt("fid", 0);
$this->FolderIDs = ForceIncomingString("did", "");
if ($this->FolderIDs == "") {
$this->aFolderID = array();
} else {
$this->aFolderID = explode($this->FolderDelimiter, $this->FolderIDs);
}
$this->CurrentBrowsingDirectory = $this->CurrentWorkingDirectory;
$this->FolderNavigator = array();
$this->FolderNavigatorLocation = "";
$this->ShowMultipleFiles = ForceIncomingBool("smf", false);
$this->GetFileID = ForceIncomingInt("gid", 0);
$this->Name = "FileBrowser";
}
function RetrieveConfigurationPropertiesFromXml($Path) {
$FauxContext = "0";
if ($this->ConfigFile == "") $this->ErrorManager->AddError($FauxContext,$this->Name, "RetrieveConfigurationPropertiesFromXml", "You must supply a path to the configuration file");
// Retrieve config file contents
$File = new File();
$File->Name = $this->ConfigFile;
$File->Path = $Path;
$FileManager = new FileManager();
$FileManager->ErrorManager = &$this->ErrorManager;
$File = $FileManager->Get($File);
// If there were errors retrieving the config file and we're in the CWD, report an error
if ($this->ErrorManager->ErrorCount > 0 && $Path == $this->CurrentWorkingDirectory) {
$this->ErrorManager->Clear();
$this->ErrorManager->AddError($FauxContext,$this->Name, "RetrieveConfigurationPropertiesFromXml", "The root configuration file could not be found/read (_config.xml).");
// If failed to retrieve the file from a non-root directory,
// just accept the root file
} elseif ($this->ErrorManager->ErrorCount > 0) {
$this->ErrorManager->Clear();
// If no errors occurred, continue to retrieve new configuration settings
} else {
// Create an XML Parser to retrieve configuration settings
$XMan = new XmlManager();
$XMan->ErrorManager = &$this->ErrorManager;
$MyConfig = $XMan->ParseNode($File->Body);
if ($MyConfig && $this->ErrorManager->ErrorCount == 0) {
$this->StyleUrl = $XMan->GetNodeValueByName($MyConfig, "StyleUrl");
$this->PageTitle = $XMan->GetNodeValueByName($MyConfig, "PageTitle");
$this->PageIntroduction = $XMan->GetNodeValueByName($MyConfig, "PageIntroduction");
$this->PageIntroduction = str_replace("[","<", $this->PageIntroduction);
$this->PageIntroduction = str_replace("]",">", $this->PageIntroduction);
$this->PageIntroduction = str_replace("\n"," ", $this->PageIntroduction);
$this->DisplayHiddenFiles = $XMan->GetNodeValueByName($MyConfig, "DisplayHiddenFiles");
$this->BrowseSubFolders = $XMan->GetNodeValueByName($MyConfig, "BrowseSubFolders");
$this->SortBy = $XMan->GetNodeValueByName($MyConfig, "SortBy");
$this->SortDirection = $XMan->GetNodeValueByName($MyConfig, "SortDirection");
$this->DateFormat = $XMan->GetNodeValueByName($MyConfig, "DateFormat");
$this->UsePageIntroductionInSubFolders = ForceBool($XMan->GetNodeValueByName($MyConfig, "UsePageIntroductionInSubFolders"), false);
$this->PluginHeight = ForceInt($XMan->GetNodeValueByName($MyConfig, "PluginHeight"), $this->PluginHeight);
$this->PluginWidth = ForceInt($XMan->GetNodeValueByName($MyConfig, "PluginWidth"), $this->PluginWidth);
$this->FilesPerPage = ForceIncomingInt("fpp", ForceInt($XMan->GetNodeValueByName($MyConfig, "FilesPerPage"), $this->FilesPerPage));
$this->MaxFilesPerPage = ForceInt($XMan->GetNodeValueByName($MyConfig, "MaxFilesPerPage"), $this->MaxFilesPerPage);
$this->FitImagesToPage = ForceBool($XMan->GetNodeValueByName($MyConfig, "FitImagesToPage"), $this->FitImagesToPage);
$this->UseThumbnails = ForceBool($XMan->GetNodeValueByName($MyConfig, "UseThumbnails"), $this->UseThumbnails);
$this->HideFiles = explode(",", $XMan->GetNodeValueByName($MyConfig, "HideFiles"));
for ($i = 0; $i < count($this->HideFiles); $i++) {
$this->FullyQualifiedHideFiles[] = $this->CurrentBrowsingDirectory."/".$this->HideFiles[$i];
}
}
}
return $this->ErrorManager->Iif();
}
}
// Define required variables for the application
$ErrorManager = new ErrorManager();
$Config = new Configuration();
$Config->ErrorManager = &$ErrorManager;
// ------------------------------------
// 1. RETRIEVE CONFIGURATION PROPERTIES
// ------------------------------------
$Config->RetrieveConfigurationPropertiesFromXml($Config->CurrentWorkingDirectory);
// Check for subfolder ids if directory browsing is allowed and some folder ids were supplied
if ($Config->BrowseSubFolders && count($Config->aFolderID) > 0) {
for ($i = 0; $i < count($Config->aFolderID); $i++) {
$CurrentFolderKey = ForceInt($Config->aFolderID[$i], 0);
$Config->CurrentBrowsingDirectory = CheckForFolder($Config->CurrentBrowsingDirectory, $CurrentFolderKey, $Config);
if (!$Config->CurrentBrowsingDirectory) {
// IF the current browsing directory wasn't found, wipe out all directory settings and start from the root
$Config->CurrentBrowsingDirectory = $Config->CurrentWorkingDirectory;
$Config->FolderIDs = "";
$Config->aFolderID = array();
break;
}
}
}
// If the folder exists, and there is a _config.xml file in the folder, reconfigure the filebrowser
if ($Config->CurrentWorkingDirectory != $Config->CurrentBrowsingDirectory) $Config->RetrieveConfigurationPropertiesFromXml($Config->CurrentBrowsingDirectory);
// -----------------------------------
// 2. RETRIEVE FILE EXTENSION SETTINGS
// -----------------------------------
$File = new File();
$File->Name = $Config->FileTypesFile;
$File->Path = $Config->CurrentWorkingDirectory;
$FileManager = new FileManager();
$FileManager->ErrorManager = &$Config->ErrorManager;
$File = $FileManager->Get($File);
// Create an XML Parser to retrieve configuration settings
$XmlManager = new XmlManager();
$XmlManager->ErrorManager = &$ErrorManager;
$FileTypes = $XmlManager->ParseNode($File->Body);
// Create an array of all defined file types
$FileCollections = array();
$FolderCollection = array();
$ExtensionLibrary = array();
for ($i = 0; $i < count($FileTypes->Child); $i++) {
if ($FileTypes->Child[$i]->Name == "FileGroup") {
$FileCollections[$i] = new FileCollection($FileTypes->Child[$i]->Attributes["Name"]);
for ($j = 0; $j < count($FileTypes->Child[$i]->Child); $j++) {
$Node = $FileTypes->Child[$i]->Child[$j];
if ($Node->Name == "Extensions") {
// Ignore all items with a handler method of none
if (@$Node->Attributes["HandlerMethod"] != "None") {
$CurrentExtensionArray = explode(",",$Node->Value);
for ($k = 0; $k < count($CurrentExtensionArray); $k++) {
$ExtensionLibrary[strtolower($CurrentExtensionArray[$k])] = array($i,$Node->Attributes["HandlerMethod"]);
}
}
}
}
}
}
// -----------------
// 3. RETRIEVE FILES
// -----------------
// Loop through files in the current browsing directory
$FolderKey = 0;
$FolderHandle = opendir($Config->CurrentBrowsingDirectory);
$CurrentExtension = "";
$RecordItem = true;
$ThumbnailCollection = array();
while (false !== ($Item = readdir($FolderHandle))) {
$RecordItem = true;
if ($Item == "."
|| $Item == ".."
|| in_array($Config->CurrentBrowsingDirectory."/".$Item, $Config->FullyQualifiedHideFiles)
) $RecordItem = false;
if ($Config->DisplayHiddenFiles == "false" && $Item == $Config->SelfUrl) $RecordItem = false;
if ($Config->DisplayHiddenFiles == "false" && substr($Item,0,1) == "_") $RecordItem = false;
if ($Config->UseThumbnails && substr($Item,0,7) == "_thumb.") {
// Don't record the current item in the regular file collections, dump it into a thumbnail collection
$RecordItem = false;
$ThumbnailCollection[] = $Item;
}
if ($RecordItem) {
// If dealing with a folder, add it to the folder collection
if (is_dir($Config->CurrentBrowsingDirectory."/".$Item)) {
$FolderCollection[] = $Item;
// If not dealing with a folder, add it to the proper file collection
} else {
// Match the current file extension with an item in the extension library
$CurrentExtension = GetExtension($Item);
$KeyMatch = @$ExtensionLibrary[$CurrentExtension];
// If the match came back positive, add the file to the collection
if ($KeyMatch) {
$FileCollections[$ExtensionLibrary[$CurrentExtension][0]]->AddFile($Item, filesize($Config->CurrentBrowsingDirectory."/".$Item), filemtime($Config->CurrentBrowsingDirectory."/".$Item), $ExtensionLibrary[$CurrentExtension][1]);
// If the match came back false, attempt to add this file to the wildcard group
} elseif (array_key_exists("*", $ExtensionLibrary)) {
$FileCollections[$ExtensionLibrary["*"][0]]->AddFile($Item, filesize($Config->CurrentBrowsingDirectory."/".$Item), filemtime($Config->CurrentBrowsingDirectory."/".$Item), $ExtensionLibrary["*"][1], $ExtensionLibrary["*"]);
} // Ignore all other files
}
}
}
// --------------------------
// 4. BUILD THE PAGE ELEMENTS
// --------------------------
// If in a subfolder,
// and there is no file currently selected,
// and we're not supposed to display the root introduction
// and there is no config file for this folder
// Display the first file
if ($Config->FileID == 0
&& $Config->CurrentWorkingDirectory != $Config->CurrentBrowsingDirectory
&& !$Config->UsePageIntroductionInSubFolders) $Config->FileID = 1;
$FilesToDisplay = $Config->FilesPerPage;
if (!$Config->ShowMultipleFiles) $FilesToDisplay = 1;
$aItemHistory = array();
$FileDisplay = "";
$FileList = "";
// Create a parameters class to manage querystring values
$Params = new Parameters();
$Params->DefineCollection($_GET);
$Params->Add("fpp", $Config->FilesPerPage);
$Params->Remove("smf");
if ($Config->FolderIDs == "") $Params->Remove("did");
$FileCounter = 0;
// Build the file listing
while (list(, $CurrentFileCollection) = each ($FileCollections)) {
// Get the sorted files
$Files = $CurrentFileCollection->GetFiles($Config->SortBy, $Config->SortDirection, $ThumbnailCollection);
if (count($Files) > 0) {
$FileList .= "
".$CurrentFileCollection->Name."
";
$RootPath = substr(CurrentWebPath(), 0, strlen(CurrentWebPath())-1);
$CurrentPath = $RootPath."/".BuildLiteralPath($Config->FolderNavigator);
for ($j = 0; $j < count($Files); $j++) {
$FileCounter += 1;
$CurrentFileName = $Files[$j]["Name"];
$CurrentFileSize = $Files[$j]["Size"];
$CurrentFileDate = $Files[$j]["Date"];
$CurrentFileHandlerMethod = $Files[$j]["HandlerMethod"];
$CurrentFileHasThumbnail = $Files[$j]["ThumbnailPresent"];
// Collect the item history
$aItemHistory[] = $FileCounter;
// Check to see if the current file is selected
$Highlighted = false;
if (($Config->FileID == $FileCounter || ($FileCounter > $Config->FileID && $FilesToDisplay < $Config->FilesPerPage && $Config->FileID > 0)) && $FilesToDisplay > 0) {
$FileDisplay .= FormatDisplayedItem($FileCounter, $CurrentFileName, $CurrentFileSize, $CurrentFileHandlerMethod, $Params, $Config);
$FilesToDisplay = $FilesToDisplay - 1;
$Highlighted = true;
}
$FileList .= FormatListItem($FileCounter, $CurrentFileName, $CurrentPath, $CurrentFileSize, $CurrentFileDate, $Highlighted, $Params, $CurrentFileHasThumbnail, $Config);
// Check for a "save as" request
if ($Config->GetFileID == $FileCounter) {
$FolderPath = substr($Config->CurrentBrowsingDirectory, strlen($Config->CurrentWorkingDirectory)+1,(strlen($Config->CurrentBrowsingDirectory)-strlen($Config->CurrentWorkingDirectory)+1));
SaveAsDialogue($FolderPath, $CurrentFileName);
}
}
$FileList .= "
");
// ------------------------------------
// 6. CONFIGURE & WRITE NAVIGATION MENU
// ------------------------------------
$TotalItemCount = ForceInt(count($aItemHistory), 0);
if ($TotalItemCount > 0) $TotalItemCount = $TotalItemCount-1;
$FirstItem = ($TotalItemCount == 0)?false:$aItemHistory[0];
$LastItem = ($TotalItemCount == 0)?false:$aItemHistory[$TotalItemCount];
$NextItem = false;
$PreviousItemGroup = false;
$PreviousItem = false;
// If viewing a file, check to see if the file id exists in the item history
if ($TotalItemCount > 0) {
$FileKey = false;
if ($Config->FileID > 0) $FileKey = array_search($Config->FileID,$aItemHistory);
if ($FileKey !== false) {
// Don't go past the end
if ($Config->ShowMultipleFiles) {
if ($FileKey + $Config->FilesPerPage <= $TotalItemCount) {
$NextItem = $aItemHistory[$FileKey+$Config->FilesPerPage];
} else {
$NextItem = false;
}
} else {
if ($FileKey + 1 <= $TotalItemCount) {
$NextItem = $aItemHistory[$FileKey+1];
} else {
$NextItem = false;
}
}
// Don't go before the beginning
if ($FileKey < $Config->FilesPerPage) {
$PreviousItemGroup = $aItemHistory[0];
} else {
$PreviousItemGroup = $aItemHistory[$FileKey-$Config->FilesPerPage];
}
if ($FileKey == 0) {
$FirstItem = $aItemHistory[0];
$PreviousItem = false;
$PreviousItemGroup = false;
} else {
$PreviousItem = $aItemHistory[$FileKey-1];
}
} else {
$NextItem = $aItemHistory[0];
$PreviousItemGroup = false;
$PreviousItem = false;
}
}
$Params->Remove("fid");
$Params->Set("did", $Config->FolderIDs);
$Params->Set("fid", $FirstItem);
$Menu = FormatMenuItem("NavFirstItem", $Params, "|<", "First", $FirstItem);
$Params->Set("fid",$PreviousItemGroup);
$Params->Add("smf",1);
$Menu .= FormatMenuItem("NavPreviousItemGroup", $Params, "<<", "Previous ".$Config->FilesPerPage, $PreviousItemGroup);
$Params->Remove("smf");
$Params->Set("fid",$PreviousItem);
$Menu .= FormatMenuItem("NavPreviousItem", $Params, "Previous", "Previous", $PreviousItem);
$Params->Set("fid",$NextItem);
$Menu .= FormatMenuItem("NavNextItem", $Params, "Next", "Next", $NextItem);
$Params->Add("smf",1);
$Params->Set("fid",$NextItem);
$Menu .= FormatMenuItem("NavNextItemGroup", $Params, ">>", "Next ".$Config->FilesPerPage, $NextItem);
$Params->Remove("smf");
$Params->Set("fid",$LastItem);
$Menu .= FormatMenuItem("NavLastItem", $Params, ">|", "Last", $LastItem);
// ----------------------------------
// 7. WRITE THE REMAINDER OF THE PAGE
// ----------------------------------
echo("
".$Menu."
\r\n");
echo("
\r\n");
// If a file has not been requested, write out the introductory paragraph (if there is one)
if (
$Config->FileID == 0 && $Config->PageIntroduction != ""
&& ($Config->CurrentWorkingDirectory == $Config->CurrentBrowsingDirectory
|| ($Config->CurrentWorkingDirectory != $Config->CurrentBrowsingDirectory
&& $Config->UsePageIntroductionInSubFolders))) echo("
".$Config->PageIntroduction."
\r\n");
// Write out the selected files
echo($FileDisplay);
echo("
\r\n" // End DisplayContainer
."
\r\n".$Menu."
\r\n"
."
\r\n");
// Write out the file/folder listing
if (trim($FileList) == "") {
echo("
No files or folders could be found.
\r\n");
} else {
echo($FileList);
}
// Write out the page footer
echo("