From eb52afdae26f544a2d0aa03e514e2ed620f93467 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 30 Jun 2020 11:27:19 +0200 Subject: [PATCH] Add support for acceptable types to lib/system/file/upload/ functionality see #3414 --- .../templates/uploadFieldComponent.tpl | 9 +++- .../acp/templates/uploadFieldComponent.tpl | 9 +++- .../js/WoltLabSuite/Core/Ui/File/Upload.js | 4 +- .../system/file/upload/UploadField.class.php | 53 +++++++++++++++++++ 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/com.woltlab.wcf/templates/uploadFieldComponent.tpl b/com.woltlab.wcf/templates/uploadFieldComponent.tpl index fbf0c32859..bd736ee225 100644 --- a/com.woltlab.wcf/templates/uploadFieldComponent.tpl +++ b/com.woltlab.wcf/templates/uploadFieldComponent.tpl @@ -42,7 +42,12 @@ new Upload("{$uploadFieldId}UploadButtonDiv", "{$uploadFieldId}uploadFileList", { internalId: '{$uploadField->getInternalId()}', {if $uploadField->getMaxFiles()}maxFiles: {$uploadField->getMaxFiles()},{/if} - imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if} + imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if}, + {if $uploadField->getAcceptableFiles()} + acceptableFiles: [ + {implode from=$uploadField->getAcceptableFiles() item=accept}'{$accept|encodeJS}'{/implode} + ], + {/if} }); }); - \ No newline at end of file + diff --git a/wcfsetup/install/files/acp/templates/uploadFieldComponent.tpl b/wcfsetup/install/files/acp/templates/uploadFieldComponent.tpl index fbf0c32859..bd736ee225 100644 --- a/wcfsetup/install/files/acp/templates/uploadFieldComponent.tpl +++ b/wcfsetup/install/files/acp/templates/uploadFieldComponent.tpl @@ -42,7 +42,12 @@ new Upload("{$uploadFieldId}UploadButtonDiv", "{$uploadFieldId}uploadFileList", { internalId: '{$uploadField->getInternalId()}', {if $uploadField->getMaxFiles()}maxFiles: {$uploadField->getMaxFiles()},{/if} - imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if} + imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if}, + {if $uploadField->getAcceptableFiles()} + acceptableFiles: [ + {implode from=$uploadField->getAcceptableFiles() item=accept}'{$accept|encodeJS}'{/implode} + ], + {/if} }); }); - \ No newline at end of file + diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/File/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/File/Upload.js index 6789618bd0..24a657278e 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/File/Upload.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/File/Upload.js @@ -31,7 +31,9 @@ define(['Core', 'Language', 'Dom/Util', 'WoltLabSuite/Core/Ui/File/Delete', 'Upl // image preview imagePreview: false, // max files - maxFiles: null + maxFiles: null, + // array of acceptable file types, null if any file type is allowed + acceptableFiles: null, }, options); this._options.multiple = this._options.maxFiles === null || this._options.maxFiles > 1; diff --git a/wcfsetup/install/files/lib/system/file/upload/UploadField.class.php b/wcfsetup/install/files/lib/system/file/upload/UploadField.class.php index 83938b1f23..eb42f08c74 100644 --- a/wcfsetup/install/files/lib/system/file/upload/UploadField.class.php +++ b/wcfsetup/install/files/lib/system/file/upload/UploadField.class.php @@ -43,6 +43,13 @@ class UploadField { */ public $allowSvgImage = false; + /** + * Acceptable file types. + * @var string[]|null + * @since 5.3 + */ + public $acceptableFiles = null; + /** * UploadField constructor. * @@ -119,10 +126,24 @@ class UploadField { * Sets the flag for `imageOnly`. This flag indicates whether only images * can uploaded via this field. Other file types will be rejected during upload. * + * If set to `true` will also set the acceptable types to `image/*`. If set to + * false it will clear the acceptable types if they are `image/*`. + * * @param boolean $imageOnly */ public function setImageOnly($imageOnly) { $this->imageOnly = $imageOnly; + + if ($imageOnly) { + $this->setAcceptableFiles(['image/*']); + } + else { + // Using == here is safe, because we match a single element array containing + // a scalar value. + if ($this->getAcceptableFiles() == ['image/*']) { + $this->setAcceptableFiles(null); + } + } } /** @@ -145,4 +166,36 @@ class UploadField { $this->allowSvgImage = $allowSvgImage; } + + /** + * Specifies acceptable file types. Use null to not specify any restrictions. + * + * Heads up: This feature is used to improve user experience, by removing + * unacceptable files from the file picker. It does not validate the type of the uploaded + * file. You are responsible to perform (proper) validation on the server side. + * + * Valid values are specified as "Unique file type specifiers": + * - A case insensitive file extension starting with a dot. + * - A mime type. + * - `audio/*` + * - `image/*` + * - `video/*` + * + * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers + * @param string[]|null $acceptableFiles + * @since 5.3 + */ + public function setAcceptableFiles($acceptableFiles = null) { + $this->acceptableFiles = $acceptableFiles; + } + + /** + * Returns the acceptable file types. + * + * @return string[]|null + * @since 5.3 + */ + public function getAcceptableFiles() { + return $this->acceptableFiles; + } } -- 2.20.1