$fn = uniqid('fax-' . time() . '-', true);
$filename = preg_replace('/\./','_', $fn) . '.xml';
Should do it.
Test:
$parts = explode('.', $filename);
$ext = array_pop($parts);
$filename = array_shift($parts);
foreach ($parts as $part)
{
if ( 1==1)
{
$filename .= '.'.$part.'_';
}
else
{
$filename .= '.'.$part;
}
}
$filename .= '.'.$ext;
echo $filename;//fax-1377117024-52152360903ae2_02709878.xml
It looks like what's happening is the _prep_filename() method in Upload.php checks the allowed_types and mimes_types against the exploded filename. The period in your filename splits off the last number before the extension (65243756 in your example filename) into the parts array. It then checks this value against allowed_types and mimes_types. Unable to find the number in allowed_types nor in mimes_types, it appends the underscore.
It's a strange issue. See here for more info: https://github.com/EllisLab/CodeIgniter/issues/1380
Breaking it down:
// system/core/libraries/Upload.php
// line 984
protected function _prep_filename($filename)
{
if (strpos($filename, '.') === FALSE OR $this->allowed_types == '*')
{
return $filename;
}
$parts = explode('.', $filename);
$ext = array_pop($parts);
$filename = array_shift($parts);
foreach ($parts as $part)
{
if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
{
$filename .= '.'.$part.'_';
}
else
{
$filename .= '.'.$part;
}
}
$filename .= '.'.$ext;
return $filename;
}
Given file name fax-1377114300-521518bca7c5a7.65243756.xml, this is what happens.
$parts = explode('.', $filename);
this breaks up $filename into an array containing 3 values:
print_r($parts); //Array ( [0] => fax-1377119574-52152d561f4694 [1] => 21065888 [2] => xml )
next line...
$ext = array_pop($parts);
pops the $parts array:
print_r($parts); //Array ( [0] => fax-1377119706-52152dda0205e5 [1] => 29551151 )
next line...
$filename = array_shift($parts);
shifts the array:
print_r($parts); //Array ( [0] => 39795691 )
so that now $parts contains only one item: 39795691.
Now it runs
foreach ($parts as $part)
{
if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
{
$filename .= '.'.$part.'_';
}
else
{
$filename .= '.'.$part;
}
}
which checks to see if any of the values in $parts (remember, in this case we only have the one item: 39795691) is in the allowed_types or mime_types arrays. Since it's a number and isn't in either of those arrays, it concatenates the part into the $filename variable and appends the underscore.
'remove_spaces' => FALSEto your config array and see if that takes care of the problem. This is set to TRUE by default, but it should only be replacing spaces with underscores. It could be a CI bug with the file uploading class.remove_spacesoption should have worked. See also techques.com/question/1-5728059/…Line 994, _prep_filename()function insystem->libraries->Upload.php file.taken from this page ch.runcode.us/q/…