From e1faba82391324735caecf01acd65a1fc9040b45 Mon Sep 17 00:00:00 2001 From: Chirag Chhatrala <60499540+chiragchhatrala@users.noreply.github.com> Date: Mon, 15 Apr 2024 18:42:36 +0530 Subject: [PATCH] Edit submissions file issue (#373) * Edit submissions file issue fixed * handleCompValChange with loader --------- Co-authored-by: Julien Nahum --- .../Forms/PublicFormController.php | 22 +++---- app/Http/Resources/FormSubmissionResource.php | 24 ++++++-- app/Jobs/Form/StoreFormSubmissionJob.php | 33 +++++------ client/components/forms/FileInput.vue | 57 ++++++++++++------- 4 files changed, 82 insertions(+), 54 deletions(-) diff --git a/app/Http/Controllers/Forms/PublicFormController.php b/app/Http/Controllers/Forms/PublicFormController.php index d93f5163..479c0ca8 100644 --- a/app/Http/Controllers/Forms/PublicFormController.php +++ b/app/Http/Controllers/Forms/PublicFormController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Forms; use App\Http\Controllers\Controller; use App\Http\Requests\AnswerFormRequest; use App\Http\Resources\FormResource; +use App\Http\Resources\FormSubmissionResource; use App\Jobs\Form\StoreFormSubmissionJob; use App\Models\Forms\Form; use App\Models\Forms\FormSubmission; @@ -36,13 +37,13 @@ class PublicFormController extends Controller // Disable pro features if needed $form->fill( $formCleaner - ->processForm($request, $form) - ->performCleaning($form->workspace) - ->getData() + ->processForm($request, $form) + ->performCleaning($form->workspace) + ->getData() ); // Increase form view counter if not login - if (! Auth::check()) { + if (!Auth::check()) { $form->views()->create(); } @@ -54,7 +55,7 @@ class PublicFormController extends Controller { // Check that form has user field $form = $request->form; - if (! $form->has_user_field) { + if (!$form->has_user_field) { return []; } @@ -66,8 +67,8 @@ class PublicFormController extends Controller public function showAsset($assetFileName) { - $path = FormController::ASSETS_UPLOAD_PATH.'/'.$assetFileName; - if (! Storage::exists($path)) { + $path = FormController::ASSETS_UPLOAD_PATH . '/' . $assetFileName; + if (!Storage::exists($path)) { return $this->error([ 'message' => 'File not found.', 'file_name' => $assetFileName, @@ -106,13 +107,14 @@ class PublicFormController extends Controller $submissionId = ($submissionId) ? Hashids::decode($submissionId) : false; $submissionId = isset($submissionId[0]) ? $submissionId[0] : false; $form = Form::whereSlug($slug)->whereVisibility('public')->firstOrFail(); - if ($form->workspace == null || ! $form->editable_submissions || ! $submissionId) { + if ($form->workspace == null || !$form->editable_submissions || !$submissionId) { return $this->error([ 'message' => 'Not allowed.', ]); } - $submission = FormSubmission::findOrFail($submissionId); + $submission = new FormSubmissionResource(FormSubmission::findOrFail($submissionId)); + $submission->publiclyAccessed(); if ($submission->form_id != $form->id) { return $this->error([ @@ -120,6 +122,6 @@ class PublicFormController extends Controller ], 403); } - return $this->success(['data' => ($submission) ? $submission->data : []]); + return $this->success($submission->toArray($request)); } } diff --git a/app/Http/Resources/FormSubmissionResource.php b/app/Http/Resources/FormSubmissionResource.php index 20e9775d..4a63a812 100644 --- a/app/Http/Resources/FormSubmissionResource.php +++ b/app/Http/Resources/FormSubmissionResource.php @@ -6,6 +6,8 @@ use Illuminate\Http\Resources\Json\JsonResource; class FormSubmissionResource extends JsonResource { + public bool $publiclyAccessed = false; + /** * Transform the resource into an array. * @@ -15,13 +17,23 @@ class FormSubmissionResource extends JsonResource public function toArray($request) { $this->generateFileLinks(); - $this->addExtraData(); - return [ - 'data' => $this->data, + if (!$this->publiclyAccessed) { + $this->addExtraData(); + } + + return array_merge([ + 'data' => $this->data + ], ($this->publiclyAccessed) ? [] : [ 'form_id' => $this->form_id, - 'id' => $this->id, - ]; + 'id' => $this->id + ]); + } + + public function publiclyAccessed($publiclyAccessed = true) + { + $this->publiclyAccessed = $publiclyAccessed; + return $this; } private function addExtraData() @@ -45,7 +57,7 @@ class FormSubmissionResource extends JsonResource return in_array($field['type'], ['files', 'signature']); }); foreach ($fileFields as $field) { - if (isset($data[$field['id']]) && ! empty($data[$field['id']])) { + if (isset($data[$field['id']]) && !empty($data[$field['id']])) { $data[$field['id']] = collect($data[$field['id']])->filter(function ($file) { return $file !== null && $file; })->map(function ($file) { diff --git a/app/Jobs/Form/StoreFormSubmissionJob.php b/app/Jobs/Form/StoreFormSubmissionJob.php index 2a26e3fd..cb98e4b3 100644 --- a/app/Jobs/Form/StoreFormSubmissionJob.php +++ b/app/Jobs/Form/StoreFormSubmissionJob.php @@ -115,13 +115,14 @@ class StoreFormSubmissionJob implements ShouldQueue // Do required transformation per type (e.g. file uploads) foreach ($data as $answerKey => $answerValue) { $field = $properties->where('id', $answerKey)->first(); - if (! $field) { + if (!$field) { continue; } if ( ($field['type'] == 'url' && isset($field['file_upload']) && $field['file_upload']) - || $field['type'] == 'files') { + || $field['type'] == 'files' + ) { if (is_array($answerValue)) { $finalData[$field['id']] = []; foreach ($answerValue as $file) { @@ -148,7 +149,7 @@ class StoreFormSubmissionJob implements ShouldQueue } // For Phone - if ($field['type'] == 'phone_number' && $answerValue && ctype_alpha(substr($answerValue, 0, 2)) && (! isset($field['use_simple_text_input']) || ! $field['use_simple_text_input'])) { + if ($field['type'] == 'phone_number' && $answerValue && ctype_alpha(substr($answerValue, 0, 2)) && (!isset($field['use_simple_text_input']) || !$field['use_simple_text_input'])) { $finalData[$field['id']] = substr($answerValue, 2); } } @@ -161,7 +162,7 @@ class StoreFormSubmissionJob implements ShouldQueue { $newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id); - return Storage::exists($newPath.'/'.$value); + return Storage::exists($newPath . '/' . $value); } /** @@ -179,10 +180,10 @@ class StoreFormSubmissionJob implements ShouldQueue } if (filter_var($value, FILTER_VALIDATE_URL) !== false && str_contains($value, parse_url(config('app.url'))['host'])) { // In case of prefill we have full url so convert to s3 - $fileName = basename($value); - $path = FormController::ASSETS_UPLOAD_PATH.'/'.$fileName; + $fileName = explode('?', basename($value))[0]; + $path = FormController::ASSETS_UPLOAD_PATH . '/' . $fileName; $newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id); - Storage::move($path, $newPath.'/'.$fileName); + Storage::move($path, $newPath . '/' . $fileName); return $fileName; } @@ -194,13 +195,13 @@ class StoreFormSubmissionJob implements ShouldQueue $fileNameParser = StorageFileNameParser::parse($value); // Make sure we retrieve the file in tmp storage, move it to persistent - $fileName = PublicFormController::TMP_FILE_UPLOAD_PATH.'/'.$fileNameParser->uuid; - if (! Storage::exists($fileName)) { + $fileName = PublicFormController::TMP_FILE_UPLOAD_PATH . '/' . $fileNameParser->uuid; + if (!Storage::exists($fileName)) { // File not found, we skip return null; } $newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id); - $completeNewFilename = $newPath.'/'.$fileNameParser->getMovedFileName(); + $completeNewFilename = $newPath . '/' . $fileNameParser->getMovedFileName(); \Log::debug('Moving file to permanent storage.', [ 'uuid' => $fileNameParser->uuid, @@ -215,13 +216,13 @@ class StoreFormSubmissionJob implements ShouldQueue private function storeSignature(?string $value) { - if ($value == null || ! isset(explode(',', $value)[1])) { + if ($value == null || !isset(explode(',', $value)[1])) { return null; } - $fileName = 'sign_'.(string) Str::uuid().'.png'; + $fileName = 'sign_' . (string) Str::uuid() . '.png'; $newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id); - $completeNewFilename = $newPath.'/'.$fileName; + $completeNewFilename = $newPath . '/' . $fileName; Storage::put($completeNewFilename, base64_decode(explode(',', $value)[1])); @@ -240,9 +241,9 @@ class StoreFormSubmissionJob implements ShouldQueue return isset($property['hidden']) && isset($property['prefill']) && FormLogicPropertyResolver::isHidden($property, $this->submissionData) - && ! is_null($property['prefill']) - && ! in_array($property['type'], ['files']) - && ! ($property['type'] == 'url' && isset($property['file_upload']) && $property['file_upload']); + && !is_null($property['prefill']) + && !in_array($property['type'], ['files']) + && !($property['type'] == 'url' && isset($property['file_upload']) && $property['file_upload']); })->each(function (array $property) use (&$formData) { if ($property['type'] === 'date' && isset($property['prefill_today']) && $property['prefill_today']) { $formData[$property['id']] = now()->format((isset($property['with_time']) && $property['with_time']) ? 'Y-m-d H:i' : 'Y-m-d'); diff --git a/client/components/forms/FileInput.vue b/client/components/forms/FileInput.vue index 2bc98469..bb78f505 100644 --- a/client/components/forms/FileInput.vue +++ b/client/components/forms/FileInput.vue @@ -129,34 +129,47 @@ export default { handler(files) { this.compVal = files.map((file) => file.url) } + }, + 'compVal': { + deep: true, + handler(newVal, oldVal) { + if (!oldVal) { + this.handleCompValChange(); + } + } } }, - async created() { - if (typeof this.compVal === 'string' || this.compVal instanceof String) { - await this.getFileFromUrl(this.compVal).then((fileObj) => { - this.files = [{ - file: fileObj, - url: this.compVal, - src: this.getFileSrc(fileObj) - }] - }) - } else if (this.compVal && this.compVal.length > 0) { - const tmpFiles = [] - for (let i = 0; i < this.compVal.length; i++) { - await this.getFileFromUrl(this.compVal[i]).then((fileObj) => { - tmpFiles.push({ - file: fileObj, - url: this.compVal[i], - src: this.getFileSrc(fileObj) - }) - }) - } - this.files = tmpFiles - } + mounted() { + this.handleCompValChange(); }, methods: { + async handleCompValChange() { + this.loading = true + if (typeof this.compVal === 'string' || this.compVal instanceof String) { + await this.getFileFromUrl(this.compVal).then((fileObj) => { + this.files = [{ + file: fileObj, + url: this.compVal, + src: this.getFileSrc(fileObj) + }] + }) + } else if (this.compVal && this.compVal.length > 0) { + const tmpFiles = [] + for (let i = 0; i < this.compVal.length; i++) { + await this.getFileFromUrl(this.compVal[i]).then((fileObj) => { + tmpFiles.push({ + file: fileObj, + url: (typeof this.compVal[i] === 'object') ? this.compVal[i]?.file_url : this.compVal[i], + src: this.getFileSrc(fileObj) + }) + }) + } + this.files = tmpFiles + } + this.loading = false + }, clearAll() { this.files = [] },