From 16f6152b17d7744d01e11e343d92933364812d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sheila=20Ba=C3=B1ez?= Date: Mon, 2 Sep 2019 11:37:19 +1200 Subject: [PATCH 1/2] Allow overwrite existing uploads --- .../PartialSubmissionController.php | 25 +++++---- src/controllers/PartialUserFormController.php | 53 ++++++++++++++----- src/models/PartialFileFieldSubmission.php | 8 +++ src/models/PartialFormSubmission.php | 13 +++++ 4 files changed, 78 insertions(+), 21 deletions(-) diff --git a/src/controllers/PartialSubmissionController.php b/src/controllers/PartialSubmissionController.php index 7a16657..172aee8 100644 --- a/src/controllers/PartialSubmissionController.php +++ b/src/controllers/PartialSubmissionController.php @@ -165,29 +165,36 @@ protected function savePartialFile($formData, array $filter, EditableFormField\E $partialFileSubmission = PartialFileFieldSubmission::create($partialData); $partialFileSubmission->write(); } - // Don't overwrite existing uploads - if (!$partialFileSubmission->UploadedFileID && is_array($formData['Value'])) { - $file = $this->uploadFile($formData, $editableField); + + if (is_array($formData['Value'])) { + $file = $this->uploadFile($formData, $editableField, $partialFileSubmission); $partialFileSubmission->UploadedFileID = $file->ID ?? 0; + $partialFileSubmission->write(); } - $partialFileSubmission->write(); } /** * @param array $formData * @param EditableFormField\EditableFileField $field + * @param PartialFileFieldSubmission $partialFileSubmission * @return bool|File - * @throws \Exception + * @throws Exception */ - protected function uploadFile($formData, $field) + protected function uploadFile($formData, $field, $partialFileSubmission) { if (!empty($formData['Value']['name'])) { $foldername = $field->getFormField()->getFolderName(); - // create the file from post data + if (!$partialFileSubmission->UploadedFileID) { + $file = File::create(); + $file->ShowInSearch = 0; + } else { + // Allow overwrite existing uploads + $file = $partialFileSubmission->UploadedFile(); + } + + // Upload the file from post data $upload = Upload::create(); - $file = File::create(); - $file->ShowInSearch = 0; if ($upload->loadIntoFile($formData['Value'], $file, $foldername)) { return $file; } diff --git a/src/controllers/PartialUserFormController.php b/src/controllers/PartialUserFormController.php index 9ba6501..48ba70c 100644 --- a/src/controllers/PartialUserFormController.php +++ b/src/controllers/PartialUserFormController.php @@ -8,6 +8,7 @@ use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware; +use SilverStripe\Forms\Form; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBHTMLText; @@ -67,28 +68,28 @@ public function partial(HTTPRequest $request) $request->getSession()->set(PartialSubmissionController::SESSION_KEY, $partial->ID); } - // TODO: Recognize visitor with the password // Set data record and load the form - $this->dataRecord = DataObject::get_by_id($partial->UserDefinedFormClass, $partial->UserDefinedFormID); - $this->setFailover($this->dataRecord); + $record = DataObject::get_by_id($partial->UserDefinedFormClass, $partial->UserDefinedFormID); + $controller = parent::create($record); + $controller->doInit(); - $form = $this->Form(); - $fields = $partial->PartialFields()->map('Name', 'Value')->toArray(); - $form->loadDataFrom($fields); + $form = $controller->Form(); + $form->loadDataFrom($partial->getFields()); + $this->populateFileData($form, $partial); // Copied from {@link UserDefinedFormController} - if ($this->Content && $form && !$this->config()->disable_form_content_shortcode) { - $hasLocation = stristr($this->Content, '$UserDefinedForm'); + if ($controller->Content && $form && !$controller->config()->disable_form_content_shortcode) { + $hasLocation = stristr($controller->Content, '$UserDefinedForm'); if ($hasLocation) { /** @see Requirements_Backend::escapeReplacement */ $formEscapedForRegex = addcslashes($form->forTemplate(), '\\$'); $content = preg_replace( '/(]*>)?\\$UserDefinedForm(<\\/p>)?/i', $formEscapedForRegex, - $this->Content + $controller->Content ); - return $this->customise([ + return $controller->customise([ 'Content' => DBField::create_field('HTMLText', $content), 'Form' => '', 'PartialLink' => $partial->getPartialLink() @@ -96,10 +97,38 @@ public function partial(HTTPRequest $request) } } - return $this->customise([ - 'Content' => DBField::create_field('HTMLText', $this->Content), + return $controller->customise([ + 'Content' => DBField::create_field('HTMLText', $controller->Content), 'Form' => $form, 'PartialLink' => $partial->getPartialLink() ])->renderWith([static::class, Page::class]); } + + /** + * Set the uploaded filenames as right title of the file fields + * + * @param Form $form + * @param PartialFormSubmission $partialSubmission + */ + protected function populateFileData($form, $partialSubmission) + { + $uploads = $partialSubmission->PartialUploads()->filter([ + 'UploadedFileID:not'=> null + ]); + + if (!$uploads->exists()) { + return; + } + + $fields = $form->Fields(); + foreach ($uploads as $upload) { + $fields->dataFieldByName($upload->Name) + ->setRightTitle( + sprintf( + 'Uploaded: %s (Attach a new file to replace the uploaded file)', + $upload->UploadedFile()->Name + ) + ); + } + } } diff --git a/src/models/PartialFileFieldSubmission.php b/src/models/PartialFileFieldSubmission.php index 5958044..039f1d1 100644 --- a/src/models/PartialFileFieldSubmission.php +++ b/src/models/PartialFileFieldSubmission.php @@ -71,4 +71,12 @@ public function canDelete($member = null) return parent::canDelete($member); } + + /** + * @return string + */ + public function getFilename() + { + return $this->UploadedFileID ? $this->UploadedFile()->Name : ''; + } } diff --git a/src/models/PartialFormSubmission.php b/src/models/PartialFormSubmission.php index a7503d5..f3baa7d 100644 --- a/src/models/PartialFormSubmission.php +++ b/src/models/PartialFormSubmission.php @@ -233,4 +233,17 @@ public function generateKey($token) { return hash_pbkdf2('sha256', $token, $this->TokenSalt, 1000, 16); } + + /** + * Get all partial fields for loading data into the form + * + * @return array + */ + public function getFields() + { + $formFields = $this->PartialFields()->map('Name', 'Value')->toArray(); + $fileFields = $this->PartialUploads()->map('Name', 'Filename')->toArray(); + + return $formFields + $fileFields; + } } From a84a81c56199809cd0d549e56b50c4c0ba03ad04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sheila=20Ba=C3=B1ez?= Date: Mon, 2 Sep 2019 15:54:47 +1200 Subject: [PATCH 2/2] Add tests for data populate --- .../PartialSubmissionController.php | 5 +-- src/controllers/PartialUserFormController.php | 5 +-- src/models/PartialFileFieldSubmission.php | 8 ----- src/models/PartialFormSubmission.php | 4 +-- tests/fixtures/partialformtest.yml | 32 +++++++++++++++---- tests/templates/Page.ss | 7 ++++ tests/unit/PartialFileFieldSubmissionTest.php | 1 + tests/unit/PartialUserFormControllerTest.php | 24 +++++++++++--- 8 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 tests/templates/Page.ss diff --git a/src/controllers/PartialSubmissionController.php b/src/controllers/PartialSubmissionController.php index 172aee8..8eba193 100644 --- a/src/controllers/PartialSubmissionController.php +++ b/src/controllers/PartialSubmissionController.php @@ -186,8 +186,9 @@ protected function uploadFile($formData, $field, $partialFileSubmission) $foldername = $field->getFormField()->getFolderName(); if (!$partialFileSubmission->UploadedFileID) { - $file = File::create(); - $file->ShowInSearch = 0; + $file = File::create([ + 'ShowInSearch' => 0 + ]); } else { // Allow overwrite existing uploads $file = $partialFileSubmission->UploadedFile(); diff --git a/src/controllers/PartialUserFormController.php b/src/controllers/PartialUserFormController.php index 48ba70c..a412d0b 100644 --- a/src/controllers/PartialUserFormController.php +++ b/src/controllers/PartialUserFormController.php @@ -63,8 +63,9 @@ public function partial(HTTPRequest $request) return $this->httpError(404); } - // Set the session if the last session has expired - if (!$request->getSession()->get(PartialSubmissionController::SESSION_KEY)) { + // Set the session if the last session has expired or from another submission + $session = $request->getSession()->get(PartialSubmissionController::SESSION_KEY); + if (!$session || $session !== $partial->ID) { $request->getSession()->set(PartialSubmissionController::SESSION_KEY, $partial->ID); } diff --git a/src/models/PartialFileFieldSubmission.php b/src/models/PartialFileFieldSubmission.php index 039f1d1..5958044 100644 --- a/src/models/PartialFileFieldSubmission.php +++ b/src/models/PartialFileFieldSubmission.php @@ -71,12 +71,4 @@ public function canDelete($member = null) return parent::canDelete($member); } - - /** - * @return string - */ - public function getFilename() - { - return $this->UploadedFileID ? $this->UploadedFile()->Name : ''; - } } diff --git a/src/models/PartialFormSubmission.php b/src/models/PartialFormSubmission.php index f3baa7d..2dd5be4 100644 --- a/src/models/PartialFormSubmission.php +++ b/src/models/PartialFormSubmission.php @@ -242,8 +242,8 @@ public function generateKey($token) public function getFields() { $formFields = $this->PartialFields()->map('Name', 'Value')->toArray(); - $fileFields = $this->PartialUploads()->map('Name', 'Filename')->toArray(); + $fileFields = $this->PartialUploads()->map('Name', 'FileName')->toArray(); - return $formFields + $fileFields; + return array_merge($formFields, $fileFields); } } diff --git a/tests/fixtures/partialformtest.yml b/tests/fixtures/partialformtest.yml index 3bc2218..79ccf3b 100644 --- a/tests/fixtures/partialformtest.yml +++ b/tests/fixtures/partialformtest.yml @@ -1,26 +1,39 @@ SilverStripe\UserForms\Model\UserDefinedForm: form1: Title: Form 1 +Firesphere\PartialUserforms\Models\PartialFormSubmission: + submission1: + UserDefinedForm: =>SilverStripe\UserForms\Model\UserDefinedForm.form1 + Parent: =>SilverStripe\UserForms\Model\UserDefinedForm.form1 + TokenSalt: aa11ss22dd33ff44 + Token: q1w2e3r4t5y6u7i8 Firesphere\PartialUserForms\Models\PartialFieldSubmission: field1: Name: 'fullname' Value: 'Test' Title: 'Full name' + SubmittedForm: =>Firesphere\PartialUserforms\Models\PartialFormSubmission.submission1 field2: Name: 'email' Value: 'test@test.com' Title: 'Email address' + SubmittedForm: =>Firesphere\PartialUserforms\Models\PartialFormSubmission.submission1 field3: Name: 'question' Value: 'I have a question, what''s the ultimate question of life, the universe, and everything' Title: 'Question' -Firesphere\PartialUserforms\Models\PartialFormSubmission: - submission1: - UserDefinedForm: =>SilverStripe\UserForms\Model\UserDefinedForm.form1 - Parent: =>SilverStripe\UserForms\Model\UserDefinedForm.form1 - PartialFields: =>Firesphere\PartialUserForms\Models\PartialFieldSubmission.field1,=>Firesphere\PartialUserForms\Models\PartialFieldSubmission.field2,=>Firesphere\PartialUserForms\Models\PartialFieldSubmission.field3 - TokenSalt: aa11ss22dd33ff44 - Token: q1w2e3r4t5y6u7i8 + SubmittedForm: =>Firesphere\PartialUserforms\Models\PartialFormSubmission.submission1 +SilverStripe\Assets\File: + file1: + Name: 'Hans.png' + Title: 'Hans Image' + Filename: partialuserforms/tests/fixtures/Hans-fullsize-sqr.png +Firesphere\PartialUserForms\Models\PartialFileFieldSubmission: + field1: + Name: 'File' + UploadedFile: =>SilverStripe\Assets\File.file1 + SubmittedForm: =>Firesphere\PartialUserforms\Models\PartialFormSubmission.submission1 + Parent: =>Firesphere\PartialUserforms\Models\PartialFormSubmission.submission1 SilverStripe\UserForms\Model\EditableFormField\EditableTextField: textfield1: Name: 'Field1' @@ -37,6 +50,11 @@ SilverStripe\UserForms\Model\EditableFormField\EditableTextField: Title: 'Field 3' ParentClass: SilverStripe\UserForms\Model\UserDefinedForm Parent: =>SilverStripe\UserForms\Model\UserDefinedForm.form1 + textfield4: + Name: 'question' + Title: 'Question' + ParentClass: SilverStripe\UserForms\Model\UserDefinedForm + Parent: =>SilverStripe\UserForms\Model\UserDefinedForm.form1 SilverStripe\UserForms\Model\EditableFormField\EditableFileField: filefield1: Name: 'File' diff --git a/tests/templates/Page.ss b/tests/templates/Page.ss new file mode 100644 index 0000000..a8880b4 --- /dev/null +++ b/tests/templates/Page.ss @@ -0,0 +1,7 @@ + + + + + $Layout + + diff --git a/tests/unit/PartialFileFieldSubmissionTest.php b/tests/unit/PartialFileFieldSubmissionTest.php index f37c36b..84cd97d 100644 --- a/tests/unit/PartialFileFieldSubmissionTest.php +++ b/tests/unit/PartialFileFieldSubmissionTest.php @@ -4,6 +4,7 @@ use Firesphere\PartialUserforms\Models\PartialFileFieldSubmission; use Firesphere\PartialUserforms\Models\PartialFormSubmission; +use SilverStripe\Assets\File; use SilverStripe\Dev\SapphireTest; use SilverStripe\Security\DefaultAdminService; use SilverStripe\Security\Security; diff --git a/tests/unit/PartialUserFormControllerTest.php b/tests/unit/PartialUserFormControllerTest.php index 18773e4..0c6f3f5 100644 --- a/tests/unit/PartialUserFormControllerTest.php +++ b/tests/unit/PartialUserFormControllerTest.php @@ -3,6 +3,7 @@ namespace Firesphere\PartialUserforms\Tests; use Firesphere\PartialUserforms\Models\PartialFormSubmission; +use SilverStripe\Assets\File; use SilverStripe\Dev\FunctionalTest; use SilverStripe\UserForms\Model\UserDefinedForm; @@ -23,13 +24,8 @@ public function testPartialPage() $this->assertEquals(404, $result->getStatusCode()); } - /** - * @todo - */ public function testPartialValidKeyToken() { - $this->markTestSkipped('Revisit and set up themes for testing'); - $token = 'q1w2e3r4t5y6u7i8'; // No Parent $key = singleton(PartialFormSubmission::class)->generateKey($token); @@ -67,9 +63,27 @@ public function testPartialInvalidKey() $this->assertEquals(404, $result->getStatusCode()); } + public function testDataPopulated() + { + $partial = $this->objFromFixture(PartialFormSubmission::class, 'submission1'); + $token = 'q1w2e3r4t5y6u7i8'; + $key = $partial->generateKey($token); + + $response = $this->get("/partial/{$key}/{$token}"); + $this->assertEquals(200, $response->getStatusCode()); + + $this->assertCount(1, $partial->PartialUploads()); + $this->assertCount(3, $partial->PartialFields()); + + $content = $response->getBody(); + $this->assertContains('I have a question', $content); + $this->assertContains('Hans-fullsize-sqr.png', $content); + } + public function setUp() { parent::setUp(); $this->objFromFixture(UserDefinedForm::class, 'form1')->publishRecursive(); + $this->objFromFixture(File::class, 'file1')->publishRecursive(); } }