Location: PHPKode > scripts > EXPOW > expow/src/class.browser.php
<?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 = "?&amp;".$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 = "?&amp;".$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 = "?&amp;".$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()."&nbsp;"
          .$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

?>
Return current item: EXPOW