[eluser]mrbinky3000[/eluser]
Okay, I think I've found a genuine bug with the native upload class, or at least an undocumented feature.
First, some info about the version of CI_Upload.php...
Code:
/**
* CodeIgniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
* @license http://ellislab.com/codeigniter/user-guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/
In a nutshell: you can't seem to combine image types and non-image types in the same array of allowed file types.
I will use the source code from the official
File Upload Class documentation page as the base code for this test. Follow the tutorial on that page to create the controller and two views.
Now, in the upload.php controller, append "doc" to the existing list of allowed file types around line 19. like so...
Code:
function do_upload()
{
$config['upload_path'] = $_SERVER['DOCUMENT_ROOT'].'/user_uploads/';
$config['allowed_types'] = 'gif|jpg|png|doc';
$config['max_size'] = '100';
$config['max_width'] = '1024';
$config['max_height'] = '768';
Now, try and upload a Microsoft Word document. It fails saying the following.
Quote:"The filetype you are attempting to upload is not allowed."
Yes, it is allowed. I specifically added it to the list!
Re-edit $config['allowed_types'] and remove everything but 'doc'. Go ahead and ammend some other non-image types. Then try it again.
IT WORKS!
The problem lies in the native uploading class. There is an "if" statement that is triggered if ANY image file types are listed in the $config['allowed_types']
Read the comments in my code for the details.
Code:
/**
* Verify that the filetype is allowed
*
* @access public
* @return bool
*/
function is_allowed_filetype()
{
/*
This is the value of the array $this->allowed_types
array(
['upload_path'] => 'C:/Users/XX/YY/ZZ/uploads/'
['allowed_types'] => 'gif|jpg|png|doc'
['max_size'] => 16000
['max_width'] => 1024
['max_height'] => 768
)
*/
if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
{
$this->set_error('upload_no_file_types');
return FALSE;
}
// "doc" passes the first test.
$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
foreach ($this->allowed_types as $val)
{
/*
The problem starts here. This method loops through all the allowed file types.
$this->allowed_types = array (
[0] => 'gif'
[1] => 'jpg'
[2] => 'png'
[3] => 'doc' <-------------- here is our doc that we added
)
The first time through this foreach loop, $val is set to "gif"
*/
$mime = $this->mimes_types(strtolower($val));
// Images get some additional checks
if (in_array($val, $image_types))
{
/*
$val is set to 'gif' the first time through the foreach loop.
'gif' is in the array of $image_types
$image_types = array(
[0] => 'gif'
[1] => 'jpg'
[2] => 'jpeg'
[3] => 'png'
[4] => 'jpe'
)
*/
if (getimagesize($this->file_temp) === FALSE)
{
/*
WHAT THE HECK? So now we are attempting to get the image size of a doc file.
of course it is going to fail!
*/
return FALSE;
}
}
if (is_array($mime))
{
if (in_array($this->file_type, $mime, TRUE))
{
return TRUE;
}
}
else
{
if ($mime == $this->file_type)
{
return TRUE;
}
}
}
return FALSE;
}
A couple of things. The text for that error message needs to change to "Can't get image size for non-image file" or something less misleading.
Second, WHY test my doc file as an image file in the first place. Why is that foreach loop even there. It should be a switch / case instead or an if statement Psuedo code below...
Code:
if (in_array($my_file_type, $image_file_types))
{
// check the image size and other stuff that pertains to images.
// if any of that stuff fails, return false
}
else
{
// This is NOT an image file, don't try and find the width, height, size, etc.
}