diff --git a/wire/core/Pagefile.php b/wire/core/Pagefile.php index bb51cd48..b1a7bf04 100644 --- a/wire/core/Pagefile.php +++ b/wire/core/Pagefile.php @@ -45,6 +45,7 @@ * @property User|NullPage $createdUser User that added/uploaded the file or NullPage if not known (3.0.154)+. #pw-group-other * @property User|NullPage $modifiedUser User that last modified the file or NullPage if not known (3.0.154)+. #pw-group-other * @property bool $formatted True when value has had Textformatters applied. #pw-internal + * @property string $uploadName Original unsanitized filename at upload, see notes for uploadName() method (3.0.212+). #pw-group-other * * @method void install($filename) * @method string httpUrl() @@ -702,6 +703,9 @@ class Pagefile extends WireData implements WireArrayItem { case 'fieldValues': $value = $this->fieldValues; break; + case 'uploadName': + $value = $this->uploadName(); + break; default: $value = $this->getFieldValue($key); } @@ -933,6 +937,24 @@ class Pagefile extends WireData implements WireArrayItem { return $basename; } + /** + * Original and unsanitized filename at the time it was uploaded + * + * Returned value is also entity encoded if $page’s output formatting state is ON. + * For files uploaded in ProcessWire 3.0.212 or newer. Falls back to current file + * basename for files that were uploaded prior to 3.0.212. + * + * @return string + * @since 3.0.212 + * + */ + public function uploadName() { + $uploadName = (string) $this->filedata('uploadName'); + if(!strlen($uploadName)) $uploadName = $this->basename(); + if($this->page && $this->page->of()) $uploadName = $this->wire()->sanitizer->entities($uploadName); + return $uploadName; + } + /** * Get or set the "tags" property, when in use. * diff --git a/wire/core/WireUpload.php b/wire/core/WireUpload.php index 82f918e2..1734d9c6 100644 --- a/wire/core/WireUpload.php +++ b/wire/core/WireUpload.php @@ -53,6 +53,14 @@ class WireUpload extends Wire { */ protected $completedFilenames = array(); + /** + * Original unsanitized file basenames indexed by completed basenames + * + * @var array + * + */ + protected $originalFilenames = array(); + /** * Allow files to be overwritten? * @@ -474,8 +482,8 @@ class WireUpload extends Wire { /** * Save the uploaded file * - * @param string $tmp_name Temporary filename - * @param string $filename Actual filename + * @param string $tmp_name Temporary filename (full path and filename) + * @param string $filename Actual filename (basename) * @param bool $ajax Is this an AJAX upload? * @return array|bool|string Boolean false on fail, array of multiple filenames, or string of filename if maxFiles=1 * @@ -486,6 +494,7 @@ class WireUpload extends Wire { $success = false; $error = ''; + $originalFilename = basename($filename); $filename = $this->getTargetFilename($filename); $_filename = $filename; $filename = $this->validateFilename($filename, $this->validExtensions); @@ -552,7 +561,7 @@ class WireUpload extends Wire { return $this->completedFilenames; } else { - $this->completedFilenames[] = $filename; + $this->addUploadedFilename($filename, $originalFilename); return $filename; } } @@ -602,6 +611,7 @@ class WireUpload extends Wire { } $basename = $file; + $originalFilename = $basename; $basename = $this->validateFilename($basename, $this->validExtensions); if($basename) { @@ -624,7 +634,7 @@ class WireUpload extends Wire { } if($destination && rename($pathname, $destination)) { - $this->completedFilenames[] = basename($destination); + $this->addUploadedFilename($destination, $originalFilename); $cnt++; } else { $fileTools->unlink($pathname, $tmpDir); @@ -649,6 +659,34 @@ class WireUpload extends Wire { return $this->completedFilenames; } + /** + * Add a completed upload file name and its original name + * + * @param string $completedFilename Sanitized filename or basename that was used for saved file + * @param string $originalFilename Unsanitized filename as uploaded + * + */ + protected function addUploadedFilename($completedFilename, $originalFilename) { + $completedFilename = basename($completedFilename); + $originalFilename = basename($originalFilename); + $this->completedFilenames[] = $completedFilename; + if($this->wire()->sanitizer->getTextTools()->strlen($originalFilename) > 255) { + $originalFilename = $completedFilename; + } + $this->originalFilenames[$completedFilename] = $originalFilename; + } + + /** + * Get unsanitized array of original filenames (basenames) indexed by completed basename + * + * @return array + * @since 3.0.212 + * + */ + public function getOriginalFilenames() { + return $this->originalFilenames; + } + /** * Set the target filename, only useful for single uploads * diff --git a/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module b/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module index 8ac88ec2..a5053a79 100644 --- a/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module +++ b/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module @@ -31,7 +31,7 @@ * @method string renderUpload($value) * @method void fileAdded(Pagefile $pagefile) * @method array extractMetadata(Pagefile $pagefile, array $metadata = array()) - * @method void processInputAddFile($filename) + * @method Pagefile|null processInputAddFile($filename) * @method void processInputDeleteFile(Pagefile $pagefile) * @method bool processInputFile(WireInputData $input, Pagefile $pagefile, $n) * @method bool processItemInputfields(Pagefile $pagefile, InputfieldWrapper $inputfields, $id, WireInputData $input) @@ -519,11 +519,20 @@ class InputfieldFile extends Inputfield implements InputfieldItemList, Inputfiel $displayName = $this->getDisplayBasename($pagefile); $deleteLabel = $this->labels['delete']; + $uploadName = $pagefile->uploadName(); + $icon = wireIconMarkupFile($pagefile->basename, "fa-fw HideIfEmpty"); + + $tooltip = $this->wire()->sanitizer->entities($pagefile->basename); + + if($uploadName && $uploadName != $pagefile->basename) { + $uploadName = $this->wire()->sanitizer->entities($uploadName); + $icon = "$icon"; + } $out = "