Files
healthcareapi/app/Http/Requests/EditDiseaseRecordRequest.php
2026-06-08 19:58:50 +07:00

246 lines
11 KiB
PHP

<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
use App\Helpers\ResponseJson;
use App\Models\Disease;
use Illuminate\Support\Facades\Log;
class EditDiseaseRecordRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
protected function prepareForValidation(): void
{
$this->merge([
'diseaseId' => $this->route('diseaseId'),
'recordId' => $this->route('recordId')
]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$mimeTypeMap = [
'audio' => [
'aac', 'midi', 'mp3', 'ogg', 'wav', 'webm', 'flac', 'aiff', 'amr', 'opus'
],
'video' => [
'mp4', 'avi', 'mkv', 'webm', 'ogg', '3gp', 'flv', 'mov',
'wmv', 'mpg', 'mpeg', 'm4v', 'h264', 'hevc'
],
'image' => [
'jpeg', 'jpg', 'png', 'gif', 'bmp', 'webp', 'tiff', 'svg', 'heif', 'heic',
'ico', 'jp2', 'j2k', 'avif'
],
'text-document' => [
'pdf', 'doc', 'docx', 'txt'
],
'compressed-document' => [
'zip', '7z', 'tar', 'gz', 'rar', 'bz2', 'xz'
],
'spreadsheet' => [
'xls', 'xlsx', 'csv', 'ods'
],
];
$rules = [
'diseaseId' => 'required|integer|exists:diseases,id',
'recordId' => [
'required',
'integer',
'exists:disease_records,id',
function ($attribute, $value, $fail) {
$exists = \App\Models\DiseaseRecord::where('id', $value)
->where('disease_id', $this->route('diseaseId'))
->exists();
if (!$exists) {
$fail('The selected record does not belong to the specified disease.');
}
},
],
];
if ($this->filled('diseaseId')) {
try {
$disease = Disease::findOrFail($this->route('diseaseId'));
if ($disease && isset($disease->schema['columns'])) {
foreach ($disease->schema['columns'] as $column) {
$columnName = $column['name'];
$columnRules = [];
switch ($column['type']) {
case 'string':
case 'text':
$columnRules[] = 'sometimes|required|string';
break;
case 'integer':
$columnRules[] = 'sometimes|required|integer';
break;
case 'decimal':
case 'float':
$columnRules[] = 'sometimes|required|numeric';
break;
case 'datetime':
case 'date':
$columnRules[] = 'sometimes|required|date';
break;
case 'time':
$columnRules[] = 'sometimes|required|date_format:H:i';
break;
case 'file':
$columnRules[] = 'sometimes|required'; // Ensures a file is uploaded.
// Check if a 'format' is defined in the schema for the column.
if (!empty($column['multiple'])) {
// Ensure the field is an array of files.
$rules[$columnName] = 'sometimes|required|array|min:1';
// Apply validation to each file in the array.
$fileRules = ['file', 'max:20480']; // Start with basic file validation.
// Add MIME type validation if a format is specified.
if (!empty($column['format'])) {
$category = trim($column['format'], '.'); // Strip the dot from the format.
if (array_key_exists($category, $mimeTypeMap)) {
$formats = $mimeTypeMap[$category];
$fileRules[] = 'mimes:' . implode(',', $formats);
} else {
Log::warning("Unsupported format '{$column['format']}' for column '{$columnName}'");
}
}
// Apply the rules to each file in the array.
$rules[$columnName . '.*'] = implode('|', $fileRules);
// print_r($rules);
} else {
// Single file upload handling.
$columnRules[] = 'sometimes|required|file|max:20480';
// Add MIME type validation if a format is specified.
if (!empty($column['format'])) {
$category = trim($column['format'], '.'); // Strip the dot from the format.
if (array_key_exists($category, $mimeTypeMap)) {
$formats = $mimeTypeMap[$category];
$columnRules[] = 'mimes:' . implode(',', $formats);
} else {
Log::warning("Unsupported format '{$column['format']}' for column '{$columnName}'");
}
}
// Apply the accumulated rules for a single file.
$rules[$columnName] = implode('|', $columnRules);
// print_r($rules);
}
// print_r($columnRules);
break;
case 'boolean':
$columnRules[] = 'sometimes|required|boolean';
break;
case 'enum':
if (!empty($column['options']) && is_array($column['options'])) {
$columnRules[] = 'sometimes|required|string';
$columnRules[] = 'in:' . implode(',', $column['options']);
}
break;
case 'email':
$columnRules[] = 'sometimes|required|email';
break;
case 'phone':
$columnRules[] = 'sometimes|required|string';
$columnRules[] = 'regex:/^([0-9\s\-\+\(\)]*)$/';
break;
}
// // Add required/nullable validation
// if (!empty($column['required'])) {
// $columnRules[] = 'required';
// } else {
// $columnRules[] = 'nullable';
// }
// // Add min/max validation if specified
// if (!empty($column['min'])) {
// switch ($column['type']) {
// case 'string':
// case 'text':
// $columnRules[] = 'min:' . $column['min'];
// break;
// case 'integer':
// case 'decimal':
// case 'float':
// $columnRules[] = 'min_digits:' . $column['min'];
// break;
// case 'file':
// $columnRules[] = 'min:' . $column['min']; // min in kilobytes
// break;
// }
// }
// if (!empty($column['max'])) {
// switch ($column['type']) {
// case 'string':
// case 'text':
// $columnRules[] = 'max:' . $column['max'];
// break;
// case 'integer':
// case 'decimal':
// case 'float':
// $columnRules[] = 'max_digits:' . $column['max'];
// break;
// case 'file':
// $columnRules[] = 'max:' . $column['max']; // max in kilobytes
// break;
// }
// }
if (!empty($columnRules)) {
$rules[$columnName] = implode('|', $columnRules);
}
}
}
} catch (\Throwable $e) {
Log::error('Error loading disease schema: ' . $e->getMessage());
}
}
return $rules;
}
public function validated($key = null, $default = null): array
{
$validated = parent::validated();
return [
'diseaseId' => $validated['diseaseId'],
'data' => collect($validated)
->except('diseaseId', 'recordId')
->toArray()
];
}
protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(
ResponseJson::failedResponse('Validation error', $validator->errors()->toArray())
);
}
}