<?php if (!defined('PmWiki')) exit();
/**
  Local Directory List for PmWiki
  Written by (c) Petko Yotov 2009-2011
  Partly based on upload.php written by Patrick Michaud

  This script is POSTCARDWARE, if you like it or use it,
  you can send me a postcard. Details at
  http://galleries.accent.bg/Cookbook/Postcard

  This text is written for PmWiki; 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 3 of the License, or
  (at your option) any later version. See pmwiki.php for full details
  and lack of warranty.

  Copyright 2009-2011 Petko Yotov http://notamment.fr
  Copyright 2004-2007 Patrick R. Michaud http://www.pmichaid.com
*/
# Version date
$RecipeInfo['DirList']['Version'] = '20110118';
$EnableUpload = 1;

Markup('dirlist', 'block',
  '/^\\(:dirlist\\s*(.*?):\\)/ei',
  "FmtDirList(\$pagename,PSS('$1'))");

SDVA($HTMLStylesFmt, array(
'dirlist' => "table.dirlist td.d { font-weight: bold; }
table.dirlist td.s, table.dirlist td.t { text-align: right; }
table.dirlist { border: 1px solid #dddddd; }
table.dirlist td { border: 1px outset #dddddd; padding: 0px 2px; margin:2px; } ",
));

SDVA($HandleActions, array( 'dirlistget' => 'HandleDirListGet' ));

SDVA($DirList, array(
  'Root' => "$FarmD/pub",
  'dirline'  => '<tr><td class="d"><a href="{$PageUrl}?dir=%4$s">%1$s</a></td><td class="s">%2$s</td><td class="t">%3$s</td></tr>',
  'fileline' => '<tr><td class="f"><a href="{$PageUrl}?action=dirlistget&amp;f=%4$s">%1$s</a></td><td class="s">%2$s</td><td class="t">%3$s</td></tr>',
  'listwrap' => '<table class="dirlist" border="0"><caption>%2$s</caption>%1$s</table>',
  'defaultfilter' => "-*~,-*.bak",
  'parent' => '..',
));

function FmtDirList($pagename, $args) {
  global $DirList, $TimeFmt;
  $opt = ParseArgs($args);

  $Root = (@$opt[''][0]>'')? "{$DirList['Root']}/{$opt[''][0]}" : $DirList['Root'];
  
  $Ddir = preg_replace('!^\\/+!', '', stripmagic(@$_GET['dir']));
  
  $dir = ($Ddir>'')? "$Root/$Ddir" : $Root;
  
  $Fdir = substr($dir, strlen($DirList['Root'])+1);
  
  $dir = str_replace(array('..', '//'), array('', '/'), $dir);

  $filelist = $dirlist = array();
  $dirp = @opendir($dir);
  if($dirp) {
    while (($file=readdir($dirp)) !== false) {
      if ($file{0} == '.') continue;
      
      $f = "$dir/$file";
	  
      if(@$opt['dirfilter']>'' && is_dir($f)) {
        $a = MatchNames(array($file), $opt['dirfilter']);
        if(count($a)!=1) continue;
      }
      elseif(@$opt['filter']>'' && !is_dir($f)) {
        $a = MatchNames(array($file), $opt['filter']);
        if(count($a)!=1) continue;
      }

      if(intval(@$opt['nodefaultfilter'])==0) {
        $a = MatchNames(array($file), $DirList['defaultfilter']);
        if(count($a)!=1) continue;
      }
      $time = strftime($TimeFmt, @filemtime($f));
      $size = dirlist_nformat(@filesize($f));
      if(is_dir($f) ) $dirlist[$file] = array( $size, $time);
      else $filelist[$file] = array( $size, $time);
    }
    closedir($dirp);
    ksort($dirlist,  SORT_LOCALE_STRING);
    ksort($filelist, SORT_LOCALE_STRING);
  }
  else return "Failed to open '$dir'.";
  $dirup = implode('/', array_slice(explode('/', $Ddir), 0, -1));


  $html = "";
  if( ! IsEnabled($opt['nodirs'], 0)) {
    if($Ddir>'') $html .= sprintf($DirList['dirline'], $DirList['parent'], '', '', $dirup);
    foreach($dirlist as $name=>$a) {
      $url = urlencode(preg_replace('!^\\/+!', '', "$Ddir/$name"));
      $html .= sprintf($DirList['dirline'], $name, $a[0], $a[1], $url);
    }
  }
  if( ! IsEnabled($opt['nofiles'], 0)) {
    foreach($filelist as $name=>$a) {
      $url =  urlencode(preg_replace('!^\\/+!', '',"$Fdir/$name"));
      $html .= sprintf($DirList['fileline'], $name, $a[0], $a[1], $url);
    }
  }
  $wrap = sprintf($DirList['listwrap'], $html, $dir);
  return FmtPageName($wrap, $pagename);
}

function dirlist_nformat($x) {
  if($x<1024) return $x;
  if($x<1024*1024) return round($x/1024, 1). ' k';
  if($x<1024*1024*1024) return round($x/1024/1024, 1). ' M';
  return round($x/1024/1024/1024, 1).' G';
}

if(!function_exists('MatchNames')){function MatchNames($l,$p){return MatchPageNames($l,$p);}}

function HandleDirListGet($pagename, $auth = 'read') {
  global $DirList, $DownloadDisposition, $UploadExts;
  SDV($DownloadDisposition, "inline");
  $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
  if (!$page) Abort("?cannot read $pagename");
  
  $f = str_replace(array('..', '/.'), array('', ''), @$_REQUEST['f']);
  $f = preg_replace('/^\\/+/', '', $f);

  $filepath = $DirList['Root'].'/'.$f;
  if (!$f || !file_exists($filepath)) {
    header("HTTP/1.0 404 Not Found");
    Abort("?requested file not found");
    exit();
  }
  preg_match('/\\.([^.]+)$/',$filepath,$match);
  if ($UploadExts[@$match[1]])
    header("Content-Type: {$UploadExts[@$match[1]]}");
  else header("Content-Type: text/plain");
  header("Content-Length: ".filesize($filepath));
  $upname = preg_replace("/^.*?\\/+/", '', $f);
  header("Content-disposition: $DownloadDisposition; filename=\"$upname\"");
  $fp = fopen($filepath, "r");
  if ($fp) {
    while (!feof($fp)) echo fread($fp, 4096);
    fclose($fp);
  }
  exit();
}
