Edit submissions file issue (#373)

* Edit submissions file issue fixed

* handleCompValChange with loader

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
Chirag Chhatrala 2024-04-15 18:42:36 +05:30 committed by GitHub
parent 4f4f7128fa
commit e1faba8239
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 82 additions and 54 deletions

View File

@ -5,6 +5,7 @@ namespace App\Http\Controllers\Forms;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests\AnswerFormRequest; use App\Http\Requests\AnswerFormRequest;
use App\Http\Resources\FormResource; use App\Http\Resources\FormResource;
use App\Http\Resources\FormSubmissionResource;
use App\Jobs\Form\StoreFormSubmissionJob; use App\Jobs\Form\StoreFormSubmissionJob;
use App\Models\Forms\Form; use App\Models\Forms\Form;
use App\Models\Forms\FormSubmission; use App\Models\Forms\FormSubmission;
@ -36,13 +37,13 @@ class PublicFormController extends Controller
// Disable pro features if needed // Disable pro features if needed
$form->fill( $form->fill(
$formCleaner $formCleaner
->processForm($request, $form) ->processForm($request, $form)
->performCleaning($form->workspace) ->performCleaning($form->workspace)
->getData() ->getData()
); );
// Increase form view counter if not login // Increase form view counter if not login
if (! Auth::check()) { if (!Auth::check()) {
$form->views()->create(); $form->views()->create();
} }
@ -54,7 +55,7 @@ class PublicFormController extends Controller
{ {
// Check that form has user field // Check that form has user field
$form = $request->form; $form = $request->form;
if (! $form->has_user_field) { if (!$form->has_user_field) {
return []; return [];
} }
@ -66,8 +67,8 @@ class PublicFormController extends Controller
public function showAsset($assetFileName) public function showAsset($assetFileName)
{ {
$path = FormController::ASSETS_UPLOAD_PATH.'/'.$assetFileName; $path = FormController::ASSETS_UPLOAD_PATH . '/' . $assetFileName;
if (! Storage::exists($path)) { if (!Storage::exists($path)) {
return $this->error([ return $this->error([
'message' => 'File not found.', 'message' => 'File not found.',
'file_name' => $assetFileName, 'file_name' => $assetFileName,
@ -106,13 +107,14 @@ class PublicFormController extends Controller
$submissionId = ($submissionId) ? Hashids::decode($submissionId) : false; $submissionId = ($submissionId) ? Hashids::decode($submissionId) : false;
$submissionId = isset($submissionId[0]) ? $submissionId[0] : false; $submissionId = isset($submissionId[0]) ? $submissionId[0] : false;
$form = Form::whereSlug($slug)->whereVisibility('public')->firstOrFail(); $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([ return $this->error([
'message' => 'Not allowed.', 'message' => 'Not allowed.',
]); ]);
} }
$submission = FormSubmission::findOrFail($submissionId); $submission = new FormSubmissionResource(FormSubmission::findOrFail($submissionId));
$submission->publiclyAccessed();
if ($submission->form_id != $form->id) { if ($submission->form_id != $form->id) {
return $this->error([ return $this->error([
@ -120,6 +122,6 @@ class PublicFormController extends Controller
], 403); ], 403);
} }
return $this->success(['data' => ($submission) ? $submission->data : []]); return $this->success($submission->toArray($request));
} }
} }

View File

@ -6,6 +6,8 @@ use Illuminate\Http\Resources\Json\JsonResource;
class FormSubmissionResource extends JsonResource class FormSubmissionResource extends JsonResource
{ {
public bool $publiclyAccessed = false;
/** /**
* Transform the resource into an array. * Transform the resource into an array.
* *
@ -15,13 +17,23 @@ class FormSubmissionResource extends JsonResource
public function toArray($request) public function toArray($request)
{ {
$this->generateFileLinks(); $this->generateFileLinks();
$this->addExtraData();
return [ if (!$this->publiclyAccessed) {
'data' => $this->data, $this->addExtraData();
}
return array_merge([
'data' => $this->data
], ($this->publiclyAccessed) ? [] : [
'form_id' => $this->form_id, 'form_id' => $this->form_id,
'id' => $this->id, 'id' => $this->id
]; ]);
}
public function publiclyAccessed($publiclyAccessed = true)
{
$this->publiclyAccessed = $publiclyAccessed;
return $this;
} }
private function addExtraData() private function addExtraData()
@ -45,7 +57,7 @@ class FormSubmissionResource extends JsonResource
return in_array($field['type'], ['files', 'signature']); return in_array($field['type'], ['files', 'signature']);
}); });
foreach ($fileFields as $field) { 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) { $data[$field['id']] = collect($data[$field['id']])->filter(function ($file) {
return $file !== null && $file; return $file !== null && $file;
})->map(function ($file) { })->map(function ($file) {

View File

@ -115,13 +115,14 @@ class StoreFormSubmissionJob implements ShouldQueue
// Do required transformation per type (e.g. file uploads) // Do required transformation per type (e.g. file uploads)
foreach ($data as $answerKey => $answerValue) { foreach ($data as $answerKey => $answerValue) {
$field = $properties->where('id', $answerKey)->first(); $field = $properties->where('id', $answerKey)->first();
if (! $field) { if (!$field) {
continue; continue;
} }
if ( if (
($field['type'] == 'url' && isset($field['file_upload']) && $field['file_upload']) ($field['type'] == 'url' && isset($field['file_upload']) && $field['file_upload'])
|| $field['type'] == 'files') { || $field['type'] == 'files'
) {
if (is_array($answerValue)) { if (is_array($answerValue)) {
$finalData[$field['id']] = []; $finalData[$field['id']] = [];
foreach ($answerValue as $file) { foreach ($answerValue as $file) {
@ -148,7 +149,7 @@ class StoreFormSubmissionJob implements ShouldQueue
} }
// For Phone // 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); $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); $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 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); $fileName = explode('?', basename($value))[0];
$path = FormController::ASSETS_UPLOAD_PATH.'/'.$fileName; $path = FormController::ASSETS_UPLOAD_PATH . '/' . $fileName;
$newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id); $newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id);
Storage::move($path, $newPath.'/'.$fileName); Storage::move($path, $newPath . '/' . $fileName);
return $fileName; return $fileName;
} }
@ -194,13 +195,13 @@ class StoreFormSubmissionJob implements ShouldQueue
$fileNameParser = StorageFileNameParser::parse($value); $fileNameParser = StorageFileNameParser::parse($value);
// Make sure we retrieve the file in tmp storage, move it to persistent // Make sure we retrieve the file in tmp storage, move it to persistent
$fileName = PublicFormController::TMP_FILE_UPLOAD_PATH.'/'.$fileNameParser->uuid; $fileName = PublicFormController::TMP_FILE_UPLOAD_PATH . '/' . $fileNameParser->uuid;
if (! Storage::exists($fileName)) { if (!Storage::exists($fileName)) {
// File not found, we skip // File not found, we skip
return null; return null;
} }
$newPath = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $this->form->id); $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.', [ \Log::debug('Moving file to permanent storage.', [
'uuid' => $fileNameParser->uuid, 'uuid' => $fileNameParser->uuid,
@ -215,13 +216,13 @@ class StoreFormSubmissionJob implements ShouldQueue
private function storeSignature(?string $value) private function storeSignature(?string $value)
{ {
if ($value == null || ! isset(explode(',', $value)[1])) { if ($value == null || !isset(explode(',', $value)[1])) {
return null; 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); $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])); Storage::put($completeNewFilename, base64_decode(explode(',', $value)[1]));
@ -240,9 +241,9 @@ class StoreFormSubmissionJob implements ShouldQueue
return isset($property['hidden']) return isset($property['hidden'])
&& isset($property['prefill']) && isset($property['prefill'])
&& FormLogicPropertyResolver::isHidden($property, $this->submissionData) && FormLogicPropertyResolver::isHidden($property, $this->submissionData)
&& ! is_null($property['prefill']) && !is_null($property['prefill'])
&& ! in_array($property['type'], ['files']) && !in_array($property['type'], ['files'])
&& ! ($property['type'] == 'url' && isset($property['file_upload']) && $property['file_upload']); && !($property['type'] == 'url' && isset($property['file_upload']) && $property['file_upload']);
})->each(function (array $property) use (&$formData) { })->each(function (array $property) use (&$formData) {
if ($property['type'] === 'date' && isset($property['prefill_today']) && $property['prefill_today']) { 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'); $formData[$property['id']] = now()->format((isset($property['with_time']) && $property['with_time']) ? 'Y-m-d H:i' : 'Y-m-d');

View File

@ -129,34 +129,47 @@ export default {
handler(files) { handler(files) {
this.compVal = files.map((file) => file.url) this.compVal = files.map((file) => file.url)
} }
},
'compVal': {
deep: true,
handler(newVal, oldVal) {
if (!oldVal) {
this.handleCompValChange();
}
}
} }
}, },
async created() { mounted() {
if (typeof this.compVal === 'string' || this.compVal instanceof String) { this.handleCompValChange();
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
}
}, },
methods: { 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() { clearAll() {
this.files = [] this.files = []
}, },