diff --git a/_config/extensions.yml b/_config/extensions.yml index 3e243dccb..5ec2910c4 100644 --- a/_config/extensions.yml +++ b/_config/extensions.yml @@ -4,3 +4,6 @@ Name: userformsextensions SilverStripe\UserForms\Model\UserDefinedForm: extensions: UpgradePolymorphicExtension: SilverStripe\UserForms\Extension\UpgradePolymorphicExtension +SilverStripe\Assets\File: + extensions: + - SilverStripe\UserForms\Extension\UserFormFileExtension diff --git a/code/Control/UserDefinedFormController.php b/code/Control/UserDefinedFormController.php index 692f5ca8f..a14b21ecc 100644 --- a/code/Control/UserDefinedFormController.php +++ b/code/Control/UserDefinedFormController.php @@ -21,6 +21,7 @@ use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationResult; use SilverStripe\Security\Security; +use SilverStripe\UserForms\Extension\UserFormFileExtension; use SilverStripe\UserForms\Form\UserForm; use SilverStripe\UserForms\Model\EditableFormField; use SilverStripe\UserForms\Model\EditableFormField\EditableFileField; @@ -269,6 +270,7 @@ public function process($data, $form) /** @var AssetContainer|File $file */ $file = $upload->getFile(); $file->ShowInSearch = 0; + $file->UserFormUpload = UserFormFileExtension::USER_FORM_UPLOAD_TRUE; $file->write(); // generate image thumbnail to show in asset-admin diff --git a/code/Extension/UserFormFileExtension.php b/code/Extension/UserFormFileExtension.php new file mode 100644 index 000000000..75f30a68a --- /dev/null +++ b/code/Extension/UserFormFileExtension.php @@ -0,0 +1,80 @@ + "Enum('f, t', null)", + ]; + + private static $belongs_to = [ + 'SubmittedFileField' => SubmittedFileField::class + ]; + + /** + * Check if the file is associated with a userform submission + * Save the result in the database as a tri-state for two reasons: + * a) performance - prevent the need for an extra DB query + * b) if in the future the UserForm submission is deleted and the uploaded file is not (file is orphaned), + * then it is still recorded that the file was originally uploaded from a userform submission + * + * @param bool $value + * @see File::isTrackedFormUpload(), UserDefinedFormController::process() + */ + public function updateTrackedFormUpload(&$value): void + { + /** @var File|Versioned|UserFormFileExtension $file */ + $file = $this->owner; + if ($file->UserFormUpload != self::USER_FORM_UPLOAD_UNKNOWN) { + $value = $file->UserFormUpload == self::USER_FORM_UPLOAD_TRUE; + return; + } + if ($file->ClassName == Folder::class) { + $value = false; + } else { + $value = $file->SubmittedFileField()->exists(); + } + $this->updateDB($value); + } + + /** + * Update File.UserFormUpload draft table without altering File.LastEdited + * + * @param bool $value + */ + private function updateDB(bool $value): void + { + if (!$this->owner->isInDB()) { + return; + } + $tableName = Convert::raw2sql(DataObject::getSchema()->tableName(File::class)); + $column = 'UserFormUpload'; + $enumVal = $value ? self::USER_FORM_UPLOAD_TRUE : self::USER_FORM_UPLOAD_FALSE; + SQLUpdate::create() + ->setTable(sprintf('"%s"', $tableName)) + ->addWhere(['"ID" = ?' => [$this->owner->ID]]) + ->addAssignments([sprintf('"%s"', $column) => $enumVal]) + ->execute(); + } +} diff --git a/composer.json b/composer.json index c2a17ac6e..22a9811c0 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,7 @@ } ], "require": { + "php": ">=7.1", "silverstripe/cms": "^4.0", "symbiote/silverstripe-gridfieldextensions": "^3.1", "silverstripe/segment-field": "^2.0", diff --git a/tests/Extension/UserFormFileExtensionTest.php b/tests/Extension/UserFormFileExtensionTest.php new file mode 100644 index 000000000..13af9f31d --- /dev/null +++ b/tests/Extension/UserFormFileExtensionTest.php @@ -0,0 +1,49 @@ +write(); + $this->assertNull($file->UserFormUpload); + + $value = true; + $file->invokeWithExtensions('updateTrackedFormUpload', $value); + $this->assertFalse($value); + + // refresh DataObject to get latest DB changes + $file = File::get()->byID($file->ID); + + $this->assertEquals(UserFormFileExtension::USER_FORM_UPLOAD_FALSE, $file->UserFormUpload); + } + + public function testUpdateIsUserFormUploadTrue() + { + $file = File::create(); + $file->write(); + $this->assertNull($file->UserFormUpload); + + $submittedFileField = SubmittedFileField::create(); + $submittedFileField->UploadedFileID = $file->ID; + $submittedFileField->write(); + + $value = false; + $file->invokeWithExtensions('updateTrackedFormUpload', $value); + $this->assertTrue($value); + + // refresh DataObject to get latest DB changes + $file = File::get()->byID($file->ID); + + $this->assertEquals(UserFormFileExtension::USER_FORM_UPLOAD_TRUE, $file->UserFormUpload); + } +}