Hi,
I had the same issue
!
And after loosing some long hours doing some debuging on every side of the problem (browser side: JS, Networking, etc., server side: web-server, php-config, memcache config, Filesystem: owners, permissions, disk-space, etc.
)
, I found out that somehow the exec_hook "attachment_upload" is called twice (don't know why
because I'm not a dev-guy for roundcube, neither PHP OOP
) :
1. first call somehow alters(empty) the value of args['path'] (loosing the original uploaded file), than
2. at the second exec_hook calls the function upload() (from plugins/filesystem_attachments/filesystem_attachments.php), having this argument altered(emptied) already because as comments from above definition of the function exec_hook() says:
The (probably) altered hook arguments
, this already happened ( that "probably" should be emphasised
) :
./program/lib/Roundcube/rcube_plugin_api.php :
/**
* Triggers a plugin hook.
* This is called from the application and executes all registered handlers
*
* @param string $hook Hook name
* @param array $args Named arguments (key->value pairs)
*
* @return array The (probably) altered hook arguments
*/
public function exec_hook($hook, $args = array())
{
if (!is_array($args)) {
$args = array('arg' => $args);
}
// TODO: avoid recursion by checking in_array($hook, $this->exec_stack) ?
$args += array('abort' => false);
array_push($this->exec_stack, $hook);
// Use for loop here, so handlers added in the hook will be executed too
for ($i = 0; $i < count($this->handlers[$hook]); $i++) {
if ($hook=="attachment_upload") error_log("debug: exec_hook(".$hook."): i=$i, args = ".print_r($args, true));
$ret = call_user_func($this->handlers[$hook][$i], $args);
if ($hook=="attachment_upload") error_log("debug: exec_hook(".$hook."): i=$i, ret = ".print_r($ret, true));
if ($ret && is_array($ret)) {
$args = $ret + $args;
}
if ($args['break']) {
break;
}
}
array_pop($this->exec_stack);
return $args;
}
The temporary fix that it seems to work for the moment for me, was to add a backup value stored as key "uploaded_full_path" (beside existing "path") in the constructed args array from program/steps/mail/attachments.inc at line 123, like below:
// handle file(s) upload
if (is_array($_FILES['_attachments']['tmp_name'])) {
$multiple = count($_FILES['_attachments']['tmp_name']) > 1;
foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
// Process uploaded attachment if there is no error
$err = $_FILES['_attachments']['error'][$i];
if (!$err) {
$attachment = $RCMAIL->plugins->exec_hook('attachment_upload', array(
'uploaded_full_path' => $filepath,
'path' => $filepath,
'size' => $_FILES['_attachments']['size'][$i],
'name' => $_FILES['_attachments']['name'][$i],
'mimetype' => rcube_mime::file_content_type($filepath, $_FILES['_attachments']['name'][$i], $_FILES['_attachments']['type'][$i]),
'group' => $COMPOSE_ID,
));
}
than to change the used value by move_uploaded_file() in upload() function in plugins/filesystem_attachments/filesystem_attachments.php, from $args['path'] to $args['uploaded_full_path'], like below:
/**
* Save a newly uploaded attachment
*/
function upload($args)
{
$args['status'] = false;
$group = $args['group'];
$rcmail = rcube::get_instance();
// use common temp dir for file uploads
$temp_dir = $rcmail->config->get('temp_dir');
$tmpfname = tempnam($temp_dir, 'rcmAttmnt');
if (move_uploaded_file($args['uploaded_full_path'], $tmpfname) && file_exists($tmpfname)) {
$args['id'] = $this->file_id();
$args['path'] = $tmpfname;
$args['status'] = true;
@chmod($tmpfname, 0600); // set correct permissions (#1488996)
// Note the file for later cleanup
$_SESSION['plugins']['filesystem_attachments'][$group][$args['id']] = $tmpfname;
}
return $args;
}
Proving logs (after I've added some debugs):
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: Array
(
[_attachments] => Array
(
[name] => Array
(
[0] => IMG-20180315-WA0026.jpg
)
[type] => Array
(
[0] => image/jpeg
)
[tmp_name] => Array
(
[0] => /var/lib/roundcube/uploads/php9MztBt
)
[error] => Array
(
[0] => 0
)
[size] => Array
(
[0] => 81506
)
)
)
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: i=0 filepath=/var/lib/roundcube/uploads/php9MztBt err=0
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=0, args = Array
(
[uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
[path] => /var/lib/roundcube/uploads/php9MztBt
[size] => 81506
[name] => IMG-20180315-WA0026.jpg
[mimetype] => image/jpeg
[group] => 1606078455aab1a19cacae
[abort] =>
)
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=0, ret = Array
(
[uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
[path] =>
[size] => 81506
[name] => IMG-20180315-WA0026.jpg
[mimetype] => image/jpeg
[group] => 1606078455aab1a19cacae
[abort] =>
[status] => 1
[id] => 1606078455aab1a19cacae71e3f4515469c99be6682965159bc06a
)
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=1, args = Array
(
[uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
[path] =>
[size] => 81506
[name] => IMG-20180315-WA0026.jpg
[mimetype] => image/jpeg
[group] => 1606078455aab1a19cacae
[abort] =>
[status] => 1
[id] => 1606078455aab1a19cacae71e3f4515469c99be6682965159bc06a
)
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: upload(args= Array
(
[uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
[path] =>
[size] => 81506
[name] => IMG-20180315-WA0026.jpg
[mimetype] => image/jpeg
[group] => 1606078455aab1a19cacae
[abort] =>
[status] =>
[id] => 1606078455aab1a19cacae71e3f4515469c99be6682965159bc06a
)
)
[16-Mar-2018 04:06:46 Europe/Bucharest] debug: exec_hook(attachment_upload): i=1, ret = Array
(
[uploaded_full_path] => /var/lib/roundcube/uploads/php9MztBt
[path] => /var/lib/roundcube/temp/rcmAttmnt9y92Px
[size] => 81506
[name] => IMG-20180315-WA0026.jpg
[mimetype] => image/jpeg
[group] => 1606078455aab1a19cacae
[abort] =>
[status] => 1
[id] => 1181521166006064803400
)
P.S.: My Roundcube version is the latest from Ubuntu LTS 16.04: roundcube-1.2~beta+dfsg.1-0ubuntu1.