<?php if(!defined('PmWiki')) { highlight_file(__FILE__); exit; }
/*
 Copyright Christian Ridderstrom and Paul A. Rubin

 Syntax:
    (:attachlist [options] [prefix:]dir [options] :)

 */

Markup('uploadlist', '<split',
       '/\\(:attachlist\\s+(.*?):\\)/ei',
       "UploadList('$pagename', '$1', 'uploads:')");

Markup('uploadlist2', '<uploadlist',
       '/\\(:attachlist\\s+(\\w+:)(.*?):\\)/ei',
       "UploadList('$pagename', '$2', '$1')");

$HTMLStylesFmt['uploadlist'] = "
span.uploadlistdetailed { float:left; width:20em; }
span.uploadlistinfo { font-size:smaller; }
";

$IMapLocalPath['uploads:'] = '/home/lyx/www/wiki.lyx.org/uploads';
$IMapLocalPath['pre1:'] = '/home/lyx/www/wiki.lyx.org/uploads/SiteTest';

/*
Ideas for improvements:
* Make it warn if it has unrecognized arguments
 */

function UploadList($pagename, $argStr, $prefix='') {
  global $IMapLocalPath;
  $s = "";

  if(!array_key_exists($prefix, $IMapLocalPath))
    return "@@The prefix '$prefix' doesn't exist.@@";

  $baseDir = rtrim($IMapLocalPath[$prefix], '/');

  // Define default options
  $defArgs = array('fmt' => 'simple', 'verbose' => 'no',
           'filter' => '.*', 'recurse' => 'no',
           'case' => 'no', 'itemprefix' => '*', 
           'listdirs' => 'yes', 'listfiles' => 'yes');
  
  // Get arguments from directive and merge with default arguments
  $args = array_merge($defArgs,
              array_change_key_case(ParseArgs($argStr), CASE_LOWER));

  // Create structure with options
  $opts = array('fmt' => $args['fmt'],
        'recurse' => eregi('^y', $args['recurse']), 
        'filter' => $args['filter'],
        'case' => eregi('^y', $args['case']),    
        'listFiles' => eregi('^y', $args['listfiles']),
        'listDirs' => eregi('^y', $args['listdirs']),
        'baseDir' => $baseDir,
        'baseURI' => 'uploads:',
        'verbose' => eregi('^y', $args['verbose']),
        'noaction' => eregi('^y', $args['noaction']),
        'matchFcn' => 'UploadListMatchFcn',
        'fmtItemFcn' => eregi('^d', $args['fmt'])
        ? 'UploadListFmtItemDetailed' : 'UploadListFmtItemSimple',
        'fileManager' => 'http://wiki.lyx.org/ipfm/index.php?dir=');
  
  // Extract name of directory to list files for
  $dir = $args[''][0];
  if(! $opts['noaction']) {
    if($dir == "")
      return "[@(:attachlist <no-dir>:)@]";
    
    if(strpos($dir, '../') !== false)
      return "Illegal directory path, '$dir'";
    
    if($dir == "./" || $dir == ".") $dir = "/";
    if($dir != "/") {
      $opts['baseDir'] .= "/$dir";
      $opts['baseURI'] .= "/$dir";
      $opts['fileManager'] .= "/$dir/";
    }
  }
  
  if($opts['verbose']) {    // Show arguments if verbose.
    $s .= "<pre>\$args=". print_r($args, true)."\ndir=$dir</pre>\n";
    $s .= "<pre>\$opts=" . print_r($opts, true)."\ndir=$dir</pre>\n";
  }
  
  if(! $opts['noaction']) {
    $result = join(UploadListFcn($opts, $args['itemprefix']), "\n");
  }
  $s .= $result;
  
  return $s;
}

function UploadListFcn($opts, $itemPrefix = '*', $dir = '/') {
  // $dir    contains the names of any nested subdirectories.
  //        It starts and ends with a '/'.
  // $itemPrefix is a string prepended to each item in the listing,
  //          it is changed depending on the current level.
  
  $result = array();      // The listing is returned through this array
  
  $d = rtrim($opts['baseDir'] . "$dir", '/');
  
  if (!is_dir($d))
    return array("'@@$d@@' is not a directory!");
  
  if (false == ($dh = opendir($d)))
    return array("Cannot open directory $d");
  
  while (($name = readdir($dh)) != false) {
    if ($name == '.' || $name == '..') continue;
    
    $p = "$d/$name"; // fully qualified file name
    
    if(is_dir($p)) {
      if($opts['recurse'] || $opts['listDirs'])
    $result[] = $itemPrefix .$opts['fmtItemFcn']($opts, $name, $p, $dir);
      
      if($opts['recurse']) {
    $z = UploadListFcn($opts, $itemPrefix . '*', "$dir$name/");
    
    if (is_array($z))    // Array? Implies success, merge it
      $result = array_merge($result, $z);
    else
      $result[] = $z;    // Otherwise append error message
      }
    }
    else {            // It is not a directory
      if($opts['listFiles'] && $opts['matchFcn']($opts, $name))
    $result[] = $itemPrefix .$opts['fmtItemFcn']($opts, $name, $p, $dir);
    }
  }
  closedir($dh);
  
  return $result;
}


// Default function for checking if $name should be included in the listing
function UploadListMatchFcn(& $opts, $name) {
  if ($opts['case'])
    return ereg($opts['filter'], $name);
  else
    return eregi($opts['filter'], $name); 
}

// Default function for formatting the output of a simple item
function UploadListFmtItemSimple(&$opts, $name, $path, $dir) {
  $r = "";
  if(is_dir($path)) {
    if($opts['recurse'] || $opts['listDirs'])
      $r = "[[" . $opts['fileManager']. ltrim($dir,'/') . "$name | $name/]]";
    //    $r = "[=" . ltrim($dir, '/') . "$name/=]";
  }
  else
    $r = " [[" . $opts['baseURI'] . "$dir$name | $name]]";
  
  return $r;
}

// Default function for formatting the output of a detailed file item
function UploadListFmtItemDetailed($opts, $name, $path, $dir) {
  $r = "";
  $s = filesize($path);
  $m = gmstrftime("%Y-%m-%d %H:%M GMT", filemtime($path));
  
  if(is_dir($path)) {
    if($opts['recurse'] || $opts['listDirs'])
      $r = "[[" . $opts['fileManager']. ltrim($dir,'/') . "$name | $name/]]";
  }
  else 
    $r = Keep("<span class='uploadlistdetailed'>")
      . " [[" . $opts['baseURI'] . "$dir$name | $name]] "
      . Keep("</span><span class='uploadlistinfo'>")
      . "($s bytes, $m)"
      . Keep("</span>");
  return $r;
}

?>