<?php
# class.browser.php
# Part of Expow 0.8
# 20 07 01 Author: Remy Lalanne
# In this file:
# 1. class c_browser
# 2. class c_browser_gui + misc functions
# 3. class c_tag
# 4. class c_browser_gui_html
# 5. misc functions
################################################################################
# c_browser class
#
# paths management
################################################################################
class c_browser {
# public
# the internal path of the root (absolute or relative) no trailing slash
var $DOCUMENT_ROOT;
# the URI equivalent to DOCUMENT_ROOT - with trailing slash
var $root_URL;
# a relative path in root or false - with trailing slash
var $path;
# a relative path in path or false - dirs with trailing slash
var $sub_path;
function c_browser()
{
$this->DOCUMENT_ROOT = false;
$this->root_URL = false;
$this->path = false;
$this->sub_path = false;
}
function get_intern_path($fname = false)
{
return $this->DOCUMENT_ROOT.'/'.$this->get_uri($fname);
}
function get_url($fname = false)
{
return $this->root_URL.$this->get_uri($fname);
}
# url without port and server info
function get_uri($fname = false)
{
return $this->path.$this->sub_path.$fname;
}
# this function makes sub_path up or path up if sub_path == false
function up()
{
$last = $this->get_uri();
if ($this->sub_path){
$res = dirname($this->sub_path);
if (strcmp($res,$this->sub_path) && $res != '.'){
$this->sub_path = $res.'/';
return $last;
}
else {
$this->sub_path = false;
return $last;
}
}
$this->sub_path = false;
$res = dirname($this->path);
if (strcmp($res,$this->path) && $res != '.'){
$this->path = $res.'/';
return $last;
}
$this->path = false;
return $last;
}
# returns number of levels of sub_path
function sub_tree_nblevels()
{
$sub_path_bak = $this->sub_path;
$nb_sub = 0;
while($this->sub_path){
$this->up();
$nb_sub++;
}
$this->sub_path = $sub_path_bak;
return $nb_sub;
}
} //c_browser
################################################################################
# c_browser_gui class
#
# Purpose:
# Drive an icon directory.
# Get readable informations of files
# Ready to print components for icon(s) creation.
#
# Input:
# Specify the directory of bitmaps (jpg gif png) under $icon_dir,
# then associate images:
#
# associate with names
# "hello.txt.png" --> "hello.txt"
# "apache.gif" --> "apache" file/directory
#
# with file extensions
# ".txt.png" --> ".txt" files.
#
################################################################################
class c_browser_gui extends c_browser {
# public
# URL for bitmaps directory or false
var $img_dir;
# absolute path for custom icons directory or false
var $icon_dir;
function c_browser_gui( )
{
$this->c_browser();
$this->img_dir = false;
$this->icon_dir = false;
}
# this function returns entries without trailing slashes
function get_entry($fname = false)
{
return basename($this->get_intern_path($fname));
}
#
# Returns the filename of the bitmap to use, false if no bitmap found.
#
function img($fname = false)
{
$fname2 = $this->get_entry($fname);
$ext = strrchr ($fname2,'.');
$ext = str_replace(".","",$ext);
if ($this->icon_dir){
//$path_parts = pathinfo($fname); //buggy pathinfo() "." problem...
//$ext= ".".$path_parts["extension"];
$icon_dir_URL = str_replace($this->DOCUMENT_ROOT,"",$this->icon_dir);
// from name
if (file_exists($this->icon_dir."$fname2.png")) return $icon_dir_URL.$fname2.".png";
if (file_exists($this->icon_dir."$fname2.gif")) return $icon_dir_URL.$fname2.".gif";
if (file_exists($this->icon_dir."$fname2.jpg")) return $icon_dir_URL.$fname2.".jpg";
//from extension
if (file_exists($this->icon_dir."$ext.png")) return $icon_dir_URL.$ext.".png";
if (file_exists($this->icon_dir."$ext.gif")) return $icon_dir_URL.$ext.".gif";
if (file_exists($this->icon_dir."$ext.jpg")) return $icon_dir_URL.$ext.".jpg";
}
if(is_dir($this->get_intern_path($fname)) && $this->img_dir)
return $this->img_dir."folder.gif";
if (!strcmp($ext,"") && $this->img_dir)
return $this->img_dir."unknown.gif";
return false;
}
function perms($fname = false)
{
return FormatePermissions(fileperms($this->get_intern_path($fname)));
}
function get_emblems($fname)
{
if(is_link($this->get_intern_path(str_replace("/","",$fname)))){
$res = " -> ".readlink($this->get_intern_path(str_replace("/","",$fname)));
//$res = linkinfo($this->get_intern_path(str_replace("/","",$fname)));
}
if (file_exists($this->get_intern_path($fname)."index.html")
|| file_exists($this->get_intern_path($fname)."index.php3")
|| file_exists($this->get_intern_path($fname)."index.php"))
$res .= "(i)";
return $res;
}
function size($fname = false)
{
return FormatTailleFichier(filesize($this->get_intern_path($fname)));
}
function date($fname = false)
{
return date("d-M-Y H:i", filemtime($this->get_intern_path($fname)));
}
function get_class($fname = false)
{
// php bug in is_link() with a trailing slash
if (!file_exists($this->get_intern_path($fname))) return "notfound";
if (is_link($this->get_intern_path(str_replace("/","",$fname)))) return "link";
if (is_dir ($this->get_intern_path($fname))) return "directory";
if (is_image ($this->get_intern_path($fname))) return "image";
return "file";
}
} //c_browser_gui
################################################################################
# Extern functions for c_browser_gui
#
# FormatePermissions(), FormatTailleFichier() are from phpmyexplorer
################################################################################
function FormatePermissions($mode)
{
// Determine le type
if($mode & 0x1000) $type='p'; // FIFO pipe
else if($mode & 0x2000) $type='c'; // Character special
else if($mode & 0x4000) $type='d'; // Directory
else if($mode & 0x6000) $type='b'; // Block special
else if($mode & 0x8000) $type='-'; // Regular
else if($mode & 0xA000) $type='l'; // Symbolic Link
else if($mode & 0xC000) $type='s'; // Socket
else $type='u'; // UNKNOWN
// Determine les permissions par groupe
$owner["read"] = ($mode & 00400) ? 'r' : '-';
$owner["write"] = ($mode & 00200) ? 'w' : '-';
$owner["execute"] = ($mode & 00100) ? 'x' : '-';
$group["read"] = ($mode & 00040) ? 'r' : '-';
$group["write"] = ($mode & 00020) ? 'w' : '-';
$group["execute"] = ($mode & 00010) ? 'x' : '-';
$world["read"] = ($mode & 00004) ? 'r' : '-';
$world["write"] = ($mode & 00002) ? 'w' : '-';
$world["execute"] = ($mode & 00001) ? 'x' : '-';
// Adjuste pour SUID, SGID et sticky bit
if( $mode & 0x800 ) $owner["execute"] = ($owner[execute]=='x') ? 's' : 'S';
if( $mode & 0x400 ) $group["execute"] = ($group[execute]=='x') ? 's' : 'S';
if( $mode & 0x200 ) $world["execute"] = ($world[execute]=='x') ? 't' : 'T';
return "$type$owner[read]$owner[write]$owner[execute]$group[read]$group[write]$group[execute]$world[read]$world[write]$world[execute]";
}
function FormatTailleFichier($Taille)
{
//if($Taille == 0) $format = "";
if($Taille <= 1024) $format = $Taille;
else if($Taille <= (10*1024)) $format = sprintf ("%.2fK",($Taille/1024));
else if($Taille <= (100*1024)) $format = sprintf ("%.1fK",($Taille/1024));
else if($Taille <= (1024*1024)) $format = sprintf ("%dK",($Taille/1024));
else if($Taille <= (10*1024*1024)) $format = sprintf ("%.2fM",($Taille/(1024*1024)));
else if($Taille <= (100*1024*1024))$format = sprintf ("%.1fM",($Taille/(1024*1024)));
else $format = sprintf ("%dM",($Taille/(1024*1024)));
return $format;
}
function is_image( $filename )
{
$ext = strrchr($filename, '.');
if ( $ext == ".jpg" || $ext == ".JPG" ||
$ext == ".gif" || $ext == ".GIF" ||
$ext == ".png" || $ext == ".PNG")
return true;
return false;
}
################################################################################
# c_tag class
#
# basic XML tag object.
################################################################################
class c_tag {
var $name;
var $props; // associated array of properties with values
function c_tag($name){ $this->name=$name; $this->props=array();}
function end(){ return "</".$this->name.">"; }
function get()
{
$str = "<".$this->name;
$array_keys = array_keys ($this->props);
$array_values = array_values($this->props);
for($i=0;$i<sizeof($this->props);$i++)
$str .= " ".$array_keys[$i]."=\"".$array_values[$i]."\"";
return $str.">";
}
}
################################################################################
# class c_browser_gui_html
#
# Purpose:
# file listing, html anchor navigation / linking.
# zoom percentage.
#
# Output:
# HTML 4.0 output. Tags and classes:
# table, tr, th, td, img, a, font, br, nobr, pre
# a.directory, a.file, a.link, a.notfound, a|font.overlib,
# td.opened, td.selected, td.browser, td.first, td.last
# tr.a, tr.b, font.extension
#
# QUICK USE
# $c_browser = c_browser_gui_html();
# $c_browser->DOCUMENT_ROOT = "../path/to/the/rootdirectory";
# $c_browser->tree_output(); # outputs the directory
# $c_browser->make_icon("your_file"); # outputs one icon of that directory
################################################################################
class c_browser_gui_html extends c_browser_gui
{
# public
# anchor on the name - DIRECT LINKED - c_tag
var $anchor1;
# to give the new path to url ("&xxxx=newpath") or not. string|false
var $a_path_var1;
# anchor on the icon. calls back current page - c_tag
var $anchor2;
# define the new path in hrefs under this name ("&xxxx=newpath"). string|false
var $subpath_var;
#
# Anchors properties
#
# both anchors
# onMouseOver event call overlib javascript functions or not. true|false
var $ol_flag;
# define other variables in hrefs - "x=y&x2=y2" string|false
var $href_args;
#
# Html image
#
# preload full image in icons true|false
var $preload_flag;
# max side for picture previews integer
var $ol_max_side;
# icon max size percentage from base. int
var $zoom_percent;
#
# Additionnal variables
# This variables are not needed by internal functions, but may be
# usefull to storing it inside the object.
# file's date size and perms true|false
var $details_flag;
# line color alternance for display
# use 'a' and 'b' for example.
var $line_color;
function c_browser_gui_html( )
{
$this->c_browser_gui();
# target management
$this->anchor1 = new c_tag("a");
$this->anchor2 = new c_tag("a");
$this->a_path_var1 = false;
$this->subpath_var = false;
$this->ol_flag = false;
$this->href_args = false;
# html image
$this->preload_flag = false;
$this->ol_max_side = 160;
$this->zoom_percent = 100;
# html row
$this->details_flag = true;
$this->line_color = 'a';
}
function line_head ()
{
if ($this->details_flag)
echo "<tr><th align=left>Name</th><th align=right>Size</th><th align=right>Last modified</th><th align=right>Perms</th></tr>\n";
}
#
# Returns vertical lines either in html bitmap or in text
#
function sub_output( $sub_level )
{
if ($this->img_dir){
$vert_tag = new c_tag("img");
$vert_tag->props["src"] = $this->img_dir."vertical.gif";
$vert_tag->props["width"] = 16 *($this->zoom_percent/100);
$vert_tag->props["height"] = 20 *($this->zoom_percent/100);
$vert_tag->props["alt"] = "[SUB]";
for ($i=0; $i<$sub_level;$i++)
$html .= $vert_tag->get();
return $html;
}
for ($i=0; $i<$sub_level;$i++)
$html .= "[SUB]";
return $html;
}
#
# embed img() parent class with html
# width and height are 100% base
#
function img_html($fname = false, $width = 16, $height = 14)
{
$zoomed_width = $width *$this->zoom_percent/100;
$zoomed_height = $height*$this->zoom_percent/100;
if(is_image($this->get_entry($fname)) && $this->preload_flag)
return "<img src=\"".$this->get_url($fname)."\" width=$zoomed_width height=$zoomed_height alt=\"[IMG]\" border=0>";
if($res = $this->img($fname))
return "<img src=\"$res\" width=$zoomed_width height=$zoomed_height alt=\"[IMG]\" border=0>";
if(is_dir($this->get_intern_path($fname)))
return "[DIR]";
$fname2 = $this->get_entry($fname);
$ext = strrchr($fname2,'.');
$ext = str_replace(".","",$ext);
$font_size = $this->zoom_percent/50;
return "<font size=$font_size class=extension>$ext</font>";
}
#
# ANCHOR_BUILDING
#
# Fills class, OnMouseOver, and OnMouseOut properties.
function a_misc($c_tag, $fname = false)
{
$c_tag->props["class"] = $this->get_class($fname);
if (is_image($fname) && $this->ol_flag != false){
$c_tag->props["onMouseOver"] = $this->get_onmouseover($fname);
$c_tag->props["onMouseOut" ] = "nd();";
}
return $c_tag;
}
function href_direct($c_tag, $fname = false)
{
if ($this->a_path_var1)
$add = "?&".$this->a_path_var1."=".$this->sub_path.$fname.$this->href_args;
$c_tag->props["href"] = $this->get_url($fname).$add;
return $c_tag;
}
/*
function href_expow($c_tag, $fname = false)
{
if ($this->a_path_var1){
$add = "?&".$this->a_path_var1."=".urlencode($this->sub_path.$fname);
}
$c_tag->props["href"] .= $add;
return $c_tag;
}
*/
function href_sub($c_tag, $fname = false)
{
if ($this->subpath_var)
$add = "?&".$this->subpath_var."=".urlencode($this->sub_path.$fname).$this->href_args;
$c_tag->props["href"] .= $add;
$c_tag->props["class"] = $this->get_class($fname);
return $c_tag;
}
function get_onmouseover($fname) //overlib call with preview inside
{
$size = getimagesize($this->get_intern_path($fname));
$caption = "<br><font class=overlib>".$size[0]."x".$size[1]."</font>";
$res = "";
$dx = $this->ol_max_side - $size[0];
$dy = $this->ol_max_side - $size[1];
$nx = $ny = $this->ol_max_side;
if ($dx<$dy)
if ($size[0] != 0)
$ny = $nx * $size[1]/$size[0];
else
if ($size[1] != 0)
$nx = $ny * $size[0]/$size[1];
$src = $this->get_url($fname);
$res = "<img src=\'$src\' width=\'$nx\' height=\'$ny\'>" // '' used for javascript
.$caption;
return "return overlib('$res', FULLHTML)";
}
#
# Returns the html entry componed of img_html() and the name,
# linked according to anchor2 and anchor1 respectivly.
#
function entry($fname)
{
if (!is_readable($this->get_intern_path($fname)))
return $this->img_html($fname).$this->get_entry($fname).$this->get_emblems($fname);
if ($this->anchor2){
$anchor2 = $this->href_sub($this->anchor2,$fname);
$anchor2->props["class"] = $this->get_class($fname);
$anchor2->props["class"] = "extension";
$anchor2->props["href"] .= "#open";
if (is_image($fname) && $this->ol_flag){
$anchor2->props["onMouseOver"] = $this->get_onmouseover($fname);
$anchor2->props["onMouseOut" ] = "nd();";
}
}
$anchor1 = $this->a_misc($this->anchor1,$fname);
$anchor1 = $this->href_direct($anchor1,$fname);
return $anchor2->get().$this->img_html($fname).$anchor2->end()." "
.$anchor1->get().$this->get_entry($fname).$this->get_emblems($fname).$anchor1->end();
}
function make_icon($fname = false)
{
$extension = strrchr ($fname,'.');
$extension = str_replace(".","",$extension);
$anchor1 = $this->a_misc($this->anchor1,$fname);
$anchor1 = $this->href_direct($anchor1,$fname);
return "<table cellspacing=0 cellpadding=0 class=".$this->get_class($fname)."><tr><td>"
."<table border=0 cellpadding=0 cellspacing=0 width=100 height=64>"
."<tr><td align=center width=100% height=100%>\n"
.$anchor1->get().$this->img_html($fname,80,64).$anchor1->end()
."\n</td>"
."<td width=16 align=center valign=top>\n<font size=1 color=#707070>"
.$this->perms($fname)."</font>\n</td>"
."</tr><tr><td height=0 valign=bottom colspan=2>\n"
.$anchor1->get().$this->get_entry($fname).$anchor1->end()
."\n</td></tr></table></td></tr></table>";
}
function table_row_data( $sub_level = 0, $fname = false, $opened = false)
{
if($opened || !$fname)
$string = "<a name=open></a>";
return "<td><nobr>".$string.$this->sub_output($sub_level).$this->entry($fname)."</nobr></td>";
}
function table_row_details( $fname = false)
{
return sprintf("<td align=right class=size>%s</td><td align=right class=date><nobr>%s</nobr></td><td align=right class=perms>%s</td>",
$this->size($fname),$this->date($fname),$this->perms($fname));
}
} //c_browser_gui_html
?>