Ignore:
Timestamp:
03/23/11 15:15:28 (13 years ago)
Author:
alexandrecorreia
Message:

Ticket #1660 - Enviar arquivos pelo filemanager, tratado o erro para o php.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2/filemanager/inc/jupload.php

    r3386 r3894  
    11<?php 
    2  
    32 
    43/** 
     
    5352 * 
    5453 */ 
    55  
    5654class JUpload { 
    5755 
    58     var $appletparams; 
    59     var $classparams; 
    60     var $files; 
    61  
    62     public function JUpload($appletparams = array(), $classparams = array()) { 
    63         if (gettype($classparams) != 'array') 
    64             $this->abort('Invalid type of parameter classparams: Expecting an array'); 
    65         if (gettype($appletparams) != 'array') 
    66             $this->abort('Invalid type of parameter appletparams: Expecting an array'); 
    67  
    68         // set some defaults for the applet params 
    69         if (!isset($appletparams['afterUploadURL'])) 
    70             $appletparams['afterUploadURL'] = $_SERVER['PHP_SELF'] . '?afterupload=1'; 
    71         if (!isset($appletparams['name'])) 
    72             $appletparams['name'] = 'JUpload'; 
    73         if (!isset($appletparams['archive'])) 
    74             $appletparams['archive'] = 'wjhk.jupload.jar'; 
    75         if (!isset($appletparams['code'])) 
    76             $appletparams['code'] = 'wjhk.jupload2.JUploadApplet'; 
    77         if (!isset($appletparams['debugLevel'])) 
    78             $appletparams['debugLevel'] = 0; 
    79         if (!isset($appletparams['httpUploadParameterType'])) 
    80             $appletparams['httpUploadParameterType'] = 'array'; 
    81         if (!isset($appletparams['showLogWindow'])) 
    82             $appletparams['showLogWindow'] = ($appletparams['debugLevel'] > 0) ? 'true' : 'false'; 
    83         if (!isset($appletparams['width'])) 
    84             $appletparams['width'] = 500; 
    85         if (!isset($appletparams['height'])) 
    86             $appletparams['height'] = ($appletparams['showLogWindow'] == 'true') ? 500 : 300; 
    87         if (!isset($appletparams['mayscript'])) 
    88             $appletparams['mayscript'] = 'true'; 
    89         if (!isset($appletparams['scriptable'])) 
    90             $appletparams['scriptable'] = 'false'; 
    91         //if (!isset($appletparams['stringUploadSuccess'])) 
    92             $appletparams['stringUploadSuccess'] = 'SUCCESS'; 
    93         //if (!isset($appletparams['stringUploadError'])) 
    94             $appletparams['stringUploadError'] = 'ERROR: (.*)'; 
    95         $maxpost = $this->tobytes(ini_get('post_max_size')); 
    96         $maxmem = $this->tobytes(ini_get('memory_limit')); 
    97         $maxfs = $this->tobytes(ini_get('upload_max_filesize')); 
    98         $obd = ini_get('open_basedir'); 
    99         if (!isset($appletparams['maxChunkSize'])) { 
    100             $maxchunk = ($maxpost < $maxmem) ? $maxpost : $maxmem; 
    101             $maxchunk = ($maxchunk < $maxfs) ? $maxchunk : $maxfs; 
    102             $maxchunk /= 4; 
    103             $optchunk = (500000 > $maxchunk) ? $maxchunk : 500000; 
    104             $appletparams['maxChunkSize'] = $optchunk; 
    105         } 
    106         $appletparams['maxChunkSize'] = $this->tobytes($appletparams['maxChunkSize']); 
    107         if (!isset($appletparams['maxFileSize'])) 
    108             $appletparams['maxFileSize'] = $maxfs; 
    109         $appletparams['maxFileSize'] = $this->tobytes($appletparams['maxFileSize']); 
    110         if (isset($classparams['errormail'])) { 
    111             $appletparams['urlToSendErrorTo'] = $_SERVER["PHP_SELF"] . '?errormail'; 
    112         } 
    113  
    114         // Same for class parameters 
    115         if (!isset($classparams['demo_mode'])) 
    116             $classparams['demo_mode'] = false; 
    117         if ($classparams['demo_mode']) { 
    118             $classparams['create_destdir'] = false; 
    119             $classparams['allow_subdirs'] = true; 
    120             $classparams['allow_zerosized'] = true; 
    121             $classparams['duplicate'] = 'overwrite'; 
    122         } 
    123         if (!isset($classparams['debug_php']))                                                                                  // set true to log some messages in PHP log 
    124             $classparams['debug_php'] = false; 
    125         if (!isset($this->classparams['allowed_mime_types']))                           // array of allowed MIME type 
    126                         $classparams['allowed_mime_types'] = 'all'; 
    127         if (!isset($this->classparams['allowed_file_extensions']))      // array of allowed file extensions 
    128                         $classparams['allowed_file_extensions'] = 'all'; 
    129         if (!isset($classparams['verbose_errors']))                                             // shouldn't display server info on a production site! 
    130             $classparams['verbose_errors'] = true; 
    131         if (!isset($classparams['session_regenerate'])) 
    132             $classparams['session_regenerate'] = false; 
    133         if (!isset($classparams['create_destdir'])) 
    134             $classparams['create_destdir'] = true; 
    135         if (!isset($classparams['allow_subdirs'])) 
    136             $classparams['allow_subdirs'] = false; 
    137         if (!isset($classparams['spaces_in_subdirs'])) 
    138             $classparams['spaces_in_subdirs'] = false; 
    139         if (!isset($classparams['allow_zerosized'])) 
    140             $classparams['allow_zerosized'] = false; 
    141         if (!isset($classparams['duplicate'])) 
    142             $classparams['duplicate'] = 'rename'; 
    143         if (!isset($classparams['dirperm'])) 
    144             $classparams['dirperm'] = 0755; 
    145         if (!isset($classparams['fileperm'])) 
    146             $classparams['fileperm'] = 0644; 
    147         if (!isset($classparams['destdir'])) { 
    148             if ($obd != '') 
    149                 $classparams['destdir'] = $obd; 
    150             else 
    151                 $classparams['destdir'] = '/var/tmp/jupload_test'; 
    152         } 
    153         if ($classparams['create_destdir']) 
    154             @mkdir($classparams['destdir'], $classparams['dirperm']); 
    155         if (!is_dir($classparams['destdir']) && is_writable($classparams['destdir'])) 
    156             $this->abort('Destination dir not accessible'); 
    157         if (!isset($classparams['tmp_prefix'])) 
    158             $classparams['tmp_prefix'] = 'jutmp.'; 
    159         if (!isset($classparams['var_prefix'])) 
    160             $classparams['var_prefix'] = 'juvar.'; 
    161         if (!isset($classparams['jscript_wrapper'])) 
    162             $classparams['jscript_wrapper'] = 'JUploadSetProperty'; 
    163         if (!isset($classparams['tag_jscript'])) 
    164             $classparams['tag_jscript'] = '<!--JUPLOAD_JSCRIPT-->'; 
    165         if (!isset($classparams['tag_applet'])) 
    166             $classparams['tag_applet'] = '<!--JUPLOAD_APPLET-->'; 
    167         if (!isset($classparams['tag_flist'])) 
    168             $classparams['tag_flist'] = '<!--JUPLOAD_FILES-->'; 
    169         if (!isset($classparams['http_flist_start'])) 
    170             $classparams['http_flist_start'] = 
    171                         "<table border='1'><TR><TH>Filename</TH><TH>file size</TH><TH>Relative path</TH><TH>Full name</TH><TH>md5sum</TH><TH>Specific parameters</TH></TR>"; 
    172         if (!isset($classparams['http_flist_end'])) 
    173             $classparams['http_flist_end'] = "</table>\n"; 
    174         if (!isset($classparams['http_flist_file_before'])) 
    175             $classparams['http_flist_file_before'] = "<tr><td>"; 
    176         if (!isset($classparams['http_flist_file_between'])) 
    177             $classparams['http_flist_file_between'] = "</td><td>"; 
    178         if (!isset($classparams['http_flist_file_after'])) 
    179             $classparams['http_flist_file_after'] = "</td></tr>\n"; 
    180  
    181         $this->appletparams = $appletparams; 
    182         $this->classparams = $classparams; 
    183         $this->page_start(); 
    184     } 
    185  
    186     /** 
    187      * Log a message on the current output, as a HTML comment. 
    188      */ 
    189     protected function logDebug($function, $msg, $htmlComment=true) { 
    190         $output = "[DEBUG] [$function] $msg"; 
    191         if ($htmlComment) { 
    192                 echo("<!-- $output -->\r\n"); 
    193         } else { 
    194                 echo("$output\r\n"); 
    195         } 
    196     } 
    197  
    198     /** 
    199      * Log a message to the PHP log. 
    200      * Declared "protected" so it may be Extended if you require customised logging (e.g. particular log file location). 
    201      */ 
    202     protected function logPHPDebug($function, $msg) { 
    203         if ($this->classparams['debug_php'] === true) { 
    204                 $output = "[DEBUG] [$function] ".$this->arrayexpand($msg); 
    205                 error_log($output); 
    206         } 
    207     } 
    208  
    209     private function arrayexpand($array) { 
    210         $output = ''; 
    211         if (is_array($array)) { 
    212                 foreach ($array as $key => $value) { 
    213                         $output .= "\n ".$key.' => '.$this->arrayexpand($value); 
    214                 } 
    215         } else { 
    216                 $output .= $array; 
    217         } 
    218         return $output; 
    219     } 
    220  
    221  
    222     /** 
    223      * Convert a value ending in 'G','M' or 'K' to bytes 
    224      * 
    225      */ 
    226     private function tobytes($val) { 
    227         $val = trim($val); 
    228         $last = strtolower($val{strlen($val)-1}); 
    229         switch($last) { 
    230         case 'g': 
    231             $val *= 1024; 
    232         case 'm': 
    233             $val *= 1024; 
    234         case 'k': 
    235             $val *= 1024; 
    236         } 
    237         return $val; 
    238     } 
    239  
    240     /** 
    241      * Build a string, containing a javascript wrapper function 
    242      * for setting applet properties via JavaScript. This is necessary, 
    243      * because we use the "modern" method of including the applet (using 
    244      * <object> resp. <embed> tags) in order to trigger automatic JRE downloading. 
    245      * Therefore, in Netscape-like browsers, the applet is accessible via 
    246      * the document.embeds[] array while in others, it is accessible via the 
    247      * document.applets[] array. 
    248      * 
    249      * @return A string, containing the necessary wrapper function (named JUploadSetProperty) 
    250      */ 
    251     private function str_jsinit() { 
    252         $N = "\n"; 
    253         $name = $this->appletparams['name']; 
    254         $ret = '<script type="text/javascript">'.$N; 
    255         $ret .= '<!--'.$N; 
    256         $ret .= 'function '.$this->classparams['jscript_wrapper'].'(name, value) {'.$N; 
    257         $ret .= '  document.applets["'.$name.'"] == null || document.applets["'.$name.'"].setProperty(name,value);'.$N; 
    258         $ret .= '  document.embeds["'.$name.'"] == null || document.embeds["'.$name.'"].setProperty(name,value);'.$N; 
    259         $ret .= '}'.$N; 
    260         $ret .= '//-->'.$N; 
    261         $ret .= '</script>'; 
    262         return $ret; 
    263     } 
    264  
    265     /** 
    266      * Build a string, containing the applet tag with all parameters. 
    267      * 
    268      * @return A string, containing the applet tag 
    269      */ 
    270     private function str_applet() { 
    271         $N = "\n"; 
    272         $params = $this->appletparams; 
    273         // return the actual applet tag 
    274         $ret = '<object classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"'.$N; 
    275         $ret .= '  codebase = "http://java.sun.com/update/1.5.0/jinstall-1_5-windows-i586.cab#Version=5,0,0,3"'.$N; 
    276         $ret .= '  width = "'.$params['width'].'"'.$N; 
    277         $ret .= '  height = "'.$params['height'].'"'.$N; 
    278         $ret .= '  name = "'.$params['name'].'">'.$N; 
    279         foreach ($params as $key => $val) { 
    280             if ($key != 'width' && $key != 'height') 
    281                 $ret .= '  <param name = "'.$key.'" value = "'.$val.'" />'.$N; 
    282         } 
    283         $ret .= '  <comment>'.$N; 
    284         $ret .= '    <embed'.$N; 
    285         $ret .= '      type = "application/x-java-applet;version=1.5"'.$N; 
    286         foreach ($params as $key => $val) 
    287             $ret .= '      '.$key.' = "'.$val.'"'.$N; 
    288         $ret .= '      pluginspage = "http://java.sun.com/products/plugin/index.html#download">'.$N; 
    289         $ret .= '      <noembed>'.$N; 
    290         $ret .= '        Java 1.5 or higher plugin required.'.$N; 
    291         $ret .= '      </noembed>'.$N; 
    292         $ret .= '    </embed>'.$N; 
    293         $ret .= '  </comment>'.$N; 
    294         $ret .= '</object>'; 
    295         return $ret; 
    296     } 
    297  
    298     private function abort($msg = '') { 
    299         $this->cleanup(); 
    300         if ($msg != '') 
    301             die(str_replace('(.*)',$msg,$this->appletparams['stringUploadError'])."\n"); 
    302         exit; 
    303     } 
    304  
    305     private function warning($msg = '') { 
    306         $this->cleanup(); 
    307         if ($msg != '') 
    308             echo('WARNING: '.$msg."\n"); 
    309         echo $this->appletparams['stringUploadSuccess']."\n"; 
    310         exit; 
    311     } 
    312  
    313     private function cleanup() { 
    314         // remove all uploaded files of *this* request 
    315         if (isset($_FILES)) { 
    316             foreach ($_FILES as $key => $val) 
    317                 @unlink($val['tmp_name']); 
    318         } 
    319         // remove accumulated file, if any. 
    320         @unlink($this->classparams['destdir'].'/'.$this->classparams['tmp_prefix'].session_id()); 
    321         @unlink($this->classparams['destdir'].'/'.$this->classparams['tmp_prefix'].'tmp'.session_id()); 
    322         // reset session var 
    323         $_SESSION[$this->classparams['var_prefix'].'size'] = 0; 
    324         return; 
    325     } 
    326  
    327     private function mkdirp($path) { 
    328         // create subdir (hierary) below destdir; 
    329         $dirs = explode('/', $path); 
    330         $path = $this->classparams['destdir']; 
    331         foreach ($dirs as $dir) { 
    332             $path .= '/'.$dir; 
    333             if (!file_exists($path)) {                                          // @ does NOT always supress the error! 
    334                 @mkdir($path, $this->classparams['dirperm']); 
    335             } 
    336         } 
    337         if (!is_dir($path) && is_writable($path)) 
    338             $this->abort('Destination dir not accessible'); 
    339     } 
     56        var $appletparams; 
     57        var $classparams; 
     58        var $files; 
     59 
     60        public function JUpload($appletparams = array(), $classparams = array()) { 
     61                if (gettype($classparams) != 'array') 
     62                        $this->abort('Invalid type of parameter classparams: Expecting an array'); 
     63                if (gettype($appletparams) != 'array') 
     64                        $this->abort('Invalid type of parameter appletparams: Expecting an array'); 
     65 
     66                // set some defaults for the applet params 
     67                if (!isset($appletparams['afterUploadURL'])) 
     68                        $appletparams['afterUploadURL'] = $_SERVER['PHP_SELF'] . '?afterupload=1'; 
     69                if (!isset($appletparams['name'])) 
     70                        $appletparams['name'] = 'JUpload'; 
     71                if (!isset($appletparams['archive'])) 
     72                        $appletparams['archive'] = 'wjhk.jupload.jar'; 
     73                if (!isset($appletparams['code'])) 
     74                        $appletparams['code'] = 'wjhk.jupload2.JUploadApplet'; 
     75                if (!isset($appletparams['debugLevel'])) 
     76                        $appletparams['debugLevel'] = 0; 
     77                if (!isset($appletparams['httpUploadParameterType'])) 
     78                        $appletparams['httpUploadParameterType'] = 'array'; 
     79                if (!isset($appletparams['showLogWindow'])) 
     80                        $appletparams['showLogWindow'] = ($appletparams['debugLevel'] > 0) ? 'true' : 'false'; 
     81                if (!isset($appletparams['width'])) 
     82                        $appletparams['width'] = 500; 
     83                if (!isset($appletparams['height'])) 
     84                        $appletparams['height'] = ($appletparams['showLogWindow'] == 'true') ? 500 : 300; 
     85                if (!isset($appletparams['mayscript'])) 
     86                        $appletparams['mayscript'] = 'true'; 
     87                if (!isset($appletparams['scriptable'])) 
     88                        $appletparams['scriptable'] = 'false'; 
     89                //if (!isset($appletparams['stringUploadSuccess'])) 
     90                $appletparams['stringUploadSuccess'] = 'SUCCESS'; 
     91                //if (!isset($appletparams['stringUploadError'])) 
     92                $appletparams['stringUploadError'] = 'ERROR: (.*)'; 
     93                $maxpost = $this->tobytes(ini_get('post_max_size')); 
     94                $maxmem = $this->tobytes(ini_get('memory_limit')); 
     95                $maxfs = $this->tobytes(ini_get('upload_max_filesize')); 
     96                $obd = ini_get('open_basedir'); 
     97                if (!isset($appletparams['maxChunkSize'])) { 
     98                        $maxchunk = ($maxpost < $maxmem) ? $maxpost : $maxmem; 
     99                        $maxchunk = ($maxchunk < $maxfs) ? $maxchunk : $maxfs; 
     100                        $maxchunk /= 4; 
     101                        $optchunk = (500000 > $maxchunk) ? $maxchunk : 500000; 
     102                        $appletparams['maxChunkSize'] = $optchunk; 
     103                } 
     104                $appletparams['maxChunkSize'] = $this->tobytes($appletparams['maxChunkSize']); 
     105                if (!isset($appletparams['maxFileSize'])) 
     106                        $appletparams['maxFileSize'] = $maxfs; 
     107                $appletparams['maxFileSize'] = $this->tobytes($appletparams['maxFileSize']); 
     108                if (isset($classparams['errormail'])) { 
     109                        $appletparams['urlToSendErrorTo'] = $_SERVER["PHP_SELF"] . '?errormail'; 
     110                } 
     111 
     112                // Same for class parameters 
     113                if (!isset($classparams['demo_mode'])) 
     114                        $classparams['demo_mode'] = false; 
     115                if ($classparams['demo_mode']) { 
     116                        $classparams['create_destdir'] = false; 
     117                        $classparams['allow_subdirs'] = true; 
     118                        $classparams['allow_zerosized'] = true; 
     119                        $classparams['duplicate'] = 'overwrite'; 
     120                } 
     121                if (!isset($classparams['debug_php']))                    // set true to log some messages in PHP log 
     122                        $classparams['debug_php'] = false; 
     123                if (!isset($this->classparams['allowed_mime_types']))    // array of allowed MIME type 
     124                        $classparams['allowed_mime_types'] = 'all'; 
     125                if (!isset($this->classparams['allowed_file_extensions']))  // array of allowed file extensions 
     126                        $classparams['allowed_file_extensions'] = 'all'; 
     127                if (!isset($classparams['verbose_errors']))             // shouldn't display server info on a production site! 
     128                        $classparams['verbose_errors'] = true; 
     129                if (!isset($classparams['session_regenerate'])) 
     130                        $classparams['session_regenerate'] = false; 
     131                if (!isset($classparams['create_destdir'])) 
     132                        $classparams['create_destdir'] = true; 
     133                if (!isset($classparams['allow_subdirs'])) 
     134                        $classparams['allow_subdirs'] = false; 
     135                if (!isset($classparams['spaces_in_subdirs'])) 
     136                        $classparams['spaces_in_subdirs'] = false; 
     137                if (!isset($classparams['allow_zerosized'])) 
     138                        $classparams['allow_zerosized'] = false; 
     139                if (!isset($classparams['duplicate'])) 
     140                        $classparams['duplicate'] = 'rename'; 
     141                if (!isset($classparams['dirperm'])) 
     142                        $classparams['dirperm'] = 0755; 
     143                if (!isset($classparams['fileperm'])) 
     144                        $classparams['fileperm'] = 0644; 
     145                if (!isset($classparams['destdir'])) { 
     146                        if ($obd != '') 
     147                                $classparams['destdir'] = $obd; 
     148                        else 
     149                                $classparams['destdir'] = '/var/tmp/jupload_test'; 
     150                } 
     151                if ($classparams['create_destdir']) 
     152                        @mkdir($classparams['destdir'], $classparams['dirperm']); 
     153                if (!is_dir($classparams['destdir']) && is_writable($classparams['destdir'])) 
     154                        $this->abort('Destination dir not accessible'); 
     155                if (!isset($classparams['tmp_prefix'])) 
     156                        $classparams['tmp_prefix'] = 'jutmp.'; 
     157                if (!isset($classparams['var_prefix'])) 
     158                        $classparams['var_prefix'] = 'juvar.'; 
     159                if (!isset($classparams['jscript_wrapper'])) 
     160                        $classparams['jscript_wrapper'] = 'JUploadSetProperty'; 
     161                if (!isset($classparams['tag_jscript'])) 
     162                        $classparams['tag_jscript'] = '<!--JUPLOAD_JSCRIPT-->'; 
     163                if (!isset($classparams['tag_applet'])) 
     164                        $classparams['tag_applet'] = '<!--JUPLOAD_APPLET-->'; 
     165                if (!isset($classparams['tag_flist'])) 
     166                        $classparams['tag_flist'] = '<!--JUPLOAD_FILES-->'; 
     167                if (!isset($classparams['http_flist_start'])) 
     168                        $classparams['http_flist_start'] = 
     169                                          "<table border='1'><TR><TH>Filename</TH><TH>file size</TH><TH>Relative path</TH><TH>Full name</TH><TH>md5sum</TH><TH>Specific parameters</TH></TR>"; 
     170                if (!isset($classparams['http_flist_end'])) 
     171                        $classparams['http_flist_end'] = "</table>\n"; 
     172                if (!isset($classparams['http_flist_file_before'])) 
     173                        $classparams['http_flist_file_before'] = "<tr><td>"; 
     174                if (!isset($classparams['http_flist_file_between'])) 
     175                        $classparams['http_flist_file_between'] = "</td><td>"; 
     176                if (!isset($classparams['http_flist_file_after'])) 
     177                        $classparams['http_flist_file_after'] = "</td></tr>\n"; 
     178 
     179                $this->appletparams = $appletparams; 
     180                $this->classparams = $classparams; 
     181                $this->page_start(); 
     182        } 
     183 
     184        /** 
     185         * Log a message on the current output, as a HTML comment. 
     186         */ 
     187        protected function logDebug($function, $msg, $htmlComment=true)  
     188        { 
     189                $output = "[DEBUG] [$function] $msg"; 
     190                if ($htmlComment) { 
     191                        echo("<!-- $output -->\r\n"); 
     192                } else { 
     193                        echo("$output\r\n"); 
     194                } 
     195        } 
     196 
     197        /** 
     198         * Log a message to the PHP log. 
     199         * Declared "protected" so it may be Extended if you require customised logging (e.g. particular log file location). 
     200         */ 
     201        protected function logPHPDebug($function, $msg)  
     202        { 
     203                if ($this->classparams['debug_php'] === true) { 
     204                        $output = "[DEBUG] [$function] " . $this->arrayexpand($msg); 
     205                        error_log($output); 
     206                } 
     207        } 
     208 
     209        private function arrayexpand($array)  
     210        { 
     211                $output = ''; 
     212                if (is_array($array)) { 
     213                        foreach ($array as $key => $value) { 
     214                                $output .= "\n " . $key . ' => ' . $this->arrayexpand($value); 
     215                        } 
     216                } else { 
     217                        $output .= $array; 
     218                } 
     219                return $output; 
     220        } 
     221 
     222        /** 
     223         * Convert a value ending in 'G','M' or 'K' to bytes 
     224         * 
     225         */ 
     226        private function tobytes($val)  
     227        { 
     228                $val = trim($val); 
     229                $last = strtolower($val{strlen($val) - 1}); 
     230                switch ($last) { 
     231                        case 'g': 
     232                                $val *= 1024; 
     233                        case 'm': 
     234                                $val *= 1024; 
     235                        case 'k': 
     236                                $val *= 1024; 
     237                } 
     238                return $val; 
     239        } 
     240 
     241        /** 
     242         * Build a string, containing a javascript wrapper function 
     243         * for setting applet properties via JavaScript. This is necessary, 
     244         * because we use the "modern" method of including the applet (using 
     245         * <object> resp. <embed> tags) in order to trigger automatic JRE downloading. 
     246         * Therefore, in Netscape-like browsers, the applet is accessible via 
     247         * the document.embeds[] array while in others, it is accessible via the 
     248         * document.applets[] array. 
     249         * 
     250         * @return A string, containing the necessary wrapper function (named JUploadSetProperty) 
     251         */ 
     252        private function str_jsinit()  
     253        { 
     254                $N = "\n"; 
     255                $name = $this->appletparams['name']; 
     256                $ret = '<script type="text/javascript">' . $N; 
     257                $ret .= '<!--' . $N; 
     258                $ret .= 'function ' . $this->classparams['jscript_wrapper'] . '(name, value) {' . $N; 
     259                $ret .= '  document.applets["' . $name . '"] == null || document.applets["' . $name . '"].setProperty(name,value);' . $N; 
     260                $ret .= '  document.embeds["' . $name . '"] == null || document.embeds["' . $name . '"].setProperty(name,value);' . $N; 
     261                $ret .= '}' . $N; 
     262                $ret .= '//-->' . $N; 
     263                $ret .= '</script>'; 
     264                return $ret; 
     265        } 
     266 
     267        /** 
     268         * Build a string, containing the applet tag with all parameters. 
     269         * 
     270         * @return A string, containing the applet tag 
     271         */ 
     272        private function str_applet() { 
     273                $N = "\n"; 
     274                $params = $this->appletparams; 
     275                // return the actual applet tag 
     276                $ret = '<object classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"' . $N; 
     277                $ret .= '  codebase = "http://java.sun.com/update/1.5.0/jinstall-1_5-windows-i586.cab#Version=5,0,0,3"' . $N; 
     278                $ret .= '  width = "' . $params['width'] . '"' . $N; 
     279                $ret .= '  height = "' . $params['height'] . '"' . $N; 
     280                $ret .= '  name = "' . $params['name'] . '">' . $N; 
     281                foreach ($params as $key => $val) { 
     282                        if ($key != 'width' && $key != 'height') 
     283                                $ret .= '  <param name = "' . $key . '" value = "' . $val . '" />' . $N; 
     284                } 
     285                $ret .= '  <comment>' . $N; 
     286                $ret .= '    <embed' . $N; 
     287                $ret .= '      type = "application/x-java-applet;version=1.5"' . $N; 
     288                foreach ($params as $key => $val) 
     289                        $ret .= '      ' . $key . ' = "' . $val . '"' . $N; 
     290                $ret .= '      pluginspage = "http://java.sun.com/products/plugin/index.html#download">' . $N; 
     291                $ret .= '      <noembed>' . $N; 
     292                $ret .= '        Java 1.5 or higher plugin required.' . $N; 
     293                $ret .= '      </noembed>' . $N; 
     294                $ret .= '    </embed>' . $N; 
     295                $ret .= '  </comment>' . $N; 
     296                $ret .= '</object>'; 
     297                return $ret; 
     298        } 
     299 
     300        private function abort($msg = '')  
     301        { 
     302                $this->cleanup(); 
     303                if ($msg != '') 
     304                        die(str_replace('(.*)', $msg, $this->appletparams['stringUploadError']) . "\n"); 
     305                exit; 
     306        } 
     307 
     308        private function warning($msg = '')  
     309        { 
     310                $this->cleanup(); 
     311                if ($msg != '') 
     312                        echo('WARNING: ' . $msg . "\n"); 
     313                echo $this->appletparams['stringUploadSuccess'] . "\n"; 
     314                exit; 
     315        } 
     316 
     317        private function cleanup()  
     318        { 
     319                // remove all uploaded files of *this* request 
     320                if (isset($_FILES)) { 
     321                        foreach ($_FILES as $key => $val) 
     322                                @unlink($val['tmp_name']); 
     323                } 
     324                // remove accumulated file, if any. 
     325                @unlink($this->classparams['destdir'] . '/' . $this->classparams['tmp_prefix'] . session_id()); 
     326                @unlink($this->classparams['destdir'] . '/' . $this->classparams['tmp_prefix'] . 'tmp' . session_id()); 
     327                // reset session var 
     328                $_SESSION[$this->classparams['var_prefix'] . 'size'] = 0; 
     329                return; 
     330        } 
     331 
     332        private function mkdirp($path)  
     333        { 
     334                // create subdir (hierary) below destdir; 
     335                $dirs = explode('/', $path); 
     336                $path = $this->classparams['destdir']; 
     337                foreach ($dirs as $dir)  
     338                { 
     339                        $path .= '/' . $dir; 
     340                        if (!file_exists($path)) {              // @ does NOT always supress the error! 
     341                                @mkdir($path, $this->classparams['dirperm']); 
     342                        } 
     343                } 
     344                if (!is_dir($path) && is_writable($path)) 
     345                        $this->abort('Destination dir not accessible'); 
     346        } 
    340347 
    341348        /** 
     
    348355         *              - If yes, and the duplicate class param is set to reject, an error is thrown. 
    349356         */ 
    350     private function dstfinal(&$name, &$subdir) { 
    351         $name = preg_replace('![`$\\\\/|]!', '_', $name); 
    352         if ($this->classparams['allow_subdirs'] && ($subdir != '')) { 
    353             $subdir = trim(preg_replace('!\\\\!','/',$subdir),'/'); 
    354             $subdir = preg_replace('![`$|]!', '_', $subdir); 
    355             if (!$this->classparams['spaces_in_subdirs']) { 
    356                 $subdir = str_replace(' ','_',$subdir); 
    357             } 
    358             // recursively create subdir 
    359             if (!$this->classparams['demo_mode']) 
    360                 $this->mkdirp($subdir); 
    361             // append a slash 
    362             $subdir .= '/'; 
    363         } else { 
    364             $subdir = ''; 
    365         } 
    366         $ret = $this->classparams['destdir'].'/'.$subdir.$name; 
    367         if (file_exists($ret)) { 
    368             if ($this->classparams['duplicate'] == 'overwrite') { 
    369                 return $ret; 
    370             } 
    371             if ($this->classparams['duplicate'] == 'reject') { 
    372                 $this->abort('A file with the same name already exists'); 
    373             } 
    374             if ($this->classparams['duplicate'] == 'warning') { 
    375                 $this->warning("File $name already exists - rejected"); 
    376             } 
    377             if ($this->classparams['duplicate'] == 'rename') { 
    378                 $cnt = 1; 
    379                 $dir = $this->classparams['destdir'].'/'.$subdir; 
    380                 $ext = strrchr($name, '.'); 
    381                 if ($ext) { 
    382                     $nameWithoutExtension = substr($name, 0, strlen($name) - strlen($ext)); 
    383                 } else { 
    384                     $ext = ''; 
    385                     $nameWithoutExtension = $name; 
    386                 } 
    387  
    388                 $rtry = $dir.$nameWithoutExtension.'.['.$cnt.']'.$ext; 
    389                 while (file_exists($rtry)) { 
    390                     $cnt++; 
    391                     $rtry = $dir.$nameWithoutExtension.'.['.$cnt.']'.$ext; 
    392                 } 
    393                 //We store the result name in the byReference name parameter. 
    394                 $name = $nameWithoutExtension.'.['.$cnt.']'.$ext; 
    395                 $ret = $rtry; 
    396             } 
    397         } 
    398         return $ret; 
    399     } 
    400  
    401   /** 
    402    * Example function to process the files uploaded.  This one simply displays the files' data. 
    403    * 
    404    */ 
    405     public function defaultAfterUploadManagement() { 
    406         $flist = '[defaultAfterUploadManagement] Nb uploaded files is: ' . sizeof($this->files); 
    407         $flist = $this->classparams['http_flist_start']; 
    408         foreach ($this->files as $f) { 
    409                 //$f is an array, that contains all info about the uploaded file. 
    410                 $this->logDebug('defaultAfterUploadManagement', "  Reading file ${f['name']}"); 
    411             $flist .= $this->classparams['http_flist_file_before']; 
    412             $flist .= $f['name']; 
    413             $flist .= $this->classparams['http_flist_file_between']; 
    414             $flist .= $f['size']; 
    415             $flist .= $this->classparams['http_flist_file_between']; 
    416             $flist .= $f['relativePath']; 
    417             $flist .= $this->classparams['http_flist_file_between']; 
    418             $flist .= $f['fullName']; 
    419             $flist .= $this->classparams['http_flist_file_between']; 
    420             $flist .= $f['md5sum']; 
    421             $addBR = false; 
    422                 foreach ($f as $key=>$value) { 
    423                         //If it's a specific key, let's display it: 
    424                         if ($key != 'name' && $key != 'size' && $key != 'relativePath' && $key != 'fullName' && $key != 'md5sum') { 
    425                                 if ($addBR) { 
    426                                         $flist .= "<br>"; 
    427                                 } else { 
    428                                         // First line. We must add a new 'official' list separator. 
    429                                         $flist .= $this->classparams['http_flist_file_between']; 
    430                                         $addBR = true; 
    431                                 } 
    432                                 $flist .= "$key => $value"; 
    433                         } 
    434                 } 
    435             $flist .= $this->classparams['http_flist_file_after']; 
    436         } 
    437         $flist .= $this->classparams['http_flist_end']; 
    438  
    439         return $flist; 
    440     } 
    441  
    442   /** 
    443    * Generation of the applet tag, and necessary things around (js content). Insertion of this into the content of the 
    444    * page. 
    445    * See the tag_jscript and tag_applet class parameters. 
    446    */ 
    447     private function generateAppletTag($str) { 
    448         $this->logDebug('generateAppletTag', 'Entering function'); 
    449       $str = preg_replace('/'.$this->classparams['tag_jscript'].'/', $this->str_jsinit(), $str); 
    450       return preg_replace('/'.$this->classparams['tag_applet'].'/', $this->str_applet(), $str); 
    451     } 
    452  
    453   /** 
    454    * This function is called when constructing the page, when we're not reveiving uploaded files. It 'just' construct 
    455    * the applet tag, by calling the relevant function. 
    456    * 
    457    * This *must* be public, because it is called from PHP's output buffering 
    458    */ 
    459     public function interceptBeforeUpload($str) { 
    460         $this->logDebug('interceptBeforeUpload', 'Entering function'); 
    461         return $this->generateAppletTag($str); 
    462     } 
     357        private function dstfinal(&$name, &$subdir)  
     358        { 
     359                $name = preg_replace('![`$\\\\/|]!', '_', $name); 
     360                if ($this->classparams['allow_subdirs'] && ($subdir != '')) { 
     361                        $subdir = trim(preg_replace('!\\\\!', '/', $subdir), '/'); 
     362                        $subdir = preg_replace('![`$|]!', '_', $subdir); 
     363                        if (!$this->classparams['spaces_in_subdirs']) { 
     364                                $subdir = str_replace(' ', '_', $subdir); 
     365                        } 
     366                        // recursively create subdir 
     367                        if (!$this->classparams['demo_mode']) 
     368                                $this->mkdirp($subdir); 
     369                        // append a slash 
     370                        $subdir .= '/'; 
     371                } else { 
     372                        $subdir = ''; 
     373                } 
     374                $ret = $this->classparams['destdir'] . '/' . $subdir . $name; 
     375                if (file_exists($ret)) { 
     376                        if ($this->classparams['duplicate'] == 'overwrite') { 
     377                                return $ret; 
     378                        } 
     379                        if ($this->classparams['duplicate'] == 'reject') { 
     380                                $this->abort('A file with the same name already exists'); 
     381                        } 
     382                        if ($this->classparams['duplicate'] == 'warning') { 
     383                                $this->warning("File $name already exists - rejected"); 
     384                        } 
     385                        if ($this->classparams['duplicate'] == 'rename') { 
     386                                $cnt = 1; 
     387                                $dir = $this->classparams['destdir'] . '/' . $subdir; 
     388                                $ext = strrchr($name, '.'); 
     389                                if ($ext) { 
     390                                        $nameWithoutExtension = substr($name, 0, strlen($name) - strlen($ext)); 
     391                                } else { 
     392                                        $ext = ''; 
     393                                        $nameWithoutExtension = $name; 
     394                                } 
     395 
     396                                $rtry = $dir . $nameWithoutExtension . '.[' . $cnt . ']' . $ext; 
     397                                while (file_exists($rtry)) { 
     398                                        $cnt++; 
     399                                        $rtry = $dir . $nameWithoutExtension . '.[' . $cnt . ']' . $ext; 
     400                                } 
     401                                //We store the result name in the byReference name parameter. 
     402                                $name = $nameWithoutExtension . '.[' . $cnt . ']' . $ext; 
     403                                $ret = $rtry; 
     404                        } 
     405                } 
     406                return $ret; 
     407        } 
     408 
     409        /** 
     410         * Example function to process the files uploaded.  This one simply displays the files' data. 
     411         * 
     412         */ 
     413        public function defaultAfterUploadManagement()  
     414        { 
     415                $flist = '[defaultAfterUploadManagement] Nb uploaded files is: ' . sizeof($this->files); 
     416                $flist = $this->classparams['http_flist_start']; 
     417                foreach ($this->files as $f) { 
     418                        //$f is an array, that contains all info about the uploaded file. 
     419                        $this->logDebug('defaultAfterUploadManagement', "  Reading file ${f['name']}"); 
     420                        $flist .= $this->classparams['http_flist_file_before']; 
     421                        $flist .= $f['name']; 
     422                        $flist .= $this->classparams['http_flist_file_between']; 
     423                        $flist .= $f['size']; 
     424                        $flist .= $this->classparams['http_flist_file_between']; 
     425                        $flist .= $f['relativePath']; 
     426                        $flist .= $this->classparams['http_flist_file_between']; 
     427                        $flist .= $f['fullName']; 
     428                        $flist .= $this->classparams['http_flist_file_between']; 
     429                        $flist .= $f['md5sum']; 
     430                        $addBR = false; 
     431                        foreach ($f as $key => $value) { 
     432                                //If it's a specific key, let's display it: 
     433                                if ($key != 'name' && $key != 'size' && $key != 'relativePath' && $key != 'fullName' && $key != 'md5sum') { 
     434                                        if ($addBR) { 
     435                                                $flist .= "<br>"; 
     436                                        } else { 
     437                                                // First line. We must add a new 'official' list separator. 
     438                                                $flist .= $this->classparams['http_flist_file_between']; 
     439                                                $addBR = true; 
     440                                        } 
     441                                        $flist .= "$key => $value"; 
     442                                } 
     443                        } 
     444                        $flist .= $this->classparams['http_flist_file_after']; 
     445                } 
     446                $flist .= $this->classparams['http_flist_end']; 
     447 
     448                return $flist; 
     449        } 
     450 
     451        /** 
     452         * Generation of the applet tag, and necessary things around (js content). Insertion of this into the content of the 
     453         * page. 
     454         * See the tag_jscript and tag_applet class parameters. 
     455         */ 
     456        private function generateAppletTag($str)  
     457        { 
     458                $this->logDebug('generateAppletTag', 'Entering function'); 
     459                $str = preg_replace('/' . $this->classparams['tag_jscript'] . '/', $this->str_jsinit(), $str); 
     460                return preg_replace('/' . $this->classparams['tag_applet'] . '/', $this->str_applet(), $str); 
     461        } 
     462 
     463        /** 
     464         * This function is called when constructing the page, when we're not reveiving uploaded files. It 'just' construct 
     465         * the applet tag, by calling the relevant function. 
     466         * 
     467         * This *must* be public, because it is called from PHP's output buffering 
     468         */ 
     469        public function interceptBeforeUpload($str)  
     470        { 
     471                $this->logDebug('interceptBeforeUpload', 'Entering function'); 
     472                return $this->generateAppletTag($str); 
     473        } 
    463474 
    464475        /** 
     
    467478         * This *must* be public, because it is called from PHP's output buffering. 
    468479         */ 
    469     public function interceptAfterUpload($str) { 
    470         $this->logDebug('interceptAfterUpload', 'Entering function'); 
    471         $this->logPHPDebug('interceptAfterUpload', $this->files); 
    472  
    473       if (count($this->files) > 0) { 
    474                 if (isset($this->classparams['callbackAfterUploadManagement'])) { 
    475                 $this->logDebug('interceptAfterUpload', 'Before call of ' .$this->classparams['callbackAfterUploadManagement']); 
    476                         $strForFListContent = call_user_func($this->classparams['callbackAfterUploadManagement'], $this, $this->files); 
    477                 } else { 
    478                         $strForFListContent = $this->defaultAfterUploadManagement(); 
    479         } 
    480         $str = preg_replace('/'.$this->classparams['tag_flist'].'/', $strForFListContent, $str); 
    481             } 
    482       return $this->generateAppletTag($str); 
    483     } 
    484  
    485          /** 
    486                 * This method manages the receiving of the debug log, when an error occurs. 
    487                 */ 
    488      private function receive_debug_log() { 
    489         // handle error report 
    490         if (isset($_POST['description']) && isset($_POST['log'])) { 
    491             $msg = $_POST['log']; 
    492             mail($this->classparams['errormail'], $_POST['description'], $msg); 
    493         } else { 
    494             if (isset($_SERVER['SERVER_ADMIN'])) 
    495                 mail($_SERVER['SERVER_ADMIN'], 'Empty jupload error log', 
    496                     'An empty log has just been posted.'); 
    497             $this->logPHPDebug('receive_debug_log', 'Empty error log received'); 
    498         } 
    499         exit; 
    500      } 
    501  
    502   /** 
    503    * This method is the heart of the system. It manage the files sent by the applet, check the incoming parameters (md5sum) and 
    504    * reconstruct the files sent in chunk mode. 
    505    * 
    506    * The result is stored in the $files array, and can then be managed by the function given in the callbackAfterUploadManagement 
    507    * class parameter, or within the page whose URL is given in the afterUploadURL applet parameter. 
    508    * Or you can Extend the class and redeclare defaultAfterUploadManagement() to your needs. 
    509    */ 
    510     private function receive_uploaded_files() { 
    511                         $this->logDebug('receive_uploaded_files', 'Entering POST management'); 
    512  
    513                         if (session_id() == '') { include_once('../../header.session.inc.php'); } 
    514                         // we check for the session *after* handling possible error log 
    515                         // because an error could have happened because the session-id is missing. 
    516                         if (!isset($_SESSION[$this->classparams['var_prefix'].'size'])) { 
    517                             $this->abort('Invalid session (in afterupload, POST, check of size)'); 
    518                         } 
    519                         if (!isset($_SESSION[$this->classparams['var_prefix'].'files'])) { 
    520                             $this->abort('Invalid session (in afterupload, POST, check of files)'); 
    521                         } 
    522                         $this->files = $_SESSION[$this->classparams['var_prefix'].'files']; 
    523                         if (!is_array($this->files)) { 
    524                             $this->abort('Invalid session (in afterupload, POST, is_array(files))'); 
    525                         } 
    526                         if ($this->appletParameters['sendMD5Sum']  &&  !isset($_POST['md5sum'])) { 
    527                             $this->abort('Required POST variable md5sum is missing'); 
    528                         } 
    529                         $cnt = 0; 
    530                         foreach ($_FILES as $key => $value) { 
    531                                 //Let's read the $_FILES data 
    532                                 if (isset($files_data)) { 
    533                                         unset($files_data); 
    534                                 } 
    535                     $jupart                     = (isset($_POST['jupart']))                             ? (int)$_POST['jupart']         : 0; 
    536                     $jufinal            = (isset($_POST['jufinal']))                    ? (int)$_POST['jufinal']        : 1; 
    537                     $relpaths           = (isset($_POST['relpathinfo']))        ? $_POST['relpathinfo']         : null; 
    538                     $md5sums            = (isset($_POST['md5sum']))                             ? $_POST['md5sum']                              : null; 
    539                     $mimetypes  = (isset($_POST['mimetype']))           ? $_POST['mimetype']                    : null; 
    540                     //$relpaths = (isset($_POST["relpathinfo$cnt"])) ? $_POST["relpathinfo$cnt"] : null; 
    541                     //$md5sums = (isset($_POST["md5sum$cnt"])) ? $_POST["md5sum$cnt"] : null; 
    542  
    543                     if (gettype($relpaths) == 'string') { 
    544                         $relpaths = array($relpaths); 
    545                     } 
    546                     if (gettype($md5sums) == 'string') { 
    547                         $md5sums = array($md5sums); 
    548                     } 
    549                     if ($this->appletParameters['sendMD5Sum']  && !is_array($md5sums)) { 
    550                         $this->abort('Expecting an array of MD5 checksums'); 
    551                     } 
    552                     if (!is_array($relpaths)) { 
    553                         $this->abort('Expecting an array of relative paths'); 
    554                     } 
    555                     if (!is_array($mimetypes)) { 
    556             $this->abort('Expecting an array of MIME types'); 
    557         } 
    558         // Check the MIME type (note: this is easily forged!) 
    559         if (isset($this->classparams['allowed_mime_types']) && is_array($this->classparams['allowed_mime_types'])) { 
    560                 if (!in_array($mimetypes[$cnt], $this->classparams['allowed_mime_types'])) { 
    561                         $this->abort('MIME type '.$mimetypes[$cnt].' not allowed'); 
    562                 } 
    563         } 
    564         if (isset($this->classparams['allowed_file_extensions']) && is_array($this->classparams['allowed_file_extensions'])) { 
    565                 $fileExtension = substr(strrchr($value['name'][$cnt], "."), 1); 
    566                 if (!in_array($fileExtension, $this->classparams['allowed_file_extensions'])) { 
    567                         $this->abort('File extension '.$fileExtension.' not allowed'); 
    568                 } 
    569         } 
    570  
    571         $dstdir = $this->classparams['destdir']; 
    572                     $dstname = $dstdir.'/'.$this->classparams['tmp_prefix'].session_id(); 
    573                     $tmpname = $dstdir.'/'.$this->classparams['tmp_prefix'].'tmp'.session_id(); 
    574  
    575                     // Controls are now done. Let's store the current uploaded files properties in an array, for future use. 
    576                                 $files_data['name']                                     = $value['name'][$cnt]; 
    577                                 $files_data['size']                                     = 'not calculated yet'; 
    578                                 $files_data['tmp_name']                 = $value['tmp_name'][$cnt]; 
    579                                 $files_data['error']                    = $value['error'][$cnt]; 
    580                                 $files_data['relativePath'] = $relpaths[$cnt]; 
    581                                 $files_data['md5sum']                   = $md5sums[$cnt]; 
    582                                 $files_data['mimetype']                 = $mimetypes[$cnt]; 
    583  
    584         if (!move_uploaded_file($files_data['tmp_name'], $tmpname)) { 
    585                 if ($classparams['verbose_errors']) { 
    586             $this->abort("Unable to move uploaded file (from ${files_data['tmp_name']} to $tmpname)"); 
    587                 } else { 
    588             trigger_error("Unable to move uploaded file (from ${files_data['tmp_name']} to $tmpname)",E_USER_WARNING); 
    589             $this->abort("Unable to move uploaded file"); 
    590                 } 
    591         } 
    592  
    593                                 // In demo mode, no file storing is done. We just delete the newly uploaded file. 
    594         if ($this->classparams['demo_mode']) { 
    595             if ($jufinal || (!$jupart)) { 
    596                 if ($jupart) { 
    597                 $files_data['size']             = ($jupart-1) * $this->appletparams['maxChunkSize'] + filesize($tmpname); 
    598                 } else { 
    599                 $files_data['size']             = filesize($tmpname); 
    600                 } 
    601               $files_data['fullName']   = 'Demo mode<BR>No file storing'; 
    602                 array_push($this->files, $files_data); 
    603             } 
    604             unlink($tmpname); 
    605             $cnt++; 
    606             continue; 
    607         } 
    608         //If we get here, the upload is a real one (no demo) 
    609         if ($jupart) { 
    610             // got a chunk of a multi-part upload 
    611             $len = filesize($tmpname); 
    612             $_SESSION[$this->classparams['var_prefix'].'size'] += $len; 
    613             if ($len > 0) { 
    614                 $src = fopen($tmpname, 'rb'); 
    615                 $dst = fopen($dstname, ($jupart == 1) ? 'wb' : 'ab'); 
    616                 while ($len > 0) { 
    617                     $rlen = ($len > 8192) ? 8192 : $len; 
    618                     $buf = fread($src, $rlen); 
    619                     if (!$buf) { 
    620                         fclose($src); 
    621                         fclose($dst); 
    622                         unlink($dstname); 
    623                         $this->abort('read IO error'); 
    624                     } 
    625                     if (!fwrite($dst, $buf, $rlen)) { 
    626                         fclose($src); 
    627                         fclose($dst); 
    628                         unlink($dstname); 
    629                         $this->abort('write IO error'); 
    630                     } 
    631                     $len -= $rlen; 
    632                 } 
    633                 fclose($src); 
    634                 fclose($dst); 
    635                 unlink($tmpname); 
    636             } 
    637             if ($jufinal) { 
    638                 // This is the last chunk. Check total lenght and 
    639                 // rename it to it's final name. 
    640                 $dlen = filesize($dstname); 
    641                 if ($dlen != $_SESSION[$this->classparams['var_prefix'].'size']) 
    642                     $this->abort('file size mismatch'); 
    643                 if ($this->appletParameters['sendMD5Sum'] ) { 
    644                         if ($md5sums[$cnt] != md5_file($dstname)) 
    645                         $this->abort('MD5 checksum mismatch'); 
    646                 } 
    647                 // remove zero sized files 
    648                 if (($dlen > 0) || $this->classparams['allow_zerosized']) { 
    649                     $dstfinal = $this->dstfinal($files_data['name'],$files_data['relativePath']); 
    650                     if (!rename($dstname, $dstfinal)) 
    651                         $this->abort('rename IO error'); 
    652                     if (!chmod($dstfinal, $this->classparams['fileperm'])) 
    653                         $this->abort('chmod IO error'); 
    654                 $files_data['size']             = filesize($dstfinal); 
    655                 $files_data['fullName'] = $dstfinal; 
    656                         $files_data['path']     = dirname($dstfinal); 
    657                     array_push($this->files, $files_data); 
    658                 } else { 
    659                     unlink($dstname); 
    660                 } 
    661                 // reset session var 
    662                 $_SESSION[$this->classparams['var_prefix'].'size'] = 0; 
    663             } 
    664         } else { 
    665             // Got a single file upload. Trivial. 
    666             if ($md5sums[$cnt] != md5_file($tmpname)) 
    667                 $this->abort('MD5 checksum mismatch'); 
    668             $dstfinal = $this->dstfinal($files_data['name'],$files_data['relativePath']); 
    669             if (!rename($tmpname, $dstfinal)) 
    670                 $this->abort('rename IO error'); 
    671             if (!chmod($dstfinal, $this->classparams['fileperm'])) 
    672                 $this->abort('chmod IO error'); 
    673             $files_data['size']         = filesize($dstfinal); 
    674             $files_data['fullName']     = $dstfinal; 
    675             $files_data['path'] = dirname($dstfinal); 
    676             array_push($this->files, $files_data); 
    677         } 
    678         $cnt++; 
    679       } 
    680  
    681       echo $this->appletparams['stringUploadSuccess']."\n"; 
    682       $_SESSION[$this->classparams['var_prefix'].'files'] = $this->files; 
    683       session_write_close(); 
    684       exit; 
    685     } 
    686  
    687     /** 
    688      * 
    689      * 
    690      */ 
    691      private function page_start() { 
    692                         $this->logDebug('page_start', 'Entering function'); 
    693  
    694                         // If the applet checks for the serverProtocol, it issues a HEAD request 
    695                         // -> Simply return an empty doc. 
    696                         if ($_SERVER['REQUEST_METHOD'] == 'HEAD') { 
    697                                 // Nothing to do 
    698  
    699                         } else if ($_SERVER['REQUEST_METHOD'] == 'GET') { 
    700                           // A GET request means: return upload page 
    701                                 $this->logDebug('page_start', 'Entering GET management'); 
    702  
    703                     if (session_id() == '') { include_once('../../header.session.inc.php'); } 
    704                     if (isset($_GET['afterupload'])) { 
    705                         $this->logDebug('page_start', 'afterupload is set'); 
    706                 if (!isset($_SESSION[$this->classparams['var_prefix'].'files'])) { 
    707                     $this->abort('Invalid session (in afterupload, GET, check of $_SESSION): files array is not set'); 
    708                 } 
    709                 $this->files = $_SESSION[$this->classparams['var_prefix'].'files']; 
    710                 if (!is_array($this->files)) { 
    711                     $this->abort('Invalid session (in afterupload, GET, check of is_array(files)): files is not an array'); 
    712                 } 
    713                 // clear session data ready for new upload 
    714                 $_SESSION[$this->classparams['var_prefix'].'files'] = array(); 
    715  
    716                       // start intercepting the content of the calling page, to display the upload result. 
    717                       ob_start(array(& $this, 'interceptAfterUpload')); 
    718  
    719                     } else { 
    720                         $this->logDebug('page_start', 'afterupload is not set'); 
    721                         if ($this->classparams['session_regenerate']) { session_regenerate_id(true); } 
    722                 $this->files = array(); 
    723                 $_SESSION[$this->classparams['var_prefix'].'size'] = 0; 
    724                 $_SESSION[$this->classparams['var_prefix'].'files'] = $this->files; 
    725                       // start intercepting the content of the calling page, to display the applet tag. 
    726                       ob_start(array(& $this, 'interceptBeforeUpload')); 
    727                     } 
    728  
    729                         } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { 
    730                           // If we got a POST request, this is the real work. 
    731                                 if (isset($_GET['errormail'])) { 
    732                                         //Hum, an error occurs on server side. Let's manage the debug log, that we just received. 
    733                                         $this->receive_debug_log(); 
     480        public function interceptAfterUpload($str)  
     481        { 
     482                $this->logDebug('interceptAfterUpload', 'Entering function'); 
     483                $this->logPHPDebug('interceptAfterUpload', $this->files); 
     484 
     485                if (count($this->files) > 0) { 
     486                        if (isset($this->classparams['callbackAfterUploadManagement'])) { 
     487                                $this->logDebug('interceptAfterUpload', 'Before call of ' . $this->classparams['callbackAfterUploadManagement']); 
     488                                $strForFListContent = call_user_func($this->classparams['callbackAfterUploadManagement'], $this, $this->files); 
     489                        } else { 
     490                                $strForFListContent = $this->defaultAfterUploadManagement(); 
     491                        } 
     492                        $str = preg_replace('/' . $this->classparams['tag_flist'] . '/', $strForFListContent, $str); 
     493                } 
     494                return $this->generateAppletTag($str); 
     495        } 
     496 
     497        /** 
     498         * This method manages the receiving of the debug log, when an error occurs. 
     499         */ 
     500        private function receive_debug_log()  
     501        { 
     502                // handle error report 
     503                if (isset($_POST['description']) && isset($_POST['log'])) { 
     504                        $msg = $_POST['log']; 
     505                        mail($this->classparams['errormail'], $_POST['description'], $msg); 
     506                } else { 
     507                        if (isset($_SERVER['SERVER_ADMIN'])) 
     508                                mail($_SERVER['SERVER_ADMIN'], 'Empty jupload error log', 'An empty log has just been posted.'); 
     509                        $this->logPHPDebug('receive_debug_log', 'Empty error log received'); 
     510                } 
     511                exit; 
     512        } 
     513 
     514        /** 
     515         * This method is the heart of the system. It manage the files sent by the applet, check the incoming parameters (md5sum) and 
     516         * reconstruct the files sent in chunk mode. 
     517         * 
     518         * The result is stored in the $files array, and can then be managed by the function given in the callbackAfterUploadManagement 
     519         * class parameter, or within the page whose URL is given in the afterUploadURL applet parameter. 
     520         * Or you can Extend the class and redeclare defaultAfterUploadManagement() to your needs. 
     521         */ 
     522        private function receive_uploaded_files()  
     523        { 
     524                $this->logDebug('receive_uploaded_files', 'Entering POST management'); 
     525 
     526                if (session_id() == '') { 
     527                        include_once('../../header.session.inc.php'); 
     528                } 
     529                // we check for the session *after* handling possible error log 
     530                // because an error could have happened because the session-id is missing. 
     531                if (!isset($_SESSION[$this->classparams['var_prefix'] . 'size'])) { 
     532                        $this->abort('Invalid session (in afterupload, POST, check of size)'); 
     533                } 
     534                if (!isset($_SESSION[$this->classparams['var_prefix'] . 'files'])) { 
     535                        $this->abort('Invalid session (in afterupload, POST, check of files)'); 
     536                } 
     537                $this->files = $_SESSION[$this->classparams['var_prefix'] . 'files']; 
     538                if (!is_array($this->files)) { 
     539                        $this->abort('Invalid session (in afterupload, POST, is_array(files))'); 
     540                } 
     541                if ($this->appletParameters['sendMD5Sum'] && !isset($_POST['md5sum'])) { 
     542                        $this->abort('Required POST variable md5sum is missing'); 
     543                } 
     544                $cnt = 0; 
     545                foreach ($_FILES as $key => $value) { 
     546                        //Let's read the $_FILES data 
     547                        if (isset($files_data)) { 
     548                                unset($files_data); 
     549                        } 
     550                        $jupart = (isset($_POST['jupart'])) ? (int) $_POST['jupart'] : 0; 
     551                        $jufinal = (isset($_POST['jufinal'])) ? (int) $_POST['jufinal'] : 1; 
     552                        $relpaths = (isset($_POST['relpathinfo'])) ? $_POST['relpathinfo'] : null; 
     553                        $md5sums = (isset($_POST['md5sum'])) ? $_POST['md5sum'] : null; 
     554                        $mimetypes = (isset($_POST['mimetype'])) ? $_POST['mimetype'] : null; 
     555                        //$relpaths = (isset($_POST["relpathinfo$cnt"])) ? $_POST["relpathinfo$cnt"] : null; 
     556                        //$md5sums = (isset($_POST["md5sum$cnt"])) ? $_POST["md5sum$cnt"] : null; 
     557 
     558                        if (gettype($relpaths) == 'string') { 
     559                                $relpaths = array($relpaths); 
     560                        } 
     561                        if (gettype($md5sums) == 'string') { 
     562                                $md5sums = array($md5sums); 
     563                        } 
     564                        if ($this->appletParameters['sendMD5Sum'] && !is_array($md5sums)) { 
     565                                $this->abort('Expecting an array of MD5 checksums'); 
     566                        } 
     567                        if (!is_array($relpaths)) { 
     568                                $this->abort('Expecting an array of relative paths'); 
     569                        } 
     570                        if (!is_array($mimetypes)) { 
     571                                $this->abort('Expecting an array of MIME types'); 
     572                        } 
     573                        // Check the MIME type (note: this is easily forged!) 
     574                        if (isset($this->classparams['allowed_mime_types']) && is_array($this->classparams['allowed_mime_types'])) { 
     575                                if (!in_array($mimetypes[$cnt], $this->classparams['allowed_mime_types'])) { 
     576                                        $this->abort('MIME type ' . $mimetypes[$cnt] . ' not allowed'); 
     577                                } 
     578                        } 
     579                        if (isset($this->classparams['allowed_file_extensions']) && is_array($this->classparams['allowed_file_extensions'])) { 
     580                                $fileExtension = substr(strrchr($value['name'][$cnt], "."), 1); 
     581                                if (!in_array($fileExtension, $this->classparams['allowed_file_extensions'])) { 
     582                                        $this->abort('File extension ' . $fileExtension . ' not allowed'); 
     583                                } 
     584                        } 
     585 
     586                        $dstdir = $this->classparams['destdir']; 
     587                        $dstname = $dstdir . '/' . $this->classparams['tmp_prefix'] . session_id(); 
     588                        $tmpname = $dstdir . '/' . $this->classparams['tmp_prefix'] . 'tmp' . session_id(); 
     589 
     590                        // Controls are now done. Let's store the current uploaded files properties in an array, for future use. 
     591                        $files_data['name'] = $value['name'][$cnt]; 
     592                        $files_data['size'] = 'not calculated yet'; 
     593                        $files_data['tmp_name'] = $value['tmp_name'][$cnt]; 
     594                        $files_data['error'] = $value['error'][$cnt]; 
     595                        $files_data['relativePath'] = $relpaths[$cnt]; 
     596                        $files_data['md5sum'] = $md5sums[$cnt]; 
     597                        $files_data['mimetype'] = $mimetypes[$cnt]; 
     598 
     599                        if (!move_uploaded_file($files_data['tmp_name'], $tmpname)) { 
     600                                if ($classparams['verbose_errors']) { 
     601                                        $this->abort("Unable to move uploaded file (from ${files_data['tmp_name']} to $tmpname)"); 
    734602                                } else { 
    735                                         $this->receive_uploaded_files(); 
    736                                 } 
    737                         } 
    738     } 
     603                                        trigger_error("Unable to move uploaded file (from ${files_data['tmp_name']} to $tmpname)", E_USER_WARNING); 
     604                                        $this->abort("Unable to move uploaded file"); 
     605                                } 
     606                        } 
     607 
     608                        // In demo mode, no file storing is done. We just delete the newly uploaded file. 
     609                        if ($this->classparams['demo_mode']) { 
     610                                if ($jufinal || (!$jupart)) { 
     611                                        if ($jupart) { 
     612                                                $files_data['size'] = ($jupart - 1) * $this->appletparams['maxChunkSize'] + filesize($tmpname); 
     613                                        } else { 
     614                                                $files_data['size'] = filesize($tmpname); 
     615                                        } 
     616                                        $files_data['fullName'] = 'Demo mode<BR>No file storing'; 
     617                                        array_push($this->files, $files_data); 
     618                                } 
     619                                unlink($tmpname); 
     620                                $cnt++; 
     621                                continue; 
     622                        } 
     623                        //If we get here, the upload is a real one (no demo) 
     624                        if ($jupart) { 
     625                                // got a chunk of a multi-part upload 
     626                                $len = filesize($tmpname); 
     627                                $_SESSION[$this->classparams['var_prefix'] . 'size'] += $len; 
     628                                if ($len > 0) { 
     629                                        $src = fopen($tmpname, 'rb'); 
     630                                        $dst = fopen($dstname, ($jupart == 1) ? 'wb' : 'ab'); 
     631                                        while ($len > 0) { 
     632                                                $rlen = ($len > 8192) ? 8192 : $len; 
     633                                                $buf = fread($src, $rlen); 
     634                                                if (!$buf) { 
     635                                                        fclose($src); 
     636                                                        fclose($dst); 
     637                                                        unlink($dstname); 
     638                                                        $this->abort('read IO error'); 
     639                                                } 
     640                                                if (!fwrite($dst, $buf, $rlen)) { 
     641                                                        fclose($src); 
     642                                                        fclose($dst); 
     643                                                        unlink($dstname); 
     644                                                        $this->abort('write IO error'); 
     645                                                } 
     646                                                $len -= $rlen; 
     647                                        } 
     648                                        fclose($src); 
     649                                        fclose($dst); 
     650                                        unlink($tmpname); 
     651                                } 
     652                                if ($jufinal) { 
     653                                        // This is the last chunk. Check total lenght and 
     654                                        // rename it to it's final name. 
     655                                        $dlen = filesize($dstname); 
     656                                        if ($dlen != $_SESSION[$this->classparams['var_prefix'] . 'size']) 
     657                                                $this->abort('file size mismatch'); 
     658                                        if ($this->appletParameters['sendMD5Sum']) { 
     659                                                if ($md5sums[$cnt] != md5_file($dstname)) 
     660                                                        $this->abort('MD5 checksum mismatch'); 
     661                                        } 
     662                                        // remove zero sized files 
     663                                        if (($dlen > 0) || $this->classparams['allow_zerosized']) { 
     664                                                $dstfinal = $this->dstfinal($files_data['name'], $files_data['relativePath']); 
     665                                                if (!rename($dstname, $dstfinal)) 
     666                                                        $this->abort('rename IO error'); 
     667                                                if (!chmod($dstfinal, $this->classparams['fileperm'])) 
     668                                                        $this->abort('chmod IO error'); 
     669                                                $files_data['size'] = filesize($dstfinal); 
     670                                                $files_data['fullName'] = $dstfinal; 
     671                                                $files_data['path'] = dirname($dstfinal); 
     672                                                array_push($this->files, $files_data); 
     673                                        } else { 
     674                                                unlink($dstname); 
     675                                        } 
     676                                        // reset session var 
     677                                        $_SESSION[$this->classparams['var_prefix'] . 'size'] = 0; 
     678                                } 
     679                        } else { 
     680                                // Got a single file upload. Trivial. 
     681                                if ($md5sums[$cnt] != md5_file($tmpname)) 
     682                                        $this->abort('MD5 checksum mismatch'); 
     683                                $dstfinal = $this->dstfinal($files_data['name'], $files_data['relativePath']); 
     684                                if (!rename($tmpname, $dstfinal)) 
     685                                        $this->abort('rename IO error'); 
     686                                if (!chmod($dstfinal, $this->classparams['fileperm'])) 
     687                                        $this->abort('chmod IO error'); 
     688                                $files_data['size'] = filesize($dstfinal); 
     689                                $files_data['fullName'] = $dstfinal; 
     690                                $files_data['path'] = dirname($dstfinal); 
     691                                array_push($this->files, $files_data); 
     692                        } 
     693                        $cnt++; 
     694                } 
     695 
     696                echo $this->appletparams['stringUploadSuccess'] . "\n"; 
     697                $_SESSION[$this->classparams['var_prefix'] . 'files'] = $this->files; 
     698                session_write_close(); 
     699                exit; 
     700        } 
     701 
     702        /** 
     703         * 
     704         * 
     705         */ 
     706        private function page_start() { 
     707                $this->logDebug('page_start', 'Entering function'); 
     708 
     709                // If the applet checks for the serverProtocol, it issues a HEAD request 
     710                // -> Simply return an empty doc. 
     711                if ($_SERVER['REQUEST_METHOD'] == 'HEAD') { 
     712                        // Nothing to do 
     713                } else if ($_SERVER['REQUEST_METHOD'] == 'GET') { 
     714                        // A GET request means: return upload page 
     715                        $this->logDebug('page_start', 'Entering GET management'); 
     716 
     717                        if (session_id() == '') { 
     718                                include_once('../../header.session.inc.php'); 
     719                        } 
     720                        if (isset($_GET['afterupload'])) { 
     721                                $this->logDebug('page_start', 'afterupload is set'); 
     722                                if (!isset($_SESSION[$this->classparams['var_prefix'] . 'files'])) { 
     723                                        $this->abort('Invalid session (in afterupload, GET, check of $_SESSION): files array is not set'); 
     724                                } 
     725                                $this->files = $_SESSION[$this->classparams['var_prefix'] . 'files']; 
     726                                if (!is_array($this->files)) { 
     727                                        $this->abort('Invalid session (in afterupload, GET, check of is_array(files)): files is not an array'); 
     728                                } 
     729                                // clear session data ready for new upload 
     730                                $_SESSION[$this->classparams['var_prefix'] . 'files'] = array(); 
     731 
     732                                // start intercepting the content of the calling page, to display the upload result. 
     733                                ob_start(array(& $this, 'interceptAfterUpload')); 
     734                        } else { 
     735                                $this->logDebug('page_start', 'afterupload is not set'); 
     736                                if ($this->classparams['session_regenerate']) { 
     737                                        session_regenerate_id(true); 
     738                                } 
     739                                $this->files = array(); 
     740                                $_SESSION[$this->classparams['var_prefix'] . 'size'] = 0; 
     741                                $_SESSION[$this->classparams['var_prefix'] . 'files'] = $this->files; 
     742                                // start intercepting the content of the calling page, to display the applet tag. 
     743                                ob_start(array(& $this, 'interceptBeforeUpload')); 
     744                        } 
     745                } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { 
     746                        // If we got a POST request, this is the real work. 
     747                        if (isset($_GET['errormail'])) { 
     748                                //Hum, an error occurs on server side. Let's manage the debug log, that we just received. 
     749                                $this->receive_debug_log(); 
     750                        } else { 
     751                                $this->receive_uploaded_files(); 
     752                        } 
     753                } 
     754        } 
     755 
    739756} 
    740757 
Note: See TracChangeset for help on using the changeset viewer.