source: trunk/lib/Upload.inc.php @ 40

Last change on this file since 40 was 40, checked in by scdev, 18 years ago

${1}

File size: 29.3 KB
Line 
1<?php
2/**
3 * Upload.inc.php
4 * Code by Strangecode :: www.strangecode.com :: This document contains copyrighted information
5 *
6 * The Upload class provides an interface to deal with http uploaded files.
7 *
8 * @author  Quinn Comendant <quinn@strangecode.com>
9 * @requires App.inc.php
10 * @version 1.3
11 */
12
13// Message Types.
14define('UPLOAD_MSG_ERR', MSG_ERR);
15define('UPLOAD_MSG_ERROR', MSG_ERROR);
16define('UPLOAD_MSG_WARNING', MSG_WARNING);
17define('UPLOAD_MSG_NOTICE', MSG_NOTICE);
18define('UPLOAD_MSG_SUCCESS', MSG_SUCCESS);
19define('UPLOAD_MSG_ALL', MSG_SUCCESS + MSG_NOTICE + MSG_WARNING + MSG_ERROR);
20
21require_once dirname(__FILE__) . '/App.inc.php';
22
23class Upload {
24   
25    // General object parameters.
26    var $_params = array(
27   
28        // Which messages do we pass to raiseMsg?
29        'display_messages' => UPLOAD_MSG_ALL,
30       
31        // Existing files will be overwritten when there is a name conflict?
32        'allow_overwriting' => false,
33
34        // The filesystem path to the final upload directory.
35        'upload_path' => null,
36
37        // The file permissions of the uploaded files. Remember, files will be owned by the web server user.
38        'dest_file_perms' => 0600,
39
40        // Require file to have one of the following file name extentions.
41        'valid_file_extensions' => array('jpg', 'jpeg', 'gif', 'png', 'pdf', 'txt', 'text', 'html', 'htm'),
42    );
43
44    // Array of files with errors.
45    var $errors = array();
46
47    // Array of file name extensions and corresponding mime-types.
48    var $mime_extension_map = array(
49        'ez'      => 'application/andrew-inset',
50        'hqx'     => 'application/mac-binhex40',
51        'cpt'     => 'application/mac-compactpro',
52        'doc'     => 'application/msword',
53        'bin'     => 'application/octet-stream',
54        'class'   => 'application/octet-stream',
55        'dll'     => 'application/octet-stream',
56        'dms'     => 'application/octet-stream',
57        'exe'     => 'application/octet-stream',
58        'lha'     => 'application/octet-stream',
59        'lzh'     => 'application/octet-stream',
60        'so'      => 'application/octet-stream',
61        'oda'     => 'application/oda',
62        'pdf'     => 'application/pdf',
63        'ps'      => 'application/postscript',
64        'eps'     => 'application/postscript',
65        'ai'      => 'application/postscript',
66        'smi'     => 'application/smil',
67        'smil'    => 'application/smil',
68        'mif'     => 'application/vnd.mif',
69        'xls'     => 'application/vnd.ms-excel',
70        'ppt'     => 'application/vnd.ms-powerpoint',
71        'stc'     => 'application/vnd.sun.xml.calc.template',
72        'sxc'     => 'application/vnd.sun.xml.calc',
73        'std'     => 'application/vnd.sun.xml.draw.template',
74        'sxd'     => 'application/vnd.sun.xml.draw',
75        'sti'     => 'application/vnd.sun.xml.impress.template',
76        'sxi'     => 'application/vnd.sun.xml.impress',
77        'sxm'     => 'application/vnd.sun.xml.math',
78        'sxg'     => 'application/vnd.sun.xml.writer.global',
79        'stw'     => 'application/vnd.sun.xml.writer.template',
80        'sxw'     => 'application/vnd.sun.xml.writer',
81        'vsd'     => 'application/vnd.visio',
82        'wbxml'   => 'application/vnd.wap.wbxml',
83        'wmlc'    => 'application/vnd.wap.wmlc',
84        'wmlsc'   => 'application/vnd.wap.wmlscriptc',
85        'bcpio'   => 'application/x-bcpio',
86        'vcd'     => 'application/x-cdlink',
87        'pgn'     => 'application/x-chess-pgn',
88        'Z'       => 'application/x-compress',
89        'cpio'    => 'application/x-cpio',
90        'csh'     => 'application/x-csh',
91        'dcr'     => 'application/x-director',
92        'dir'     => 'application/x-director',
93        'dxr'     => 'application/x-director',
94        'dvi'     => 'application/x-dvi',
95        'spl'     => 'application/x-futuresplash',
96        'gtar'    => 'application/x-gtar',
97        'tgz'     => 'application/x-gtar',
98        'gz'      => 'application/x-gzip',
99        'hdf'     => 'application/x-hdf',
100        'php3'    => 'application/x-httpd-php3',
101        'php'     => 'application/x-httpd-php',
102        'js'      => 'application/x-javascript',
103        'skd'     => 'application/x-koan',
104        'skm'     => 'application/x-koan',
105        'skp'     => 'application/x-koan',
106        'skt'     => 'application/x-koan',
107        'latex'   => 'application/x-latex',
108        'wmd'     => 'application/x-ms-wmd',
109        'wmz'     => 'application/x-ms-wmz',
110        'cdf'     => 'application/x-netcdf',
111        'nc'      => 'application/x-netcdf',
112        'pl'      => 'application/x-perl',
113        'pm'      => 'application/x-perl',
114        'shar'    => 'application/x-shar',
115        'swf'     => 'application/x-shockwave-flash',
116        'sh'      => 'application/x-sh',
117        'sit'     => 'application/x-stuffit',
118        'sv4cpio' => 'application/x-sv4cpio',
119        'sv4crc'  => 'application/x-sv4crc',
120        'tar'     => 'application/x-tar',
121        'tcl'     => 'application/x-tcl',
122        'texi'    => 'application/x-texinfo',
123        'texinfo' => 'application/x-texinfo',
124        'tex'     => 'application/x-tex',
125        'man'     => 'application/x-troff-man',
126        'me'      => 'application/x-troff-me',
127        'ms'      => 'application/x-troff-ms',
128        'roff'    => 'application/x-troff',
129        't'       => 'application/x-troff',
130        'tr'      => 'application/x-troff',
131        'ustar'   => 'application/x-ustar',
132        'src'     => 'application/x-wais-source',
133        'xhtml'   => 'application/xhtml+xml',
134        'xht'     => 'application/xhtml+xml',
135        'xml'     => 'application/xml',
136        'zip'     => 'application/zip',
137        'au'      => 'audio/basic',
138        'snd'     => 'audio/basic',
139        'kar'     => 'audio/midi',
140        'mid'     => 'audio/midi',
141        'midi'    => 'audio/midi',
142        'mp3'     => 'audio/mpeg',
143        'mp2'     => 'audio/mpeg',
144        'mpga'    => 'audio/mpeg',
145        'aiff'    => 'audio/x-aiff',
146        'aif'     => 'audio/x-aiff',
147        'aifc'    => 'audio/x-aiff',
148        'm3u'     => 'audio/x-mpegurl',
149        'wax'     => 'audio/x-ms-wax',
150        'wma'     => 'audio/x-ms-wma',
151        'rpm'     => 'audio/x-pn-realaudio-plugin',
152        'ram'     => 'audio/x-pn-realaudio',
153        'rm'      => 'audio/x-pn-realaudio',
154        'ra'      => 'audio/x-realaudio',
155        'wav'     => 'audio/x-wav',
156        'pdb'     => 'chemical/x-pdb',
157        'xyz'     => 'chemical/x-xyz',
158        'bmp'     => 'image/bmp',
159        'gif'     => 'image/gif',
160        'ief'     => 'image/ief',
161        'jpg'     => 'image/jpeg',
162        'jpe'     => 'image/jpeg',
163        'jpeg'    => 'image/jpeg',
164        'png'     => 'image/png',
165        'tif'     => 'image/tiff',
166        'tiff'    => 'image/tiff',
167        'wbmp'    => 'image/vnd.wap.wbmp',
168        'ras'     => 'image/x-cmu-raster',
169        'pnm'     => 'image/x-portable-anymap',
170        'pbm'     => 'image/x-portable-bitmap',
171        'pgm'     => 'image/x-portable-graymap',
172        'ppm'     => 'image/x-portable-pixmap',
173        'rgb'     => 'image/x-rgb',
174        'xbm'     => 'image/x-xbitmap',
175        'xpm'     => 'image/x-xpixmap',
176        'xwd'     => 'image/x-xwindowdump',
177        'iges'    => 'model/iges',
178        'igs'     => 'model/iges',
179        'mesh'    => 'model/mesh',
180        'msh'     => 'model/mesh',
181        'silo'    => 'model/mesh',
182        'vrml'    => 'model/vrml',
183        'wrl'     => 'model/vrml',
184        'ics'     => 'text/calendar',
185        'ifb'     => 'text/calendar',
186        'vcs'     => 'text/calendar',
187        'vfb'     => 'text/calendar',
188        'css'     => 'text/css',
189        'diff'    => 'text/diff',
190        'patch'   => 'text/diff',
191        'html'    => 'text/html',
192        'htm'     => 'text/html',
193        'shtml'   => 'text/html',
194        'txt'     => 'text/plain',
195        'asc'     => 'text/plain',
196        'log'     => 'text/plain',
197        'po'      => 'text/plain',
198        'rtx'     => 'text/richtext',
199        'rtf'     => 'text/rtf',
200        'sgm'     => 'text/sgml',
201        'sgml'    => 'text/sgml',
202        'tsv'     => 'text/tab-separated-values',
203        'wmls'    => 'text/vnd.wap.wmlscript',
204        'wml'     => 'text/vnd.wap.wml',
205        'etx'     => 'text/x-setext',
206        'vcf'     => 'text/x-vcard',
207        'xsl'     => 'text/xml',
208        'mpeg'    => 'video/mpeg',
209        'mpe'     => 'video/mpeg',
210        'mpg'     => 'video/mpeg',
211        'mov'     => 'video/quicktime',
212        'qt'      => 'video/quicktime',
213        'mxu'     => 'video/vnd.mpegurl',
214        'asf'     => 'video/x-ms-asf',
215        'asx'     => 'video/x-ms-asf',
216        'wmv'     => 'video/x-ms-wmv',
217        'wm'      => 'video/x-ms-wm',
218        'wmx'     => 'video/x-ms-wmx',
219        'wvx'     => 'video/x-ms-wvx',
220        'avi'     => 'video/x-msvideo',
221        'movie'   => 'video/x-sgi-movie',
222        'ice'     => 'x-conference/x-cooltalk',
223    );
224   
225    /**
226     * Set (or overwrite existing) parameters by passing an array of new parameters.
227     *
228     * @access public
229     * @param  array    $params     Array of parameters (key => val pairs).
230     */
231    function setParam($params)
232    {
233        if (isset($params) && is_array($params)) {
234       
235            // Enforce valid upload_path parameter.
236            if (isset($params['upload_path'])) {
237                $params['upload_path'] = realpath($params['upload_path']);
238                // Must be directory.
239                if (!is_dir($params['upload_path'])) {
240                    App::logMsg(sprintf('Upload directory invalid: %s', $params['upload_path']), LOG_ERR, __FILE__, __LINE__);
241                    trigger_error(sprintf('Upload directory invalid: %s', $params['upload_path']), E_USER_ERROR);
242                }
243                // Must be writable.
244                if (!is_writable($params['upload_path'])) {
245                    App::logMsg(sprintf('Upload directory not writable: %s', $params['upload_path']), LOG_ERR, __FILE__, __LINE__);
246                    trigger_error(sprintf('Upload directory not writable: %s', $params['upload_path']), E_USER_ERROR);
247                }
248                // Set the default upload path, stripping any extra slashes if needed.
249                $params['upload_path'] = preg_replace('!/+$!', '', $params['upload_path']);
250            }
251       
252            // Merge new parameters with old overriding only those passed.
253            $this->_params = array_merge($this->_params, $params);
254        } else {
255            App::logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
256        }
257    }
258
259    /**
260     * Return the value of a parameter, if it exists.
261     *
262     * @access public
263     * @param string $param        Which parameter to return.
264     * @return mixed               Configured parameter value.
265     */
266    function getParam($param)
267    {
268        if (isset($this->_params[$param])) {
269            return $this->_params[$param];
270        } else {
271            App::logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
272            return null;
273        }
274    }
275
276    /**
277     * Process uploaded files. Processes files existing within the specified $_FILES['form_name'] array.
278     * It tests for errors, cleans the filename, optionally sets custom file names. It will process
279     * multiple files automatically if the file form element is an array (<input type="file" name="myfiles[]" />).
280     *
281     * @access  public
282     * @param   string  $form_name          The name of the form to process.
283     * @param   string  $custom_file_name   The new name of the file. does not work if processing multiple files.
284     * @return  mixed   Returns FALSE if a major error occured preventing any file uploads.
285     *                  Returns an empty array if any minor errors occured or no files were found.
286     *                  Returns a multidimentional array of filenames, sizes and extentions, if one-or-more files succeeded uploading.
287     *                  Note: this last option presents a problem in the case of when some files uploaded successfully, and some failed.
288     *                        In this case it is necessary to check the Upload::anyErrors method to discover if any did fail.
289     */
290    function process($form_name, $custom_file_name=null)
291    {
292        // Ensure we have a upload directory.
293        if (!$this->getParam('upload_path')) {
294            App::logMsg(sprintf('Upload directory not set before processing.'), LOG_ERR, __FILE__, __LINE__);
295            $this->raiseMsg(_("There was a problem with the file upload. Please try again later."), MSG_ERR, __FILE__, __LINE__);
296            return false;
297        }
298       
299        // Ensure the file form element specified actually exists.
300        if (!isset($_FILES[$form_name])) {
301            App::logMsg(sprintf(_("Form element %s does not exist."), $form_name), LOG_ERR, __FILE__, __LINE__);
302            $this->raiseMsg(_("There was a problem with the file upload. Please try again later."), MSG_ERR, __FILE__, __LINE__);
303            return false;
304        }
305       
306        if (is_array($_FILES[$form_name]['name'])) {
307            $files = $_FILES[$form_name];
308        } else {
309            // Convert variables to single-cell array so it will loop.
310            $files = array(
311                'name'      => array($_FILES[$form_name]['name']),
312                'type'      => array($_FILES[$form_name]['type']),
313                'tmp_name'  => array($_FILES[$form_name]['tmp_name']),
314                'error'     => array($_FILES[$form_name]['error']),
315                'size'      => array($_FILES[$form_name]['size']),
316            );
317        }
318
319        // To keep this script running even if user tries to stop browser.
320        ignore_user_abort(true); 
321        ini_set('max_execution_time', 300);
322        ini_set('max_input_time', 300);
323
324        $new_file_names = array();
325
326        $num = sizeof($files['name']);
327        for ($i=0; $i<$num; $i++) {
328            $file_path_name = '';
329
330            if ('' == trim($files['tmp_name'][$i])) {
331                // User may not have attached a file.
332                continue;
333            }
334           
335            // Determine final file name.
336            if ($num == 1) {
337                // Single upload.
338                if (isset($custom_file_name) && '' != $custom_file_name) {
339                    // Valid custom file name.
340                    $file_name = $custom_file_name;
341                    $this->raiseMsg(sprintf(_("The file <strong>%s</strong> has been renamed to <strong>%s</strong>."), $files['name'][$i], $file_name), MSG_NOTICE, __FILE__, __LINE__);
342                    App::logMsg(sprintf('Using custom file name: %s', $file_name), LOG_DEBUG, __FILE__, __LINE__);
343                } else {
344                    // Invalid custom file name provided. Use uploaded file name.
345                    $file_name = $files['name'][$i];
346                    App::logMsg(sprintf('Using uploaded file name: %s', $file_name), LOG_DEBUG, __FILE__, __LINE__);
347                }
348            } else {
349                // Multiple upload. Final file names must be array.
350                if (isset($custom_file_name) && is_array($custom_file_name) && '' != $custom_file_name[$i]) {
351                    // Valid custom file name.
352                    $file_name = $custom_file_name[$i];
353                    $this->raiseMsg(sprintf(_("The file <strong>%s</strong> has been renamed to <strong>%s</strong>."), $files['name'][$i], $file_name), MSG_NOTICE, __FILE__, __LINE__);
354                    App::logMsg(sprintf('Using custom file name: %s', $file_name), LOG_DEBUG, __FILE__, __LINE__);
355                } else {
356                    // Invalid custom file name provided. Use uploaded file name.
357                    $file_name = $files['name'][$i];
358                    App::logMsg(sprintf('Using uploaded file name: %s', $file_name), LOG_DEBUG, __FILE__, __LINE__);
359                }
360            }
361
362            // Clean the file name of bad characters.
363            $file_name = $this->cleanFileName($file_name);
364           
365            // If the file name has no extension, use the mime-type extension.
366            if (!preg_match('/\.[^.]{1,5}$/', $file_name) && function_exists('mime_content_type')) {
367                if ($ext = array_search(mime_content_type($files['tmp_name'][$i]), $this->mime_extension_map)) {
368                    $file_name .= ".$ext";
369                }
370            }
371           
372            // Set the path and file name.
373            $file_path_name = $this->getParam('upload_path') . '/' . $file_name;
374           
375           
376            // Check The php upload error messages.
377            if (UPLOAD_ERR_INI_SIZE === $files['error'][$i]) {
378                if ($this->getParam('display_messages')) {
379                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: it exceeds the maximum allowed upload file size of %s."), $file_name, ini_get('upload_max_filesize')), MSG_ERR, __FILE__, __LINE__);
380                }
381                App::logMsg(sprintf(_("The file %s failed uploading with PHP error %s UPLOAD_ERR_INI_SIZE (currently %s)."), $files['error'][$i], $file_name, ini_get('upload_max_filesize')), LOG_ERR, __FILE__, __LINE__);
382                $this->errors[] = $file_name;
383                continue;
384            }
385            if (UPLOAD_ERR_FORM_SIZE === $files['error'][$i]) {
386                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: it exceeds the maximum allowed upload file size of %s."), $file_name, $_POST['MAX_FILE_SIZE']), MSG_ERR, __FILE__, __LINE__);
387                App::logMsg(sprintf(_("The file %s failed uploading with PHP error %s UPLOAD_ERR_FORM_SIZE (currently %s)."), $files['error'][$i], $file_name, $_POST['MAX_FILE_SIZE']), LOG_ERR, __FILE__, __LINE__);
388                $this->errors[] = $file_name;
389                continue;
390            }
391            if (UPLOAD_ERR_PARTIAL === $files['error'][$i]) {
392                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: it was only partially uploaded."), $file_name), MSG_ERR, __FILE__, __LINE__);
393                App::logMsg(sprintf(_("The file %s failed uploading with PHP error %s UPLOAD_ERR_PARTIAL."), $files['error'][$i], $file_name), LOG_ERR, __FILE__, __LINE__);
394                $this->errors[] = $file_name;
395                continue;
396            }
397            if (UPLOAD_ERR_NO_FILE === $files['error'][$i]) {
398                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: no file was uploaded."), $file_name), MSG_ERR, __FILE__, __LINE__);
399                App::logMsg(sprintf(_("The file %s failed uploading with PHP error %s UPLOAD_ERR_NO_FILE."), $files['error'][$i], $file_name), LOG_ERR, __FILE__, __LINE__);
400                $this->errors[] = $file_name;
401                continue;
402            }
403            if (UPLOAD_ERR_NO_TMP_DIR === $files['error'][$i]) {
404                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: temporary upload directory missing."), $file_name), MSG_ERR, __FILE__, __LINE__);
405                App::logMsg(sprintf(_("The file %s failed uploading with PHP error %s UPLOAD_ERR_NO_TMP_DIR."), $files['error'][$i], $file_name), LOG_ERR, __FILE__, __LINE__);
406                $this->errors[] = $file_name;
407                continue;
408            }
409           
410            // Check to be sure it's an uploaded file.
411            if (!is_uploaded_file($files['tmp_name'][$i])) {
412                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading."), $file_name), MSG_ERR, __FILE__, __LINE__);
413                App::logMsg(sprintf(_("The file %s failed is_uploaded_file."), $file_name), LOG_ERR, __FILE__, __LINE__);
414                $this->errors[] = $file_name;
415                continue;
416            }
417           
418            // Check to be sure the file is not empty.
419            if ($files['size'][$i] < 1) {
420                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: it contains zero bytes."), $file_name), MSG_ERR, __FILE__, __LINE__);
421                App::logMsg(sprintf(_("The uploaded file %s contains zero bytes."), $file_name), LOG_ERR, __FILE__, __LINE__);
422                $this->errors[] = $file_name;
423                continue;
424            }
425           
426            // Check to be sure the file has a valid file name extension.
427            if (!in_array(strtolower($this->getFilenameExtension($file_name)), $this->getParam('valid_file_extensions'))) {
428                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: it is an unrecognized type. Files must have one of the following file name extensions: %s."), $file_name, join(', ', $this->getParam('valid_file_extensions'))), MSG_ERR, __FILE__, __LINE__);
429                App::logMsg(sprintf(_("The uploaded file %s has an unrecognized file name extension."), $file_name), LOG_WARNING, __FILE__, __LINE__);
430                $this->errors[] = $file_name;
431                continue;
432            }
433           
434            // Check to be sure the file has a unique file name.
435            if (!$this->getParam('allow_overwriting') && $this->exists($file_name)) {
436                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading: a file with that name already exists."), $file_name), MSG_ERR, __FILE__, __LINE__);
437                App::logMsg(sprintf(_("The uploaded file %s doesn't have a unique filename."), $file_name), LOG_WARNING, __FILE__, __LINE__);
438                $this->errors[] = $file_name;
439                continue;
440            }
441           
442            // Move the file to the final place.
443            if (move_uploaded_file($files['tmp_name'][$i], $file_path_name)) {
444                chmod($file_path_name, $this->getParam('dest_file_perms'));
445                App::logMsg(sprintf('File uploaded: %s', $file_path_name), LOG_INFO, __FILE__, __LINE__);
446                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> uploaded successfully."), $file_name), MSG_SUCCESS, __FILE__, __LINE__);
447                if (!isset($custom_file_name) && $files['name'][$i] != $file_name) {
448                    // Notify user if uploaded file name was modified (unless a custom file name will be used anyways).
449                    $this->raiseMsg(sprintf(_("The file <strong>%s</strong> was renamed to <strong>%s</strong>."), $files['name'][$i], $file_name), MSG_NOTICE, __FILE__, __LINE__);
450                }
451                $new_file_names[] = array(
452                    'name' => $file_name,
453                    'size' => filesize($file_path_name),
454                    'extension' => strtolower(substr($file_name, strrpos($file_name, '.') + 1)),
455                );
456                continue;
457            } else {
458                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> failed uploading."), $file_name), MSG_ERR, __FILE__, __LINE__);
459                App::logMsg(sprintf(_("Moving file failed: %s -> %s"), $files['tmp_name'][$i], $file_path_name), LOG_ALERT, __FILE__, __LINE__);
460                $this->errors[] = $file_name;
461                continue;
462            }
463        }
464       
465        // Return names of files uploaded (or empty array when none processed).
466        return $new_file_names;
467    }
468   
469    /**
470     * Remove file within upload path.
471     *
472     * @access  public
473     * @param   string  $file_name  A name of a file.
474     * @return  bool                Success of operation.
475     */
476    function deleteFile($file_name)
477    {
478        // Ensure we have a upload directory.
479        if (!$this->getParam('upload_path')) {
480            App::logMsg(sprintf('Upload directory not set before processing.'), LOG_ERR, __FILE__, __LINE__);
481            return false;
482        }
483       
484        $file_path_name = $this->getParam('upload_path') . '/' . $file_name;
485
486        if (!is_file($file_path_name)) {
487            App::logMsg(sprintf(_("Error deleting nonexistent file: %s"), $file_path_name), LOG_ERR, __FILE__, __LINE__);
488            return false;
489        } else if (unlink($file_path_name)) {
490            App::logMsg(sprintf('Deleted file: %s', $file_path_name), LOG_INFO, __FILE__, __LINE__);
491        } else {
492            $this->raiseMsg(sprintf(_("The file <strong>%s</strong> could not be deleted."), $file_name), MSG_ERR, __FILE__, __LINE__);
493            App::logMsg(sprintf(_("Failed deleting file: %s"), $file_path_name), LOG_ERR, __FILE__, __LINE__);
494            return false;
495        }
496    }
497   
498    /**
499     * Renames a file within the upload path.
500     *
501     * @access  public
502     * @param   string  $old_name   The currently existing file name.
503     * @param   string  $new_name   The new name for this file.
504     * @return  bool                Success of operation.
505     */
506    function moveFile($old_name, $new_name)
507    {
508        // Ensure we have an upload directory.
509        if (!$this->getParam('upload_path')) {
510            App::logMsg(sprintf('Upload directory not set before processing.'), LOG_ERR, __FILE__, __LINE__);
511            return false;
512        }
513       
514        $old_file_path_name = $this->getParam('upload_path') . '/' . $old_name;
515        $new_file_path_name = $this->getParam('upload_path') . '/' . $new_name;
516        if (file_exists($old_file_path_name)) {
517            if (rename($old_file_path_name, $new_file_path_name)) {
518                $this->raiseMsg(sprintf(_("The file <strong>%s</strong> has been renamed to <strong>%s</strong>."), basename($old_file_path_name), basename($new_file_path_name)), MSG_NOTICE, __FILE__, __LINE__);
519                App::logMsg(sprintf('File renamed from %s to %s', $old_file_path_name, $new_file_path_name), LOG_DEBUG, __FILE__, __LINE__);
520            } else {
521                $this->raiseMsg(sprintf(_("Error renaming file to %s"), $new_file_path_name), MSG_WARNING, __FILE__, __LINE__);
522                App::logMsg(sprintf(_("Error renaming file to %s"), $new_file_path_name), LOG_WARNING, __FILE__, __LINE__);
523                return false;
524            }
525        } else {
526            $this->raiseMsg(sprintf(_("Couldn't rename nonexistent file <strong>%s</strong>."), $old_name), MSG_WARNING, __FILE__, __LINE__);
527            App::logMsg(sprintf(_("Error renaming nonexistent file: %s"), $old_file_path_name), LOG_WARNING, __FILE__, __LINE__);
528            return false;
529        }
530    }
531   
532    /**
533     * Tests if a file exists within the current upload_path.
534     *
535     * @access  public
536     * @param   string  $file_name  A name of a file.
537     * @return  bool                Existence of file.
538     */
539    function exists($file_name)
540    {
541        // Ensure we have a upload directory.
542        if (!$this->getParam('upload_path')) {
543            App::logMsg(sprintf('Upload directory not set before processing.'), LOG_ERR, __FILE__, __LINE__);
544            return false;
545        }
546       
547        return file_exists($this->getParam('upload_path') . '/' . $file_name);
548    }
549
550    /**
551     * Get filename by glob pattern. Searches a directory for an image that matches the
552     * specified glob pattern and returns the filename of the first file found.
553     *
554     * @access  public
555     * @param   string  $pattern   Pattern to match filename.
556     * @return  string filename on success, empty string on failure.
557     * @author  Quinn Comendant <quinn@strangecode.com>
558     * @since   15 Nov 2005 20:55:22
559     */
560    function getFilenameGlob($pattern)
561    {
562        $file_list = glob(sprintf('%s/%s', $this->getParam('upload_path'), $pattern));
563        if (isset($file_list[0])) {
564            return basename($file_list[0]);
565        } else {
566            return '';
567        }
568    }
569
570    /**
571     * Returns an array of file names that failed uploading.
572     *
573     * @access  public
574     * @return  array   List of file names.
575     */
576    function getErrors()
577    {
578        return $this->errors;
579    }
580
581    /**
582     * Determintes if any errors occured while calling the Upload::process method.
583     *
584     * @access  public
585     */
586    function anyErrors()
587    {
588        return sizeof($this->errors) > 0;
589    }
590
591    /**
592     * Removes unsafe characters from file name.
593     *
594     * @access  public
595     * @param   string  $file_name  A name of a file.
596     * @return  string              The same name, but cleaned.
597     */
598    function cleanFileName($file_name)
599    {
600        $bad  = 'áéíóúàèìòùäëïöüÁÉÍÓÚÀÈÌÒÙÄËÏÖÜâêîôûÂÊÎÔÛñçÇ@';
601        $good = 'aeiouaeiouaeiouAEIOUAEIOUAEIOUaeiouAEIOUncCa';
602        $file_name = trim($file_name);
603        $file_name = strtr($file_name, $bad, $good);
604        $file_name = preg_replace('/[^-\w.,~_=+()]/i', '_', $file_name);
605        $file_name = substr($file_name, 0, 250);
606        return $file_name;
607    }
608
609
610    /**
611     * Returns the extention of a file name, or an empty string if non exists.
612     *
613     * @access  public
614     * @param   string  $file_name  A name of a file, with extention after a dot.
615     * @return  string              The value found after the dot
616     */
617    function getFilenameExtension($file_name)
618    {
619        preg_match('/.*?\.(\w+)$/i', trim($file_name), $ext);
620        return isset($ext[1]) ? $ext[1] : '';
621    }
622   
623    /**
624     * An alias for App::raiseMsg that only sends messages configured by display_messages.
625     *
626     * @access public
627     *
628     * @param string $message The text description of the message.
629     * @param int    $type    The type of message: MSG_NOTICE,
630     *                        MSG_SUCCESS, MSG_WARNING, or MSG_ERR.
631     * @param string $file    __FILE__.
632     * @param string $line    __LINE__.
633     */
634    function raiseMsg($message, $type, $file, $line)
635    {
636        if ($this->getParam('display_messages') === true || (is_int($this->getParam('display_messages')) && $this->getParam('display_messages') >= $type)) {
637            App::raiseMsg($message, $type, $file, $line);
638        }
639    }
640}
641
642?>
Note: See TracBrowser for help on using the repository browser.