Merge pull request #501 from muskie9/enhancement/fileSizeLimit#430

ENHANCEMENT add customisable file upload size limit
This commit is contained in:
Damian Mooyman 2016-08-23 17:36:29 +12:00 committed by GitHub
commit 7167f3a1c5
3 changed files with 120 additions and 6 deletions

View File

@ -5,7 +5,6 @@
* *
* @package userforms * @package userforms
*/ */
class EditableFileField extends EditableFormField class EditableFileField extends EditableFormField
{ {
@ -13,6 +12,10 @@ class EditableFileField extends EditableFormField
private static $plural_names = 'File Fields'; private static $plural_names = 'File Fields';
private static $db = array(
'MaxFileSizeMB' => 'Float',
);
private static $has_one = array( private static $has_one = array(
'Folder' => 'Folder' // From CustomFields 'Folder' => 'Folder' // From CustomFields
); );
@ -43,13 +46,35 @@ class EditableFileField extends EditableFormField
); );
$fields->addFieldToTab("Root.Main", new LiteralField("FileUploadWarning", $fields->addFieldToTab("Root.Main", new LiteralField("FileUploadWarning",
"<p class=\"message notice\">" . _t("UserDefinedForm.FileUploadWarning", "<p class=\"message notice\">" . _t("UserDefinedForm.FileUploadWarning",
"Files uploaded through this field could be publicly accessible if the exact URL is known") "Files uploaded through this field could be publicly accessible if the exact URL is known")
. "</p>"), "Type"); . "</p>"), "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 $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() public function getFormField()
{ {
$field = FileField::create($this->Name, $this->EscapedTitle) $field = FileField::create($this->Name, $this->EscapedTitle)
@ -57,16 +82,22 @@ class EditableFileField extends EditableFormField
->setTemplate('UserFormsFileField'); ->setTemplate('UserFormsFileField');
$field->setFieldHolderTemplate('UserFormsField_holder') $field->setFieldHolderTemplate('UserFormsField_holder')
->setTemplate('UserFormsFileField'); ->setTemplate('UserFormsFileField');
$field->getValidator()->setAllowedExtensions( $field->getValidator()->setAllowedExtensions(
array_diff( 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')), array_filter(Config::inst()->get('File', 'allowed_extensions')),
$this->config()->allowed_extensions_blacklist $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(); $folder = $this->Folder();
if ($folder && $folder->exists()) { if ($folder && $folder->exists()) {
$field->setFolderName( $field->setFolderName(
@ -107,4 +138,20 @@ class EditableFileField extends EditableFormField
parent::migrateSettings($data); 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);
}
} }

View File

@ -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` You can define further exclusions through the `EditableFileField.allowed_extensions_blacklist`
configuration setting. 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`). 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. The field is disabled by default since implementors need to determine how files are secured.

View File

@ -0,0 +1,67 @@
<?php
/**
* @package userforms
*/
class EditableFileFieldTest extends SapphireTest
{
/**
* @var string
*/
public static $fixture_file = 'userforms/tests/EditableFormFieldTest.yml';
/**
* @var
*/
private $php_max_file_size;
/**
* Hold the server default max file size upload limit for later
*/
public function setUp()
{
parent::setUp();
$editableFileField = singleton('EditableFileField');
$this->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);
}
}