diff --git a/include/class.attachment.php b/include/class.attachment.php index 3247d06912d8baafaa895843556b6236f809a35d..cd2ef95ac8586ece6a790311be897c435fb87e9f 100644 --- a/include/class.attachment.php +++ b/include/class.attachment.php @@ -56,6 +56,10 @@ class Attachment extends VerySimpleModel { return $this->file; } + function getFilename() { + return $this->name ?: $this->file->name; + } + function getHashtable() { return $this->ht; } @@ -112,7 +116,8 @@ class GenericAttachments { function upload($files, $inline=false, $lang=false) { $i=array(); - if (!is_array($files)) $files=array($files); + if (!is_array($files)) + $files = array($files); foreach ($files as $file) { if (is_numeric($file)) $fileId = $file; @@ -131,6 +136,17 @@ class GenericAttachments { 'file_id' => $fileId, 'inline' => $_inline ? 1 : 0, )); + + // Record varying file names in the attachment record + if (is_array($file) && isset($file['name'])) { + $filename = $file['name']; + } + if ($filename) { + // This should be a noop since the ORM caches on PK + $file = AttachmentFile::lookup($fileId); + if ($file->name != $filename) + $att->name = $filename; + } if ($lang) $att->lang = $lang; diff --git a/include/class.forms.php b/include/class.forms.php index 9f4ece823e177d93a81a0df42d2a2f97923edc12..5a3302259f0d45c5f63aef02df47cd8881648951 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -3123,6 +3123,14 @@ class FileUploadWidget extends Widget { function getValue() { $data = $this->field->getSource(); $ids = array(); + $base = parent::getValue(); + if (is_array($base)) { + foreach ($base as $info) { + list($id, $name) = explode(',', $info, 2); + // Keep the values as the IDs + $ids[$name] = $id; + } + } // Handle manual uploads (IE<10) if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES[$this->name])) { foreach (AttachmentFile::format($_FILES[$this->name]) as $file) { @@ -3132,13 +3140,13 @@ class FileUploadWidget extends Widget { } catch (FileUploadError $ex) {} } - return array_merge($ids, parent::getValue() ?: array()); + return $ids; } // If no value was sent, assume an empty list elseif ($data && is_array($data) && !isset($data[$this->name])) return array(); - return parent::getValue(); + return $ids; } } diff --git a/include/class.mailer.php b/include/class.mailer.php index 83f097050624924326e9da6b22e90eeb041f5deb..2665944089e6bbc72c4b1a71a48e780d1879bb37 100644 --- a/include/class.mailer.php +++ b/include/class.mailer.php @@ -82,7 +82,7 @@ class Mailer { function addAttachment(Attachment $attachment) { // XXX: This looks too assuming; however, the attachment processor // in the ::send() method seems hard coded to expect this format - $this->attachments[$attachment->file_id] = $attachment->file; + $this->attachments[$attachment->file_id] = $attachment; } function addFile(AttachmentFile $file) { @@ -433,7 +433,10 @@ class Mailer { $file = false; foreach ($self->attachments as $id=>$F) { if (strcasecmp($F->getKey(), $match[1]) === 0) { - $file = $F; + if ($F instanceof Attachment) + $file = $F->getFile(); + else + $file = $F; break; } } @@ -452,8 +455,16 @@ class Mailer { //XXX: Attachments if(($attachments=$this->getAttachments())) { foreach($attachments as $id=>$file) { + // Read the filename from the Attachment if possible + if ($file instanceof Attachment) { + $filename = $file->getFilename(); + $file = $file->getFile(); + } + else { + $filename = $file->getName(); + } $mime->addAttachment($file->getData(), - $file->getType(), $file->getName(),false); + $file->getType(), $filename, false); } } diff --git a/include/class.thread.php b/include/class.thread.php index b228fd63e3d3de9f083b45314d5bebbcd4947dae..d1439b243c8e4257b58c994c009c139b29fd01ba 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -877,7 +877,7 @@ implements TemplateVariable { Save attachment to the DB. @file is a mixed var - can be ID or file hashtable. */ - function saveAttachment(&$file) { + function saveAttachment(&$file, $name=false) { $inline = is_array($file) && @$file['inline']; @@ -898,6 +898,21 @@ implements TemplateVariable { 'file_id' => $fileId, 'inline' => $inline ? 1 : 0, )); + + // Record varying file names in the attachment record + if (is_array($file) && isset($file['name'])) { + $filename = $file['name']; + } + elseif (is_string($name)) { + $filename = $name; + } + if ($filename) { + // This should be a noop since the ORM caches on PK + $file = AttachmentFile::lookup($fileId); + if ($file->name != $filename) + $att->name = $filename; + } + if (!$att->save()) return false; return $att; @@ -905,9 +920,10 @@ implements TemplateVariable { function saveAttachments($files) { $attachments = array(); - foreach ($files as $file) - if (($A = $this->saveAttachment($file))) + foreach ($files as $name=>$file) { + if (($A = $this->saveAttachment($file, $name))) $attachments[] = $A; + } return $attachments; } @@ -921,7 +937,7 @@ implements TemplateVariable { foreach ($this->attachments as $att) { $json[$att->file->getKey()] = array( 'download_url' => $att->file->getDownloadUrl(), - 'filename' => $att->file->name, + 'filename' => $att->getFilename(), ); } diff --git a/include/client/templates/thread-entry.tmpl.php b/include/client/templates/thread-entry.tmpl.php index fe9f686e8201d0e1ee66551dd0d29e55c6ec7039..70e4bbb5c6fae24ba42a48a2c67520b044d03e58 100644 --- a/include/client/templates/thread-entry.tmpl.php +++ b/include/client/templates/thread-entry.tmpl.php @@ -70,8 +70,8 @@ if ($user && ($url = $user->get_gravatar(48))) <span class="attachment-info"> <i class="icon-paperclip icon-flip-horizontal"></i> <a class="no-pjax truncate filename" href="<?php echo $A->file->getDownloadUrl(); - ?>" download="<?php echo Format::htmlchars($A->file->name); ?>" - target="_blank"><?php echo Format::htmlchars($A->file->name); + ?>" download="<?php echo Format::htmlchars($A->getFilename()); ?>" + target="_blank"><?php echo Format::htmlchars($A->getFilename()); ?></a><?php echo $size;?> </span> <?php } ?> diff --git a/include/staff/templates/thread-entry.tmpl.php b/include/staff/templates/thread-entry.tmpl.php index f06b376ef463876cfcbcc5df7737acde11d34cd9..01839aac5e37639df635dfc366cb289a159242a8 100644 --- a/include/staff/templates/thread-entry.tmpl.php +++ b/include/staff/templates/thread-entry.tmpl.php @@ -70,8 +70,8 @@ if ($user && ($url = $user->get_gravatar(48))) <span class="attachment-info"> <i class="icon-paperclip icon-flip-horizontal"></i> <a class="no-pjax truncate filename" href="<?php echo $A->file->getDownloadUrl(); - ?>" download="<?php echo Format::htmlchars($A->file->name); ?>" - target="_blank"><?php echo Format::htmlchars($A->file->name); + ?>" download="<?php echo Format::htmlchars($A->getFilename()); ?>" + target="_blank"><?php echo Format::htmlchars($A->getFilename()); ?></a><?php echo $size;?> </span> <?php } ?> diff --git a/include/upgrader/streams/core/9143a511-00000000.patch.sql b/include/upgrader/streams/core/9143a511-00000000.patch.sql index 83bfa49cc58d80a53dc9b873e55eee5b5ebf7767..dd28bbed98dfcff312264e17889231ab9f4547e7 100644 --- a/include/upgrader/streams/core/9143a511-00000000.patch.sql +++ b/include/upgrader/streams/core/9143a511-00000000.patch.sql @@ -1,6 +1,6 @@ /** * @signature 959aca6ed189cd918d227a3ea8a135a3 - * @version v1.9.6 + * @version v1.10.0 * @title Retire `private`, `required`, and `edit_mask` for fields * */ @@ -109,6 +109,10 @@ DROP TABLE IF EXISTS `%TABLE_PREFIX%_search`; UPDATE `%TABLE_PREFIX%config` SET `value` = '1' WHERE `key` = 'reindex' and `namespace` = 'mysqlsearch'; +-- Support varying names for duplicated content +ALTER TABLE `%TABLE_PREFIX%attachment` + ADD `name` varchar(255) NULL default NULL AFTER `file_id`; + -- Finished with patch UPDATE `%TABLE_PREFIX%config` SET `value` = '00000000000000000000000000000000' diff --git a/js/filedrop.field.js b/js/filedrop.field.js index 4e82280aeeb894a8249c8723fefd22570635d1c8..8b863fc9f6f897b3c85b72f61d0422dc31394c7b 100644 --- a/js/filedrop.field.js +++ b/js/filedrop.field.js @@ -109,7 +109,7 @@ // Upload failed. TODO: Add a button to the UI to retry on // HTTP 500 return e.remove(); - e.find('[name="'+that.options.name+'"]').val(json.id); + e.find('[name="'+that.options.name+'"]').val(''+json.id+','+file.name); e.data('fileId', json.id); e.find('.progress-bar') .width('100%') diff --git a/setup/inc/streams/core/install-mysql.sql b/setup/inc/streams/core/install-mysql.sql index 873da492077dee0aa9ac826c7f9e6be4fa122558..963adce7f9fa57eed7c8bd5c81f1ba33cba1a68f 100644 --- a/setup/inc/streams/core/install-mysql.sql +++ b/setup/inc/streams/core/install-mysql.sql @@ -21,6 +21,7 @@ CREATE TABLE `%TABLE_PREFIX%attachment` ( `object_id` int(11) unsigned NOT NULL, `type` char(1) NOT NULL, `file_id` int(11) unsigned NOT NULL, + `name` varchar(255) NULL default NULL, `inline` tinyint(1) unsigned NOT NULL DEFAULT '0', `lang` varchar(16), PRIMARY KEY (`id`),