diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-82177-ExtFormAddFileSizeValidator.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-82177-ExtFormAddFileSizeValidator.rst new file mode 100644 index 0000000000000000000000000000000000000000..5445f776ba18fdfd56f004ac0bd0def100d9c53f --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-82177-ExtFormAddFileSizeValidator.rst @@ -0,0 +1,45 @@ +.. include:: ../../Includes.txt + +========================================= +Feature: #82177 - add file size validator +========================================= + +See :issue:`82177` + +Description +=========== + +A new ExtbaseValidator called "FileSizeValidator" has been added which is able to validate a file +resource regarding its file size. This validator has 2 options: + +- minimum + +The minimum file size to accept. Use the format <size>B|K|M|G. For exmaple: 10M means 10 megabytes. + +- maximum + +The maximum file size to accept. Use the format <size>B|K|M|G. For exmaple: 10M means 10 megabytes. + +Please keep in mind that the maximum file size also depends on you php.ini settings. + +Example configuration: + +.. code-block:: yaml + + validators: + - + identifier: FileSize + options: + minimum: 1M + maximum: 10M + +This validator can also be used within the form editor for file and image upload elements. + +Impact +====== + +A file upload element can be validated regarding its file size. It is possible to add, remove and +edit the FileSizeValidator for file upload elements like "ImageUpload" and "FileUpload" within the +form editor. + +.. index:: Backend, Frontend, ext:form \ No newline at end of file diff --git a/typo3/sysext/form/Classes/Mvc/ProcessingRule.php b/typo3/sysext/form/Classes/Mvc/ProcessingRule.php index bd41f1411d42f99a5f95bd303c534a8abc7c1c64..81756cd673cc382bf469c74e7f96fd84bc908833 100644 --- a/typo3/sysext/form/Classes/Mvc/ProcessingRule.php +++ b/typo3/sysext/form/Classes/Mvc/ProcessingRule.php @@ -142,6 +142,18 @@ class ProcessingRule $this->validator->addValidator($validator); } + /** + * Removes the specified validator. + * + * @param ValidatorInterface $validator The validator to remove + * @throws \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException + * @internal + */ + public function removeValidator(ValidatorInterface $validator) + { + $this->validator->removeValidator($validator); + } + /** * @param mixed $value * @return mixed diff --git a/typo3/sysext/form/Classes/Mvc/Property/PropertyMappingConfiguration.php b/typo3/sysext/form/Classes/Mvc/Property/PropertyMappingConfiguration.php index bde3904d820e0d3506b7ef9753f976c5ef5603c1..753eac7d29f2a58ac3887d9a9b3f89e8210c62df 100644 --- a/typo3/sysext/form/Classes/Mvc/Property/PropertyMappingConfiguration.php +++ b/typo3/sysext/form/Classes/Mvc/Property/PropertyMappingConfiguration.php @@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Extbase\Object\ObjectManager; +use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator; use TYPO3\CMS\Form\Domain\Model\FormElements\FileUpload; use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface; use TYPO3\CMS\Form\Mvc\Property\TypeConverter\UploadedFileReferenceConverter; @@ -55,8 +56,18 @@ class PropertyMappingConfiguration $mimeTypeValidator = GeneralUtility::makeInstance(ObjectManager::class) ->get(MimeTypeValidator::class, ['allowedMimeTypes' => $renderable->getProperties()['allowedMimeTypes']]); + + $processingRule = $renderable->getRootForm()->getProcessingRule($renderable->getIdentifier()); + $validators = [$mimeTypeValidator]; + foreach ($processingRule->getValidators() as $validator) { + if (get_class($validator) !== NotEmptyValidator::class) { + $validators[] = $validator; + $processingRule->removeValidator($validator); + } + } + $uploadConfiguration = [ - UploadedFileReferenceConverter::CONFIGURATION_FILE_VALIDATORS => [$mimeTypeValidator], + UploadedFileReferenceConverter::CONFIGURATION_FILE_VALIDATORS => $validators, UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_CONFLICT_MODE => 'rename', ]; diff --git a/typo3/sysext/form/Classes/Mvc/Property/TypeConverter/UploadedFileReferenceConverter.php b/typo3/sysext/form/Classes/Mvc/Property/TypeConverter/UploadedFileReferenceConverter.php index 153395745f4cda3070c41a4191725abefc3b7a92..f86c03baafab97aa8ef5b7cc03c0ddd38bdbf8e8 100644 --- a/typo3/sysext/form/Classes/Mvc/Property/TypeConverter/UploadedFileReferenceConverter.php +++ b/typo3/sysext/form/Classes/Mvc/Property/TypeConverter/UploadedFileReferenceConverter.php @@ -15,6 +15,7 @@ namespace TYPO3\CMS\Form\Mvc\Property\TypeConverter; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\Resource\File as File; use TYPO3\CMS\Core\Resource\FileReference as CoreFileReference; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -25,6 +26,7 @@ use TYPO3\CMS\Extbase\Property\Exception\TypeConverterException; use TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface; use TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter; use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator; +use TYPO3\CMS\Form\Service\TranslationService; /** * Class UploadedFileReferenceConverter @@ -265,23 +267,32 @@ class UploadedFileReferenceConverter extends AbstractTypeConverter */ protected function getUploadErrorMessage(int $errorCode): string { + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(static::class); switch ($errorCode) { case \UPLOAD_ERR_INI_SIZE: - return 'The uploaded file exceeds the upload_max_filesize directive in php.ini'; + $logger->error('The uploaded file exceeds the upload_max_filesize directive in php.ini.', []); + return TranslationService::getInstance()->translate('upload.error.150530345', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); case \UPLOAD_ERR_FORM_SIZE: - return 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'; + $logger->error('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', []); + return TranslationService::getInstance()->translate('upload.error.150530345', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); case \UPLOAD_ERR_PARTIAL: - return 'The uploaded file was only partially uploaded'; + $logger->error('The uploaded file was only partially uploaded.', []); + return TranslationService::getInstance()->translate('upload.error.150530346', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); case \UPLOAD_ERR_NO_FILE: - return 'No file was uploaded'; + $logger->error('No file was uploaded.', []); + return TranslationService::getInstance()->translate('upload.error.150530347', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); case \UPLOAD_ERR_NO_TMP_DIR: - return 'Missing a temporary folder'; + $logger->error('Missing a temporary folder.', []); + return TranslationService::getInstance()->translate('upload.error.150530348', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); case \UPLOAD_ERR_CANT_WRITE: - return 'Failed to write file to disk'; + $logger->error('Failed to write file to disk.', []); + return TranslationService::getInstance()->translate('upload.error.150530348', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); case \UPLOAD_ERR_EXTENSION: - return 'File upload stopped by extension'; + $logger->error('File upload stopped by extension.', []); + return TranslationService::getInstance()->translate('upload.error.150530348', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); default: - return 'Unknown upload error'; + $logger->error('Unknown upload error.', []); + return TranslationService::getInstance()->translate('upload.error.150530348', null, 'EXT:form/Resources/Private/Language/locallang.xlf'); } } } diff --git a/typo3/sysext/form/Classes/Mvc/Validation/FileSizeValidator.php b/typo3/sysext/form/Classes/Mvc/Validation/FileSizeValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..2afc5bc497a1c14feda470bb7d95cb36fcf8f7ef --- /dev/null +++ b/typo3/sysext/form/Classes/Mvc/Validation/FileSizeValidator.php @@ -0,0 +1,105 @@ +<?php +declare(strict_types=1); +namespace TYPO3\CMS\Form\Mvc\Validation; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Domain\Model\FileReference; +use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator; +use TYPO3\CMS\Form\Mvc\Validation\Exception\InvalidValidationOptionsException; + +/** + * Validator for countable types + * + * Scope: frontend + * @internal + */ +class FileSizeValidator extends AbstractValidator +{ + /** + * @var array + */ + protected $supportedOptions = [ + 'minimum' => ['0B', 'The minimum file size to accept', 'string'], + 'maximum' => [PHP_INT_MAX . 'B', 'The maximum file size to accept', 'string'] + ]; + + /** + * The given value is valid + * + * @param FileReference|File $resource + * @api + */ + public function isValid($resource) + { + $this->validateOptions(); + if ($resource instanceof FileReference) { + $resource = $resource->getOriginalResource(); + } elseif (!$resource instanceof File) { + $this->addError( + $this->translateErrorMessage( + 'validation.error.1505303626', + 'form' + ), + 1505303626 + ); + return; + } + + $fileSize = $resource->getSize(); + $minFileSize = GeneralUtility::getBytesFromSizeMeasurement($this->options['minimum']); + $maxFileSize = GeneralUtility::getBytesFromSizeMeasurement($this->options['maximum']); + + $labels = ' Bytes| Kilobyte| Megabyte| Gigabyte'; + if ($fileSize < $minFileSize) { + $this->addError( + $this->translateErrorMessage( + 'validation.error.1505305752', + 'form', + [GeneralUtility::formatSize($minFileSize, $labels)] + ), + 1505305752, + [GeneralUtility::formatSize($minFileSize, $labels)] + ); + } + if ($fileSize > $maxFileSize) { + $this->addError( + $this->translateErrorMessage( + 'validation.error.1505305753', + 'form', + [GeneralUtility::formatSize($maxFileSize, $labels)] + ), + 1505305753, + [GeneralUtility::formatSize($maxFileSize, $labels)] + ); + } + } + + /** + * Checks if this validator is correctly configured + * + * @throws InvalidValidationOptionsException if the configured validation options are incorrect + */ + protected function validateOptions() + { + if (!preg_match('/^(\d*\.?\d+)(B|K|M|G)$/i', $this->options['minimum'])) { + throw new InvalidValidationOptionsException('The option "minimum" has an invalid format. Valid formats are something like this: "10B|K|M|G".', 1505304205); + } + if (!preg_match('/^(\d*\.?\d+)(B|K|M|G)$/i', $this->options['maximum'])) { + throw new InvalidValidationOptionsException('The option "maximum" has an invalid format. Valid formats are something like this: "10B|K|M|G".', 1505304206); + } + } +} diff --git a/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml b/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml index 7fc3d8b9245b785471865565d0c806000a769f14..bb445df8d33311770428bf24f151f933e859c4fc 100644 --- a/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml +++ b/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml @@ -362,6 +362,11 @@ TYPO3: #options: #minimum: 0 #maximum: 0 + FileSize: + implementationClassName: 'TYPO3\CMS\Form\Mvc\Validation\FileSizeValidator' + #options: + #minimum: '0B' + #maximum: '10M' ########### MIXINS ########### mixins: diff --git a/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml b/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml index 61d1dd1b29e3ad1c4508422f20717184e9f2c583..f9ce552d3ea7f7e36ecfc64813b49cc0628698bd 100644 --- a/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml +++ b/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml @@ -113,6 +113,8 @@ TYPO3: errorMessage: 'formEditor.formElementPropertyValidatorsDefinition.FormElementIdentifierWithinCurlyBraces.label' FormElementIdentifierWithinCurlyBracesExclusive: errorMessage: 'formEditor.formElementPropertyValidatorsDefinition.FormElementIdentifierWithinCurlyBraces.label' + FileSize: + errorMessage: 'formEditor.formElementPropertyValidatorsDefinition.FileSize.label' formElementGroups: input: @@ -970,6 +972,14 @@ TYPO3: options: minimum: '' maximum: '' + FileSize: + formEditor: + iconIdentifier: 't3-form-icon-validator' + label: 'formEditor.elements.FileUploadMixin.validators.FileSize.editor.header.label' + predefinedDefaults: + options: + minimum: '0B' + maximum: '10M' ########### MIXINS ########### mixins: @@ -1267,6 +1277,34 @@ TYPO3: 10: value: '1:/user_upload/' label: '1:/user_upload/' + 900: + identifier: 'validators' + templateName: 'Inspector-ValidatorsEditor' + label: 'formEditor.elements.FileUploadMixin.editor.validators.label' + selectOptions: + 10: + value: '' + label: 'formEditor.elements.FileUploadMixin.editor.validators.EmptyValue.label' + 20: + value: 'FileSize' + label: 'formEditor.elements.FileUploadMixin.editor.validators.FileSize.label' + + propertyCollections: + validators: + 10: + identifier: 'FileSize' + editors: + __inheritances: + 10: 'TYPO3.CMS.Form.mixins.formElementMixins.BaseCollectionEditorsMixin' + 20: 'TYPO3.CMS.Form.mixins.formElementMixins.MinimumMaximumEditorsMixin' + 100: + label: 'formEditor.elements.FileUploadMixin.validators.FileSize.editor.header.label' + 200: + propertyValidators: + 10: 'FileSize' + 300: + propertyValidators: + 10: 'FileSize' formEmailFinisherMixin: editors: diff --git a/typo3/sysext/form/Resources/Private/Language/Database.xlf b/typo3/sysext/form/Resources/Private/Language/Database.xlf index 11d75883963186e07c7f7ad94009cae98c86aeb5..3d12b67a0e297a44f062337eda47738f499230a1 100644 --- a/typo3/sysext/form/Resources/Private/Language/Database.xlf +++ b/typo3/sysext/form/Resources/Private/Language/Database.xlf @@ -243,6 +243,9 @@ <trans-unit id="formEditor.formElementPropertyValidatorsDefinition.FormElementIdentifierWithinCurlyBraces.label" xml:space="preserve"> <source>Invalid form element</source> </trans-unit> + <trans-unit id="formEditor.formElementPropertyValidatorsDefinition.FileSize.label" xml:space="preserve"> + <source>Invalid file size format, valid e.g. "10B|K|M|G"</source> + </trans-unit> <trans-unit id="formEditor.formElementGroups.input.label" xml:space="preserve"> <source>Basic elements</source> @@ -455,6 +458,18 @@ <trans-unit id="formEditor.elements.FileUploadMixin.editor.saveToFileMount.label" xml:space="preserve"> <source>Uploads save path</source> </trans-unit> + <trans-unit id="formEditor.elements.FileUploadMixin.editor.validators.label" xml:space="preserve"> + <source>Validators</source> + </trans-unit> + <trans-unit id="formEditor.elements.FileUploadMixin.editor.validators.EmptyValue.label" xml:space="preserve"> + <source>Add validator</source> + </trans-unit> + <trans-unit id="formEditor.elements.FileUploadMixin.editor.validators.FileSize.label" xml:space="preserve"> + <source>File size</source> + </trans-unit> + <trans-unit id="formEditor.elements.FileUploadMixin.validators.FileSize.editor.header.label" xml:space="preserve"> + <source>File size</source> + </trans-unit> <trans-unit id="formEditor.elements.Form.editor.submitButtonLabel.label" xml:space="preserve"> <source>Submit label</source> diff --git a/typo3/sysext/form/Resources/Private/Language/locallang.xlf b/typo3/sysext/form/Resources/Private/Language/locallang.xlf index e8db63fce39328e5ce33a7508aae999dc84a68d9..845d152aa8188d184ff68e77d05412af8008b218 100644 --- a/typo3/sysext/form/Resources/Private/Language/locallang.xlf +++ b/typo3/sysext/form/Resources/Private/Language/locallang.xlf @@ -14,58 +14,58 @@ </trans-unit> <trans-unit id="validation.error.1221560910" xml:space="preserve"> - <source>This field is mandatory</source> + <source>This field is mandatory.</source> </trans-unit> <trans-unit id="validation.error.1221560718" xml:space="preserve"> - <source>This field is mandatory</source> + <source>This field is mandatory.</source> </trans-unit> <trans-unit id="validation.error.1347992400" xml:space="preserve"> - <source>This field is mandatory</source> + <source>This field is mandatory.</source> </trans-unit> <trans-unit id="validation.error.1347992453" xml:space="preserve"> - <source>This field is mandatory</source> + <source>This field is mandatory.</source> </trans-unit> <trans-unit id="validation.error.1238087674" xml:space="preserve"> - <source>Please enter a valid Date</source> + <source>Please enter a valid Date.</source> </trans-unit> <trans-unit id="validation.error.1221551320" xml:space="preserve"> - <source>Please enter letters or digits</source> + <source>Please enter letters or digits.</source> </trans-unit> <trans-unit id="validation.error.1221565786" xml:space="preserve"> - <source>Please enter a valid text (e.g. without XML tags)</source> + <source>Please enter a valid text (e.g. without XML tags).</source> </trans-unit> <trans-unit id="validation.error.1238110957" xml:space="preserve"> - <source>Please enter a valid text</source> + <source>Please enter a valid text.</source> </trans-unit> <trans-unit id="validation.error.1269883975" xml:space="preserve"> - <source>Please enter a valid text</source> + <source>Please enter a valid text.</source> </trans-unit> <trans-unit id="validation.error.1428504122" xml:space="preserve"> - <source>Please enter a text between %s and %s characters</source> + <source>Please enter a text between %s and %s characters.</source> </trans-unit> <trans-unit id="validation.error.1238108068" xml:space="preserve"> - <source>Please enter a text which is longer than %s characters</source> + <source>Please enter a text which is longer than %s characters.</source> </trans-unit> <trans-unit id="validation.error.1238108069" xml:space="preserve"> - <source>Please enter a text which is not longer than %s characters</source> + <source>Please enter a text which is not longer than %s characters.</source> </trans-unit> <trans-unit id="validation.error.1221559976" xml:space="preserve"> - <source>Please enter a valid email address</source> + <source>Please enter a valid email address.</source> </trans-unit> <trans-unit id="validation.error.1221560494" xml:space="preserve"> - <source>Please enter a valid number</source> + <source>Please enter a valid number.</source> </trans-unit> <trans-unit id="validation.error.1221560288" xml:space="preserve"> - <source>Please enter a valid floating point number</source> + <source>Please enter a valid floating point number.</source> </trans-unit> <trans-unit id="validation.error.1221563685" xml:space="preserve"> - <source>Please enter a valid number</source> + <source>Please enter a valid number.</source> </trans-unit> <trans-unit id="validation.error.1221561046" xml:space="preserve"> - <source>Please enter a valid number between %s and %s</source> + <source>Please enter a valid number between %s and %s.</source> </trans-unit> <trans-unit id="validation.error.1221565130" xml:space="preserve"> - <source>Please enter a valid value</source> + <source>Please enter a valid value.</source> </trans-unit> <trans-unit id="validation.error.1475002976" xml:space="preserve"> <source>The given subject is not countable.</source> @@ -80,7 +80,16 @@ <source>The media type "%s" is not allowed for this file.</source> </trans-unit> <trans-unit id="validation.error.1476396435" xml:space="preserve"> - <source>Do not fill this field</source> + <source>Do not fill this field.</source> + </trans-unit> + <trans-unit id="validation.error.1505303626" xml:space="preserve"> + <source>The given value was not an instance of \TYPO3\CMS\Extbase\Domain\Model\FileReference or \TYPO3\CMS\Core\Resource\File.</source> + </trans-unit> + <trans-unit id="validation.error.1505305752" xml:space="preserve"> + <source>The file must be at least %s in size.</source> + </trans-unit> + <trans-unit id="validation.error.1505305753" xml:space="preserve"> + <source>The file size can not exceed %s in size.</source> </trans-unit> <trans-unit id="form_new_wizard_title" xml:space="preserve"> <source>Form</source> @@ -88,6 +97,18 @@ <trans-unit id="form_new_wizard_description" xml:space="preserve"> <source>A form allowing website users to submit messages.</source> </trans-unit> + <trans-unit id="upload.error.150530345" xml:space="preserve"> + <source>Maximum file size exceeded.</source> + </trans-unit> + <trans-unit id="upload.error.150530346" xml:space="preserve"> + <source>The file is partially uploaded, please try again.</source> + </trans-unit> + <trans-unit id="upload.error.150530347" xml:space="preserve"> + <source>No file was uploaded.</source> + </trans-unit> + <trans-unit id="upload.error.150530348" xml:space="preserve"> + <source>Upload not possible.</source> + </trans-unit> </body> </file> </xliff> diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js index 761b60626d13f5edc1b25c3a88ff990da32cb698..17f63f1985d591c69e60d4678e6ca63e12103a0c 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js @@ -244,6 +244,12 @@ define(['jquery', return getFormEditorApp().getFormElementPropertyValidatorDefinition('FormElementIdentifierWithinCurlyBracesInclusive')['errorMessage'] || 'invalid value'; } }); + + getFormEditorApp().addPropertyValidationValidator('FileSize', function(formElement, propertyPath) { + if (!formElement.get(propertyPath).match(/^(\d*\.?\d+)(B|K|M|G)$/i)) { + return getFormEditorApp().getFormElementPropertyValidatorDefinition('FileSize')['errorMessage'] || 'invalid value'; + } + }); }; /** diff --git a/typo3/sysext/form/Tests/Unit/Mvc/Validation/FileSizeValidatorTest.php b/typo3/sysext/form/Tests/Unit/Mvc/Validation/FileSizeValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2ce79cf1cf6a6ec2199106aafd769cb38c45fdb7 --- /dev/null +++ b/typo3/sysext/form/Tests/Unit/Mvc/Validation/FileSizeValidatorTest.php @@ -0,0 +1,127 @@ +<?php +namespace TYPO3\CMS\Form\Tests\Unit\Mvc\Validation; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Resource\ResourceStorage; +use TYPO3\CMS\Form\Mvc\Validation\Exception\InvalidValidationOptionsException; +use TYPO3\CMS\Form\Mvc\Validation\FileSizeValidator; + +/** + * Test case + */ +class FileSizeValidatorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase +{ + + /** + * @test + */ + public function FileSizeValidatorThrowsExceptionIfMinimumOptionIsInvalid() + { + $this->expectException(InvalidValidationOptionsException::class); + $this->expectExceptionCode(1505304205); + + $options = ['minimum' => '0', 'maximum' => '1B']; + $validator = $this->getMockBuilder(FileSizeValidator::class) + ->setMethods(['translateErrorMessage']) + ->setConstructorArgs(['options' => $options]) + ->getMock(); + + $validator->validate(true); + } + + /** + * @test + */ + public function FileSizeValidatorThrowsExceptionIfMaximumOptionIsInvalid() + { + $this->expectException(InvalidValidationOptionsException::class); + $this->expectExceptionCode(1505304206); + + $options = ['minimum' => '0B', 'maximum' => '1']; + $validator = $this->getMockBuilder(FileSizeValidator::class) + ->setMethods(['translateErrorMessage']) + ->setConstructorArgs(['options' => $options]) + ->getMock(); + + $validator->validate(true); + } + + /** + * @test + */ + public function FileSizeValidatorHasErrosIfFileResourceSizeIsToSmall() + { + $options = ['minimum' => '1M', 'maximum' => '10M']; + $validator = $this->getMockBuilder(FileSizeValidator::class) + ->setMethods(['translateErrorMessage']) + ->setConstructorArgs(['options' => $options]) + ->getMock(); + + $mockedStorage = $this->getMockBuilder(ResourceStorage::class) + ->disableOriginalConstructor() + ->getMock(); + + $file = new File(['identifier' => '/foo', 'size' => '1'], $mockedStorage); + $this->assertTrue($validator->validate($file)->hasErrors()); + } + + /** + * @test + */ + public function FileSizeValidatorHasErrosIfFileResourceSizeIsToBig() + { + $options = ['minimum' => '1M', 'maximum' => '1M']; + $validator = $this->getMockBuilder(FileSizeValidator::class) + ->setMethods(['translateErrorMessage']) + ->setConstructorArgs(['options' => $options]) + ->getMock(); + + $mockedStorage = $this->getMockBuilder(ResourceStorage::class) + ->disableOriginalConstructor() + ->getMock(); + + $file = new File(['identifier' => '/foo', 'size' => '1048577'], $mockedStorage); + $this->assertTrue($validator->validate($file)->hasErrors()); + } + + /** + * @test + */ + public function FileSizeValidatorHasNoErrorsIfInputIsEmptyString() + { + $options = ['minimum' => '0B', 'maximum' => '1M']; + $validator = $this->getMockBuilder(FileSizeValidator::class) + ->setMethods(['translateErrorMessage']) + ->setConstructorArgs(['options' => $options]) + ->getMock(); + + $this->assertFalse($validator->validate('')->hasErrors()); + } + + /** + * @test + */ + public function FileSizeValidatorHasErrorsIfInputIsNoFileResource() + { + $options = ['minimum' => '0B', 'maximum' => '1M']; + $validator = $this->getMockBuilder(FileSizeValidator::class) + ->setMethods(['translateErrorMessage']) + ->setConstructorArgs(['options' => $options]) + ->getMock(); + + $this->assertTrue($validator->validate('string')->hasErrors()); + } +}