Thank you @asmecher for this very detailed and very clear answer.
Download filenames for single files
Substitution of getClientFileName()
by getOriginalFileName()
works well indeed.
For the sake of consistency (if anyone stumble on this post with similar needs), I also changed the downloadAllFiles function in the same way so the zip will contain files with original nomenclature as well :
function downloadAllFiles($args, $request) {
// Retrieve the authorized objects.
(...)
foreach ($submissionFiles as $submissionFile) {
// Remove absolute path so the archive doesn't include it (otherwise all files are organized by absolute path)
// $filePaths[str_replace($filesDir, '', $submissionFile->getFilePath())] = $submissionFile->getClientFileName();
$filePaths[str_replace($filesDir, '', $submissionFile->getFilePath())] = $submissionFile->getOriginalFileName();
}
However when using getOriginalFilename()
, if the filename is edited via the UI and changed (say “abc.docx” for “abcdefg.docx”):

this new name is not sent when donwloading:

I would not want an editor to edit the file name at the pre-review stage thinking that it would then be anonymized… Is there a way to prevent this?
After giving it some thought, I finally went for an “hybrid” pattern by introducing a getCustomClientFileName()
function that picks
client parts (SubmissionId
+ FileId
+ RevisionId
+ timestamp
) concatenated with original name
in \lib\pkp\classes\submission\SubmissionFile.inc.php
(on a side note: I am glad I insisted on taking a multi-instances approach for our OJS deployment/set-up (i.e. 1 OJS instance per journal), that way I can better customized on a per journal basis, e.g. this function):
/**
* MHV_20200727 -- Get the filename that should be sent to clients when downloading.
* @return string
*/
function getCustomClientFileName() {
// Generate a human readable time stamp.
$timestamp = date('Ymd', strtotime($this->getDateUploaded()));
$genreDao = DAORegistry::getDAO('GenreDAO');
$genre = $genreDao->getById($this->getGenreId());
// Make the file name unique across all files and file revisions.
// Also make sure that files can be ordered sensibly by file name.
return $this->getSubmissionId() . '-'.
// ($genre? ($genre->getLocalizedName() . '-'):'') .
$this->getFileId() . '-' .
$this->getRevision() . '-' .
// $this->getFileStage() . '-' .
// $timestamp .
$timestamp . '-' .
//'.' .
//$this->getExtension();
$this->getOriginalFilename(); // MHV_20200727 : Original file name contains the "." + extension
}
Did I forget to consider other important aspects? Is there a risk to run into problems by doing this?
One last question if I may : I see that the original getClientFileName function
is also called from classes/services/GalleyService.inc.php
and classes/file/SubmissionFileManager.inc.php
.
I think I can leave the former as is but I am not sure whether I should change or not the downloadById
function within the latter file by swaping the getClientFileName
for my custom function?
Downloading multiple files at once
Thank you. I was able to backport the fix to my 3.1.2-4 instance. Works perfectly.
Marie-Hélène V.
Université de Montréal