mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
Merge pull request #1017 from NightJar/new/5/set-max-upload-size-via-config
This commit is contained in:
commit
a356b0f8ce
@ -56,6 +56,16 @@ class UserDefinedFormController extends PageController
|
|||||||
|
|
||||||
private static string $file_upload_stage = Versioned::DRAFT;
|
private static string $file_upload_stage = Versioned::DRAFT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size that an uploaded file must not excede for it to be attached to an email
|
||||||
|
* Follows PHP "shorthand bytes" definition rules.
|
||||||
|
* @see self::parseByteSizeString()
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @config
|
||||||
|
*/
|
||||||
|
private static $maximum_email_attachment_size = '1M';
|
||||||
|
|
||||||
protected function init()
|
protected function init()
|
||||||
{
|
{
|
||||||
parent::init();
|
parent::init();
|
||||||
@ -215,6 +225,42 @@ JS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum size uploaded files can be before they're excluded from CMS configured recipient emails
|
||||||
|
*
|
||||||
|
* @return int size in megabytes
|
||||||
|
*/
|
||||||
|
public function getMaximumAllowedEmailAttachmentSize()
|
||||||
|
{
|
||||||
|
return $this->parseByteSizeString($this->config()->get('maximum_email_attachment_size'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert file sizes with a single character for unit size to true byte count.
|
||||||
|
* Just as with php.ini and e.g. 128M -> 1024 * 1024 * 128 bytes.
|
||||||
|
* @see https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
|
||||||
|
*
|
||||||
|
* @param string $byteSize
|
||||||
|
* @return int bytes
|
||||||
|
*/
|
||||||
|
protected function parseByteSizeString($byteSize)
|
||||||
|
{
|
||||||
|
// kilo, mega, giga
|
||||||
|
$validUnits = 'kmg';
|
||||||
|
$valid = preg_match("/^(?<number>\d+)((?<unit>[$validUnits])b?)?$/i", $byteSize, $matches);
|
||||||
|
if (!$valid) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Expected a positive integer followed optionally by K, M, or G. Found '$byteSize' instead"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$power = 0;
|
||||||
|
// prepend b for bytes to $validUnits to give correct mapping of ordinal position to exponent
|
||||||
|
if (isset($matches['unit'])) {
|
||||||
|
$power = stripos("b$validUnits", $matches['unit']);
|
||||||
|
}
|
||||||
|
return intval($matches['number']) * pow(1024, $power);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the form that is submitted through the site
|
* Process the form that is submitted through the site
|
||||||
*
|
*
|
||||||
@ -268,7 +314,7 @@ JS
|
|||||||
if (!$field->getFolderExists()) {
|
if (!$field->getFolderExists()) {
|
||||||
$field->createProtectedFolder();
|
$field->createProtectedFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = Versioned::withVersionedMode(function () use ($field, $form) {
|
$file = Versioned::withVersionedMode(function () use ($field, $form) {
|
||||||
$stage = Injector::inst()->get(self::class)->config()->get('file_upload_stage');
|
$stage = Injector::inst()->get(self::class)->config()->get('file_upload_stage');
|
||||||
Versioned::set_stage($stage);
|
Versioned::set_stage($stage);
|
||||||
@ -308,8 +354,8 @@ JS
|
|||||||
// write file to form field
|
// write file to form field
|
||||||
$submittedField->UploadedFileID = $file->ID;
|
$submittedField->UploadedFileID = $file->ID;
|
||||||
|
|
||||||
// attach a file only if lower than 1MB
|
// attach a file to recipient email only if lower than configured size
|
||||||
if ($file->getAbsoluteSize() < 1024 * 1024 * 1) {
|
if ($file->getAbsoluteSize() <= $this->getMaximumAllowedEmailAttachmentSize()) {
|
||||||
$attachments[] = $file;
|
$attachments[] = $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
|
|||||||
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
|
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
|
||||||
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
|
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
|
||||||
use SilverStripe\UserForms\Model\UserDefinedForm;
|
use SilverStripe\UserForms\Model\UserDefinedForm;
|
||||||
|
use SilverStripe\UserForms\Tests\Control\fixtures\SizeStringTestableController;
|
||||||
use SilverStripe\Versioned\Versioned;
|
use SilverStripe\Versioned\Versioned;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
use SilverStripe\View\SSViewer;
|
use SilverStripe\View\SSViewer;
|
||||||
@ -47,7 +48,9 @@ class UserDefinedFormControllerTest extends FunctionalTest
|
|||||||
// Set backend and base url
|
// Set backend and base url
|
||||||
TestAssetStore::activate('AssetStoreTest');
|
TestAssetStore::activate('AssetStoreTest');
|
||||||
|
|
||||||
Config::modify()->merge(SSViewer::class, 'themes', ['simple', '$default']);
|
$config = Config::modify();
|
||||||
|
$config->set(UserDefinedFormController::class, 'maximum_email_attachment_size', "1M");
|
||||||
|
$config->merge(SSViewer::class, 'themes', ['simple', '$default']);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown(): void
|
protected function tearDown(): void
|
||||||
@ -273,7 +276,8 @@ class UserDefinedFormControllerTest extends FunctionalTest
|
|||||||
$actions = $controller->Form()->getFormActions();
|
$actions = $controller->Form()->getFormActions();
|
||||||
|
|
||||||
$expected = new FieldList(new FormAction('process', 'Custom Button'));
|
$expected = new FieldList(new FormAction('process', 'Custom Button'));
|
||||||
$expected->push(FormAction::create('clearForm', 'Clear')->setAttribute('type', 'reset'));
|
$clearAction = new FormAction('clearForm', 'Clear');
|
||||||
|
$expected->push($clearAction->setAttribute('type', 'reset'));
|
||||||
$expected->setForm($controller->Form());
|
$expected->setForm($controller->Form());
|
||||||
|
|
||||||
$this->assertEquals($actions, $expected);
|
$this->assertEquals($actions, $expected);
|
||||||
@ -404,7 +408,7 @@ class UserDefinedFormControllerTest extends FunctionalTest
|
|||||||
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
||||||
|
|
||||||
$userForm = $this->setupFormFrontend('upload-form');
|
$userForm = $this->setupFormFrontend('upload-form');
|
||||||
$controller = UserDefinedFormController::create($userForm);
|
$controller = new UserDefinedFormController($userForm);
|
||||||
$field = $this->objFromFixture(EditableFileField::class, 'file-field-1');
|
$field = $this->objFromFixture(EditableFileField::class, 'file-field-1');
|
||||||
|
|
||||||
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
||||||
@ -440,7 +444,7 @@ class UserDefinedFormControllerTest extends FunctionalTest
|
|||||||
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
||||||
|
|
||||||
$userForm = $this->setupFormFrontend('upload-form');
|
$userForm = $this->setupFormFrontend('upload-form');
|
||||||
$controller = UserDefinedFormController::create($userForm);
|
$controller = new UserDefinedFormController($userForm);
|
||||||
$field = $this->objFromFixture(EditableFileField::class, 'file-field-1');
|
$field = $this->objFromFixture(EditableFileField::class, 'file-field-1');
|
||||||
|
|
||||||
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
||||||
@ -511,4 +515,71 @@ class UserDefinedFormControllerTest extends FunctionalTest
|
|||||||
$this->assertEquals(1, $fileDraftCount);
|
$this->assertEquals(1, $fileDraftCount);
|
||||||
$this->assertEquals(0, $fileLiveCount);
|
$this->assertEquals(0, $fileLiveCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testEmailAttachmentMaximumSizeCanBeConfigured()
|
||||||
|
{
|
||||||
|
$udfController = new UserDefinedFormController();
|
||||||
|
$config = Config::modify();
|
||||||
|
$config->set(UserDefinedFormController::class, 'maximum_email_attachment_size', '1M');
|
||||||
|
$this->assertSame(1 * 1024 * 1024, $udfController->getMaximumAllowedEmailAttachmentSize());
|
||||||
|
$config->set(UserDefinedFormController::class, 'maximum_email_attachment_size', '5M');
|
||||||
|
$this->assertSame(5 * 1024 * 1024, $udfController->getMaximumAllowedEmailAttachmentSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParseByteSizeStringTestValues()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['9846', 9846],
|
||||||
|
['1048576', 1048576],
|
||||||
|
['1k', 1024],
|
||||||
|
['1K', 1024],
|
||||||
|
['4k', 4096],
|
||||||
|
['4K', 4096],
|
||||||
|
['1kb', 1024],
|
||||||
|
['1KB', 1024],
|
||||||
|
['4kB', 4096],
|
||||||
|
['4Kb', 4096],
|
||||||
|
['1m', 1048576],
|
||||||
|
['1M', 1048576],
|
||||||
|
['4mb', 4194304],
|
||||||
|
['4MB', 4194304],
|
||||||
|
['25mB', 26214400],
|
||||||
|
['25Mb', 26214400],
|
||||||
|
['1g', 1073741824],
|
||||||
|
['2GB', 2147483648],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getParseByteSizeStringTestValues
|
||||||
|
*/
|
||||||
|
public function testParseByteSizeString($input, $expectedOutput)
|
||||||
|
{
|
||||||
|
$controller = new SizeStringTestableController(); // extends UserDefinedFormController
|
||||||
|
$this->assertSame($expectedOutput, $controller->convertSizeStringToBytes($input));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParseByteSizeStringTestBadValues()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['1234b'],
|
||||||
|
['9846B'],
|
||||||
|
['1kilobyte'],
|
||||||
|
['1 K'],
|
||||||
|
['Four kilobytes'],
|
||||||
|
['4Mbs'],
|
||||||
|
['12Gigs'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getParseByteSizeStringTestBadValues
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testParseByteSizeStringBadValuesThrowException($input)
|
||||||
|
{
|
||||||
|
$this->expectException('\InvalidArgumentException');
|
||||||
|
$controller = new SizeStringTestableController(); // extends UserDefinedFormController
|
||||||
|
$controller->convertSizeStringToBytes($input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
14
tests/php/Control/fixtures/SizeStringTestableController.php
Normal file
14
tests/php/Control/fixtures/SizeStringTestableController.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\UserForms\Tests\Control\fixtures;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\UserForms\Control\UserDefinedFormController;
|
||||||
|
|
||||||
|
class SizeStringTestableController extends UserDefinedFormController implements TestOnly
|
||||||
|
{
|
||||||
|
public function convertSizeStringToBytes($sizeString)
|
||||||
|
{
|
||||||
|
return $this->parseByteSizeString($sizeString);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user