diff --git a/file.php b/file.php index 994b77a0c2256a0218a27ffebb01b1c7d77a344b..00193f7a0b4b810964d9388a2a9a893f00406907 100644 --- a/file.php +++ b/file.php @@ -28,10 +28,11 @@ if (!$_GET['key'] // Get the object type the file is attached to $type = ''; +$attachment = null; if ($_GET['id'] - && ($a=$file->attachments->findFirst(array( + && ($attachment=$file->attachments->findFirst(array( 'id' => $_GET['id'])))) - $type = $a->type; + $type = $attachment->type; // Enforce security settings if enabled. if ($cfg->isAuthRequiredForFiles() @@ -62,7 +63,9 @@ if ($file->verifySignature($_GET['signature'], $_GET['expires'])) { return $file->display($s); // Download the file.. - $file->download(@$_GET['disposition'] ?: false, $_GET['expires']); + $filename = $attachment ? $attachment->name : $file->getName(); + $disposition = @$_GET['disposition'] ?: false; + $file->download($filename, $disposition, @$_GET['expires']); } catch (Exception $ex) { Http::response(500, 'Unable to find that file: '.$ex->getMessage()); diff --git a/include/ajax.tasks.php b/include/ajax.tasks.php index 4cc99a0d614f569e06ff1f43c6ae84303f3abe40..cd85cf613cbf696280ae79182946d6c9e6b46fea 100644 --- a/include/ajax.tasks.php +++ b/include/ajax.tasks.php @@ -113,7 +113,7 @@ class TasksAjaxAPI extends AjaxController { if ($desc && $desc->isAttachmentsEnabled() && ($attachments=$desc->getWidget()->getAttachments())) - $vars['cannedattachments'] = $attachments->getClean(); + $vars['files'] = $attachments->getFiles(); $vars['staffId'] = $thisstaff->getId(); $vars['poster'] = $thisstaff; $vars['ip_address'] = $_SERVER['REMOTE_ADDR']; @@ -811,9 +811,9 @@ class TasksAjaxAPI extends AjaxController { switch ($_POST['a']) { case 'postnote': $vars = $_POST; - $attachments = $note_form->getField('attachments')->getClean(); - $vars['cannedattachments'] = array_merge( - $vars['cannedattachments'] ?: array(), $attachments); + $attachments = $note_form->getField('attachments')->getFiles(); + $vars['files'] = array_merge( + $vars['files'] ?: array(), $attachments); if(($note=$task->postNote($vars, $errors, $thisstaff))) { $msg=__('Note posted successfully'); // Clear attachment list diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index a529c193862912a97be84195e512f1bbaa320710..2864efda74a09e4c5ceed50e699f15edbff6f5ef 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -1408,7 +1408,7 @@ function refer($tid, $target=null) { if ($desc && $desc->isAttachmentsEnabled() && ($attachments=$desc->getWidget()->getAttachments())) - $vars['cannedattachments'] = $attachments->getClean(); + $vars['files'] = $attachments->getFiles(); $vars['staffId'] = $thisstaff->getId(); $vars['poster'] = $thisstaff; $vars['ip_address'] = $_SERVER['REMOTE_ADDR']; @@ -1490,9 +1490,9 @@ function refer($tid, $target=null) { $vars = $_POST; switch ($_POST['a']) { case 'postnote': - $attachments = $note_attachments_form->getField('attachments')->getClean(); - $vars['cannedattachments'] = array_merge( - $vars['cannedattachments'] ?: array(), $attachments); + $attachments = $note_attachments_form->getField('attachments')->getFiles(); + $vars['files'] = array_merge( + $vars['files'] ?: array(), $attachments); if (($note=$task->postNote($vars, $errors, $thisstaff))) { $msg=__('Note posted successfully'); // Clear attachment list @@ -1506,9 +1506,9 @@ function refer($tid, $target=null) { } break; case 'postreply': - $attachments = $reply_attachments_form->getField('attachments')->getClean(); - $vars['cannedattachments'] = array_merge( - $vars['cannedattachments'] ?: array(), $attachments); + $attachments = $reply_attachments_form->getField('attachments')->getFiles(); + $vars['files'] = array_merge( + $vars['files'] ?: array(), $attachments); if (($response=$task->postReply($vars, $errors))) { $msg=__('Update posted successfully'); // Clear attachment list diff --git a/include/class.attachment.php b/include/class.attachment.php index 9c6cd7c40b6e980b1e387e341b135ca9840f0082..bb5e8e292f11aa0342f82299f7d2b5c1bec04dd8 100644 --- a/include/class.attachment.php +++ b/include/class.attachment.php @@ -60,6 +60,10 @@ class Attachment extends VerySimpleModel { return $this->name ?: $this->file->name; } + function getName() { + return $this->getFilename(); + } + function getHashtable() { return $this->ht; } @@ -133,7 +137,7 @@ extends InstrumentedList { foreach ($files as $file) { if (is_numeric($file)) $fileId = $file; - elseif (is_array($file) && isset($file['id']) && $file['id'] != 0) + elseif (is_array($file) && isset($file['id']) && $file['id']) $fileId = $file['id']; elseif (isset($file['tmp_name']) && ($F = AttachmentFile::upload($file))) $fileId = $F->getId(); diff --git a/include/class.canned.php b/include/class.canned.php index 21cd9aa6367f2b4ec81959d1790177fbb751ad65..388420c5f541a7667f7d3c33a020df5000a68b36 100644 --- a/include/class.canned.php +++ b/include/class.canned.php @@ -138,7 +138,7 @@ extends VerySimpleModel { $resp['files'] = array(); foreach ($this->getAttachedFiles(!$html) as $file) { - $_SESSION[':cannedFiles'][$file->id] = 1; + $_SESSION[':cannedFiles'][$file->id] = $file->name; $resp['files'][] = array( 'id' => $file->id, 'name' => $file->name, diff --git a/include/class.file.php b/include/class.file.php index d880840861b09065a34cd275ebb726773d82e105..e61b5afe76516fcecfd880359bb6193c13164b4e 100644 --- a/include/class.file.php +++ b/include/class.file.php @@ -248,7 +248,7 @@ class AttachmentFile extends VerySimpleModel { return hash_hmac('sha1', implode("\n", $pieces), SECRET_SALT); } - function download($disposition=false, $expires=false) { + function download($name=false, $disposition=false, $expires=false) { $disposition = $disposition ?: 'inline'; $bk = $this->open(); if ($bk->sendRedirectUrl($disposition)) @@ -258,7 +258,7 @@ class AttachmentFile extends VerySimpleModel { $type = $this->getType() ?: 'application/octet-stream'; if (isset($_REQUEST['overridetype'])) $type = $_REQUEST['overridetype']; - Http::download($this->getName(), $type, null, 'inline'); + Http::download($name ?: $this->getName(), $type, null, 'inline'); header('Content-Length: '.$this->getSize()); $this->sendData(false); exit(); diff --git a/include/class.forms.php b/include/class.forms.php index 760ea76d051175783a240ac1a03e1a9912457e87..c9985089b344b1c8836f91ed596f13f47d1436d8 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -3402,6 +3402,10 @@ class FileUploadField extends FormField { if ($a && ($f=$a->getFile())) $files[] = $f; } + + foreach (@$this->getClean() as $key => $value) + $files[] = array('id' => $key, 'name' => $value); + $this->files = $files; } return $this->files; @@ -3472,9 +3476,7 @@ class FileUploadField extends FormField { } function parse($value) { - // Values in the database should be integer file-ids - return array_map(function($e) { return (int) $e; }, - $value ?: array()); + return $value; } function to_php($value) { @@ -4464,6 +4466,7 @@ class FileUploadWidget extends Widget { $F = AttachmentFile::objects() ->filter(array('id__in' => array_keys($new))) ->all(); + foreach ($F as $f) { $f->tmp_name = $new[$f->getId()]; $files[] = array( @@ -4512,7 +4515,7 @@ class FileUploadWidget extends Widget { foreach (AttachmentFile::format($_FILES[$this->name]) as $file) { try { $F = $this->field->uploadFile($file); - $ids[] = $F->getId(); + $ids[$F->getId()] = $F->getName(); } catch (FileUploadError $ex) {} } @@ -4523,17 +4526,17 @@ class FileUploadWidget extends Widget { // identified in the session // // If no value was sent, assume an empty list - if (!($_files = parent::getValue())) + if (!($files = parent::getValue())) return array(); if ($_SERVER['REQUEST_METHOD'] == 'POST') { - foreach ($_files as $info) { - if (@list($id,$name) = explode(',', $info, 2)) - $files[$id] = $name; + $_files = array(); + foreach ($files as $info) { + if (@list($id, $name) = explode(',', $info, 2)) + $_files[$id] = $name; } + $files = $_files; } - else - $files = $_files; $allowed = array(); // Files already attached to the field are allowed @@ -4556,7 +4559,7 @@ class FileUploadWidget extends Widget { continue; // Keep the values as the IDs - $ids[$id] = $name ?: $allowed[$id] ?: $id; + $ids[$id] = $name; } return $ids; diff --git a/include/class.thread.php b/include/class.thread.php index 59d864060708003ca72a0439fef703752551fc62..481a34835aed3ce179a8c83bf8e07b3ed3b84596 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -1084,10 +1084,9 @@ implements TemplateVariable { $ids = array(); foreach ($files as $id => $info) { $F = array('inline' => is_array($info) && @$info['inline']); + $AF = null; - if (is_numeric($id) && $id != 0) - $fileId = $id; - elseif ($info instanceof AttachmentFile) + if ($info instanceof AttachmentFile) $fileId = $info->getId(); elseif (is_array($info) && isset($info['id'])) $fileId = $info['id']; @@ -1095,8 +1094,8 @@ implements TemplateVariable { $fileId = $AF->getId(); elseif ($add_error) { $error = $info['error'] - ?: sprintf(_S('Unable to import attachment - %s'), - $id ?: $info['name']); + ?: sprintf(_S('Unable to save attachment - %s'), + $info['name'] ?: $info['id']); if (is_numeric($error) && isset($error_descriptions[$error])) { $error = sprintf(_S('Error #%1$d: %2$s'), $error, _S($error_descriptions[$error])); @@ -1157,11 +1156,13 @@ implements TemplateVariable { elseif (is_string($name)) { $filename = $name; } + if ($filename) { // This should be a noop since the ORM caches on PK $F = @$file['file'] ?: AttachmentFile::lookup($file['id']); // XXX: This is not Unicode safe - if ($F && 0 !== strcasecmp($F->name, $filename)) + // TODO: fix name lookup + if ($F && strcasecmp($F->name, $filename) !== 0) $att->name = $filename; } @@ -1578,7 +1579,7 @@ implements TemplateVariable { $attached_files = array(); foreach (array( // Web uploads and canned attachments - $vars['files'], $vars['cannedattachments'], + $vars['files'], // Emailed or API attachments $vars['attachments'], // Inline images (attached to the draft) diff --git a/include/class.ticket.php b/include/class.ticket.php index 550785e5c3ecc13fabf8f5799c19e678f1798678..43446e89e67ed43a885f61045ec3266f3f1efbc2 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -2837,9 +2837,9 @@ implements RestrictedAccess, Threadable, Searchable { return false; } $files = array(); - foreach ($canned->attachments->getAll() as $file) { - $files[] = $file->file_id; - $_SESSION[':cannedFiles'][$file->file_id] = 1; + foreach ($canned->attachments->getAll() as $att) { + $files[] = array('id' => $att->file_id, 'name' => $att->getName()); + $_SESSION[':cannedFiles'][$att->file_id] = $att->getName(); } if ($cfg->isRichTextEnabled()) @@ -2852,7 +2852,7 @@ implements RestrictedAccess, Threadable, Searchable { $info = array('msgId' => $message instanceof ThreadEntry ? $message->getId() : 0, 'poster' => __('SYSTEM (Canned Reply)'), 'response' => $response, - 'cannedattachments' => $files + 'files' => $files ); $errors = array(); if (!($response=$this->postReply($info, $errors, false, false))) @@ -4088,8 +4088,8 @@ implements RestrictedAccess, Threadable, Searchable { $vars['note'] = ThreadEntryBody::clean($vars['note']); $create_vars = $vars; $tform = TicketForm::objects()->one()->getForm($create_vars); - $create_vars['cannedattachments'] - = $tform->getField('message')->getWidget()->getAttachments()->getClean(); + $create_vars['files'] + = $tform->getField('message')->getWidget()->getAttachments()->getFiles(); if (!($ticket=self::create($create_vars, $errors, 'staff', false))) return false; diff --git a/open.php b/open.php index a507bc979515181f5d46eb035a8ccaf9ade92e59..ef1dde53285c8d406c3ba5406fcb3f52df151854 100644 --- a/open.php +++ b/open.php @@ -33,7 +33,7 @@ if ($_POST) { $messageField = $tform->getField('message'); $attachments = $messageField->getWidget()->getAttachments(); if (!$errors && $messageField->isAttachmentsEnabled()) - $vars['cannedattachments'] = $attachments->getClean(); + $vars['files'] = $attachments->getFiles(); // Drop the draft.. If there are validation errors, the content // submitted will be displayed back to the user diff --git a/scp/tasks.php b/scp/tasks.php index aa8fc88793d858957ede515d756eac951e094c36..5375261863e375f72e088b9958b80967299383b3 100644 --- a/scp/tasks.php +++ b/scp/tasks.php @@ -48,7 +48,7 @@ if($_POST && !$errors): switch(strtolower($_POST['a'])): case 'postnote': /* Post Internal Note */ $vars = $_POST; - $vars['cannedattachments'] = $note_attachments_form->getField('attachments')->getClean(); + $vars['files'] = $note_attachments_form->getField('attachments')->getFiles(); $wasOpen = ($task->isOpen()); if(($note=$task->postNote($vars, $errors, $thisstaff))) { @@ -76,7 +76,7 @@ if($_POST && !$errors): break; case 'postreply': /* Post an update */ $vars = $_POST; - $vars['cannedattachments'] = $reply_attachments_form->getField('attachments')->getClean(); + $vars['files'] = $reply_attachments_form->getField('attachments')->getFiles(); $wasOpen = ($task->isOpen()); if (($response=$task->postReply($vars, $errors))) { diff --git a/scp/tickets.php b/scp/tickets.php index e9c310f4fdd9e5cc2c136024a94e83ca1962a1ab..d100f38d7b1af8e1505301922754e5925bc264dc 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -149,7 +149,7 @@ if($_POST && !$errors): $errors['err'] = __('Action denied. Contact admin for access'); } else { $vars = $_POST; - $vars['cannedattachments'] = $response_form->getField('attachments')->getClean(); + $vars['files'] = $response_form->getField('attachments')->getFiles(); $vars['response'] = ThreadEntryBody::clean($vars['response']); if(!$vars['response']) $errors['response']=__('Response required'); @@ -211,7 +211,7 @@ if($_POST && !$errors): break; case 'postnote': /* Post Internal Note */ $vars = $_POST; - $vars['cannedattachments'] = $note_form->getField('attachments')->getClean(); + $vars['files'] = $note_form->getField('attachments')->getFiles(); $vars['note'] = ThreadEntryBody::clean($vars['note']); if ($cfg->isTicketLockEnabled()) { @@ -403,7 +403,7 @@ if($_POST && !$errors): if ($vars['uid'] && !($user=User::lookup($vars['uid']))) $vars['uid'] = 0; - $vars['cannedattachments'] = $response_form->getField('attachments')->getClean(); + $vars['files'] = $response_form->getField('attachments')->getFiles(); if(($ticket=Ticket::open($vars, $errors))) { $msg=__('Ticket created successfully'); diff --git a/tickets.php b/tickets.php index fa88e5e55775b4aeff32dda04841b35eed6fc178..560b16f3dc963008e05aa8c610607b82992fee95 100644 --- a/tickets.php +++ b/tickets.php @@ -84,7 +84,7 @@ if ($_POST && is_object($ticket) && $ticket->getId()) { 'poster' => (string) $thisclient->getName(), 'message' => $_POST['message'] ); - $vars['cannedattachments'] = $attachments->getClean(); + $vars['files'] = $attachments->getFiles(); if (isset($_POST['draft_id'])) $vars['draft_id'] = $_POST['draft_id'];