[pmwiki-users] Upload list - recursively listing files in uploaded subdirectories

Christian Ridderström christian.ridderstrom at gmail.com
Sat Sep 5 05:13:26 CDT 2009


Hi,

I was asked to send a script in that I'm using which recursively lists 
files in subdirectories. Here's the file.

It's used at
 	wiki.lyx.org

There's some kind of "documentation" here:

 	http://wiki.lyx.org/Playground/UploadListFcn


and it's tested on this page:

 	http://wiki.lyx.org/Playground/TestUploadList

cheers,
Christian

-- 
Christian Ridderström				Mobile: +46-8 768 39 44
-------------- next part --------------
<?php if (!defined('PmWiki')) exit();
/*
 Copyright Christian Ridderstrom and Paul A. Rubin
 */

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

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

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

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

function UploadList($pagename, $argStr) {
  $s = "";
  
  // 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' => '/home/lyx/www/wiki.lyx.org/uploads',
		'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 "[@(:list-uploads <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;
}

?>


More information about the pmwiki-users mailing list