Upload Class





34
Date Submitted Thu. Nov. 9th, 2006 2:11 AM
Revision 1 of 1
Helper Nico
Tags Class | PHP | transload | upload
Comments 7 comments
Simple upload class with features such as

- Upload of multiple files at the same time.
- Filtering uploads by size and extension.
- Uploads to configurable subdirs based on date.
- Automatic file renaming if a file with the same name exists.
- Transloading. Copying files from a different host to the local host. (Like Imageshack does)
- And more...


<?php

include('class.upload.php');

// Create the upload object
$uploader = new swd_upload;

// Set an upload limit
$uploader->max_size *= 15; // 15 MB

// Add some extensions
$uploader->add_extension('jpg', 'bmp', 'png');

// Set an upload dir
$uploader->upload_path = './uploads/';

// Upload file(s)
$uploader->upload();

// Show the upload form. Use display_transloader() for the transloader.
$uploader->display_uploader('upload.php', 20);

// Show allowed extensions to user
echo $uploader->get_extensions(true);

// Display all uploaded files
$uploader->get_uploaded_files();

// Display all errors
$uploader->get_errors();

?>

 


<?php

class swd_upload
{
        /**
        *       =========================================================================
        *                                                        UPLOAD CLASS
        *       =========================================================================
        *
        *       @author:                     Nicolas Oelgart
        *       @copyright:            Nicolas Oelgart
        *       @version:                  Revision: 1.8
        *       @date:    25th August 2006
        *       @last modified:                16th October 2006
        *       @license:                  GPL
        *
        *       @website:                  www.nicoswd.com
        *       @email:                                nico@nicoswd.com
        *
        *       @requirements:  PHP 4.2 +
        *
        *       =========================================================================
        *
        *       Copyright (C) 2006  Nicolas Oelgart
        *       
        *       This program is free software; you can redistribute it and/or modify it
        *       under the terms of the GNU General Public License as published by the
        *       Free Software Foundation; either version 2 of the License, or (at your
        *       option) any later version.
        *       
        *       This program is distributed in the hope that it will be useful, but
        *       WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        *       or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
        *       for more details.
        *       
        *       You should have received a copy of the GNU General Public License along
        *       with this program; if not, write to the Free Software Foundation, Inc.,
        *       51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
        *
        *       =========================================================================
        */


        /**
        *       Max upload size in bytes. Set to FALSE fot no limit.
        *       Note: 1048576 byes = 1 MB
        *
        *       @var   integer
        */

        var $max_size = 1048576;

        /**
        *       Allowed uploads at the same time.
        *
        *       @var   integer
        */

        var $max_uploads = 5;

        /**
        *       Default allowed file extensions. (Lowercase)
        *
        *       @var   array
        */

        var $extensions = array('jpg', 'zip', 'pdf');

        /**
        *       Upload path. Will be created if not exists.
        *
        *       @var   string
        */

        var $upload_path = './uploads/';

        /**
        *       Will create subdirs based on the date format in the next variable.
        *
        *       @var   boolean
        */

        var $enable_subdirs = true;
       
        /**
        *       Subdir format. Must be a valid format for PHP's date() function.
        *       See first table on this page: http://us2.php.net/date
        *
        *       @var   string
        */

        var $subdir_format = 'Ym';

        /**
        *       Creates blank index files in each upload and subdirectory if TRUE.
        *
        *       @var   boolean
        */

        var $create_index = true;

        /**
        *       Filename for index files.
        *
        *       @var   string
        */

        var $index_file = 'index.html';

        /**
        *       Overwrite existing files. Will create an unique filename if FALSE.
        *
        *       @var   boolean
        */

        var $overwrite = false;

        /**
        *       All error messages are here. You may wish to rephrase them.
        *
        *       @var   array
        */

        var $default_errors = array
        (
                // Default errors
                '',
                'The uploaded file exceeds the upload_max_filesize directive.',
                'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
                'The uploaded file was only partially uploaded.',
                'No file was uploaded.',
                'Missing a temporary folder.',
                'Failed to write file to disk.',
                'Unknown File Error.',
               
                // Custom errors
                'Extension (%s) not allowed. "%s" not uploaded.',
                'File over allowed size of %d bytes.',
                'The upload of "%s" failed. Please try again.',
                'Max uploads of %d has been reached or an unexpected error ocurred.',
                'An unexpected error ocurred. %s has not been uploaded.',
                'Could not create upload directory. Upload cancelled.',
                'Failed to open file. Please check the URL.',
                'The server has disabled this function. Please contact the administrator.',
                'The upload directory is not writable. Could not upload file.'
        );

        /**
        *       ====================================================================================
        *                                                               END CONFIGURATION.
        *       ====================================================================================
        *
        *       You may not edit below unless you know what you're doing.
        */



        /**
        *       Holds all errors that ocurred while uplading.
        *
        *       @var   array
        */

        var $errors = array();

        /**
        *       Holds all names of all uploaded files.
        *
        *       @var   array
        */
     
        var $uploaded_files = array();

        /**
        *       Holds the formatted subdir name if enabled.
        *
        *       @var   string
        */
     
        var $subdir = '';

        /**
        *       Holds the $_FILES['swd_upload'] array.
        *
        *       @var   array
        */

        var $files;

        /**
        *       Holds the $_POST['swd_transload'] file URL.
        *
        *       @var   string
        */

        var $transload;

        /**
        *       Holds the current key.
        *
        *       @var   integer
        */

        var $_key;

       
       
        /**
        *       Class constructor
        *
        *       Sets main variables.
        */
     
        function swd_upload()
        {
                $this->files = $_FILES['swd_upload'];
                $this->transload = $_POST['swd_transload'];
               
                if ($this->enable_subdirs)
                {
                        $this->subdir = date($this->subdir_format) .'/';
                }
        }
       
       
        /**
        *       Checks quick if the filename is valid, and if the number of max uploads
        *       hasn't been passed yet. Sends array key to move() if everything ok here.
        *
        *       @return                mixed
        */

        function upload()
        {
                if (!is_array($this->files['error']) OR !$this->is_valid_upload_path())
                {
                        return false;
                }
               
                foreach ($this->files['error'] AS $key => $error)
                {
                        $filename = $this->files['name'][$key];
                        $this->_key = $key;
                       
                        if (empty($filename))
                        {
                                continue;
                        }
                        else if (sizeof($this->uploaded_files) >= $this->max_uploads)
                        {
                                $this->set_error(sprintf($this->default_errors[11], $this->max_uploads));
                                return false;
                        }
                        else if ($this->is_valid_file($filename) AND ($error === 0))
                        {
                                $this->move();
                        }
                        else if (!empty($error))
                        {
                                $this->set_error($this->default_errors[$error]);
                        }
                }
        }
       
       
        /**
        *       Transloads a file from another host to the upload directory.
        *
        *       @return                boolean
        */

        function transload()
        {
                if (ini_get('allow_url_fopen') == 0)
                {
                        $this->set_error($this->default_errors[15]);
                        return false;
                }
       
                if (!$this->is_valid_upload_path())
                {
                        return false;
                }
        
                if (!empty($this->transload))
                {
                        $filename = basename($this->transload);
                        $contents = '';
                       
                        if (!$this->is_valid_file($filename, false))
                        {
                                return false;
                        }

                        set_time_limit(0);
                        @ini_set('user_agent', 'PHP');

                        if (!($fp = @fopen($this->transload, 'rb')))
                        {
                                $this->set_error($this->default_errors[14]);
                                return false;
                        }
                       
                        while (!feof($fp))
                        {
                                $contents .= fread($fp, 8192);
                               
                                if ($this->max_size AND (strlen($contents) > $this->max_size))
                                {
                                        $this->set_error(sprintf($this->default_errors[9], $this->max_size));
                                        return false;
                                }
                        }
                       
                        fclose($fp);
       
                        if ($upload = @fopen($this->upload_path . $this->subdir . $this->rand_name($filename), 'w'))
                        {
                                fwrite($upload, $contents);
                                fclose($upload);
                        }
                       
                        $this->uploaded_files[] = $filename;
                        return true;
                }
        }
               
       
        /**
        *       Checks if the file has a valid extension and if the size is not over the
        *       max upload limit.
        *
        *       @param  string      Filename
        *       @param  boolean    If true, checks for size as well.
        *
        *       @return                boolean
        */

        function is_valid_file($filename, $checksize = true)
        {
                if (!in_array($this->file_extension($filename), $this->extensions))
                {
                        $this->set_error(sprintf($this->default_errors[8], $this->file_extension($filename), $filename));
                        return false;
                }
               
                if ($checksize AND $this->max_size)
                {
                        if ($this->files['size'][$this->_key] > $this->max_size)
                        {
                                $this->set_error(sprintf($this->default_errors[9], $this->max_size));
                                return false;
                        }
                }
               
                return true;
        }
       
       
        /**
        *       Moves the uploaded file from the temp directory to the upload directory.
        */

        function move()
        {
                $filename = $this->files['name'][$this->_key];
               
                if (is_uploaded_file($this->files['tmp_name'][$this->_key]))
                {
                        $upload_name = $this->rand_name($filename);
                       
                        if (@move_uploaded_file($this->files['tmp_name'][$this->_key], $this->upload_path . $this->subdir . $upload_name))
                        {
                                array_push($this->uploaded_files, $upload_name);
                        }
                        else
                        {
                                $this->set_error(sprintf($this->default_errors[10], $filename));
                        }
                }
                else
                {
                        $this->set_error(sprintf($this->default_errors[12], $filename));
                }
        }
       
       
        /**
        *       Checks if the upload path (and subdir if enabled) exists and attempts
        *       to create it if not. Also creates empty index files if enabled.
        *
        *       @return                boolean
        */

        function is_valid_upload_path()
        {
                $paths = array($this->upload_path);
               
                if ($this->enable_subdirs)
                {
                        array_push($paths, $this->upload_path . $this->subdir);
                }
               
                foreach ($paths AS $path)
                {
                        if (!file_exists($path) AND !@mkdir($path, 0755))
                        {
                                $this->set_error($this->default_errors[13]);
                                return false;
                        }
                        else if (!is_writable($path) AND !chmod($path, 755))
                        {
                                $this->set_error($this->default_errors[17]);
                                return false;
                        }
                       
                        if ($this->create_index AND !file_exists($path . $this->index_file))
                        {
                                @touch($path . $this->index_file);
                        }
                }
               
                return true;
        }


        /**
        *       Adds one or more extensions to the allowed extensions array.
        *
        *       @param  mixed        Allowed extensions. Can either be an array or strings as arguments.
        *
        *       @return                boolean
        */
     
        function add_extension()
        {
                $extensions = func_get_args();
               
                return $this->extensions = array_merge($this->extensions, (is_array($extensions[0]) ? $extensions[0] : $extensions));
        }
       
       
        /**
        *       Removes one or more extensions from the allowed extensions array.
        *
        *       @param  mixed        Extensions that need to be removed. Can either be an array or strings as arguments.
        *
        *       @return                boolean
        */
     
        function remove_extension()
        {
                $extensions = func_get_args();

                return $this->extensions = array_diff($this->extensions, (is_array($extensions[0]) ? $extensions[0] : $extensions));
        }
       
       
        /**
        *       Returns all allowed extensions either as array or string.
        *
        *       @param  boolean    Returns the extensions as array if FALSE.
        *       @param  string      Separator between extensions.
        *
        *       @return                mixed
        */
           
        function get_extensions($as_string = false, $separator = ', ')
        {
                $extensions = array_unique($this->extensions);
               
                return ($as_string ? implode($separator, $extensions) : $extensions);
        }
       
       
        /**
        *       Returns the last characters after the last dot in the given string.
        *
        *       @param  string      Filename
        *
        *       @return                string    Extension
        */

        function file_extension($filename)
        {
                return strtolower(substr(strrchr($filename, '.'), 1));
        }
       

        /**
        *       Generates a unique name for the uploaded file if enabled.
        *
        *       @param  string      Filename
        *
        *       @return                string    Random name
        */

        function rand_name($original)
        {
                if ($this->overwrite OR !file_exists($this->upload_path . $this->subdir . $original))
                {
                        return $original;
                }
                else
                {
                        return $this->rand_name(substr(md5(rand(1, 5000) . time() . rand(50, 7000)), -5) .'_'. $original);
                }
        }
       
       
        /**
        *       Adds an error to the array.
        *
        *       @param  string      Error message
        *
        *       @return                none
        */

        function set_error($error)
        {
                $this->errors[] = $error;
        }
               
       
        /**
        *       Displays the upload form based on the allowed max uploads.
        *
        *       @param  string      If the form should be submitted to another file, this needs to be changed to the target filename.
        *
        *       @return                string    Upload form
        */

        function display_uploader($action = false)
        {
                echo '<div id="swd_upload">'. "\r\n";
                echo '<form action="'. ($action ? $action : basename($_SERVER['PHP_SELF'])) .'" method="post" enctype="multipart/form-data">'. "\r\n";
               
                for ($i = 0; $i < $this->max_uploads; $i++)
                {
                        echo "\t" .'<p><input type="file" name="swd_upload[]" /></p>'. "\r\n";
                }
               
                echo "\t" .'<input type="submit" value="Upload files" />'. "\r\n";
                echo '</form>'. "\r\n";
                echo '</div>'. "\r\n";
        }
       
       
        /**
        *       Displays the transloader form.
        *
        *       @param  mixed        Target filename for the form, or FALSE for self.
        *       @param  integer    Size for the text field.
        *
        *       @return                string    Upload form.
        */
     
        function display_transloader($action = false, $size = 20)
        {
                echo '<div id="swd_transload">'. "\r\n";
                echo '<form action="'. ($action ? $action : basename($_SERVER['PHP_SELF'])) .'" method="post">'. "\r\n";
                echo "\t". '<input type="text" size="'. $size .'" name="swd_transload" />'. "\r\n";
                echo "\t". '<input type="submit" value="Transload" />'. "\r\n";
                echo '</form>' ."\r\n";
                echo '</div>'. "\r\n";
        }
       
       
        /**
        *       Returns all errors either as array or as HTML list.
        *
        *       @param  boolean    If true, returns errors as array.
        *
        *       @return                mixed
        */

        function get_errors($as_array = false)
        {
                if ($as_array OR sizeof($this->errors) === 0)
                {
                        return ($as_array ? $this->errors : '');
                }
               
                echo '<div id="swd_errors">'. "\r\n";
                echo '<ul>' ."\r\n";
               
                foreach ($this->errors AS $error)
                {
                        echo "\t". '<li>'. $error .'</li>'. "\r\n";
                }
               
                echo '</ul>' ."\r\n";
                echo '</div>' ."\r\n";
        }
       
        /**
        *       =========================================================================
        *                                                        UPLOAD CLASS END
        *       =========================================================================
        *       Copyright (C) 2006 by Nicolas Oelgart.
        */


}

?>

 

Comments

Comments Recursive Directories
Thu. Nov. 9th, 2006 8:36 AM    Helper brendo
Comments Recursive Directories
Mon. Nov. 13th, 2006 10:57 PM    Helper brendo
Comments Great!
Wed. Oct. 3rd, 2007 8:41 PM    Helper explode
Comments Careful with this script!
Mon. Nov. 13th, 2006 9:00 PM    Beginner ZenBug
  Comments Thanks.
Tue. Nov. 14th, 2006 6:14 AM    Helper Nico
    Comments Re: Thanks
Tue. Nov. 14th, 2006 8:28 AM    Beginner ZenBug

Voting