Updated CodeIgniter to v3.1.6

This commit is contained in:
alext 2017-10-31 13:00:34 +01:00
parent 7bfcd87e1d
commit 32e618975a
18 changed files with 179 additions and 97 deletions

View file

@ -34,6 +34,6 @@
"roave/security-advisories": "dev-master", "roave/security-advisories": "dev-master",
"gregwar/captcha": "^1.1", "gregwar/captcha": "^1.1",
"phpmailer/phpmailer": "^5.2", "phpmailer/phpmailer": "^5.2",
"codeigniter/framework": "3.1.5" "codeigniter/framework": "3.1.6"
} }
} }

12
composer.lock generated
View file

@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "9291221da0af4f9eeb4fb70314d354f2", "content-hash": "8c888cb85f0aee3ee5b357c38a3182e4",
"packages": [ "packages": [
{ {
"name": "codeigniter/framework", "name": "codeigniter/framework",
"version": "3.1.5", "version": "3.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/bcit-ci/CodeIgniter.git", "url": "https://github.com/bcit-ci/CodeIgniter.git",
"reference": "6c7a4266410070d30f8f6bcdf9c9e67f3d6478e3" "reference": "7e4f63cd4b792e7dc2dc4b8b0183a6072a3f9462"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/6c7a4266410070d30f8f6bcdf9c9e67f3d6478e3", "url": "https://api.github.com/repos/bcit-ci/CodeIgniter/zipball/7e4f63cd4b792e7dc2dc4b8b0183a6072a3f9462",
"reference": "6c7a4266410070d30f8f6bcdf9c9e67f3d6478e3", "reference": "7e4f63cd4b792e7dc2dc4b8b0183a6072a3f9462",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -37,7 +37,7 @@
], ],
"description": "The CodeIgniter framework", "description": "The CodeIgniter framework",
"homepage": "https://codeigniter.com", "homepage": "https://codeigniter.com",
"time": "2017-06-19T08:33:58+00:00" "time": "2017-09-25T16:43:58+00:00"
}, },
{ {
"name": "gregwar/captcha", "name": "gregwar/captcha",

View file

@ -55,7 +55,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @var string * @var string
* *
*/ */
const CI_VERSION = '3.1.5'; const CI_VERSION = '3.1.6';
/* /*
* ------------------------------------------------------ * ------------------------------------------------------

View file

@ -182,7 +182,7 @@ class CI_Loader {
* Loads and instantiates libraries. * Loads and instantiates libraries.
* Designed to be called from application controllers. * Designed to be called from application controllers.
* *
* @param string $library Library name * @param mixed $library Library name
* @param array $params Optional parameters to pass to the library class constructor * @param array $params Optional parameters to pass to the library class constructor
* @param string $object_name An optional object name to assign to * @param string $object_name An optional object name to assign to
* @return object * @return object
@ -1037,6 +1037,26 @@ class CI_Loader {
return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); return $this->_ci_load_stock_library($class, $subdir, $params, $object_name);
} }
// Safety: Was the class already loaded by a previous call?
if (class_exists($class, FALSE))
{
$property = $object_name;
if (empty($property))
{
$property = strtolower($class);
isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property];
}
$CI =& get_instance();
if (isset($CI->$property))
{
log_message('debug', $class.' class already loaded. Second attempt ignored.');
return;
}
return $this->_ci_init_library($class, '', $params, $object_name);
}
// Let's search for the requested library file and load it. // Let's search for the requested library file and load it.
foreach ($this->_ci_library_paths as $path) foreach ($this->_ci_library_paths as $path)
{ {
@ -1047,27 +1067,8 @@ class CI_Loader {
} }
$filepath = $path.'libraries/'.$subdir.$class.'.php'; $filepath = $path.'libraries/'.$subdir.$class.'.php';
// Safety: Was the class already loaded by a previous call?
if (class_exists($class, FALSE))
{
// Before we deem this to be a duplicate request, let's see
// if a custom object name is being supplied. If so, we'll
// return a new instance of the object
if ($object_name !== NULL)
{
$CI =& get_instance();
if ( ! isset($CI->$object_name))
{
return $this->_ci_init_library($class, '', $params, $object_name);
}
}
log_message('debug', $class.' class already loaded. Second attempt ignored.');
return;
}
// Does the file exist? No? Bummer... // Does the file exist? No? Bummer...
elseif ( ! file_exists($filepath)) if ( ! file_exists($filepath))
{ {
continue; continue;
} }
@ -1112,16 +1113,17 @@ class CI_Loader {
$prefix = config_item('subclass_prefix'); $prefix = config_item('subclass_prefix');
} }
// Before we deem this to be a duplicate request, let's see $property = $object_name;
// if a custom object name is being supplied. If so, we'll if (empty($property))
// return a new instance of the object
if ($object_name !== NULL)
{ {
$CI =& get_instance(); $property = strtolower($library_name);
if ( ! isset($CI->$object_name)) isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property];
{ }
return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
} $CI =& get_instance();
if ( ! isset($CI->$property))
{
return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
} }
log_message('debug', $library_name.' class already loaded. Second attempt ignored.'); log_message('debug', $library_name.' class already loaded. Second attempt ignored.');
@ -1143,10 +1145,8 @@ class CI_Loader {
{ {
return $this->_ci_init_library($library_name, $prefix, $params, $object_name); return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
} }
else
{ log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name);
log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name);
}
} }
} }
@ -1164,10 +1164,8 @@ class CI_Loader {
$prefix = config_item('subclass_prefix'); $prefix = config_item('subclass_prefix');
break; break;
} }
else
{ log_message('debug', $path.' exists, but does not declare '.$subclass);
log_message('debug', $path.' exists, but does not declare '.$subclass);
}
} }
} }

View file

@ -916,6 +916,7 @@ abstract class CI_DB_driver {
if ($this->_trans_begin()) if ($this->_trans_begin())
{ {
$this->_trans_status = TRUE;
$this->_trans_depth++; $this->_trans_depth++;
return TRUE; return TRUE;
} }
@ -1044,7 +1045,7 @@ abstract class CI_DB_driver {
*/ */
public function is_write_type($sql) public function is_write_type($sql)
{ {
return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', $sql); return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX|MERGE)\s/i', $sql);
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------

View file

@ -1403,11 +1403,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// ORDER BY usage is often problematic here (most notably // ORDER BY usage is often problematic here (most notably
// on Microsoft SQL Server) and ultimately unnecessary // on Microsoft SQL Server) and ultimately unnecessary
// for selecting COUNT(*) ... // for selecting COUNT(*) ...
if ( ! empty($this->qb_orderby)) $qb_orderby = $this->qb_orderby;
{ $qb_cache_orderby = $this->qb_cache_orderby;
$orderby = $this->qb_orderby; $this->qb_orderby = $this->qb_cache_orderby = NULL;
$this->qb_orderby = NULL;
}
$result = ($this->qb_distinct === TRUE OR ! empty($this->qb_groupby) OR ! empty($this->qb_cache_groupby) OR $this->qb_limit OR $this->qb_offset) $result = ($this->qb_distinct === TRUE OR ! empty($this->qb_groupby) OR ! empty($this->qb_cache_groupby) OR $this->qb_limit OR $this->qb_offset)
? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results") ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results")
@ -1417,10 +1415,10 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{ {
$this->_reset_select(); $this->_reset_select();
} }
// If we've previously reset the qb_orderby values, get them back else
elseif ( ! isset($this->qb_orderby))
{ {
$this->qb_orderby = $orderby; $this->qb_orderby = $qb_orderby;
$this->qb_cache_orderby = $qb_cache_orderby;
} }
if ($result->num_rows() === 0) if ($result->num_rows() === 0)

View file

@ -453,7 +453,7 @@ class CI_DB_mssql_driver extends CI_DB {
$sql = trim(substr($sql, 0, strrpos($sql, $orderby))); $sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
// Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results
if (count($this->qb_select) === 0) if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE)
{ {
$select = '*'; // Inevitable $select = '*'; // Inevitable
} }

View file

@ -112,9 +112,9 @@ class CI_DB_mysqli_result extends CI_DB_result {
{ {
$retval[$i] = new stdClass(); $retval[$i] = new stdClass();
$retval[$i]->name = $field_data[$i]->name; $retval[$i]->name = $field_data[$i]->name;
$retval[$i]->type = $field_data[$i]->type; $retval[$i]->type = static::_get_field_type($field_data[$i]->type);
$retval[$i]->max_length = $field_data[$i]->max_length; $retval[$i]->max_length = $field_data[$i]->max_length;
$retval[$i]->primary_key = (int) ($field_data[$i]->flags & 2); $retval[$i]->primary_key = (int) ($field_data[$i]->flags & MYSQLI_PRI_KEY_FLAG);
$retval[$i]->default = $field_data[$i]->def; $retval[$i]->default = $field_data[$i]->def;
} }
@ -123,6 +123,60 @@ class CI_DB_mysqli_result extends CI_DB_result {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/**
* Get field type
*
* Extracts field type info from the bitflags returned by
* mysqli_result::fetch_fields()
*
* @used-by CI_DB_mysqli_result::field_data()
* @param int $flags
* @return string
*/
private static function _get_field_type($flags)
{
static $map;
isset($map) OR $map = array(
MYSQLI_TYPE_DECIMAL => 'decimal',
MYSQLI_TYPE_BIT => 'bit',
MYSQLI_TYPE_TINY => 'tinyint',
MYSQLI_TYPE_SHORT => 'smallint',
MYSQLI_TYPE_INT24 => 'mediumint',
MYSQLI_TYPE_LONG => 'int',
MYSQLI_TYPE_LONGLONG => 'bigint',
MYSQLI_TYPE_FLOAT => 'float',
MYSQLI_TYPE_DOUBLE => 'double',
MYSQLI_TYPE_TIMESTAMP => 'timestamp',
MYSQLI_TYPE_DATE => 'date',
MYSQLI_TYPE_TIME => 'time',
MYSQLI_TYPE_DATETIME => 'datetime',
MYSQLI_TYPE_YEAR => 'year',
MYSQLI_TYPE_NEWDATE => 'date',
MYSQLI_TYPE_INTERVAL => 'interval',
MYSQLI_TYPE_ENUM => 'enum',
MYSQLI_TYPE_SET => 'set',
MYSQLI_TYPE_TINY_BLOB => 'tinyblob',
MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob',
MYSQLI_TYPE_BLOB => 'blob',
MYSQLI_TYPE_LONG_BLOB => 'longblob',
MYSQLI_TYPE_STRING => 'char',
MYSQLI_TYPE_VAR_STRING => 'varchar',
MYSQLI_TYPE_GEOMETRY => 'geometry'
);
foreach ($map as $flag => $name)
{
if ($flags & $flag)
{
return $name;
}
}
return $flags;
}
// --------------------------------------------------------------------
/** /**
* Free the result * Free the result
* *

View file

@ -155,9 +155,11 @@ class CI_DB_mysqli_utility extends CI_DB_utility {
while ($field = $query->result_id->fetch_field()) while ($field = $query->result_id->fetch_field())
{ {
// Most versions of MySQL store timestamp as a string // Most versions of MySQL store timestamp as a string
$is_int[$i] = in_array(strtolower($field->type), $is_int[$i] = ($field->type & MYSQLI_TYPE_TINY)
array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), OR ($field->type & MYSQLI_TYPE_SHORT)
TRUE); OR ($field->type & MYSQLI_TYPE_INT24)
OR ($field->type & MYSQLI_TYPE_LONG)
OR ($field->type & MYSQLI_TYPE_LONGLONG);
// Create a string of field names // Create a string of field names
$field_str .= $this->db->escape_identifiers($field->name).', '; $field_str .= $this->db->escape_identifiers($field->name).', ';

View file

@ -284,7 +284,7 @@ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver {
$sql = trim(substr($sql, 0, strrpos($sql, $orderby))); $sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
// Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results
if (count($this->qb_select) === 0) if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE)
{ {
$select = '*'; // Inevitable $select = '*'; // Inevitable
} }
@ -334,4 +334,20 @@ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver {
return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE; return ($this->db_debug) ? $this->display_error('db_unsupported_feature') : FALSE;
} }
// --------------------------------------------------------------------
/**
* Database version number
*
* @return string
*/
public function version()
{
if (isset($this->data_cache['version']))
{
return $this->data_cache['version'];
}
return $this->data_cache['version'] = $this->conn_id->query("SELECT SERVERPROPERTY('ProductVersion') AS ver")->fetchColumn(0);
}
} }

View file

@ -316,7 +316,7 @@ class CI_DB_pdo_sqlsrv_driver extends CI_DB_pdo_driver {
$sql = trim(substr($sql, 0, strrpos($sql, $orderby))); $sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
// Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results
if (count($this->qb_select) === 0) if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE)
{ {
$select = '*'; // Inevitable $select = '*'; // Inevitable
} }

View file

@ -478,7 +478,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
$sql = trim(substr($sql, 0, strrpos($sql, $orderby))); $sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
// Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results
if (count($this->qb_select) === 0) if (count($this->qb_select) === 0 OR strpos(implode(',', $this->qb_select), '*') !== FALSE)
{ {
$select = '*'; // Inevitable $select = '*'; // Inevitable
} }

View file

@ -80,14 +80,7 @@ class CI_Cache_apc extends CI_Driver {
$success = FALSE; $success = FALSE;
$data = apc_fetch($id, $success); $data = apc_fetch($id, $success);
if ($success === TRUE) return ($success === TRUE) ? $data : FALSE;
{
return is_array($data)
? unserialize($data[0])
: $data;
}
return FALSE;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -98,18 +91,12 @@ class CI_Cache_apc extends CI_Driver {
* @param string $id Cache ID * @param string $id Cache ID
* @param mixed $data Data to store * @param mixed $data Data to store
* @param int $ttl Length of time (in seconds) to cache the data * @param int $ttl Length of time (in seconds) to cache the data
* @param bool $raw Whether to store the raw value * @param bool $raw Whether to store the raw value (unused)
* @return bool TRUE on success, FALSE on failure * @return bool TRUE on success, FALSE on failure
*/ */
public function save($id, $data, $ttl = 60, $raw = FALSE) public function save($id, $data, $ttl = 60, $raw = FALSE)
{ {
$ttl = (int) $ttl; return apc_store($id, $data, (int) $ttl);
return apc_store(
$id,
($raw === TRUE ? $data : array(serialize($data), time(), $ttl)),
$ttl
);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -188,21 +175,30 @@ class CI_Cache_apc extends CI_Driver {
*/ */
public function get_metadata($id) public function get_metadata($id)
{ {
$success = FALSE; $cache_info = apc_cache_info('user', FALSE);
$stored = apc_fetch($id, $success); if (empty($cache_info) OR empty($cache_info['cache_list']))
if ($success === FALSE OR count($stored) !== 3)
{ {
return FALSE; return FALSE;
} }
list($data, $time, $ttl) = $stored; foreach ($cache_info['cache_list'] as &$entry)
{
if ($entry['info'] !== $id)
{
continue;
}
return array( $success = FALSE;
'expire' => $time + $ttl, $metadata = array(
'mtime' => $time, 'expire' => ($entry['ttl'] ? $entry['mtime'] + $entry['ttl'] : 0),
'data' => unserialize($data) 'mtime' => $entry['ttl'],
); 'data' => apc_fetch($id, $success)
);
return ($success === TRUE) ? $metadata : FALSE;
}
return FALSE;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View file

@ -972,7 +972,7 @@ class CI_Image_lib {
$cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height; $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
} }
$cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp'; $cmd = $this->library_path.$cmd_in.' '.escapeshellarg($this->full_src_path).' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
$retval = 1; $retval = 1;
// exec() might be disabled // exec() might be disabled

View file

@ -484,13 +484,19 @@ class CI_Profiler {
foreach ($this->CI->config->config as $config => $val) foreach ($this->CI->config->config as $config => $val)
{ {
$pre = '';
$pre_close = '';
if (is_array($val) OR is_object($val)) if (is_array($val) OR is_object($val))
{ {
$val = print_r($val, TRUE); $val = print_r($val, TRUE);
$pre = '<pre>' ;
$pre_close = '</pre>';
} }
$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">' $output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
.$config.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.htmlspecialchars($val, ENT_QUOTES, config_item('charset'))."</td></tr>\n"; .$config.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.$pre.htmlspecialchars($val, ENT_QUOTES, config_item('charset')).$pre_close."</td></tr>\n";
} }
return $output."</table>\n</fieldset>"; return $output."</table>\n</fieldset>";
@ -516,13 +522,19 @@ class CI_Profiler {
foreach ($this->CI->session->userdata() as $key => $val) foreach ($this->CI->session->userdata() as $key => $val)
{ {
$pre = '';
$pre_close = '';
if (is_array($val) OR is_object($val)) if (is_array($val) OR is_object($val))
{ {
$val = print_r($val, TRUE); $val = print_r($val, TRUE);
$pre = '<pre>' ;
$pre_close = '</pre>';
} }
$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">' $output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
.$key.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.htmlspecialchars($val, ENT_QUOTES, config_item('charset'))."</td></tr>\n"; .$key.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.$pre.htmlspecialchars($val, ENT_QUOTES, config_item('charset')).$pre_close."</td></tr>\n";
} }
return $output."</table>\n</fieldset>"; return $output."</table>\n</fieldset>";

View file

@ -310,7 +310,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
if ( ! $this->_memcached->replace($this->_lock_key, time(), 300)) if ( ! $this->_memcached->replace($this->_lock_key, time(), 300))
{ {
return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND)
? $this->_memcached->set($this->_lock_key, time(), 300) ? $this->_memcached->add($this->_lock_key, time(), 300)
: FALSE; : FALSE;
} }
} }
@ -326,7 +326,8 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
continue; continue;
} }
if ( ! $this->_memcached->set($lock_key, time(), 300)) $method = ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) ? 'add' : 'set';
if ( ! $this->_memcached->$method($lock_key, time(), 300))
{ {
log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id);
return FALSE; return FALSE;

View file

@ -341,7 +341,11 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
continue; continue;
} }
if ( ! $this->_redis->setex($lock_key, 300, time())) $result = ($ttl === -2)
? $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300))
: $this->_redis->setex($lock_key, 300, time());
if ( ! $result)
{ {
log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id);
return FALSE; return FALSE;

View file

@ -1312,7 +1312,7 @@ class CI_Upload {
} }
} }
// Fall back to the deprecated mime_content_type(), if available (still better than $_FILES[$field]['type']) // Fall back to mime_content_type(), if available (still better than $_FILES[$field]['type'])
if (function_exists('mime_content_type')) if (function_exists('mime_content_type'))
{ {
$this->file_type = @mime_content_type($file['tmp_name']); $this->file_type = @mime_content_type($file['tmp_name']);