diff --git a/code/model/editableformfields/EditableFileField.php b/code/model/editableformfields/EditableFileField.php index a66064e..10ddef6 100755 --- a/code/model/editableformfields/EditableFileField.php +++ b/code/model/editableformfields/EditableFileField.php @@ -5,7 +5,6 @@ * * @package userforms */ - class EditableFileField extends EditableFormField { @@ -13,6 +12,10 @@ class EditableFileField extends EditableFormField private static $plural_names = 'File Fields'; + private static $db = array( + 'MaxFileSizeMB' => 'Float', + ); + private static $has_one = array( 'Folder' => 'Folder' // From CustomFields ); @@ -43,13 +46,35 @@ class EditableFileField extends EditableFormField ); $fields->addFieldToTab("Root.Main", new LiteralField("FileUploadWarning", - "

" . _t("UserDefinedForm.FileUploadWarning", + "

" . _t("UserDefinedForm.FileUploadWarning", "Files uploaded through this field could be publicly accessible if the exact URL is known") - . "

"), "Type"); + . "

"), "Type"); + + $fields->addFieldToTab( + 'Root.Main', + NumericField::create('MaxFileSizeMB') + ->setTitle('Max File Size MB') + ->setDescription("Note: Maximum php allowed size is {$this->getPHPMaxFileSize()} MB") + ); return $fields; } + /** + * @return ValidationResult + */ + public function validate() + { + $result = parent::validate(); + + $max = static::get_php_max_file_size(); + if ($this->MaxFileSizeMB * 1024 > $max) { + $result->error("Your max file size limit can't be larger than the server's limit of {$this->getPHPMaxFileSizeMB()}."); + } + + return $result; + } + public function getFormField() { $field = FileField::create($this->Name, $this->EscapedTitle) @@ -57,16 +82,22 @@ class EditableFileField extends EditableFormField ->setTemplate('UserFormsFileField'); $field->setFieldHolderTemplate('UserFormsField_holder') - ->setTemplate('UserFormsFileField'); + ->setTemplate('UserFormsFileField'); $field->getValidator()->setAllowedExtensions( array_diff( - // filter out '' since this would be a regex problem on JS end + // filter out '' since this would be a regex problem on JS end array_filter(Config::inst()->get('File', 'allowed_extensions')), $this->config()->allowed_extensions_blacklist ) ); + if ($this->MaxFileSizeMB > 0) { + $field->getValidator()->setAllowedMaxFileSize($this->MaxFileSizeMB * 1024); + } else { + $field->getValidator()->setAllowedMaxFileSize(static::get_php_max_file_size()); + } + $folder = $this->Folder(); if ($folder && $folder->exists()) { $field->setFolderName( @@ -107,4 +138,20 @@ class EditableFileField extends EditableFormField parent::migrateSettings($data); } + + /** + * @return float + */ + public static function get_php_max_file_size() + { + $maxUpload = File::ini2bytes(ini_get('upload_max_filesize')); + $maxPost = File::ini2bytes(ini_get('post_max_size')); + return min($maxUpload, $maxPost); + } + + public function getPHPMaxFileSizeMB() + { + return round(static::get_php_max_file_size() / 1024.0, 1); + } + } diff --git a/docs/en/installation.md b/docs/en/installation.md index 23c3593..4b6f5d8 100644 --- a/docs/en/installation.md +++ b/docs/en/installation.md @@ -33,7 +33,7 @@ and default to a safe set of files (e.g. disallowing `*.php` uploads). You can define further exclusions through the `EditableFileField.allowed_extensions_blacklist` configuration setting. -The allowed upload size is determined by PHP configuration +The allowed upload size can be set in the cms as long as it doesn't exceed the PHP configuration for this website (the smaller value of `upload_max_filesize` or `post_max_size`). The field is disabled by default since implementors need to determine how files are secured. diff --git a/tests/EditableFileFieldTest.php b/tests/EditableFileFieldTest.php new file mode 100644 index 0000000..46537fb --- /dev/null +++ b/tests/EditableFileFieldTest.php @@ -0,0 +1,67 @@ +php_max_file_size = $editableFileField::get_php_max_file_size(); + + } + + /** + * Test that the field validator has the server default as the max file size upload + */ + public function testDefaultMaxFileSize() + { + $fileField = $this->objFromFixture('EditableFileField', 'file-field'); + $formField = $fileField->getFormField(); + + $this->assertEquals($this->php_max_file_size, $formField->getValidator()->getAllowedMaxFileSize()); + } + + /** + * Test that validation prevents the provided upload size limit to be less than or equal to the max php size + */ + public function testValidateFileSizeFieldValue() + { + + $fileField = $this->objFromFixture('EditableFileField', 'file-field'); + $this->setExpectedException('ValidationException'); + $fileField->MaxFileSizeMB = $this->php_max_file_size * 2; + $fileField->write(); + } + + /** + * Test the field validator has the updated allowed max file size + */ + public function testUpdatedMaxFileSize() + { + $fileField = $this->objFromFixture('EditableFileField', 'file-field'); + $fileField->MaxFileSizeMB = .25; + $fileField->write(); + + $formField = $fileField->getFormField(); + $this->assertEquals($formField->getValidator()->getAllowedMaxFileSize(), 256); + } + +} \ No newline at end of file