{CodeIgniter]CodeIgniterで複数のファイルをアップする

CodeIgniterのUplodクラスは、どうも一つのファイルのアップを想定しているようです。

でやってみました。

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category
 * @package    Upload Class
 * @author     KUNIHARU Tsujioka <kunitsuji@gmail.com>
 * @copyright  Copyright (c) 2008 KUNIHARU Tsujioka <kunitsuji@gmail.com>
 * @copyright  Copyright (c) 2006-2008 Usagi Project (URL:http://usagi-project.org)
 * @license    New BSD License
 */

class MYNETS_Upload extends CI_Upload {

    var $file_temp      = array();
    var $file_name      = array();
    var $orig_name      = array();
    var $file_type      = array();
    var $file_size      = array();
    var $file_ext       = array();
    ///////////////////////////////
    var $field          = 'userfile';
    ///////////////////////////////
    /**
     * Constructor
     *
     * @access  public
     */
    function __construct($props = array())
    {
        parent::__construct();
        if (count($props) > 0)
        {
            $this->initialize($props);
        }

        log_message('debug', "Upload Class Initialized");
    }

    // --------------------------------------------------------------------
    //2009/01/21 KUNIHARU Tsujioka add
    function is_uploaded($field)
    {
        if ( ! is_uploaded_file($_FILES[$field]['tmp_name']))
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }

    //2009/01/21 KUNIHARU Tsujioka add
    function set_field_name($field)
    {
        $this->field = $field;
    }
    /**
     * Perform the file upload
     *
     * @access  public
     * @return  bool
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function do_upload($field = '')
    {
        //$this->is_uploaded[$this->field] = FALSE;

        if ($field)
        {
            $this->field = $field;
        }
        // Is $_FILES[$this->field] set? If not, no reason to continue.
        if ( ! isset($_FILES[$this->field]))
        {
            $this->set_error('upload_no_file_selected');
            return FALSE;
        }

        // Is the upload path valid?
        if ( ! $this->validate_upload_path())
        {
            // errors will already be set by validate_upload_path() so just return FALSE
            return FALSE;
        }

        // Was the file able to be uploaded? If not, determine the reason why.
        if ( ! is_uploaded_file($_FILES[$this->field]['tmp_name']))
        {
            $error = ( ! isset($_FILES[$this->field]['error'])) ? 4 : $_FILES[$this->field]['error'];

            switch($error)
            {
                case 1: // UPLOAD_ERR_INI_SIZE
                    $this->set_error('upload_file_exceeds_limit');
                    break;
                case 2: // UPLOAD_ERR_FORM_SIZE
                    $this->set_error('upload_file_exceeds_form_limit');
                    break;
                case 3: // UPLOAD_ERR_PARTIAL
                   $this->set_error('upload_file_partial');
                    break;
                case 4: // UPLOAD_ERR_NO_FILE
                   $this->set_error('upload_no_file_selected');
                    break;
                case 6: // UPLOAD_ERR_NO_TMP_DIR
                    $this->set_error('upload_no_temp_directory');
                    break;
                case 7: // UPLOAD_ERR_CANT_WRITE
                    $this->set_error('upload_unable_to_write_file');
                    break;
                case 8: // UPLOAD_ERR_EXTENSION
                    $this->set_error('upload_stopped_by_extension');
                    break;
                default :   $this->set_error('upload_no_file_selected');
                    break;
            }

            return FALSE;
        }

        // Set the uploaded data as class variables
        $this->file_temp[$this->field] = $_FILES[$this->field]['tmp_name'];
        $this->file_name[$this->field] = $this->_prep_filename($_FILES[$this->field]['name']);
        $this->file_size[$this->field] = $_FILES[$this->field]['size'];
        $this->file_type[$this->field] = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$this->field]['type']);
        $this->file_type[$this->field] = strtolower($this->file_type[$this->field]);
        $this->file_ext[$this->field]    = $this->get_extension($_FILES[$this->field]['name']);

        // Convert the file size to kilobytes
        if ($this->file_size[$this->field] > 0)
        {
            $this->file_size[$this->field] = round($this->file_size[$this->field]/1024, 2);
        }

        // Is the file type allowed to be uploaded?
        if ( ! $this->is_allowed_filetype())
        {
            $this->set_error('upload_invalid_filetype');
            return FALSE;
        }

        // Is the file size within the allowed maximum?
        if ( ! $this->is_allowed_filesize())
        {
            $this->set_error('upload_invalid_filesize');
            return FALSE;
        }

        // Are the image dimensions within the allowed size?
        // Note: This can fail if the server has an open_basdir restriction.
        if ( ! $this->is_allowed_dimensions())
        {
            $this->set_error('upload_invalid_dimensions');
            return FALSE;
        }


        // Sanitize the file name for security
        $this->file_name[$this->field] = $this->clean_file_name($this->file_name[$this->field]);

        // Truncate the file name if it's too long
        if ($this->max_filename > 0)
        {
            $this->file_name[$this->field] = $this->limit_filename_length($this->file_name[$this->field], $this->max_filename);
        }

        // Remove white spaces in the name
        if ($this->remove_spaces == TRUE)
        {
            $this->file_name[$this->field] = preg_replace("/\s+/", "_", $this->file_name[$this->field]);
        }

        /*
         * Validate the file name
         * This function appends an number onto the end of
         * the file if one with the same name already exists.
         * If it returns false there was a problem.
         */
        $this->orig_name[$this->field] = $this->file_name[$this->field];

        if ($this->overwrite == FALSE)
        {
            $this->file_name[$this->field] = $this->set_filename($this->upload_path, $this->file_name[$this->field]);

            if ($this->file_name[$this->field] === FALSE)
            {
                return FALSE;
            }
        }

        /*
         * Move the file to the final destination
         * To deal with different server configurations
         * we'll attempt to use copy() first.  If that fails
         * we'll use move_uploaded_file().  One of the two should
         * reliably work in most environments
         */
        if ( ! @copy($this->file_temp[$this->field], $this->upload_path.$this->file_name[$this->field]))
        {
            if ( ! @move_uploaded_file($this->file_temp[$this->field], $this->upload_path.$this->file_name[$this->field]))
            {
                 $this->set_error('upload_destination_error');
                 return FALSE;
            }
        }

        /*
         * Run the file through the XSS hacking filter
         * This helps prevent malicious code from being
         * embedded within a file.  Scripts can easily
         * be disguised as images or other file types.
         */
        if ($this->xss_clean == TRUE)
        {
            $this->do_xss_clean();
        }

        /*
         * Set the finalized image dimensions
         * This sets the image width/height (assuming the
         * file was an image).  We use this information
         * in the "data" function.
         */
        $this->set_image_properties($this->upload_path.$this->file_name[$this->field]);

        return TRUE;
    }

    // --------------------------------------------------------------------

    /**
     * Finalized Data Array
     *
     * Returns an associative array containing all of the information
     * related to the upload, allowing the developer easy access in one array.
     *
     * @access  public
     * @return  array
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function data($filed = 'uploadfile')
    {
        return array (
                        'file_name'         => $this->file_name[$this->field],
                        'file_type'         => $this->file_type[$this->field],
                        'file_path'         => $this->upload_path,
                        'full_path'         => $this->upload_path.$this->file_name[$this->field],
                        'raw_name'          => str_replace($this->file_ext[$this->field], '', $this->file_name[$this->field]),
                        'orig_name'         => $this->orig_name[$this->field],
                        'file_ext'          => $this->file_ext[$this->field],
                        'file_size'         => $this->file_size[$this->field],
                        'is_image'          => $this->is_image(),
                        'image_width'       => $this->image_width,
                        'image_height'      => $this->image_height,
                        'image_type'        => $this->image_type,
                        'image_size_str'    => $this->image_size_str,
                    );
    }


    // --------------------------------------------------------------------

    /**
     * Set the file name
     *
     * This function takes a filename/path as input and looks for the
     * existence of a file with the same name. If found, it will append a
     * number to the end of the filename to avoid overwriting a pre-existing file.
     *
     * @access  public
     * @param   string
     * @param   string
     * @return  string
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function set_filename($path, $filename)
    {
        if ($this->encrypt_name == TRUE)
        {
            mt_srand();
            $filename = md5(uniqid(mt_rand())).$this->file_ext[$this->field];
        }

        if ( ! file_exists($path.$filename))
        {
            return $filename;
        }

        $filename = str_replace($this->file_ext[$this->field], '', $filename);

        $new_filename = '';
        for ($i = 1; $i < 100; $i++)
        {
            if ( ! file_exists($path.$filename.$i.$this->file_ext[$this->field]))
            {
                $new_filename = $filename.$i.$this->file_ext[$this->field];
                break;
            }
        }

        if ($new_filename == '')
        {
            $this->set_error('upload_bad_filename');
            return FALSE;
        }
        else
        {
            return $new_filename;
        }
    }

    // --------------------------------------------------------------------

    /**
     * Validate the image
     *
     * @access  public
     * @return  bool
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function is_image()
    {
        // IE will sometimes return odd mime-types during upload, so here we just standardize all
        // jpegs or pngs to the same file type.

        $png_mimes  = array('image/x-png');
        $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');

        if (in_array($this->file_type[$this->field], $png_mimes))
        {
            $this->file_type[$this->field] = 'image/png';
        }

        if (in_array($this->file_type[$this->field], $jpeg_mimes))
        {
            $this->file_type[$this->field] = 'image/jpeg';
        }

        $img_mimes = array(
                            'image/gif',
                            'image/jpeg',
                            'image/png',
                           );

        return (in_array($this->file_type[$this->field], $img_mimes, TRUE)) ? TRUE : FALSE;
    }

    // --------------------------------------------------------------------

    /**
     * Verify that the filetype is allowed
     *
     * @access  public
     * @return  bool
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function is_allowed_filetype()
    {
        if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
        {
            $this->set_error('upload_no_file_types');
            return FALSE;
        }

        foreach ($this->allowed_types as $val)
        {
            $mime = $this->mimes_types(strtolower($val));

            if (is_array($mime))
            {
                if (in_array($this->file_type[$this->field], $mime, TRUE))
                {
                    return TRUE;
                }
            }
            else
            {
                if ($mime == $this->file_type[$this->field])
                {
                    return TRUE;
                }
            }
        }

        return FALSE;
    }

    // --------------------------------------------------------------------

    /**
     * Verify that the file is within the allowed size
     *
     * @access  public
     * @return  bool
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function is_allowed_filesize()
    {
        if ($this->max_size != 0  AND  $this->file_size[$this->field] > $this->max_size)
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }

    // --------------------------------------------------------------------

    /**
     * Verify that the image is within the allowed width/height
     *
     * @access  public
     * @return  bool
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function is_allowed_dimensions()
    {
        if ( ! $this->is_image())
        {
            return TRUE;
        }

        if (function_exists('getimagesize'))
        {
            $D = @getimagesize($this->file_temp[$this->field]);

            if ($this->max_width > 0 AND $D['0'] > $this->max_width)
            {
                return FALSE;
            }

            if ($this->max_height > 0 AND $D['1'] > $this->max_height)
            {
                return FALSE;
            }

            return TRUE;
        }

        return TRUE;
    }

    // --------------------------------------------------------------------

    /**
     * Runs the file through the XSS clean function
     *
     * This prevents people from embedding malicious code in their files.
     * I'm not sure that it won't negatively affect certain files in unexpected ways,
     * but so far I haven't found that it causes trouble.
     *
     * @access  public
     * @return  void
     */
    //2009/01/21 KUNIHARU Tsujioka UPDATE
    function do_xss_clean()
    {
        $file = $this->upload_path.$this->file_name[$this->field];

        if (filesize($file) == 0)
        {
            return FALSE;
        }

        if (($data = @file_get_contents($file)) === FALSE)
        {
            return FALSE;
        }

        if ( ! $fp = @fopen($file, FOPEN_READ_WRITE))
        {
            return FALSE;
        }

        $CI =& get_instance();
        $data = $CI->input->xss_clean($data);

        flock($fp, LOCK_EX);
        fwrite($fp, $data);
        flock($fp, LOCK_UN);
        fclose($fp);
    }

    // --------------------------------------------------------------------

}
// END Upload Class

/* End of file Upload.php */
/* Location: ./systemmynets/libraries/MYNETS_Upload.php */

とりあえず、アップロードする回数だけチェックする必要はりますが。