Development of Files action


This is the development page for the {{files}} action.
  • For info about the version currently included in Wikka, take a look at Mod015fFilesAction.
  • For a documentation of how to use the current version, look at FilesActionInfo.
 


handlers/page/files.xml.php didn't work for me, so i use FilesActionHillar

Actual version


The code below offers a more visually improved layout for this handler and also displays the file size and the date of file upload.
- HeavyK (k m r @ h e a v y k . o r g), 3/27/04

actions/files.php
<?php
if (! function_exists('mkdir_r')) {
 function mkdir_r ($dir) {
  if (strlen($dir) == 0) return 0;
  if (is_dir($dir)) return 1;
  elseif (dirname($dir) == $dir) return 1;
  return (mkdir_r(dirname($dir)) and mkdir($dir,0755));
 }
}

if (! function_exists('bytesToHumanReadableUsage')) {
  /**
  * Converts bytes to a human readable string
  * @param int $bytes Number of bytes
  * @param int $precision Number of decimal places to include in return string
  * @param array $names Custom usage strings
  * @return string formatted string rounded to $precision
  */

  function bytesToHumanReadableUsage($bytes, $precision = 2, $names = '')
  {
     if (!is_numeric($bytes) || $bytes < 0) {
      return false;
     }
   
     for ($level = 0; $bytes >= 1024; $level++) {
      $bytes /= 1024;
     }
   
     switch ($level)
     {
      case 0:
       $suffix = (isset($names[0])) ? $names[0] : 'Bytes';
       break;
      case 1:
       $suffix = (isset($names[1])) ? $names[1] : 'KB';
       break;
      case 2:
       $suffix = (isset($names[2])) ? $names[2] : 'MB';
       break;
      case 3:
       $suffix = (isset($names[3])) ? $names[3] : 'GB';
       break;  
      case 4:
       $suffix = (isset($names[4])) ? $names[4] : 'TB';
       break;      
      default:
       $suffix = (isset($names[$level])) ? $names[$level] : '';
       break;
     }
   
     if (empty($suffix)) {
      trigger_error('Unable to find suffix for case ' . $level);
      return false;
     }
   
     return round($bytes, $precision) . ' ' . $suffix;
  }
}


if ($download <> '') {

 // link to download a file
 if ($text == '') $text = $download;
 echo "<a href=\"".$this->href('files.xml',$this->GetPageTag(),'action=download&file='.urlencode($download))."\">".$text."</a>";

} elseif ($this->page AND $this->HasAccess('write') AND ($this->method <> 'print.xml') AND ($this->method <> 'edit')) {

 // upload path
 if ($this->config['upload_path'] == '') $this->config['upload_path'] = 'files';
 $upload_path = $this->config['upload_path'].'/'.$this->GetPageTag();
 if (! is_dir($upload_path)) mkdir_r($upload_path);

 // upload action
 $uploaded = $_FILES['file'];
 if ($_REQUEST['action'] == 'upload' AND $uploaded['size'] > 0)
  copy ($uploaded['tmp_name'], $upload_path.'/'.$uploaded['name']);

 // uploaded files
  print "

      <table cellspacing=0 cellpadding=0>
        <tr>
        <td>
          &nbsp;
        </td>
        <td bgcolor=gray valign=bottom align=center>
          <font color=white size=-2>
          Attachment
          </font>
        </td>
        <td bgcolor=gray valign=bottom align=center>
          <font color=white size=-2>
          Size
          </font>
        </td>
        <td bgcolor=gray valign=bottom align=center>
          <font color=white size=-2>
          Date Added
          </font>
        </td>
        </tr>

    "
;

 $dir = opendir($upload_path);
 while ($file = readdir($dir)) {
  if ($file != '.' && $file != '..') {
      $num++;
   $delete_link = "<a href=\"".$this->href('files.xml',$this->GetPageTag(),'action=delete&file='.urlencode($file))."\">x</a>";
   $download_link = "<a href=\"".$this->href('files.xml',$this->GetPageTag(),'action=download&file='.urlencode($file))."\">".$file."</a>";
      $size = bytesToHumanReadableUsage(filesize("$upload_path/$file"));
      $date = date("n/d/Y g:i a",filemtime("$upload_path/$file"));

      print  "

          <tr>
            <td valign=top align=center>
            &nbsp;&nbsp;
            {$delete_link}
            &nbsp;&nbsp;
            </td>
            <td valign=top>
            $download_link
            </td>
            <td valign=top>
            &nbsp;
            <font size=-1 color=gray>
              $size
            </font>
            </td>
            <td valign=top>
            &nbsp;
            <font size=-1 color=gray>
              $date
            </font>
            </td>
          </tr>

        "
;
  }
 }
 closedir($dir);

  // print n/a if no files currently exist
  if (!$num)  print "<tr><td>&nbsp;</td><td colspan=3 align=center><font color=gray size=-1><i>&nbsp;&nbsp;&nbsp;</i></font></td></tr>";
  else  print "<tr><td>&nbsp;</td></tr>";

 // form
 $result = "<form action=\"".$this->href()."\" method=\"post\" enctype=\"multipart/form-data\">\n";
 if (!$this->config["rewrite_mode"]) $result .= "<input type=\"hidden\" name=\"wakka\" value=\"".$this->MiniHref()."\">\n";
 echo $result;
 //<input type="hidden" name="action" value="upload"><input type="file" name="file"><input type="submit" value="+">
 echo $this->FormClose();

  // close disp table
  print "

        <tr>
        <td>
          &nbsp;
        </td>
        <td colspan=4 valign=top align=right nowrap>
          <i>
          $result
          <input type=\"hidden\" name=\"action\" value=\"upload\">
          <font color=gray size=-2>
            add new attachment:
            <input type=\"file\" name=\"file\" style=\"padding: 0px; margin: 0px; font-size: 8px; height: 15px\">
            <input type=\"Submit\" value=\"+\" style=\"padding: 0px; margin: 0px; font-size: 8px; height: 15px\">
          "
.$this->FormClose()."
          </font>
          </i>
        </td>
        </tr>
      </table>

    "
;
}
?>


First version


actions/files.php
<?php
if (! function_exists('mkdir_r')) {
 function mkdir_r ($dir) {
  if (strlen($dir) == 0) return 0;
  if (is_dir($dir)) return 1;
  elseif (dirname($dir) == $dir) return 1;
  return (mkdir_r(dirname($dir)) and mkdir($dir,0755));
 }
}

if ($download <> '') {

 // link to download a file
 if ($text == '') $text = $download;
 echo "<a href=\"".$this->href('files.xml',$this->GetPageTag(),'action=download&file='.urlencode($download))."\">".$text."</a>";

} elseif ($this->page AND $this->HasAccess('write') AND ($this->method <> 'print.xml') AND ($this->method <> 'edit')) {

 // upload path
 if ($this->config['upload_path'] == '') $this->config['upload_path'] = 'files';
 $upload_path = $this->config['upload_path'].'/'.$this->GetPageTag();
 if (! is_dir($upload_path)) mkdir_r($upload_path);

 // upload action
 $uploaded = $_FILES['file'];
 if ($_REQUEST['action'] == 'upload' AND $uploaded['size'] > 0)
  copy ($uploaded['tmp_name'], $upload_path.'/'.$uploaded['name']);

 // form
 $result = "<form action=\"".$this->href()."\" method=\"post\" enctype=\"multipart/form-data\">\n";
 if (!$this->config["rewrite_mode"]) $result .= "<input type=\"hidden\" name=\"wakka\" value=\"".$this->MiniHref()."\">\n";
 echo $result;
 ?>
 <input type="hidden" name="action" value="upload"><input type="file" name="file"><input type="submit" value="+">
 <?php
 echo $this->FormClose();

 // uploaded files
 $dir = opendir($upload_path);
 while ($file = readdir($dir)) {
  if ($file != '.' && $file != '..') {
   $delete_link = "<a href=\"".$this->href('files.xml',$this->GetPageTag(),'action=delete&file='.urlencode($file))."\">x</a>";
   $download_link = "<a href=\"".$this->href('files.xml',$this->GetPageTag(),'action=download&file='.urlencode($file))."\">".$file."</a>";
   print "[ {$delete_link} ] ";
   if ($file == $uploaded['name'])
    print "<em>{$download_link}</em>\n";
   else
    print $download_link;
   print '<br>';
  }
 }
 closedir($dir);
}
?>


handlers/page/files.xml.php
<?php
/* mime stuff take from Paul Southworth */
$mt_f = $this->config['mime_types'];
if ($mt_f == '') $mt_f='mime.types';

/* build an array keyed on the file ext */
if (is_readable($mt_f)) {
 $mime_types=array();
 /* open our mime.types file for reading */
 $mt_fd=fopen($mt_f,"r");
 while (!feof($mt_fd)) {
  /* pull a line off the file */
  $mt_buf=trim(fgets($mt_fd,1024));
  /* discard if the line was blank or started with a comment */
  if (strlen($mt_buf) > 0) if (substr($mt_buf,0,1) != "#") {
   /* make temp array of the mime.types line we just read */
   $mt_tmp=preg_split("/[\s]+/", $mt_buf, -1, PREG_SPLIT_NO_EMPTY);
   $mt_num=count($mt_tmp);
   /* if $mt_num = 1 then we got no file extensions for the type */
   if ($mt_num > 1) {
    for ($i=1;$i<$mt_num;$i++) {
     /* if we find a comment mid-line, stop processing */
     if (strstr($mt_tmp[$i],"#")) {
      break;
     /* otherwise stick the type in an array keyed by extension */
     } else {
      $mime_types[$mt_tmp[$i]]=$mt_tmp[0];
     }
    }
   /* zero the temporary array */
   unset($mt_tmp);
   }
  }
 }
 /* close the mime.types file we were reading */
 fclose($mt_fd);
} else {
 echo "ERROR: unreadable file " . $mt_f . "\n";
}

// upload path
if ($this->config['upload_path'] == '') $this->config['upload_path'] = 'files';
$upload_path = $this->config['upload_path'].'/'.$this->GetPageTag();
if (! is_dir($upload_path)) mkdir_r($upload_path);

// do the action
switch ($_REQUEST['action']) {
 case 'download':
   $_REQUEST['file'] = urldecode($_REQUEST['file']);
   if ($this->HasAccess('read')) {
    $path = "{$upload_path}/{$_REQUEST['file']}";
    $filename = basename($path);
    header('MIME-Version: 1.0');
    $afn = split("\.",$filename);
    $ext =  strtolower($afn[count($afn)-1]);
    $mime_type = $mime_types[$ext];
    if ($mime_type == '') $mime_type = 'application/octet-stream';
    header("Content-Type: {$mime_type}; name=\"{$filename}\"");
    header('Content-Length: '. filesize($path));
    header("Content-Disposition: filename=\"{$filename}\"");
    $fp=fopen($path,'r');
    print fread($fp,filesize($path));
    fclose($fp);
    exit();
   }
 case 'delete':  
   if ($this->HasAccess('write')) {
    @unlink("{$upload_path}/{$_REQUEST['file']}");
    print $this->redirect($this->href());
   }
}
?>


Nice.. but shouldn't delete at least check some permissions? (answer: I am checking write permission...)
-- ArnarBirgisson

Why "files.xml"? shouldn't it be "files.php"? (answer: .xml actions does not include header and footer)
(files.xml didn't work, but renaming it to "files.xml.php" helped.)
=> Kommentar::
files-action only works if you copy files.xml and store it as files.xml.php as well as files.xml ??????????

Jetzt geht es, aber das ist ziemlich irre, weil ::
- files.xml
noch einmal als ::
- files.xml.php
abgespeichert werden muss. ?? es funktioniert ..


KonradTadesse


:: FileUp ::
By the way, having an upload form on a page seems to break the page preview "Store" and "Re-edit" buttons.
(fixed hidding the form on editing, thanks for your bug information)
-- Tero

Here is the same bug like in ImageAction: the use of $vars. Replace line 11 to 16 in actions/files.php with this:
 if ($tokens['download'] ) {

 // link to download a file
 $text = $this->stripquotes($action_params['download']);
 if ($tokens['text'])
 {
  $text = $this->stripquotes($action_params['text']);
 }
 echo "<a href=\"".$this->href('files.xml',$this->GetPageTag(),'action=download&file='.urlencode($this->stripquotes($action_params['download'])))."\">".$text."</a>";
}


For the function $this->stripquotes read ImageAction
--SilBaer

Fileupload on editing pages see FileUpload
--SilBaer

Fix: Added closing CurlyBrace in last replacement code.
--MarkHissinkMuller

Code cleanup


actions/files.php
<?php
$output = '';
$output .= '<div class="files">';

//this realy should be in the config
$max_upload_size = 2*1048576;
$allowed_extensions = 'gif|jpeg|jpg|jpe|png|doc|xls|csv|ppt|ppz|pps|pot|pdf|asc|txt|zip|gtar|gz|bz2|tar|rar|vpp|mpp|vsd|mm';

/* $date_format = 'n/d/Y g:i a'; (original) */
/* $date_format = 'd-M-Y H:i'; //01-Feb-2005 05:23 */
$date_format = 'Y-m-d H:i'; //2005-02-01 05:23 (easy javascript table sorting)

// mkdir_r
if (! function_exists('mkdir_r')) {
 function mkdir_r ($dir) {
     if (strlen($dir) == 0) return 0;
     if (is_dir($dir)) return 1;
     elseif (dirname($dir) == $dir) return 1;
     return (mkdir_r(dirname($dir)) and mkdir($dir,0755));
 }
}

// bytesToHumanReadableUsage
if (! function_exists('bytesToHumanReadableUsage')) {
 /**
  * Converts bytes to a human readable string
  * @param int $bytes Number of bytes
  * @param int $precision Number of decimal places to include in return string
  * @param array $names Custom usage strings
  * @return string formatted string rounded to $precision
  */

 function bytesToHumanReadableUsage($bytes, $precision = 0, $names = '') {
     if (!is_numeric($bytes) || $bytes < 0) {
         $bytes = 0;
     }
     
     if (!is_numeric($precision) || $precision < 0) {
         $precision = 0;
     }
     
     if (!is_array($names)) {
         /* $names = array(' Bytes',' KB',' MB',' GB',' TB'); //original */
         $names = array('B','k','M','G','T','P','E');
     }
     
     $level = floor(log($bytes)/log(1024));
     
     $suffix = '';
     if ($level < count($names)) {
         $suffix = $names[$level];
     }
     
     return round($bytes/pow(1024, $level), $precision) . $suffix;
 }
}

// error code constants
if (! defined('UPLOAD_ERR_OK')){
 define('UPLOAD_ERR_OK', 0);
}
if (! defined('UPLOAD_ERR_INI_SIZE')){
 define('UPLOAD_ERR_INI_SIZE', 1);
}
if (! defined('UPLOAD_ERR_FORM_SIZE')){
 define('UPLOAD_ERR_FORM_SIZE', 2);
}
if (! defined('UPLOAD_ERR_PARTIAL')){
 define('UPLOAD_ERR_PARTIAL', 3);
}
if (! defined('UPLOAD_ERR_NO_FILE')){
 define('UPLOAD_ERR_NO_FILE', 4);
}
if (! defined('UPLOAD_ERR_NO_TMP_DIR')){
 define('UPLOAD_ERR_NO_TMP_DIR', 6);
}

/*
input:
{{files download="filename.txt" text="important textfile"}}

output:
<a href="http://example.com/wiki/ExamplePage/files.xml?action=download&file=filename.txt">important textfile</a>
*/

/*
input:
{{files}}

output:
<div class="files"><table>
 <thead>
     <tr>
         <td></td>
         <th>Name</th>
         <th>Last modified</th>
         <th>Size</th>
     </tr>
 </thead>
 <tbody>
     <tr class="r1 r1m2 r1m3">
         <td></td>
         <td><a href="http://example.com/wiki/ExamplePage/files.xml?action=download&amp;file=filename.txt">filename.txt</a></td>
         <td>2005-02-03 17:57</td>
         <td align="right">189k</td>
     </tr>
     <tr class="r2 r0m2 r2m3">
         <td></td>
         <td><a href="http://example.com/wiki/ExamplePage/files.xml?action=download&amp;file=another%20file.txt">another file.txt</a></td>
         <td>2005-02-03 17:57</td>
         <td align="right">34k</td>
     </tr>
   </tbody>
</table></div>

output if you're admin:
<div class="files"><table>
 <thead>
     <tr>
         <td></td>
         <th>Name</th>
         <th>Last modified</th>
         <th>Size</th>
     </tr>
 </thead>
 <tbody>
     <tr class="r1 r1m2 r1m3">
         <td>[<a href="http://example.com/wiki/ExamplePage/files.xml?action=delete&amp;file=filename.txt">delete</a>]</td>
         <td><a href="http://example.com/wiki/ExamplePage/files.xml?action=download&amp;file=filename.txt">filename.txt</a></td>
         <td>2005-02-03 17:57</td>
         <td align="right">189k</td>
     </tr>
     <tr class="r2 r0m2 r2m3">
         <td>[<a href="http://example.com/wiki/ExamplePage/files.xml?action=delete&amp;file=another%20file.txt">delete</a>]</td>
         <td><a href="http://example.com/wiki/ExamplePage/files.xml?action=download&amp;file=another%20file.txt">another file.txt</a></td>
         <td>2005-02-03 17:57</td>
         <td align="right">34k</td>
     </tr>
   </tbody>
</table>
<form action="http://example.com/wiki/HomePage" method="post" enctype="multipart/form-data">
 <p>
     
     <input type="hidden" name="action" value="upload" />
     <input type="hidden" name="MAX_FILE_SIZE" value="2097152" />
     add new attachment:
     <input type="file" name="file" />
     <input type="submit" value="Upload" />
 </p>
</form></div>

*/

if ($vars['download'] != '') {

 // link to download a file
 if ($vars['text'] == '') $text = $vars['download'];
 $output .=  '<a href="'
 . $this->Href(
     'files.xml',
     $this->GetPageTag(),
     'action=download&amp;file='.
     rawurlencode($vars['download'])
 )
 . '">'
 . $vars['text']
 . '</a>';

// Show files to anyone with read access, we'll check for write access if they try to delete a file.
} elseif ($this->page && $this->HasAccess('read') && $this->method != 'print.xml' && $this->method != 'edit') {

 // upload path
 if ($this->config['upload_path'] == '') {
     $this->config['upload_path'] = 'files';
 }
 
 $upload_path = $this->config['upload_path'].'/'.$this->GetPageTag();
 
 if (! is_dir($upload_path)) {
     mkdir_r($upload_path);
 }
 
 // upload action
 if ($_POST['action'] == 'upload') {
     
     $status_text = '';
     
     switch ($_FILES['file']['error']) {
         case UPLOAD_ERR_OK:
             if ($_FILES['file']['size'] > $max_upload_size) {
                 $status_text = 'Attempted file upload was too big. '
                             . 'Maximum allowed size is '
                             . bytesToHumanReadableUsage($max_upload_size) . '.';
                 unlink($_FILES['file']['tmp_name']);
             }
             elseif (preg_match('/.+\.('.$allowed_extensions.')$/i', $_FILES['file']['name'])) {
                 $strippedname = str_replace('\'', '', $_FILES['file']['name']);
                 $strippedname = stripslashes($strippedname);

                 $destfile = $upload_path.'/'.$strippedname;

                 if (!file_exists($destfile)) {
                     if (move_uploaded_file($_FILES['file']['tmp_name'], $destfile)) {
                         $status_text = 'File was successfully uploaded.';
                     }
                     else {
                         $status_text = 'There was an error uploading your file.';
                     }
                 }
                 else {
                     $status_text = 'There is already a file named "' . $strippedname . '".';
                 }
             } else {
                 $status_text = 'This file\'s extension is unknown.';
                 unlink($_FILES['file']['tmp_name']);
             }
             break;
         case UPLOAD_ERR_INI_SIZE:
         case UPLOAD_ERR_FORM_SIZE:
             $status_text = 'Attempted file upload was too big. '
                         . 'Maximum allowed size is '
                         . bytesToHumanReadableUsage($max_upload_size).'.';
             break;
         case UPLOAD_ERR_PARTIAL:
             $status_text = 'File upload incomplete. Please try again.';
             break;
         case UPLOAD_ERR_NO_FILE:
             $status_text = 'No file uploaded.';
             break;
         case UPLOAD_ERR_NO_TMP_DIR:
             $status_text = 'File uploads impossible due to misconfigured server.';
             break;
     }
     if ($status_text != '') {
         $output .=  '<p class="status">' . $status_text . '</p>';
     }
 }
 
 // uploaded files
 $output .=  <<<HEREDOC
<table>
 <thead>
     <tr>
         <td></td> <!-- For the delete link. Only needed when user is admin or has write rights. -->
         <th>Name</th>
         <th>Last modified</th>
         <th>Size</th>
     </tr>
 </thead>
 <tbody>
HEREDOC
;

 $dir = opendir($upload_path);
 $num = 0;
 while ($file = readdir($dir)) {
     /* if ( $file != '.' && $file != '..') { */
     if ($file{0} != '.') {
         $num++;
         $delete_link = '<!-- delete -->';
         /* if ($this->HasAccess('write')) { */
         if ($this->IsAdmin()) {
             $delete_link = '[<a href="'
             . $this->Href('files.xml',$this->GetPageTag(),'action=delete&amp;file='.rawurlencode($file))
             . '">delete</a>]';
         }
         $download_link = '<a href="'
         . $this->Href('files.xml',$this->GetPageTag(),'action=download&amp;file='.rawurlencode($file))
         . '">'.$file.'</a>';
         $size = bytesToHumanReadableUsage(filesize($upload_path . '/' . $file));
         $date = date($date_format, filemtime($upload_path . '/' . $file));
         // easy even/odd zebra table
         // also possible to zebra color every three rows
         $row_class = 'r'.$num.' r'.($num % 2).'m2 r'.($num % 3).'m3';
         $output .= <<<HEREDOC

     <tr class="{$row_class}">
         <td>{$delete_link}</td>
         <td>{$download_link}</td>
         <td>{$date}</td>
         <td align="right">{$size}</td>
     </tr>
HEREDOC
;
     }
 }
 closedir($dir);

 // print n/a if no files currently exist
 if ($num < 1) {
     $output .= <<<HEREDOC

     <tr><td colspan="4">no files here</td></tr>
HEREDOC
;
 }
   $output .= <<<HEREDOC

   </tbody>
</table>
HEREDOC
;

   /* if ($this->HasAccess('write')) { */
   if ($this->IsAdmin()) {
    // form
    $input_for_rewrite_mode = '<!-- rewrite mode disabled -->';
    if (!$this->config['rewrite_mode']){
        $input_for_rewrite_mode = '<input type="hidden" name="wakka" value="'.$this->MiniHref().'" />';
    }
    // close disp table
    $href = $this->Href();
    $output .= <<<HEREDOC

<form action="{$href}" method="post" enctype="multipart/form-data">
 <p>
     {$input_for_rewrite_mode}
     <input type="hidden" name="action" value="upload" />
     <input type="hidden" name="MAX_FILE_SIZE" value="{$max_upload_size}" />
     add new attachment:
     <input type="file" name="file" />
     <input type="submit" value="Upload" />
 </p>
</form>
HEREDOC
;
   }
}
$output .= '</div>';
$output = $this->ReturnSafeHTML($output);
echo $output;
?>


handlers/page/files.xml.php
<?php
// upload path
if ($this->config['upload_path'] == '') {
 $this->config['upload_path'] = 'files';
}
$upload_path = $this->config['upload_path'].'/'.$this->GetPageTag();
if (!is_dir($upload_path)) {
 mkdir_r($upload_path);
}
$allowed_extensions = 'gif|jpeg|jpg|jpe|png|doc|xls|csv|ppt|ppz|pps|pot|pdf|asc|txt|zip|gtar|gz|bz2|tar|rar|vpp|mpp|vsd|mm';
$mime_types_file = $this->config['mime_types'];

$base_name = basename(urldecode($_REQUEST['file']));

$parts = explode('.', $base_name );

$extension = '';
if(count($parts) > 1){
 $extension = array_pop($parts);
}

$first_letter = $base_name{0};

if ($first_letter != '.' && stristr('|'.$allowed_extensions.'|', '|'.$extension.'|')) {
 
 $path = $upload_path.'/'.basename(urldecode($_REQUEST['file']));
 
 // do the action
 switch ($_REQUEST['action']) {
     case 'download':
         if ($this->HasAccess('read')) {
             $filename = basename($path);
             $mimetype = 'application/x-download';
             $mimes = file($mime_types_file);
             foreach($mimes as $line){
                 if(preg_match('/^(\w+\/\S+)\b.*\s'.$extension.'\b/i', $line, $matches)){
                     $mimetype = $matches[1];
                     break;
                 }
             }
             Header('Content-Length: '.filesize($path));
             Header('Content-Type: '.$mimetype);
             Header('Content-Disposition: attachment; filename="'.$filename.'"; '
             .'modification-date="'.date('r', filemtime($path)).'";');
                    Header('Connection: close');
                    @readfile($path);
                    exit();
            }
            break;
        case 'delete':
            // if ($this->HasAccess('write')) {
            if ($this->IsAdmin()) {
                @unlink($path);
            }
            print $this->redirect($this->Href());
            break;
    }
}
?>


css
.files table{
    border: 1px solid #ccc;
    border-collapse: collapse;
}
.files thead th, .files thead td {
    color: #fff;
    background: #999;
}
.files td, .files th {
    padding: 0 3px 0 3px;
}
.files tr.r0m2 {
    background: #efe;
    color: #000;
}


I cleaned up the code and added:

Hope you like it.
--CryDust


yet another actions/files.php


http://wush.net/trac/wikka/ticket/72

it is not said in the ticket, but of course my version is also fully css skinable.

some other changes:

as i state in the ticket also, the upload file limit is not working for me. see the ticket


styling the file upload form


people might get frustrated by the browse button and the file input field.
this page offers a solution: http://www.quirksmode.org/dom/inputfile.html
Not a good solution: it requires JavaScript, and the field itself accepts no (typed) input any more (in a normal file upload field you can type or paste a path - that doesn't work on any of PPK's examples): that beaks basic functionality. The only "frustration" is the lack of styleability of the button - well, too bad, at least it's accessible (provided there's also a label, of course), and that's more important. -- JavaWoman


making uploaded images useful


to make the wiki a truly useful documentation tool, one needs pictures, uploaded pictures.
at the moment pictures uploaded using FilesAction are accessible only for download
(unless i am missing something). to let a department manage it's own pictures and be
able to include them in the page, one needs to access $upload_path. the current
.htaccess file makes this impossible.

so here is what i did:

.htaccess

<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{REQUEST_FILENAME} -d
 RewriteRule ^(.*/[^\./]*[^/])$ $1/

 RewriteCond %{REQUEST_FILENAME} !robots.txt
 RewriteCond %{REQUEST_FILENAME} !favicon.ico
 RewriteCond %{REQUEST_FILENAME} !files/.*$
 RewriteRule ^(.*)$ wikka.php?wakka=$1 [QSA,L]
</IfModule>


in the wikka page:

{{image alt="db model" title="db model" url="files/CostCenters/costcenters.png"}}

this way i can include the images for viewing in the page.


detecting php-level disabled uploads

If you don't control your web server, you might run into the situation where file uploads are disabled in php.ini
http://wush.net/trac/wikka/ticket/825 contains this patch:

106a107,111
> if (! ((bool) ini_get('file_uploads'))) {
>       echo "<b>File uploads are disallowed on this server.</b>";
> }
> else
> {
282a288
> }
Comments
Comment by DarTar
2004-12-22 14:05:51
I like the very much the float box idea.

JW, why not write some guidelines about how to document the relations between

1) original code proposals
2) official wikka features
3) end user documentation on official Wikka features

following the same lines of http://wikka.jsnx.com/DocumentationGuidelines.
This would prevent "bona fide" errors by enthusiastic contributors.

And maybe a CategoryGuidelines (containing pages about naming conventions on this server) or a big WikkaGuidelines page should be created.

Definitely time to install a page rename handler, though...
Comment by JavaWoman
2004-12-23 16:38:06
A **Template** for each of the three related page types would help - combined with the proposed CloneHandler, of course. ;-)

But I'll write something if/when I can find the time. (Wish for the new year: have 48 hours in a day!)
Comment by RubenVerlinden
2005-02-25 14:17:04
Where are the permissions et for the { {files} } action?
For the moment all { {files} } actions in my Wikka Wiki only allow the wiki administrator to upload files. Not people with write allowed ACL on page which contains { {files} } action.
Comment by RubenVerlinden
2005-03-01 12:33:52
In the last function of the files.php, change the comments on the following test :

if ($this->HasAccess('write')) {
//if ($this->IsAdmin()) {
Comment by ChrisH
2005-12-30 00:05:29
I would like to clone the files action and make a {{picturefiles}} action that is used to manage the files in the default Images directory, as well as upload any files to there, rather than to a subdirectory created by the files action. I'm thinking it should just be a matter of hardcoding the path in, but I'm not sure what lines in the files action need to modified.

Also, how hard would it be to add some secruity checks to make sure only png, gif and jpg files could be uploaded?
Comment by JavaWoman
2005-12-30 08:47:22
ChrisH,

For hardcoding the path, look for where $upload_path is derived/used and replace that code in both the handler and the action.

To check for actual image files (of a particular type, if needed), the easiest is to use the PHP function getimagesize() - if it's not an image, the function will fail (and return FALSE); if it *is* an image, the type will also be returned in the result array so you can filter on that. It uses the internal data as stored in the image file, so the extension doesn't matter (relying on extension is itself a security risk!) See http://php.net/getimagesize for the details.
Comment by MinusF
2006-01-11 15:31:45
i need some help with this action. it seems that i can't upload even files the size of 512KB no matter what i set $max_upload_size to...

the upload error errormessage is never shown i get page not found errors in both explorer and firefox.

i need to upload bigger files, perhaps up to 5MB and i can't track this down.
could anyone help?
Comment by 12.106.25.162
2006-03-06 12:19:19
You have to change the php.ini file
max_upload_filesize and post_max_size both control the size of files that can be uploaded. The default for max_upload_filesize is 2M. The default for post_max_size is 8M .
Comment by LeOn
2007-08-30 11:48:14
Hi Everyone!

I wonder, if you could help me to solve my problem with FilesAction. In my test environment (Xampp, WinXP) I try to make some upload as admin and it works fine. But when I try to delete or to download a file, I get every time the message "Unknown method; the method name must not contain special characters."

I will try it out with my Linux-Box too, but i don't have access to it at work...

Thanks a lot!

By the way: I really like WikkaWiki! I already run 3 instances of it...
Comment by BrianKoontz
2007-08-30 21:12:30
LeOn, glad Wikka is to your liking! What version of Wikka are you using, and is there a publicly-accessible site I can look at? (Feel free to e-mail the URL to me if you don't want to post it here.) We also hang out on freenode, channel is #wikka.
Comment by LeOn
2007-09-29 13:41:39
Thanks for your answer, Brian, and sorry for late response!
I'm using Wikka v. 1.1.6.3. Unfortunately there is at the time only one site with restricted access for some IP-s and I'm not the admin. But the problem exists only on the test system (xampp on windoze) - I don't have trouble on the server (CentOS + standard apache/mysql).

I guess, on my test system the problem seems to be connected to the "rewrite mode". I don't know why, but the link to the file looks not like this:
http://host/wiki/wikka.php?wakka=WikiPage/files.xml&action=download&file=print.pdf
but like this:
http://host/wiki/wikka.php?wakka=WikiPage/files.xml?action=download&file=print.pdf

Means: "?" instead of "&"

I don't care about that since it doesn't make trouble on the server, but maybe this information could be useful on other problems...

Bye!

LeOn
Comment by ChrisCase
2013-07-20 19:39:39
I just spent a bit of time trying to fix a MAX_UPLOAD_SIZE issue. Adjusting it in the relevant php.ini file did not seem to fix it completely. After I adjusted MAX_UPLOAD_SIZE and MAX_POST_SIZE, I started to get an error (previously there was no error displayed).

I ended up having to change the value on this line, I made it about 100 megs, just to give some breathing room:

if(!defined('MAX_UPLOAD_SIZE')) define('MAX_UPLOAD_SIZE', 102400000);

It worked; but there should probably be a way to do so without having to change the file, rather it should be changed in the configuration as the comment seems to suggest. Maybe I will figure this out.
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki