'; // Set version to 0100 $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Set bits 6-7 to 10 $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // Output the 36 character UUID. $uuid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); return $uuid; } } if (! function_exists('change_date_format2')) { function change_date_format2($data, $source_format, $output_format) { $data = trim($data); // echo $data, $source_format, $output_format;return true; try { // Create DateTime object with the source format $dateTime = DateTime::createFromFormat($source_format, $data); // Check if the DateTime object is created successfully if ($dateTime === false) { $errors = DateTime::getLastErrors(); throw new Exception('Invalid date or format' . implode(', ', $errors['errors'])); } // Format the DateTime object with the output format $formattedDate = $dateTime->format($output_format); return $formattedDate; } catch (Exception $e) { // Handle the exception (e.g., log it, show a user-friendly message) return "Error: " . $e->getMessage(); return $data; } } } if (! function_exists('sanitize_upload_filename')) { function sanitize_upload_filename(string $fileName): string { $fileName = preg_replace('/[\x00-\x1F\x7F]/u', '', $fileName); $fileName = preg_replace('/[\x{00A0}\x{200B}-\x{200D}\x{FEFF}\x{00AD}\x{2060}\x{180E}\x{2028}\x{2029}]/u', '', $fileName); $fileName = preg_replace('/[\/\\\\:*?"<>|;`${}()\'&!#]/', '', $fileName); $fileName = preg_replace('/\.{2,}/', '.', $fileName); $fileName = trim($fileName, ". \t\n\r"); if ($fileName === '' || strlen($fileName) > 200) { $fileName = time() . '_' . bin2hex(random_bytes(8)); } return $fileName; } } if (! function_exists('validate_upload_extension')) { function validate_upload_extension($file, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS): bool { $ext = strtolower($file->getClientExtension()); if (! in_array($ext, $allowedExtensions, true)) { log_message('critical', '[UPLOAD_HELPER] Blocked extension: {ext} | File: {name}', [ 'ext' => $ext, 'name' => $file->getClientName(), ]); return false; } return true; } } if (! function_exists('file_Upload')) { function file_Upload($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS) { if ($fileToUpload !== null && $fileToUpload->isValid() && ! $fileToUpload->hasMoved()) { if (! validate_upload_extension($fileToUpload, $allowedExtensions)) { return ""; } $fileName = sanitize_upload_filename($fileToUpload->getName()); $fileToUpload->move($filepath, $fileName); return $fileName; } else { return ""; } } } /** * Extract original/display filename from a unique storage key. * Unique keys are stored as: {timestamp}_{hex}_{sanitizedOriginalName} * Legacy plain filenames are returned unchanged. */ if (! function_exists('storage_upload_display_name')) { function storage_upload_display_name(?string $storedName): string { $storedName = (string) $storedName; if ($storedName === '') { return ''; } if (preg_match('/^\d+_[a-f0-9]+_(.+)$/i', $storedName, $matches)) { return $matches[1]; } return $storedName; } } /** * Build a collision-safe storage filename while preserving the original name for display/download. */ if (! function_exists('storage_unique_upload_name')) { function storage_unique_upload_name(string $originalName): string { $displayName = sanitize_upload_filename($originalName); return time() . '_' . bin2hex(random_bytes(8)) . '_' . $displayName; } } /** * Upload via FileStorageService (S3 wrapper). * Uses folder path last segment as the S3 folder/bucket prefix. * Stores a unique disk/S3 key so same original names never overwrite each other. * * Env RETAIN_LOCAL (default false): * - false / missing: S3-only → temp stage → upload → delete local * - true: dual-write → keep permanent local copy under $filepath after S3 upload * * Processors should still use storage_ensure_local_file() when local may be missing. * * @param bool $retainLocal Unused; behaviour is controlled by env RETAIN_LOCAL only. */ if (! function_exists('storage_file_Upload')) { function storage_file_Upload($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS, bool $retainLocal = false) { if ($fileToUpload === null || ! $fileToUpload->isValid() || $fileToUpload->hasMoved()) { log_message('error', 'storage_file_Upload validation failed | ' . json_encode([ 'filepath' => $filepath, 'reason' => $fileToUpload === null ? 'file_null' : (!$fileToUpload->isValid() ? 'invalid_file' : 'already_moved'), 'error' => (is_object($fileToUpload) && method_exists($fileToUpload, 'getErrorString')) ? $fileToUpload->getErrorString() : null, ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); return ""; } if (! validate_upload_extension($fileToUpload, $allowedExtensions)) { log_message('error', 'storage_file_Upload extension rejected | ' . json_encode([ 'filepath' => $filepath, 'client_name' => method_exists($fileToUpload, 'getClientName') ? $fileToUpload->getClientName() : null, 'extension' => method_exists($fileToUpload, 'getExtension') ? $fileToUpload->getExtension() : null, 'allowed_extensions' => $allowedExtensions, ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); return ""; } $originalName = method_exists($fileToUpload, 'getClientName') && $fileToUpload->getClientName() ? $fileToUpload->getClientName() : $fileToUpload->getName(); $fileName = storage_unique_upload_name($originalName); $storage = \Config\Services::getFileStorageService(); $filepath = rtrim($filepath, '/\\'); // Env controls retention; missing / empty / false => do not keep local when on S3. $retainLocal = storage_env_retain_local(); if ($storage->usesS3()) { if ($retainLocal) { if (! is_dir($filepath)) { mkdir($filepath, 0755, true); } $fileToUpload->move($filepath . DIRECTORY_SEPARATOR, $fileName); $localPath = $filepath . DIRECTORY_SEPARATOR . $fileName; $result = $storage->upload($localPath, $filepath, $fileName); if (! ($result['success'] ?? false)) { @unlink($localPath); log_message('error', 'storage_file_Upload retain_local failed | ' . json_encode([ 'filepath' => $filepath, 'file_name' => $fileName, 'message' => $result['message'] ?? null, ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); return ''; } log_message('info', 'storage_file_Upload retain_local completed | ' . json_encode([ 'filepath' => $filepath, 'file_name' => $fileName, 'display_name' => storage_upload_display_name($fileName), 'retain_local' => true, 'bucket' => $storage->getBucket(), ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); return $fileName; } // S3-only: stage briefly, upload, always delete local. $tmpDir = storage_runtime_temp_dir(); if (! is_dir($tmpDir)) { @mkdir($tmpDir, 0755, true); } $fileToUpload->move($tmpDir . DIRECTORY_SEPARATOR, $fileName); $localPath = $tmpDir . DIRECTORY_SEPARATOR . $fileName; $result = $storage->upload($localPath, $filepath, $fileName); @unlink($localPath); log_message( ($result['success'] ?? false) ? 'info' : 'error', 'storage_file_Upload s3_only completed | ' . json_encode([ 'filepath' => $filepath, 'file_name' => $fileName, 'display_name' => storage_upload_display_name($fileName), 'success' => $result['success'] ?? false, 'key' => $result['key'] ?? null, 'message' => $result['message'] ?? null, 'bucket' => $storage->getBucket(), 'retain_local' => false, ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ); return ($result['success'] ?? false) ? $fileName : ''; } // Local-driver mode: keep file under the upload folder. $result = $storage->upload($fileToUpload, $filepath, $fileName); log_message( ($result['success'] ?? false) ? 'info' : 'error', 'storage_file_Upload completed | ' . json_encode([ 'filepath' => $filepath, 'file_name' => $fileName, 'display_name' => storage_upload_display_name($fileName), 'success' => $result['success'] ?? false, 'key' => $result['key'] ?? null, 'url' => $result['url'] ?? null, 'message' => $result['message'] ?? null, 'bucket' => $storage->getBucket(), 'uses_s3' => $storage->usesS3(), 'retain_local' => $retainLocal, ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ); return ($result['success'] ?? false) ? $fileName : ""; } } /** * Read RETAIN_LOCAL from env. Default / missing / empty => false. */ if (! function_exists('storage_env_retain_local')) { function storage_env_retain_local(): bool { $raw = env('RETAIN_LOCAL', null); if ($raw === null || $raw === '') { return false; } if (is_bool($raw)) { return $raw; } return filter_var((string) $raw, FILTER_VALIDATE_BOOLEAN); } } if (! function_exists('file_Upload_random_name')) { function file_Upload_random_name($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS, string $namePrefix = ''): array { $empty = ['stored_name' => '', 'original_name' => '']; if ($fileToUpload === null || ! $fileToUpload->isValid() || $fileToUpload->hasMoved()) { return $empty; } if (! validate_upload_extension($fileToUpload, $allowedExtensions)) { return $empty; } $originalName = sanitize_upload_filename($fileToUpload->getClientName() ?: $fileToUpload->getName()); $ext = strtolower($fileToUpload->getClientExtension() ?: pathinfo($originalName, PATHINFO_EXTENSION)); $namePrefix = preg_replace('/[^a-zA-Z0-9\-_]/', '', $namePrefix); $prefix = $namePrefix !== '' ? $namePrefix . '_' : ''; $storedName = $prefix . time() . '_' . bin2hex(random_bytes(8)) . ($ext !== '' ? '.' . $ext : ''); $fileToUpload->move($filepath, $storedName); return ['stored_name' => $storedName, 'original_name' => $originalName]; } } if (! function_exists('resolve_insurer_claim_form_file')) { function resolve_insurer_claim_form_file(array $insurer): array { $checkedPaths = []; $claimFormDir = WRITEPATH . 'insurer_claim_form/'; if (!empty($insurer['insurer_claim_form'])) { $storedFileName = basename($insurer['insurer_claim_form']); $uploadedPath = $claimFormDir . $storedFileName; $checkedPaths[] = $uploadedPath; if (is_file($uploadedPath)) { return [ 'available' => true, 'file_path' => $uploadedPath, 'file_name' => !empty($insurer['insurer_claim_form_original_name']) ? basename($insurer['insurer_claim_form_original_name']) : $storedFileName, 'source' => 'uploaded', 'checked_paths' => $checkedPaths, ]; } } $defaultPath = $claimFormDir . INSURER_DEFAULT_CLAIM_FORM_FILE; $checkedPaths[] = $defaultPath; if (is_file($defaultPath)) { return [ 'available' => true, 'file_path' => $defaultPath, 'file_name' => INSURER_DEFAULT_CLAIM_FORM_FILE, 'source' => 'irdai_default', 'checked_paths' => $checkedPaths, ]; } if (!empty($insurer['short_name'])) { $legacyPath = ROOTPATH . 'public/claim_sample_forms/' . $insurer['short_name'] . '.pdf'; $checkedPaths[] = $legacyPath; if (is_file($legacyPath)) { return [ 'available' => true, 'file_path' => $legacyPath, 'file_name' => $insurer['short_name'] . '.pdf', 'source' => 'legacy', 'checked_paths' => $checkedPaths, ]; } } return [ 'available' => false, 'file_path' => null, 'file_name' => null, 'source' => null, 'checked_paths' => $checkedPaths, ]; } } if (! function_exists('file_Upload_for_lead')) { function file_Upload_for_lead($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS) { if ($fileToUpload !== null && $fileToUpload->isValid() && ! $fileToUpload->hasMoved()) { if (! validate_upload_extension($fileToUpload, $allowedExtensions)) { return ""; } $fileName = sanitize_upload_filename($fileToUpload->getName()); $fileToUpload->move($filepath, $fileName); $fileName = $fileToUpload->getName(); return $fileName; } else { return ""; } } } // if (!function_exists('multi_file_Upload')) { // function multi_file_Upload($fileToUpload, $filepath) // { // $uploadedFiles = []; // // Handle multiple files // if (is_array($fileToUpload)) { // foreach ($fileToUpload as $file) { // if ($file !== null && $file->isValid() && !$file->hasMoved()) { // $file->move($filepath); // $fileName = $file->getName(); // safer unique name // $uploadedFiles[] = [ // 'file_name' => $fileName, // 'file_path' => $filepath . $fileName // ]; // } // } // } // // Handle single file // else { // if ($fileToUpload !== null && $fileToUpload->isValid() && !$fileToUpload->hasMoved()) { // $fileToUpload->move($filepath); // $fileName = $fileToUpload->getName(); // $uploadedFiles[] = [ // 'file_name' => $fileName, // 'file_path' => $filepath . $fileName // ]; // } // } // return $uploadedFiles; // always return array of files // } // } // function for only using in the Flutter Claim File Upload if (! function_exists('multi_file_Upload')) { function multi_file_Upload($fileToUpload, $filepath, $docs_name = [], array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS) { $uploadedFiles = []; // Normalize: always work with an array of UploadedFile objects $files = is_array($fileToUpload) ? $fileToUpload : [$fileToUpload]; foreach ($files as $file) { // If file is itself an array (multiple under same input name) if (is_array($file)) { foreach ($file as $index => $f) { if ($f !== null && $f->isValid() && ! $f->hasMoved()) { if (! validate_upload_extension($f, $allowedExtensions)) { continue; } $fileRandomName = $f->getRandomName(); $fileName = sanitize_upload_filename($f->getName()); $f->move($filepath, $fileRandomName); $uploadedFiles[] = [ 'file_name' => $fileName, 'doc_name' => $docs_name[$index] ?? $fileName, 'file_path' => $fileRandomName, ]; } } } else { // Single file if ($file !== null && $file->isValid() && ! $file->hasMoved()) { if (! validate_upload_extension($file, $allowedExtensions)) { continue; } $fileName = sanitize_upload_filename($file->getName()); $diskName = $file->getRandomName(); $file->move($filepath, $diskName); $uploadedFiles[] = [ 'file_name' => $fileName, 'file_path' => $filepath . $diskName, ]; } } } return $uploadedFiles; // always return array } } /** * Claim file upload via FileStorageService (S3) with local disk copy retained * for merge/TPA integrations during phased migration. */ if (! function_exists('storage_multi_file_Upload')) { function storage_multi_file_Upload($fileToUpload, $filepath, $docs_name = [], array $allowedExtensions = UPLOAD_EXT_CLAIM_DOCS) { $uploadedFiles = []; $filepath = rtrim($filepath, '/\\') . DIRECTORY_SEPARATOR; $storage = \Config\Services::getFileStorageService(); if (! is_dir(rtrim($filepath, '/\\'))) { mkdir(rtrim($filepath, '/\\'), 0755, true); } $files = is_array($fileToUpload) ? $fileToUpload : [$fileToUpload]; foreach ($files as $file) { if (is_array($file)) { foreach ($file as $index => $f) { $uploaded = storage_claim_file_Upload($f, $filepath, $allowedExtensions); if ($uploaded === '') { continue; } $uploadedFiles[] = [ 'file_name' => $uploaded['display_name'], 'doc_name' => $docs_name[$index] ?? $uploaded['display_name'], 'file_path' => $uploaded['disk_name'], ]; } } else { $uploaded = storage_claim_file_Upload($file, $filepath, $allowedExtensions); if ($uploaded === '') { continue; } $uploadedFiles[] = [ 'file_name' => $uploaded['display_name'], 'doc_name' => $docs_name[0] ?? $uploaded['display_name'], 'file_path' => $uploaded['disk_name'], ]; } } log_message('info', 'storage_multi_file_Upload completed | ' . json_encode([ 'filepath' => $filepath, 'uploaded_count' => count($uploadedFiles), 'uses_s3' => $storage->usesS3(), 'bucket' => $storage->getBucket(), ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); return $uploadedFiles; } } /** * Single claim file upload: save locally, then mirror to S3 when enabled. * * @return array{display_name:string,disk_name:string}|string */ if (! function_exists('storage_claim_file_Upload')) { function storage_claim_file_Upload($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_EXT_CLAIM_DOCS) { if ($fileToUpload === null || ! $fileToUpload->isValid() || $fileToUpload->hasMoved()) { return ''; } if (! validate_upload_extension($fileToUpload, $allowedExtensions)) { return ''; } $filepath = rtrim($filepath, '/\\') . DIRECTORY_SEPARATOR; $displayName = sanitize_upload_filename($fileToUpload->getName()); $diskName = $fileToUpload->getRandomName(); $storage = \Config\Services::getFileStorageService(); if ($storage->usesS3()) { $tmpDir = storage_runtime_temp_dir(); if (! is_dir($tmpDir)) { @mkdir($tmpDir, 0755, true); } $fileToUpload->move($tmpDir . DIRECTORY_SEPARATOR, $diskName); $localPath = $tmpDir . DIRECTORY_SEPARATOR . $diskName; $result = $storage->upload($localPath, rtrim($filepath, '/\\'), $diskName); @unlink($localPath); log_message( ($result['success'] ?? false) ? 'info' : 'error', 'storage_claim_file_Upload s3_only | ' . json_encode([ 'filepath' => $filepath, 'disk_name' => $diskName, 'display_name' => $displayName, 'success' => $result['success'] ?? false, 'key' => $result['key'] ?? null, 'message' => $result['message'] ?? null, 'bucket' => $storage->getBucket(), ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ); if (! ($result['success'] ?? false)) { return ''; } } else { if (! is_dir($filepath)) { @mkdir($filepath, 0755, true); } $fileToUpload->move($filepath, $diskName); } return [ 'display_name' => $displayName, 'disk_name' => $diskName, ]; } } /** * Build a TPA-facing download URL for a claim file. * Prefers Nhance file-download API (attachment stream from local/S3). * Falls back to folder+file URL when file id is missing. */ if (! function_exists('storage_claim_file_download_url')) { function storage_claim_file_download_url(string $diskName, $fileId = null, int $expirationMinutes = 360): string { $diskName = basename(trim($diskName)); if ($diskName === '') { return ''; } $uploadPath = WRITEPATH . 'uploads/claim_files'; $storage = \Config\Services::getFileStorageService(); // Prefer app file-download URL when claim_files id is known (TPA-safe, attachment). if ($fileId !== null && $fileId !== '') { if ($storage->usesS3()) { if (! $storage->exists($uploadPath, $diskName)) { log_message('error', 'storage_claim_file_download_url | missing on S3 | ' . $diskName); return ''; } } else { $localPath = $storage->resolveLocalPath($uploadPath, $diskName); if (! is_file($localPath)) { return ''; } } return base_url('storage/file-download/claim/' . md5((string) (int) $fileId)); } if ($storage->usesS3()) { if (! $storage->exists($uploadPath, $diskName)) { log_message('error', 'storage_claim_file_download_url | missing on S3 | ' . $diskName); return ''; } // No file id: folder+file download endpoint return base_url('storage/file-download') . '?folder=claim_files&file=' . rawurlencode($diskName); } $localPath = $storage->resolveLocalPath($uploadPath, $diskName); if (! is_file($localPath)) { return ''; } return base_url('storage/file-download') . '?folder=claim_files&file=' . rawurlencode($diskName); } } /** * Soft-delete claim_files row and remove unused local/S3 object. * * @return bool */ if (! function_exists('storage_soft_delete_claim_file')) { function storage_soft_delete_claim_file(int $claimFileId): bool { if ($claimFileId <= 0) { return false; } $claimFiles = new \App\Models\ClaimFilesModel(); $record = $claimFiles->find($claimFileId); if (empty($record)) { return false; } $updated = $claimFiles->update($claimFileId, ['is_active' => 0]); if (! $updated) { return false; } $diskName = basename((string) (! empty($record['url']) ? $record['url'] : ($record['file_name'] ?? ''))); if ($diskName === '') { return true; } $stillUsed = $claimFiles ->where('is_active', 1) ->where('id !=', $claimFileId) ->groupStart() ->where('url', $diskName) ->orWhere('url', WRITEPATH . 'uploads/claim_files/' . $diskName) ->orWhere('file_name', $diskName) ->groupEnd() ->countAllResults(); if ($stillUsed === 0) { $storage = \Config\Services::getFileStorageService(); $storage->delete(WRITEPATH . 'uploads/claim_files', $diskName); } return true; } } /** * Resolve a claim file from local/S3 into a readable local path. * * @return array{success:bool,path:?string,is_temp:bool,message:string} */ if (! function_exists('storage_resolve_claim_file_path')) { function storage_resolve_claim_file_path(string $uploadPath, string $fileName): array { $empty = [ 'success' => false, 'path' => null, 'is_temp' => false, 'message' => 'File not found', ]; $fileName = basename(trim($fileName)); if ($fileName === '') { $empty['message'] = 'Invalid file name'; return $empty; } $storage = \Config\Services::getFileStorageService(); $uploadPath = rtrim($uploadPath, '/\\'); $localPath = $storage->resolveLocalPath($uploadPath, $fileName); if (is_file($localPath) && is_readable($localPath)) { return [ 'success' => true, 'path' => $localPath, 'is_temp' => false, 'message' => 'Local file found', ]; } if (! $storage->usesS3()) { return $empty; } $download = $storage->download($uploadPath, $fileName); if (! ($download['success'] ?? false)) { $empty['message'] = (string) ($download['message'] ?? 'S3 download failed'); return $empty; } if (! empty($download['path']) && is_file((string) $download['path'])) { return [ 'success' => true, 'path' => (string) $download['path'], 'is_temp' => false, 'message' => 'Resolved from storage path', ]; } $content = $download['content'] ?? null; if (! is_string($content) || $content === '') { $empty['message'] = 'S3 returned empty content'; return $empty; } $tmpDir = rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'claim_files_runtime'; if (! is_dir($tmpDir)) { @mkdir($tmpDir, 0755, true); } $tmpPath = $tmpDir . DIRECTORY_SEPARATOR . uniqid('claim_', true) . '_' . $fileName; $written = @file_put_contents($tmpPath, $content); if ($written === false || ! is_file($tmpPath)) { $empty['message'] = 'Failed to write temp file'; return $empty; } storage_register_temp_file($tmpPath); return [ 'success' => true, 'path' => $tmpPath, 'is_temp' => true, 'message' => 'Resolved from S3 content', ]; } } if (! function_exists('storage_cleanup_temp_claim_file')) { function storage_cleanup_temp_claim_file(array $resolved): void { if (($resolved['success'] ?? false) && ($resolved['is_temp'] ?? false) && ! empty($resolved['path'])) { storage_cleanup_temp_file((string) $resolved['path']); } } } /** * Runtime temp directory for S3→local staging (never a permanent upload folder). */ if (! function_exists('storage_runtime_temp_dir')) { function storage_runtime_temp_dir(): string { return rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'storage_runtime'; } } /** * Register a temp path for automatic cleanup at request/CLI shutdown. * * @var list|null */ if (! function_exists('storage_register_temp_file')) { function storage_register_temp_file(string $path): void { static $registered = []; static $shutdownRegistered = false; $path = (string) $path; if ($path === '' || in_array($path, $registered, true)) { return; } $registered[] = $path; if (! $shutdownRegistered) { $shutdownRegistered = true; register_shutdown_function(static function () use (&$registered): void { foreach ($registered as $tmp) { storage_cleanup_temp_file($tmp); } $registered = []; }); } } } /** * Delete a temp runtime file (storage_runtime / claim_files_runtime only). */ if (! function_exists('storage_cleanup_temp_file')) { function storage_cleanup_temp_file(?string $path): void { if ($path === null || $path === '' || ! is_file($path)) { return; } $real = realpath($path); if ($real === false) { @unlink($path); return; } $allowed = []; foreach ([storage_runtime_temp_dir(), rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'claim_files_runtime'] as $dir) { if (! is_dir($dir)) { @mkdir($dir, 0755, true); } $resolvedDir = realpath($dir); if ($resolvedDir !== false) { $allowed[] = $resolvedDir; } } foreach ($allowed as $root) { if (strpos($real, rtrim($root, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR) === 0) { @unlink($real); return; } } } } /** * Resolve a mail-template attachment to a readable local path (local first, else S3→temp). */ if (! function_exists('storage_resolve_mail_attachment_path')) { function storage_resolve_mail_attachment_path(?string $relativePath, ?string $fileName = null): array { $name = basename((string) ($fileName ?: $relativePath)); if ($name === '') { return ['success' => false, 'path' => null, 'is_temp' => false, 'display_name' => '']; } $uploadDir = WRITEPATH . 'uploads/attachments'; $legacyPath = $relativePath ? (WRITEPATH . ltrim(str_replace('\\', '/', $relativePath), '/')) : null; if ($legacyPath && is_file($legacyPath)) { return [ 'success' => true, 'path' => $legacyPath, 'is_temp' => false, 'display_name' => storage_upload_display_name($name), ]; } $resolved = storage_resolve_claim_file_path($uploadDir, $name); $resolved['display_name'] = storage_upload_display_name($name); if (($resolved['success'] ?? false) && ($resolved['is_temp'] ?? false) && ! empty($resolved['path'])) { storage_register_temp_file((string) $resolved['path']); } return $resolved; } } /** * Ensure a file exists on local disk for job processors. * Local first (legacy leftovers); if missing and S3 has it, download into * writable/cache/storage_runtime/ (temp) and auto-clean at request shutdown. */ if (! function_exists('storage_ensure_local_file')) { function storage_ensure_local_file(string $uploadPath, string $fileName): ?string { $fileName = basename(trim($fileName)); if ($fileName === '') { return null; } $storage = \Config\Services::getFileStorageService(); $localPath = $storage->resolveLocalPath($uploadPath, $fileName); if (is_file($localPath) && is_readable($localPath)) { return $localPath; } if (! $storage->usesS3()) { return null; } $result = $storage->download($uploadPath, $fileName); if (! ($result['success'] ?? false)) { return null; } $content = $result['content'] ?? null; if (! is_string($content) || $content === '') { // download() may have returned a local path already if (! empty($result['path']) && is_file((string) $result['path'])) { $existing = (string) $result['path']; // If path is already under runtime, register cleanup; else leave as-is. storage_register_temp_file($existing); return $existing; } return null; } $tmpDir = storage_runtime_temp_dir(); if (! is_dir($tmpDir)) { @mkdir($tmpDir, 0755, true); } $tmpPath = $tmpDir . DIRECTORY_SEPARATOR . uniqid('stor_', true) . '_' . $fileName; if (@file_put_contents($tmpPath, $content) === false || ! is_file($tmpPath)) { return null; } storage_register_temp_file($tmpPath); return $tmpPath; } } /** * After generating a local workbook, mirror to S3 (when enabled) and remove local permanent copy. */ if (! function_exists('storage_mirror_generated_file')) { function storage_mirror_generated_file(string $localPath, string $uploadPath, string $fileName): bool { if (! is_file($localPath)) { return false; } $storage = \Config\Services::getFileStorageService(); if (! $storage->usesS3()) { return true; } $result = $storage->upload($localPath, rtrim($uploadPath, '/\\'), $fileName); @unlink($localPath); return (bool) ($result['success'] ?? false); } } if (! function_exists('file_unlink')) { function file_unlink($filepath) { if (is_file($filepath) && file_exists($filepath)) { unlink($filepath); } } } if (! function_exists('compressImage')) { function compressImage($file, $destinationPath, $newWidth = 100, $newHeight = 100) { // Load the image manipulation library $image = \Config\Services::image(); // Resize and compress the image $image->withFile($file) ->fit($newWidth, $newHeight, 'center') ->save($destinationPath); return true; } } if (! function_exists('fancy_date_time_format')) { function fancy_date_time_format($datetime, $return_type = 'fancy') { date_default_timezone_set('Asia/Kolkata'); $currentDateTime = new DateTime(); $passedDateTime = new DateTime($datetime); // Calculate the interval between the current time and the passed datetime $interval = $currentDateTime->diff($passedDateTime); // If the interval is more than 1 month or the year is different, return the original datetime if ($interval->m > 1 || $interval->y != 0) { if ($return_type == 'fancy') { return change_date_format($datetime, 'Y-m-d H:i:s', 'd M Y h:i a'); } return $datetime; } elseif ($interval->m == 1 && $interval->y == 0) { return "1 month ago"; } elseif ($interval->d >= 7) { $weeks = floor($interval->d / 7); return $weeks == 1 ? "1 week ago" : "$weeks weeks ago"; } elseif ($interval->d >= 1) { return $interval->d == 1 ? "1 day ago" : $interval->d . " days ago"; } elseif ($interval->h >= 1) { return $interval->h == 1 ? "1 hour ago" : $interval->h . " hours ago"; } elseif ($interval->i >= 1) { return $interval->i == 1 ? "1 minute ago" : $interval->i . " minutes ago"; } else { return "Just now"; } } } if (! function_exists('check_string_date')) { function check_string_date($str) { if (DateTime::createFromFormat('Y-m-d H:i:s', $str) !== false) { return true; } return false; } } if (! function_exists('generate_download_link')) { function generate_download_link($rand_string) { // Generate the link using provided emp_code and client_policy_id $link = htmlspecialchars(base_url('download-e-card/' . $rand_string)); // Return the link wrapped in anchor tag // return 'Click To '; return $link; } } if (! function_exists('generate_random_alphanumeric')) { function generate_random_alphanumeric($length = 12) { $random_string = ''; for ($i = 0; $i < $length; $i++) { $random_ascii = rand(0, 61); if ($random_ascii < 10) { $random_character = chr($random_ascii + 48); } elseif ($random_ascii < 36) { $random_character = chr($random_ascii + 55); } else { $random_character = chr($random_ascii + 61); } $random_string .= $random_character; } return $random_string; } } if (! function_exists('get_base64_image')) { function get_base64_image($path) { // Get file extension $type = pathinfo($path, PATHINFO_EXTENSION); // Read file content $dataContent = file_get_contents($path); // Encode as base64 $base64Image = 'data:image/' . $type . ';base64,' . base64_encode($dataContent); return $base64Image; } } if (! function_exists('format_indian_number')) { function format_indian_number($number) { // Round the number to two decimal places $number = isset($number) ? $number : 0; $number = round($number, 2); // Split the number into integer and decimal parts $numberParts = explode('.', number_format($number, 2, '.', '')); $integerPart = $numberParts[0]; $decimalPart = isset($numberParts[1]) ? $numberParts[1] : '00'; // Format the integer part with commas $length = strlen($integerPart); $formattedStr = ''; $counter = 0; for ($i = $length - 1; $i >= 0; $i--) { $formattedStr = $integerPart[$i] . $formattedStr; $counter++; if ($counter == 3 && $i != 0) { $formattedStr = ',' . $formattedStr; $counter = 0; } elseif ($counter == 2 && $i != 0 && $length - $i > 3) { $formattedStr = ',' . $formattedStr; $counter = 0; } } // Combine the integer and decimal parts return $formattedStr . '.' . $decimalPart; } } if (! function_exists('get_username')) { function get_username($user_id) { // Connect to the database $db = \Config\Database::connect(); // Query the database $query = $db->table('user_profiles') ->select('first_name') ->where('id', $user_id) ->get(); // Get the result $result = $query->getRow(); // Return the username if found, otherwise return null return $result ? $result->first_name : null; } } if (! function_exists('get_role_id')) { function get_role_id() { $role_id = isset(get_session_userdata()->role) ? get_session_userdata()->role : null; return $role_id; } } if (! function_exists('teams')) { function teams() { // Load the UserTeamsModel $teamModel = new \App\Models\UserTeamsModel(); // Get the user ID from the session $user_id = get_session_userid(); // Fetch the team IDs associated with the user $user_teams = $teamModel->select('team_id')->where('user_id', $user_id)->findAll(); // Debugging: Log or print the query result to check its structure // var_dump($user_teams); // You can use this temporarily for testing // log_message('info', 'User Teams: ' . json_encode($user_teams)); // Optionally log it // Check if the result is not empty if (! empty($user_teams)) { // Extract only the 'team_id' values $team_ids = array_column($user_teams, 'team_id'); return $team_ids; // Return array of team IDs } else { return []; // Return empty array if no teams found } } } if (! function_exists('generate_client_code')) { function generate_client_code($string = 'GC') { $clientModel = new \App\Models\ClientModel(); $latestClient = $clientModel->select('id')->orderBy('id', 'DESC')->first(); $id = $latestClient ? $latestClient['id'] : 0; $year = date('y'); $newId = $id + 1; $client_code = $year . $string . $newId; return $client_code; } } if (! function_exists('generate_tsi_code')) { function generate_tsi_code($type) { $PolicyTransactionModel = new \App\Models\PolicyTransactionModel(); $latestClient = $PolicyTransactionModel->select('id')->orderBy('id', 'DESC')->first(); $id = $latestClient ? $latestClient['id'] : 0; $year = date('y'); $month = date('m'); $string = 'P'; if ($type == 2) { $string2 = 'R'; } else { $string2 = 'F'; } $newId = $id + 1; $tsi_code = $string2 . $month . $year . $string . $newId; return $tsi_code; } } if (! function_exists('generateRandomCode')) { function generateRandomCode($prefix = 'RTL-', $length = 6) { // Generate a random number with the specified length $randomNumber = str_pad(mt_rand(0, pow(10, $length) - 1), $length, '0', STR_PAD_LEFT); // Return the code with the prefix return $prefix . $randomNumber; } } if (! function_exists('excelFileGDriveUpload')) { function excelFileGDriveUpload($file_id, $table_name) { $doc_type = "UPLOADS"; $uploadFilePath = WRITEPATH . 'uploads/' . ($table_name == 'batch_file' ? 'import_excel' : 'excel'); $models = [ 'batch_file' => [ 'model' => new BatchFileModel(), 'select' => "client_id, client_policy_id, file_name", ], 'files' => [ 'model' => new FileModel(), 'select' => "client_id, policy_id as client_policy_id, file_name", ], ]; if (! array_key_exists($table_name, $models)) { return; } // Retrieve data $data = $models[$table_name]['model'] ->select($models[$table_name]['select']) ->where('id', $file_id) ->where('is_active', 1) ->first(); if ($data) { $resolved = storage_ensure_local_file($uploadFilePath, $data['file_name']); if (empty($resolved) || ! is_file($resolved)) { return; } $uploadFilePath = $resolved; $GoogleDriveController = new GoogleDriveController(); $result = $GoogleDriveController->uploadFiletoGdrive( // client_id : $data['client_id'], client_policy_id: $data['client_policy_id'], doc_type: $doc_type, file_path: $uploadFilePath, file_name: $data['file_name'] ); // dd($result); return true; } else { return false; } } } if (! function_exists('checkFamilyFloaters')) { function checkFamilyFloaters($policy_premium_data, $client_policy_data, $emp_data) { if ($policy_premium_data['premium_type'] == 1) { //only family floater if ($emp_data['relationship'] == 'Self') { return true; } if ($client_policy_data['policy_type_id'] == 3 && $client_policy_data['is_addon'] == 3) { if ($emp_data['rata_premimum'] > 0) { return true; } else { return false; } } return false; } else { //individual return true; } } } if (! function_exists('numberToWords')) { function numberToWords($number) { $words = [ '0' => 'Zero', '1' => 'One', '2' => 'Two', '3' => 'Three', '4' => 'Four', '5' => 'Five', '6' => 'Six', '7' => 'Seven', '8' => 'Eight', '9' => 'Nine', '10' => 'Ten', '11' => 'Eleven', '12' => 'Twelve', '13' => 'Thirteen', '14' => 'Fourteen', '15' => 'Fifteen', '16' => 'Sixteen', '17' => 'Seventeen', '18' => 'Eighteen', '19' => 'Nineteen', '20' => 'Twenty', '30' => 'Thirty', '40' => 'Forty', '50' => 'Fifty', '60' => 'Sixty', '70' => 'Seventy', '80' => 'Eighty', '90' => 'Ninety', ]; if ($number < 21) { return $words[$number]; } if ($number < 100) { $tens = (int) ($number / 10) * 10; $units = $number % 10; return $words[$tens] . ($units ? ' ' . $words[$units] : ''); } if ($number < 1000) { $hundreds = (int) ($number / 100); $remainder = $number % 100; return $words[$hundreds] . ' Hundred' . ($remainder ? ' and ' . numberToWords($remainder) : ''); } $levels = ['', ' Thousand', ' Million', ' Billion', ' Trillion', ' Quadrillion', ' Quintillion']; for ($i = 0, $unit = 1; $i < count($levels); $i++, $unit *= 1000) { if ($number < $unit * 1000) { $current = (int) ($number / $unit); $remainder = $number % $unit; return numberToWords($current) . $levels[$i] . ($remainder ? ' ' . numberToWords($remainder) : ''); } } return $number; // Fallback for numbers beyond the supported range } } if (! function_exists('print_rr')) { function print_rr($data) { echo "
";
        print_r($data);
        echo "
"; } } if (! function_exists('get_server_details')) { /** * Get the hostname and server name. * * @return array */ function get_server_details(): array { $hostname = gethostname(); // Get the hostname of the server $serverName = $_SERVER['SERVER_NAME'] ?? 'Unknown'; // Get the server name return [ 'hostname' => $hostname, 'server_name' => $serverName, ]; } } if (! function_exists('isJsonString')) { function isJsonString($input) { json_decode($input); // Decode the string return (json_last_error() === JSON_ERROR_NONE); // Check if the last JSON error is "no error" } } if (! function_exists('isValidDate')) { function isValidDate($date, $format) { $parsed_date = DateTime::createFromFormat($format, $date); return $parsed_date && $parsed_date->format($format) === $date; } } if (! function_exists('change_date_format')) { function change_date_format($date_str, $source_format = null, $output_format = 'Y-m-d') { $date_str = trim($date_str); // Allowed date formats $allowed_formats = [ // ISO 8601 datetime (must come before plain Y-m-d to avoid partial match issues) 'Y-m-d\TH:i:sP', // 2025-07-26T00:00:00+05:30 'Y-m-d\TH:i:s\Z', // 2025-07-26T00:00:00Z 'Y-m-d\TH:i:s', // 2025-07-26T00:00:00 // Day Month Year (clear unambiguous formats) 'd M Y', // 01 Dec 2024 'd-M-Y', // 01-Dec-2024 'd/M/Y', // 01/Dec/2024 'd.M.Y', // 01.Dec.2024 'd,M,Y', // 01,Dec,2024 // Month Day Year (clear unambiguous formats) 'M d Y', // Dec 01 2024 'M-d-Y', // Dec-01-2024 'M/d/Y', // Dec/01/2024 'M.d.Y', // Dec.01.2024 'M,d,Y', // Dec,01,2024 // Year Month Day (clear unambiguous formats) 'Y M d', // 2024 Dec 01 'Y-M-d', // 2024-Dec-01 'Y/M/d', // 2024/Dec/01 'Y.M.d', // 2024.Dec.01 'Y,M,d', // 2024,Dec,01 // Year Numeric Month Numeric Day 'Y-m-d', // 2024-12-01 'Y/m/d', // 2024/12/01 'Y.m.d', // 2024.12.01 'Y,m,d', // 2024,12,01 'd/m/Y', // 01/01/2025 'd-m-Y', // 01-01-2025 'm/d/Y h:i:s A', // 01-01-2025 'm/d/Y', // 25-05-2025 ]; try { // Case 1: Source and Output formats are provided if ($source_format !== null && $output_format !== null) { $date = DateTime::createFromFormat($source_format, $date_str); if (! $date) { // throw new Exception("Invalid date string for source format: $source_format"); // log_message('error', "❌ Date format error : Invalid date string | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}"); return null; } return $date->format($output_format); } // Case 2: Source format is provided, Output format is null if ($source_format !== null && $output_format === null) { $date = DateTime::createFromFormat($source_format, $date_str); if (! $date) { // throw new Exception("Invalid date string for source format: $source_format"); // log_message('error', "❌ Date format error : Invalid date string | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}"); return null; } return $date->format('Y-m-d'); // MySQL default format } // Case 3: Source format is null, auto-detect format if ($source_format === null) { foreach ($allowed_formats as $format) { if (isValidDate($date_str, $format)) { $date = DateTime::createFromFormat($format, $date_str); return $date->format($output_format); // Default is MySQL format } } // If no format matches, throw an exception $allowed_placeholders = implode(', ', $allowed_formats); // throw new Exception("Invalid date string format. Allowed formats: $allowed_placeholders"); // log_message( // 'error', // "❌ Date format error: Invalid date string. Allowed formats: {$allowed_placeholders} | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}" // ); return null; } } catch (Exception $e) { // return "Error: " . $e->getMessage(); // log_message('error', "❌ Date format error: {$e->getMessage()} | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}"); return null; } return null; } } // if (!function_exists('check_pay_by_employee_or_company')) // { // function check_pay_by_employee_or_company($is_payable_employee = null, $relationship = null) { // $relationship = strtolower(str_replace(" ", "_", $relationship)); // $result = 0; // if($relationship == 'self'){ // $result = $is_payable_employee['self'] == 1 ? 1 : 0; // }else if($relationship == 'spouse'){ // $result = $is_payable_employee['spouse'] == 1 ? 1 : 0; // }else if(in_array($relationship, ['son', 'daughter'])){ // $result = $is_payable_employee['childern'] == 1 ? 1 : 0; // }else if(in_array($relationship, ['father', 'mother', 'father_in_law', 'mother_in_law'])){ // $result = $is_payable_employee['elders'] == 1 ? 1 : 0; // } // return $result; // } // } if (! function_exists('check_pay_by_employee_or_company')) { function check_pay_by_employee_or_company($policy_terms = null, $relationship = null) { // dd($policy_terms, $relationship); if (! $policy_terms || ! ($policy_terms = json_decode($policy_terms, true))) { return 0; } // dd($policy_terms, $relationship); if (! isset($policy_terms['is_payable_employee'])) { return 0; } $is_payable_employee = $policy_terms['is_payable_employee']; $relationship = strtolower(str_replace(" ", "_", $relationship)); // dd($is_payable_employee, $relationship); $relationshipMap = [ 'self' => 'self', 'spouse' => 'spouse', 'son' => 'childern', 'daughter' => 'childern', 'father' => 'elders', 'mother' => 'elders', 'father_in_law' => 'elders', 'mother_in_law' => 'elders', ]; if (array_key_exists($relationship, $relationshipMap)) { $key = $relationshipMap[$relationship]; return isset($is_payable_employee[$key]) && $is_payable_employee[$key] == 1 ? 1 : 0; } return 0; } } if (! function_exists('is_json_string')) { function is_json_string($string) { if (! is_string($string)) { return false; } $decoded = json_decode($string, true); return (json_last_error() === JSON_ERROR_NONE && is_array($decoded)); } } if (! function_exists('check_cd_entry_exist')) { function check_cd_entry_exist($params) { $db = db_connect(); $client_id = $params['client_id']; $client_policy_id = $params['client_policy_id']; $insurer_id = $params['insurer_id']; $cd_ac_pk = $params['cd_ac_pk']; $event_name = $params['event_name']; // Check if truncated entry (sub_type = 8) exists $has_truncated = $db->table('cash_deposit') ->where('client_id', $client_id) ->where('insurer_id', $insurer_id) ->where('cd_ac_pk', $cd_ac_pk) ->where('client_policy_id', $client_policy_id) ->where('event_name', $event_name) ->where('sub_type', 8) ->where('is_active', 1) ->countAllResults(); if ($has_truncated) { echo "has_truncated"; // Get all entries with same details (including truncated) $entries = $db->table('cash_deposit') ->where('client_id', $client_id) ->where('insurer_id', $insurer_id) ->where('cd_ac_pk', $cd_ac_pk) ->where('client_policy_id', $client_policy_id) ->where('event_name', $event_name) ->where('is_active', 1) ->where('sub_type !=', 8) ->get() ->getResultArray(); if (count($entries) > 1) { // Only one entry found (truncated) return true; } else { return false; } } else { // Check if any other entry exists $entry = $db->table('cash_deposit') ->where('client_id', $client_id) ->where('insurer_id', $insurer_id) ->where('cd_ac_pk', $cd_ac_pk) ->where('client_policy_id', $client_policy_id) ->where('event_name', $event_name) ->where('is_active', 1) ->get() ->getRowArray(); if (! empty($entry)) { return true; } } return false; } } if (! function_exists('expected_amount_calc')) { function expected_amount_calc($data, $index) { $agreed_amount = (float) ($data['agreed_amount'][$index] ?? 0); $agreed_bp_per = (float) ($data['agreed_bp'][$index] ?? 0); $agreed_tp_per = (float) ($data['agreed_tp'][$index] ?? 0); $agreed_tep_per = (float) ($data['agreed_ter'][$index] ?? 0); $standard_bp_per = (float) ($data['standard_bp'][$index] ?? 0); $standard_tp_per = (float) ($data['standard_tp'][$index] ?? 0); $standard_tep_per = (float) ($data['standard_ter'][$index] ?? 0); if ($data['bro_payable_by'] == 0) { $base_premium = (float) ($data['co_premium'][$index] ?? 0); $third_part_premium = (float) ($data['co_tp_premium'][$index] ?? 0); $terrisom_premium = (float) ($data['co_ter_premium'][$index] ?? 0); } else { $base_premium = (float) ($data['base_premium'][$index] ?? 0); $third_part_premium = (float) ($data['tp_premium'][$index] ?? 0); $terrisom_premium = (float) ($data['ter_premium'][$index] ?? 0); } $sum_of_agreed_premium = $agreed_bp_per + $agreed_tp_per + $agreed_tep_per; $expectedAmount = 0; if ($agreed_amount > 0) { $expectedAmount = $agreed_amount; } elseif ($sum_of_agreed_premium > 0) { $expectedAmount = ($base_premium * $agreed_bp_per / 100) + ($third_part_premium * $agreed_tp_per / 100) + ($terrisom_premium * $agreed_tep_per / 100); } else { $expectedAmount = ($base_premium * $standard_bp_per / 100) + ($third_part_premium * $standard_tp_per / 100) + ($terrisom_premium * $standard_tep_per / 100); } return round($expectedAmount, 2); // Optional: round to 2 decimal places } } if (! function_exists('getFileIfExists')) { function getFileIfExists($path) { return file_exists(FCPATH . $path) ? base_url($path) : ''; } } if (! function_exists('removeNumberFormatting')) { function removeNumberFormatting($number) { return (float) str_replace(',', '', trim($number)); } } if (! function_exists('formatKey')) { function formatKey($key, $len = 3) { $words = explode('_', $key); $formatted = array_map(function ($word) use ($len) { return strlen($word) < $len ? strtoupper($word) : ucfirst(strtolower($word)); }, $words); return implode(' ', $formatted); } } if (! function_exists('getMimeTypeByFileName')) { function getMimeTypeByFileName($file_name) { $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); $mime_types = [ 'pdf' => 'application/pdf', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif', 'doc' => 'application/msword', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'xls' => 'application/vnd.ms-excel', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'csv' => 'text/csv', 'txt' => 'text/plain', 'zip' => 'application/zip', 'rar' => 'application/x-rar-compressed', 'json' => 'application/json', ]; return $mime_types[$ext] ?? 'application/octet-stream'; // default fallback } } if (! function_exists('validateExcelFile')) { function validateExcelFile($file) { // 1. Check if the file was uploaded without errors if (! $file->isValid() || $file->hasMoved()) { return false; } // 2. Size check (16MB) if ($file->getSizeByUnit('mb') > 16) { return false; } // 3. Define allowed types $allowedMimes = [ 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.oasis.opendocument.spreadsheet', 'application/zip', 'application/octet-stream', ]; $allowedExtensions = ['xls', 'xlsx', 'ods', 'xlsm']; // Get the actual values using CI4 methods $mime = $file->getClientMimeType(); $extension = $file->getExtension(); // This is the CI4 method // 4. Validate if (in_array($mime, $allowedMimes) || in_array($extension, $allowedExtensions)) { return true; } return false; } } if (! function_exists('generate_ecard_download_link_based_on_tpa')) { function generate_ecard_download_link_based_on_tpa($params) { $apiServiceController = new ApiServiceController(); $data = $apiServiceController->ecardRequest($params, $return_type = 'internal'); log_message('error', 'E-card request call from the helper for mail send'); if (isset($data['eCardDownload']) && ! empty($data['eCardDownload'])) { return $data['eCardDownload']; } else { return $data['message']; } } } if (! function_exists('canSendOtp')) { function canSendOtp(array $row, int $limitSeconds = 60): array { // If OTP does not exist → allow if (empty($row['otp']) || empty($row['updated_at'])) { return ['allowed' => true]; } $lastUpdated = strtotime($row['updated_at']); $currentTime = time(); // Calculate expiry time $allowedAfter = $lastUpdated + $limitSeconds; // If still within limit → block if ($currentTime < $allowedAfter) { return [ 'allowed' => false, 'retry_after' => $allowedAfter - $currentTime, ]; } return ['allowed' => true]; } } if (! function_exists('checkDuplicateClaim')) { function checkDuplicateClaim(array $params): bool { $ticketMaster = new TicketMasterModel(); $query = $ticketMaster->where('is_active', 1); if (empty($params['doa']) && empty($params['claim_amount'])) { return false; } $hasValidCondition = false; foreach ($params as $key => $value) { if ($value !== null && $value !== '') { $query->where($key, $value); $hasValidCondition = true; } } if (! $hasValidCondition) { return false; } $result = $query->countAllResults(); // print_r($ticketMaster->getLastQuery()->getQuery()); die; if ($result > 0) {return true;} else {return false;} } } function getRealClientIP() { $request = service('request'); if (! empty($_SERVER['HTTP_CF_CONNECTING_IP'])) { return $_SERVER['HTTP_CF_CONNECTING_IP']; } if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]; } return $request->getIPAddress(); } function generateFingerprint(bool $exclude_ua = false): string { $request = service('request'); $ua = $request->getUserAgent()->getAgentString(); $ip = getRealClientIP(); // Normalize localhost if ($ip === '127.0.0.1' || $ip === '::1') { $ipGroup = 'localhost'; } // IPv4 handling elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $parts = explode('.', $ip); // Use /24 subnet (first 3 octets) $ipGroup = $parts[0] . '.' . $parts[1] . '.' . $parts[2]; } // IPv6 handling elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { // Use first 4 blocks of IPv6 (rough /64 grouping) $blocks = explode(':', $ip); $ipGroup = implode(':', array_slice($blocks, 0, 4)); } // Fallback else { $ipGroup = 'unknown'; } if ($exclude_ua) { return hash('sha256', $ipGroup); } return hash('sha256', $ua . '|' . $ipGroup); } if (! function_exists('convertGoogleDriveToDownloadLink')) { function convertGoogleDriveToDownloadLink(?string $url): ?string { if (empty($url)) { return null; } // Trim spaces $url = trim($url); // Pattern to extract Google Drive file ID $patterns = [ '#https?://drive\.google\.com/file/d/([^/]+)/?#', '#https?://drive\.google\.com/open\?id=([^&]+)#', '#https?://drive\.google\.com/uc\?id=([^&]+)#', ]; foreach ($patterns as $pattern) { if (preg_match($pattern, $url, $matches)) { $fileId = $matches[1]; // Return direct download link return 'https://drive.google.com/uc?export=download&id=' . $fileId; } } // Not a Google Drive link → return original return $url; } } if (! function_exists('get_cd_balance')) { function get_cd_balance(): array { $session = session(); return [ 'has_cd_balance' => $session->has('cd_balance'), 'cd_balance' => $session->get('cd_balance') ?? null, 'hr_data' => $session->get('hr_data') ?? [], 'cd_balance_info' => $session->get('cd_balance_info') ?? [], ]; } } if (! function_exists('clear_cd_balance_session')) { function clear_cd_balance_session(): void { $session = session(); $session->remove('cd_balance'); $session->remove('hr_data'); $session->remove('cd_balance_info'); log_message('error', 'clear_cd_balance_session clered'); } } if (! function_exists('format_gender_v2')) { function format_gender_v2($gender) { if (empty($gender)) { return null; } $g = strtoupper(trim($gender)); // Direct-ah check pannuvom if (str_starts_with($g, 'M')) { return 'M'; } // Male, M if (str_starts_with($g, 'F')) { return 'F'; } // Female, F // Others, Transgender, O - ivatrai 'O' ena return seiyum if (str_starts_with($g, 'O') || str_starts_with($g, 'T')) { return 'O'; } return $g; // Vera ethuvum illaiyengil original-aiye return pannum } } if (! function_exists('map_relationship')) { /** * Employee -> self, WIFE -> spouse ena maatri return seiyum. */ function map_relationship($relation) { if (empty($relation)) { return ''; } // Case prechanai varaamal irukka lowercase-kku maatri check seivom $r = strtolower(trim($relation)); if ($r == 'employee') { return 'self'; } else if ($r == 'wife') { return 'spouse'; } // Matra anaithu relationship-um iruppathu polave (Original-aga) return aagum return $relation; } } /** * Extract identity from POST body or GET params. * Looks for 'email' or 'mobile_number'. */ function resolveIdentity($request): ?string { // Try POST body first $email = $request->getPost('email'); // print_r($email);die; $mobile = $request->getPost('mobile_number'); // Fallback to GET params if (! $email && ! $mobile) { $email = $request->getGet('email'); $mobile = $request->getGet('mobile_number'); } // Fallback to JSON params if (! $email && ! $mobile) { $req_data = $request->getJSON(); // print_r( $req_data); $mobile = $req_data->mobile_number ?? null; // return trim($mobile_number); $email = $req_data->email ?? null; if (! $email) { $email = $req_data->email_id ?? null; } // return trim($email); } if ($email) { return strtolower(trim($email)); } if ($mobile) { return trim($mobile); } return null; } function recordRateLimitFailure(string $context = 'authApi'): void { /** @var IncomingRequest $request */ $request = \Config\Services::request(); $limiter = \Config\Services::limiter(); // or your custom limiter service $fingerprint = $request->getVar('rateLimitFingerprint') ?? generateFingerprint(exclude_ua: true); $identity = $request->getVar('rateLimitIdentity') ?? resolveIdentity($request); // Record IP-level failure $limiter->recordIpFailure($fingerprint); // Record user-level failure if (! empty($identity)) { $limiter->recordUserFailure($identity, $context); } } if (! function_exists('getCurrentFinancialYear')) { function getCurrentFinancialYear() { // Get current year and month $date = new DateTime(); $currentYear = (int) $date->format('Y'); $currentMonth = (int) $date->format('m'); // If month is Jan, Feb, or March, we are still in the previous year's FY if ($currentMonth < 4) { $startYear = $currentYear - 1; $endYear = $currentYear; } else { $startYear = $currentYear; $endYear = $currentYear + 1; } return $startYear . '-' . $endYear; } } if (! function_exists('format_financial_year')) { function format_financial_year(string $financialYear): string { if (empty($financialYear) || ! str_contains($financialYear, '-')) { return $financialYear; } $years = explode('-', $financialYear); // Ensure we have both parts $startYear = $years[0] ?? ''; $endYear = $years[1] ?? ''; return "APR " . $startYear . " - MAR " . $endYear; } } if (! function_exists('add_google_calender_event')) { function add_google_calender_event($data) { $calendar = new \App\Libraries\GoogleCalendarService(); // Check if user is authenticated without passing tokens manually if (! $calendar->isReady()) { return ['status' => 'failed', 'code' => '404', 'message' => 'Google Access Token Expired']; } try { $response = $calendar->createEvent($data); return ['status' => 'success', 'code' => '200', 'message' => 'Follow-up Saved', 'response' => $response]; } catch (\Exception $e) { return ['status' => 'failed', 'code' => '500', 'message' => 'Error: ' . $e->getMessage()]; } } } if (! function_exists('cleanNumber')) { function cleanNumber($value){ if (empty($value)) { return 0; } $value = str_replace(',', '', trim($value)); return is_numeric($value) ? (float)$value : 0; } }