diff --git a/app/Commands/StorageMigrateLocalToS3.php b/app/Commands/StorageMigrateLocalToS3.php index 7ea17b0..b346c2d 100644 --- a/app/Commands/StorageMigrateLocalToS3.php +++ b/app/Commands/StorageMigrateLocalToS3.php @@ -15,7 +15,7 @@ class StorageMigrateLocalToS3 extends BaseCommand protected $name = 'storage:migrate-local-to-s3'; - protected $description = 'Migrate existing local writable/uploads files to S3 (policy & endorsement folders).'; + protected $description = 'Migrate existing local writable/uploads files to S3 (policy, endorsement, agent, enquiry, quotation, claims).'; protected $usage = 'storage:migrate-local-to-s3 [options]'; @@ -25,9 +25,12 @@ class StorageMigrateLocalToS3 extends BaseCommand '--delete-local' => 'Delete local file after successful S3 upload + verify.', '--verify' => 'Compare MD5 of local file vs S3 read-back after upload (default: on).', '--no-verify' => 'Skip read-back verification after upload.', - '--module' => 'Migrate only one module: policy or endorsement.', + '--module' => 'Migrate one or more modules (comma-separated): policy,endorsement,agent,enquiry,quotation,claims', ]; + /** @var list */ + private array $allowedModules = ['policy', 'endorsement', 'agent', 'enquiry', 'quotation', 'claims']; + /** @var array */ private array $stats = [ 'scanned' => 0, @@ -52,10 +55,24 @@ class StorageMigrateLocalToS3 extends BaseCommand $deleteLocal = (bool) CLI::getOption('delete-local'); $verify = ! CLI::getOption('no-verify'); $moduleFilter = CLI::getOption('module'); + // Support: --module "agent, enquiry, quotation, claims" + // and bare tokens after a partial --module agent, enquiry quotation claims + if (is_string($moduleFilter) && $moduleFilter !== '') { + $extraTokens = []; + foreach ($params as $param) { + if (! is_string($param) || $param === '' || str_starts_with($param, '-')) { + continue; + } + $extraTokens[] = $param; + } + if ($extraTokens !== []) { + $moduleFilter = rtrim($moduleFilter, ',') . ',' . implode(',', $extraTokens); + } + } - if (is_string($moduleFilter) && $moduleFilter !== '' && ! in_array($moduleFilter, ['policy', 'endorsement'], true)) { - CLI::error('Invalid --module value. Allowed: policy, endorsement'); + $modules = $this->parseModuleFilter($moduleFilter); + if ($modules === null) { return EXIT_ERROR; } @@ -75,17 +92,26 @@ class StorageMigrateLocalToS3 extends BaseCommand CLI::write('S3 region : ' . $config->s3Region, 'cyan'); CLI::write('S3 prefix : ' . ($config->s3Prefix !== '' ? $config->s3Prefix : '(none)'), 'cyan'); CLI::write('Mode : ' . ($dryRun ? 'DRY RUN' : 'LIVE'), $dryRun ? 'yellow' : 'green'); + if ($modules !== []) { + CLI::write('Modules : ' . implode(', ', $modules), 'cyan'); + } CLI::newLine(); $targets = $this->migrationTargets(); - if (is_string($moduleFilter) && $moduleFilter !== '') { + if ($modules !== []) { $targets = array_values(array_filter( $targets, - static fn (array $target) => $target['module'] === $moduleFilter + static fn (array $target) => in_array($target['module'], $modules, true) )); } + if ($targets === []) { + CLI::error('No migration targets matched the given --module filter.'); + + return EXIT_ERROR; + } + foreach ($targets as $target) { $this->migrateTarget($target, $s3Driver, $storage, $dryRun, $force, $deleteLocal, $verify); } @@ -106,6 +132,40 @@ class StorageMigrateLocalToS3 extends BaseCommand return $this->stats['failed'] === 0 ? EXIT_SUCCESS : EXIT_ERROR; } + /** + * Parse --module as a single value or comma-separated list (case-insensitive). + * + * @return list|null empty list = all modules; null = invalid input + */ + private function parseModuleFilter(mixed $moduleFilter): ?array + { + if (! is_string($moduleFilter) || trim($moduleFilter) === '') { + return []; + } + + $requested = array_values(array_filter(array_map( + static fn (string $value): string => strtolower(trim($value)), + explode(',', $moduleFilter) + ), static fn (string $value): bool => $value !== '')); + + if ($requested === []) { + return []; + } + + $invalid = array_values(array_diff($requested, $this->allowedModules)); + if ($invalid !== []) { + CLI::error( + 'Invalid --module value(s): ' . implode(', ', $invalid) + . '. Allowed: ' . implode(', ', $this->allowedModules) + . '. Example: --module agent,enquiry,quotation,claims' + ); + + return null; + } + + return array_values(array_unique($requested)); + } + /** * @return list */ @@ -147,6 +207,62 @@ class StorageMigrateLocalToS3 extends BaseCommand 'localRelative' => 'uploads/endorsement/endorsement_pdf', 'topLevelOnly' => true, ], + [ + 'label' => 'agent_certificate', + 'module' => 'agent', + 'subFolder' => 'certificate_file', + 'localRelative' => 'uploads/agent/certificate_file', + 'topLevelOnly' => true, + ], + [ + 'label' => 'agent_incentive', + 'module' => 'agent', + 'subFolder' => 'incentive_file', + 'localRelative' => 'uploads/agent/incentive_file', + 'topLevelOnly' => true, + ], + [ + 'label' => 'enquiry_id_proof', + 'module' => 'enquiry', + 'subFolder' => 'id_proof', + 'localRelative' => 'uploads/enquiry/id_proof', + 'topLevelOnly' => true, + ], + [ + 'label' => 'enquiry_rc', + 'module' => 'enquiry', + 'subFolder' => 'rc', + 'localRelative' => 'uploads/enquiry/rc', + 'topLevelOnly' => true, + ], + [ + 'label' => 'enquiry_previous_policy', + 'module' => 'enquiry', + 'subFolder' => 'previous_policy', + 'localRelative' => 'uploads/enquiry/previous_policy', + 'topLevelOnly' => true, + ], + [ + 'label' => 'enquiry_root', + 'module' => 'enquiry', + 'subFolder' => '', + 'localRelative' => 'uploads/enquiry', + 'topLevelOnly' => true, + ], + [ + 'label' => 'quotation', + 'module' => 'quotation', + 'subFolder' => '', + 'localRelative' => 'uploads/quotation', + 'topLevelOnly' => true, + ], + [ + 'label' => 'claims', + 'module' => 'claims', + 'subFolder' => '', + 'localRelative' => 'uploads/claims', + 'topLevelOnly' => true, + ], ]; } diff --git a/app/Commands/StorageUploadTest.php b/app/Commands/StorageUploadTest.php index 96de2e5..c54406c 100644 --- a/app/Commands/StorageUploadTest.php +++ b/app/Commands/StorageUploadTest.php @@ -55,6 +55,14 @@ class StorageUploadTest extends BaseCommand 'policy_md' => fn () => $this->scenarioPolicyMarkdown(), 'endorsement_original' => fn () => $this->scenarioEndorsementOriginal(), 'endorsement_completion' => fn () => $this->scenarioEndorsementCompletion(), + 'agent_certificate' => fn () => $this->scenarioGeneric('agent', 'certificate_file', 'certificate.pdf'), + 'agent_incentive' => fn () => $this->scenarioGeneric('agent', 'incentive_file', 'incentive.xlsx'), + 'enquiry_id_proof' => fn () => $this->scenarioGeneric('enquiry', 'id_proof', 'id_proof.pdf'), + 'enquiry_rc' => fn () => $this->scenarioGeneric('enquiry', 'rc', 'rc.pdf'), + 'enquiry_previous_policy' => fn () => $this->scenarioGeneric('enquiry', 'previous_policy', 'previous_policy.pdf'), + 'enquiry_root' => fn () => $this->scenarioGeneric('enquiry', '', 'enquiry_extra.pdf'), + 'quotation' => fn () => $this->scenarioGeneric('quotation', '', 'quotation_extra.pdf'), + 'claims' => fn () => $this->scenarioGeneric('claims', '', 'claim_file.pdf'), ]; foreach ($scenarios as $label => $callback) { @@ -175,6 +183,17 @@ class StorageUploadTest extends BaseCommand $this->assertTemporaryUrl('endorsement', 'endorsement_pdf', $fileName); } + private function scenarioGeneric(string $module, string $subFolder, string $sampleName): void + { + $source = $this->createTempFile($sampleName, '%PDF-1.4 storage module test for ' . $module); + $fileName = time() . '_spark_test_' . preg_replace('/[^a-z0-9]+/i', '_', $sampleName); + $content = file_get_contents($source); + + $this->uploadFile($module, $subFolder, $fileName, $source, $content); + $this->assertReadable($module, $subFolder, $fileName, $content); + $this->assertTemporaryUrl($module, $subFolder, $fileName); + } + /** * @param string|false $content */ diff --git a/app/Controllers/AgentController.php b/app/Controllers/AgentController.php index a2c7e37..3f667ec 100644 --- a/app/Controllers/AgentController.php +++ b/app/Controllers/AgentController.php @@ -403,19 +403,11 @@ class AgentController extends ResourceController $data = $this->request->getPost(); // handle file uploads - $certificateFile = $this->request->getFile('certificate_file_name'); - - $certificateFileName = null; - - // certificate upload - if ($certificateFile && $certificateFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/agent/certificate_file/'; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); - } - $certificateFileName = time() . '_' . $certificateFile->getRandomName(); - $certificateFile->move($uploadPath, $certificateFileName); - } + $certificateFileName = storage_upload_if_valid( + $this->request->getFile('certificate_file_name'), + 'agent', + 'certificate_file' + ); $rates = $this->parseRetentionRatesFromRequest(); @@ -465,9 +457,6 @@ class AgentController extends ResourceController return $this->respond(['status' => 'failed', 'code' => 200, 'data' => 'Date Not Found'], 200); } - // handle file uploads - $certificateFile = $this->request->getFile('certificate_file_name'); - $updateData = [ 'name' => $data['name'] ?? null, 'email' => $data['email'] ?? null, @@ -479,13 +468,13 @@ class AgentController extends ResourceController 'retention_rate' => null, ]; - if ($certificateFile && $certificateFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/agent/certificate_file/'; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); - } - $certificateFileName = time() . '_' . $certificateFile->getRandomName(); - $certificateFile->move($uploadPath, $certificateFileName); + // handle file uploads + $certificateFileName = storage_upload_if_valid( + $this->request->getFile('certificate_file_name'), + 'agent', + 'certificate_file' + ); + if ($certificateFileName !== null) { $updateData['certificate_file_name'] = $certificateFileName; } @@ -582,18 +571,17 @@ class AgentController extends ResourceController // Fetch record from DB $fileRecord = $this->AgentModel->where('is_active',1)->find((int)$id); - if (!$fileRecord) { + if (!$fileRecord || empty($fileRecord['certificate_file_name'])) { return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File not found'], 200); } - $filePath = WRITEPATH . 'uploads/agent/certificate_file/' . $fileRecord['certificate_file_name']; + $fileName = $fileRecord['certificate_file_name']; - if (!file_exists($filePath)) { + if (!storage_exists('agent', 'certificate_file', $fileName)) { return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File missing on server'], 200); } - // Force file download - return $this->response->download($filePath, null); + return storage_download('agent', 'certificate_file', $fileName); } catch (\Exception $e) { return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $e->getMessage()], 500); @@ -632,19 +620,11 @@ class AgentController extends ResourceController } // handle file uploads - $incentiveFile = $this->request->getFile('incentive_file_name'); - - $incentiveFileName = null; - - // incentive upload - if ($incentiveFile && $incentiveFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/agent/incentive_file/'; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); - } - $incentiveFileName = time() . '_' . $incentiveFile->getRandomName(); - $incentiveFile->move($uploadPath, $incentiveFileName); - } + $incentiveFileName = storage_upload_if_valid( + $this->request->getFile('incentive_file_name'), + 'agent', + 'incentive_file' + ); $insertData = [ 'agent_id' => $data['agent_id'], @@ -703,18 +683,17 @@ class AgentController extends ResourceController // Fetch record from DB $fileRecord = $this->AgentIncentiveFileModel->where('is_active',1)->where('file_type',$fileType)->find((int)$id); - if (!$fileRecord) { + if (!$fileRecord || empty($fileRecord['incentive_file_name'])) { return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File not found'], 200); } - $filePath = WRITEPATH . 'uploads/agent/incentive_file/' . $fileRecord['incentive_file_name']; + $fileName = $fileRecord['incentive_file_name']; - if (!file_exists($filePath)) { + if (!storage_exists('agent', 'incentive_file', $fileName)) { return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File missing on server'], 200); } - // Force file download - return $this->response->download($filePath, null); + return storage_download('agent', 'incentive_file', $fileName); } catch (\Exception $e) { return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $e->getMessage()], 500); diff --git a/app/Controllers/AgentIncentiveController.php b/app/Controllers/AgentIncentiveController.php index f14737d..37df040 100644 --- a/app/Controllers/AgentIncentiveController.php +++ b/app/Controllers/AgentIncentiveController.php @@ -118,22 +118,27 @@ class AgentIncentiveController extends ResourceController } /* ==================================================================== - * STEP 4 — Move file + * STEP 4 — Upload file to storage (S3/local) * ==================================================================== */ - $uploadPath = WRITEPATH . 'uploads/agent/incentive_file/'; - if (!is_dir($uploadPath)) mkdir($uploadPath, 0777, true); + $gridFileName = storage_upload_if_valid($gridFile, 'agent', 'incentive_file'); + if ($gridFileName === null) { + return $this->respond([ + 'status' => 'failed', + 'code' => 400, + 'data' => 'No valid file uploaded.', + ], 200); + } - $gridFileName = time() . '_' . $gridFile->getRandomName(); - $gridFile->move($uploadPath, $gridFileName); + $localPath = storage_local_path('agent', 'incentive_file', $gridFileName); /* ==================================================================== * STEP 5 — Parse Excel FIRST (before saving file record) * ==================================================================== */ - $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($uploadPath . $gridFileName); + $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($localPath); $rows = $spreadsheet->getActiveSheet()->toArray(null, true, true, false); if (empty($rows)) { - if (file_exists($uploadPath . $gridFileName)) unlink($uploadPath . $gridFileName); + storage_delete('agent', 'incentive_file', $gridFileName); return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'File is empty.'], 200); } @@ -278,7 +283,7 @@ class AgentIncentiveController extends ResourceController * Do NOT insert file record at all * ==================================================================== */ if (!empty($errors)) { - if (file_exists($uploadPath . $gridFileName)) unlink($uploadPath . $gridFileName); + storage_delete('agent', 'incentive_file', $gridFileName); return $this->respond([ 'status' => 'failed', diff --git a/app/Controllers/ClaimController.php b/app/Controllers/ClaimController.php index 4898dfa..d80baac 100644 --- a/app/Controllers/ClaimController.php +++ b/app/Controllers/ClaimController.php @@ -484,19 +484,16 @@ class ClaimController extends ResourceController } $relativePath = ltrim((string) ($file['file_path'] ?? ''), '/'); - $filePath = WRITEPATH . $relativePath; + $storedName = basename($relativePath !== '' ? $relativePath : (string) ($file['file_name'] ?? '')); - if (empty($relativePath) || !file_exists($filePath)) { + if ($storedName === '' || !storage_exists('claims', '', $storedName)) { return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File missing on server'], 404); } - $mime = $file['file_mime_type'] ?? mime_content_type($filePath) ?? 'application/octet-stream'; - $downloadName = $file['file_name'] ?: basename($filePath); + $downloadName = $file['file_name'] ?: $storedName; - return $this->response - ->setHeader('Content-Type', $mime) - ->setHeader('Content-Disposition', 'inline; filename="' . $downloadName . '"') - ->setBody(file_get_contents($filePath)); + return storage_inline('claims', '', $storedName) + ->setHeader('Content-Disposition', 'inline; filename="' . $downloadName . '"'); } catch (\Exception $e) { return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500); } @@ -621,11 +618,6 @@ class ClaimController extends ResourceController private function saveClaimFiles(int $claimId, $createdBy = null): array { - $uploadPath = WRITEPATH . self::CLAIM_UPLOAD_DIR; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); - } - $result = [ 'saved' => [], 'errors' => [], @@ -637,25 +629,26 @@ class ClaimController extends ResourceController foreach ($filesToProcess as $file) { try { - $storedName = time() . '_' . $file->getRandomName(); + $clientName = $file->getClientName() ?: null; + $clientExt = $file->getClientExtension(); + $clientMime = $file->getClientMimeType(); + $storedName = storage_upload_if_valid($file, 'claims', ''); - if (!$file->move($uploadPath, $storedName)) { - $result['errors'][] = $file->getErrorString() ?: 'Unable to move uploaded file'; + if ($storedName === null) { + $result['errors'][] = $file->getErrorString() ?: 'Unable to upload file'; continue; } if (!$this->ClaimFilesModel->insert([ 'claim_id' => $claimId, - 'file_name' => $file->getClientName() ?: $storedName, + 'file_name' => $clientName ?: $storedName, 'file_path' => self::CLAIM_UPLOAD_DIR . $storedName, - 'file_extension' => $file->getClientExtension(), - 'file_mime_type' => $file->getClientMimeType(), + 'file_extension' => $clientExt, + 'file_mime_type' => $clientMime, 'is_active' => 1, 'created_by' => $createdBy, ])) { - if (is_file($uploadPath . $storedName)) { - unlink($uploadPath . $storedName); - } + storage_delete('claims', '', $storedName); $result['errors'][] = $this->ClaimFilesModel->errors() ?: 'Failed to save file record'; continue; } diff --git a/app/Controllers/EnquiryController.php b/app/Controllers/EnquiryController.php index 802f650..fdb3ac9 100644 --- a/app/Controllers/EnquiryController.php +++ b/app/Controllers/EnquiryController.php @@ -266,37 +266,21 @@ class EnquiryController extends ResourceController log_message('error',json_encode($data)); // handle file uploads - $idProofFile = $this->request->getFile('id_proof_file_name'); - $rcFile = $this->request->getFile('rc_file_name'); - $previousPolicy = $this->request->getFile('previous_policy_file_name'); - - $idProofFileName = null; - $rcFileName = null; - $previousPolicyFileName = null; - - // ID proof upload - if ($idProofFile && $idProofFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/enquiry/id_proof/'; - if (!is_dir($uploadPath)) mkdir($uploadPath, 0777, true); - $idProofFileName = time() . '_' . $idProofFile->getRandomName(); - $idProofFile->move($uploadPath, $idProofFileName); - } - - // RC upload - if ($rcFile && $rcFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/enquiry/rc/'; - if (!is_dir($uploadPath)) mkdir($uploadPath, 0777, true); - $rcFileName = time() . '_' . $rcFile->getRandomName(); - $rcFile->move($uploadPath, $rcFileName); - } - - // Previous policy upload - if ($previousPolicy && $previousPolicy->isValid()) { - $uploadPath = WRITEPATH . 'uploads/enquiry/previous_policy/'; - if (!is_dir($uploadPath)) mkdir($uploadPath, 0777, true); - $previousPolicyFileName = time() . '_' . $previousPolicy->getRandomName(); - $previousPolicy->move($uploadPath, $previousPolicyFileName); - } + $idProofFileName = storage_upload_if_valid( + $this->request->getFile('id_proof_file_name'), + 'enquiry', + 'id_proof' + ); + $rcFileName = storage_upload_if_valid( + $this->request->getFile('rc_file_name'), + 'enquiry', + 'rc' + ); + $previousPolicyFileName = storage_upload_if_valid( + $this->request->getFile('previous_policy_file_name'), + 'enquiry', + 'previous_policy' + ); //get insurer_branch_id if(isset($data['insurer_id'])) @@ -475,31 +459,30 @@ class EnquiryController extends ResourceController // File updates - $idProofFile = $this->request->getFile('id_proof_file_name'); - $rcFile = $this->request->getFile('rc_file_name'); - $previousPolicy = $this->request->getFile('previous_policy_file_name'); - - if ($idProofFile && $idProofFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/enquiry/id_proof/'; - if (!is_dir($uploadPath)) mkdir($uploadPath, 0777, true); - $idProofFileName = time() . '_' . $idProofFile->getRandomName(); - $idProofFile->move($uploadPath, $idProofFileName); + $idProofFileName = storage_upload_if_valid( + $this->request->getFile('id_proof_file_name'), + 'enquiry', + 'id_proof' + ); + if ($idProofFileName !== null) { $updateData['id_proof_file_name'] = $idProofFileName; } - if ($rcFile && $rcFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/enquiry/rc/'; - if (!is_dir($uploadPath)) mkdir($uploadPath, 0777, true); - $rcFileName = time() . '_' . $rcFile->getRandomName(); - $rcFile->move($uploadPath, $rcFileName); + $rcFileName = storage_upload_if_valid( + $this->request->getFile('rc_file_name'), + 'enquiry', + 'rc' + ); + if ($rcFileName !== null) { $updateData['rc_file_name'] = $rcFileName; } - if ($previousPolicy && $previousPolicy->isValid()) { - $uploadPath = WRITEPATH . 'uploads/enquiry/previous_policy/'; - if (!is_dir($uploadPath)) mkdir($uploadPath, 0777, true); - $previousPolicyFileName = time() . '_' . $previousPolicy->getRandomName(); - $previousPolicy->move($uploadPath, $previousPolicyFileName); + $previousPolicyFileName = storage_upload_if_valid( + $this->request->getFile('previous_policy_file_name'), + 'enquiry', + 'previous_policy' + ); + if ($previousPolicyFileName !== null) { $updateData['previous_policy_file_name'] = $previousPolicyFileName; } @@ -599,14 +582,13 @@ class EnquiryController extends ResourceController return $this->respond([ 'status' => 'failed','code' => 404,'data' => 'File not found in database'], 200); } - $filePath = WRITEPATH . "uploads/enquiry/{$folder}/" . $fileRecord[$fileColumn]; + $fileName = $fileRecord[$fileColumn]; - if (!file_exists($filePath)) { + if (!storage_exists('enquiry', $folder, $fileName)) { return $this->respond(['status' => 'failed','code' => 404,'data' => 'File missing on server'], 200); } - // Force file download - return $this->response->download($filePath, null); + return storage_download('enquiry', $folder, $fileName); } catch (\Exception $e) { return $this->respond(['status' => 'failed','code' => 500,'message' => $e->getMessage() ], 500); @@ -633,15 +615,11 @@ class EnquiryController extends ResourceController foreach ($files['files'] as $file) { if ($file->isValid()) { - $uploadPath = WRITEPATH . "uploads/enquiry/"; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); + $newName = storage_upload_if_valid($file, 'enquiry', ''); + if ($newName === null) { + continue; } - // Generate file name - $newName = time() . '_' . $file->getRandomName(); - $file->move($uploadPath, $newName); - // Save DB record $this->FilesModel->insert([ 'enquiry_id' => $enquiryId, @@ -669,21 +647,18 @@ class EnquiryController extends ResourceController $file = $this->FilesModel->find((int)$fileId); - if (!$file) { + if (!$file || empty($file['file_name'])) { return $this->respond(['status' => 'failed','message' => 'Invalid file id'], 404); } - $filePath = WRITEPATH . "uploads/enquiry/{$file['file_name']}"; - - if (!file_exists($filePath)) { + if (!storage_exists('enquiry', '', $file['file_name'])) { return $this->respond([ 'status' => 'failed', 'message' => 'File missing on server' ], 404); } - // Force file download - return $this->response->download($filePath, null); + return storage_download('enquiry', '', $file['file_name']); } public function deleteEnquiryFile() @@ -701,12 +676,8 @@ class EnquiryController extends ResourceController return $this->respond(['status' => 'failed','message' => 'Invalid file id'], 404); } - // File full path - $filePath = WRITEPATH . "uploads/enquiry/{$file['file_name']}"; - - // Delete file from server - if (file_exists($filePath)) { - unlink($filePath); + if (!empty($file['file_name'])) { + storage_delete('enquiry', '', $file['file_name']); } // Delete DB record diff --git a/app/Controllers/InvoiceController.php b/app/Controllers/InvoiceController.php index 6498c64..ecacb48 100644 --- a/app/Controllers/InvoiceController.php +++ b/app/Controllers/InvoiceController.php @@ -1192,14 +1192,15 @@ class InvoiceController extends ResourceController $file = $this->request->getFile('file_name'); if ($file && $file->isValid()) { $month = date('Y-m-d'); - $uploadPath = WRITEPATH . 'uploads/agent/incentive_file/'; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); + $storedFileName = storage_upload_if_valid($file, 'agent', 'incentive_file'); + if ($storedFileName === null) { + return $this->respond([ + 'status' => 'failed', + 'code' => 400, + 'message' => 'No valid file uploaded', + ], 400); } - $storedFileName = time() . '_' . $file->getRandomName(); - $file->move($uploadPath, $storedFileName); - $this->AgentIncentiveFileModel->insert([ 'incentive_month' => $month, 'incentive_file_name' => $storedFileName, @@ -1208,7 +1209,8 @@ class InvoiceController extends ResourceController 'created_by' => $updatedBy > 0 ? $updatedBy : null, ], true); - $spreadsheet = IOFactory::load($uploadPath . $storedFileName); + $localPath = storage_local_path('agent', 'incentive_file', $storedFileName); + $spreadsheet = IOFactory::load($localPath); $excelRows = $spreadsheet->getActiveSheet()->toArray(null, true, true, false); if (empty($excelRows)) { diff --git a/app/Controllers/QuotationController.php b/app/Controllers/QuotationController.php index 9804958..5af678e 100644 --- a/app/Controllers/QuotationController.php +++ b/app/Controllers/QuotationController.php @@ -72,17 +72,11 @@ class QuotationController extends ResourceController try { $data = $this->request->getPost(); - $uploadFile = $this->request->getFile('additional_uploaded_file_name'); - $uploadedFileName = null; - - if ($uploadFile && $uploadFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/quotation/'; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); - } - $uploadedFileName = time() . '_' . $uploadFile->getRandomName(); - $uploadFile->move($uploadPath, $uploadedFileName); - } + $uploadedFileName = storage_upload_if_valid( + $this->request->getFile('additional_uploaded_file_name'), + 'quotation', + '' + ); //get insurer_branch_id $query = $this->db->query("SELECT id FROM insurer_branch WHERE insurer_id = ? LIMIT 1", [$data['insurer_id']]); @@ -147,14 +141,12 @@ class QuotationController extends ResourceController ]; // File upload - $uploadFile = $this->request->getFile('additional_uploaded_file_name'); - if ($uploadFile && $uploadFile->isValid()) { - $uploadPath = WRITEPATH . 'uploads/quotation/'; - if (!is_dir($uploadPath)) { - mkdir($uploadPath, 0777, true); - } - $uploadedFileName = time() . '_' . $uploadFile->getRandomName(); - $uploadFile->move($uploadPath, $uploadedFileName); + $uploadedFileName = storage_upload_if_valid( + $this->request->getFile('additional_uploaded_file_name'), + 'quotation', + '' + ); + if ($uploadedFileName !== null) { $updateData['additional_uploaded_file_name'] = $uploadedFileName; } @@ -236,18 +228,17 @@ class QuotationController extends ResourceController // Fetch record from DB $fileRecord = $this->QuotationModel->where('is_active',1)->find((int)$id); - if (!$fileRecord) { + if (!$fileRecord || empty($fileRecord['additional_uploaded_file_name'])) { return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File not found'], 200); } - $filePath = WRITEPATH . 'uploads/quotation/' . $fileRecord['additional_uploaded_file_name']; + $fileName = $fileRecord['additional_uploaded_file_name']; - if (!file_exists($filePath)) { + if (!storage_exists('quotation', '', $fileName)) { return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File missing on server'], 200); } - // Force file download - return $this->response->download($filePath, null); + return storage_download('quotation', '', $fileName); } catch (\Exception $e) { return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $e->getMessage()], 500); diff --git a/app/Services/StorageBrowserService.php b/app/Services/StorageBrowserService.php index d114eab..68efca4 100644 --- a/app/Services/StorageBrowserService.php +++ b/app/Services/StorageBrowserService.php @@ -21,6 +21,14 @@ class StorageBrowserService 'uploads/policy/policy_md', 'uploads/endorsement', 'uploads/endorsement/endorsement_pdf', + 'uploads/agent/certificate_file', + 'uploads/agent/incentive_file', + 'uploads/enquiry/id_proof', + 'uploads/enquiry/rc', + 'uploads/enquiry/previous_policy', + 'uploads/enquiry', + 'uploads/quotation', + 'uploads/claims', ]; /** @var list */