initial commit
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\ResponseJson; // Import the ResponseJson helper
|
||||
use App\Http\Requests\CreateUserRequest;
|
||||
use App\Http\Requests\EditUserRequest;
|
||||
use App\Http\Requests\UserIdRequest;
|
||||
use App\Services\AdminUserService;
|
||||
use App\Services\DiseaseService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class AdminUserController extends Controller
|
||||
{
|
||||
protected AdminUserService $adminUserService;
|
||||
|
||||
public function __construct(AdminUserService $adminUserService)
|
||||
{
|
||||
$this->adminUserService = $adminUserService;
|
||||
}
|
||||
|
||||
public function createUser(CreateUserRequest $request): JsonResponse
|
||||
{
|
||||
|
||||
$validatedData = $request->validated();
|
||||
|
||||
[$success, $message, $data] = $this->adminUserService->createUser($validatedData);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $validatedData);
|
||||
}
|
||||
|
||||
if ($validatedData['role'] === 'operator' && isset($validatedData['disease_ids'])) {
|
||||
[$assignSuccess, $assignMessage, $data] = $this->adminUserService->assignOperatorToDiseases($data['id'], $validatedData['disease_ids']);
|
||||
|
||||
if ($assignSuccess) {
|
||||
$message .= ' ' . $assignMessage;
|
||||
} else {
|
||||
return ResponseJson::failedResponse($assignMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $data);
|
||||
}
|
||||
|
||||
public function approveUser(UserIdRequest $request, $userId): JsonResponse
|
||||
{
|
||||
[$success, $message, $data] = $this->adminUserService->approveUser($userId);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('User approved successfully.', $data);
|
||||
}
|
||||
|
||||
public function rejectUser(UserIdRequest $request, $userId): JsonResponse
|
||||
{
|
||||
[$success, $message, $data] = $this->adminUserService->rejectUser($userId);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('User rejected successfully.', $data);
|
||||
}
|
||||
|
||||
public function editUser(EditUserRequest $request, $id): JsonResponse
|
||||
{
|
||||
|
||||
[$success, $message, $data] = $this->adminUserService->editUser($id, $request->validated());
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('User updated successfully.', $data);
|
||||
}
|
||||
|
||||
public function deleteUser(UserIdRequest $request, $userId): JsonResponse
|
||||
{
|
||||
[$success, $message, $data] = $this->adminUserService->deleteUser($userId);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('User deleted successfully.', $data);
|
||||
}
|
||||
|
||||
public function getUsers(Request $request): JsonResponse
|
||||
{
|
||||
[$success, $message, $data]= $this->adminUserService->getUsers($request->all());
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
return ResponseJson::successResponse('Users retrieved successfully.', $data);
|
||||
}
|
||||
|
||||
public function getUserDetails(UserIdRequest $request, $userId): JsonResponse
|
||||
{
|
||||
[$success, $message, $data] = $this->adminUserService->getUserDetails($userId);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('User details retrieved successfully.', $data);
|
||||
}
|
||||
|
||||
public function getUserProfile(Request $request)
|
||||
{
|
||||
$user = $request->user(); // Get the authenticated user
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Profile retrieved successfully.',
|
||||
'data' => [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'email' => $user->email,
|
||||
'role' => $user->role,
|
||||
'institution' => $user->institution,
|
||||
'gender' => $user->gender,
|
||||
'phone' => $user->phone_number,
|
||||
'approval_status' => $user->approval_status,
|
||||
'created_at' => $user->created_at,
|
||||
'updated_at' => $user->updated_at,
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\ResponseJson;
|
||||
use App\Http\Requests\LoginUserRequest;
|
||||
use App\Http\Requests\RegisterUserRequest;
|
||||
use App\Services\AuthUserService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
private AuthUserService $authUserService;
|
||||
|
||||
public function __construct(AuthUserService $authUserService)
|
||||
{
|
||||
$this->authUserService = $authUserService;
|
||||
}
|
||||
|
||||
public function register(RegisterUserRequest $request)
|
||||
{
|
||||
[$success, $message, $data] = $this->authUserService->register(
|
||||
$request->name,
|
||||
$request->email,
|
||||
$request->password,
|
||||
$request->institution,
|
||||
$request->gender,
|
||||
$request->phone_number,
|
||||
$request->tujuan_permohonan,
|
||||
);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $data);
|
||||
}
|
||||
|
||||
public function login(LoginUserRequest $request)
|
||||
{
|
||||
[$success, $message, $data] = $this->authUserService->login(
|
||||
$request->email,
|
||||
$request->password
|
||||
);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $data);
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$this->authUserService->logout($request->user());
|
||||
return ResponseJson::successResponse('Berhasil Logout', []);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\CommentService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Helpers\ResponseJson;
|
||||
use App\Http\Requests\CreateCommentRequest;
|
||||
use App\Http\Requests\DeleteCommentRequest;
|
||||
use App\Http\Requests\EditCommentRequest;
|
||||
|
||||
class CommentController extends Controller
|
||||
{
|
||||
protected CommentService $commentService;
|
||||
|
||||
public function __construct(CommentService $commentService)
|
||||
{
|
||||
$this->commentService = $commentService;
|
||||
}
|
||||
|
||||
public function createComment(CreateCommentRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$userId = $request->user()->id;
|
||||
|
||||
[$success, $message, $comment] = $this->commentService->createComment($data, $userId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $comment);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $comment);
|
||||
}
|
||||
|
||||
public function editComment(EditCommentRequest $request, $diseaseId, $commentId): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$userId = $request->user()->id;
|
||||
|
||||
[$success, $message, $comment] = $this->commentService->editComment($commentId, $data, $userId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $comment);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $comment);
|
||||
}
|
||||
|
||||
public function deleteComment(DeleteCommentRequest $request, $diseaseId, $commentId): JsonResponse
|
||||
{
|
||||
$userId = request()->user()->id;
|
||||
|
||||
[$success, $message, $comment] = $this->commentService->deleteComment($commentId, $userId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $comment);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $comment);
|
||||
}
|
||||
|
||||
public function getComments($diseaseId): JsonResponse
|
||||
{
|
||||
[$success, $message, $comments] = $this->commentService->getComments($diseaseId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $comments);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $comments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, ValidatesRequests;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\ResponseJson; // Import the ResponseJson helper
|
||||
use App\Services\DiseaseService;
|
||||
use App\Http\Requests\CreateDiseaseRequest;
|
||||
use App\Http\Requests\EditDiseaseRequest;
|
||||
use App\Http\Requests\DiseaseIdRequest;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class DiseaseController extends Controller
|
||||
{
|
||||
protected DiseaseService $diseaseService;
|
||||
|
||||
public function __construct(DiseaseService $diseaseService)
|
||||
{
|
||||
$this->diseaseService = $diseaseService;
|
||||
}
|
||||
|
||||
public function createDisease(CreateDiseaseRequest $request): JsonResponse
|
||||
{
|
||||
$userId = $request->user()->id;
|
||||
|
||||
[$success, $message, $data] = $this->diseaseService->createDisease($request->validated(), $userId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $data);
|
||||
}
|
||||
|
||||
public function editDisease(EditDiseaseRequest $request, $diseaseId): JsonResponse
|
||||
{
|
||||
// Log::info('EditDisease Request Data: ', $request->validated());
|
||||
|
||||
$userId = $request->user()->id;
|
||||
|
||||
[$success, $message, $data] = $this->diseaseService->editDisease($diseaseId, $request->validated(), $userId);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('Disease updated successfully.', $data);
|
||||
}
|
||||
|
||||
public function deleteDisease(DiseaseIdRequest $request, $diseaseId): JsonResponse
|
||||
{
|
||||
$userId = $request->user()->id;
|
||||
|
||||
[$success, $message, $data] = $this->diseaseService->deleteDisease($diseaseId, $userId);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('Disease deleted successfully.', $data);
|
||||
}
|
||||
|
||||
public function getDiseases(Request $request): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
[$success, $message, $data] = $this->diseaseService->getDisease($request->all(), $user);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('Disease retrieved successfully.', $data);
|
||||
}
|
||||
|
||||
public function getDiseaseDetails(DiseaseIdRequest $request, $diseaseId): JsonResponse
|
||||
{
|
||||
[$success, $message, $data] = $this->diseaseService->getDiseaseDetails($diseaseId);
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('Disease details retrieved successfully.', $data);
|
||||
}
|
||||
|
||||
public function getStatistics(Request $request): JsonResponse
|
||||
{
|
||||
[$success, $message, $data]= $this->diseaseService->getStatistics($request->all());
|
||||
|
||||
if(!$success){
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
return ResponseJson::successResponse('Disease statistics retrieved successfully.', $data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\ResponseJson; // Import the ResponseJson helper
|
||||
use App\Services\DiseaseRecordService;
|
||||
use App\Http\Requests\CreateDiseaseRecordRequest;
|
||||
use App\Http\Requests\CreateDiseaseRequest;
|
||||
use App\Http\Requests\ShowDiseaseRecordRequest;
|
||||
use App\Http\Requests\EditDiseaseRecordRequest;
|
||||
use App\Http\Requests\DeleteDiseaseRecordRequest;
|
||||
use App\Http\Requests\IndexDiseaseRecordRequest;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class DiseaseRecordController extends Controller
|
||||
{
|
||||
protected DiseaseRecordService $diseaseRecordService;
|
||||
|
||||
public function __construct(DiseaseRecordService $diseaseRecordService)
|
||||
{
|
||||
$this->diseaseRecordService = $diseaseRecordService;
|
||||
}
|
||||
|
||||
public function createDiseaseRecord(CreateDiseaseRecordRequest $request): JsonResponse
|
||||
{
|
||||
//var_dump($request->all());
|
||||
// return ResponseJson::failedResponse("tez", []);
|
||||
$userId = $request->user()->id;
|
||||
//echo(is_array($request->input('record_data')));
|
||||
[$success, $message, $data] = $this->diseaseRecordService->createDiseaseRecord($request->validated(), $userId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $data);
|
||||
}
|
||||
|
||||
public function editDiseaseRecord(EditDiseaseRecordRequest $request, $diseaseId, $recordId): JsonResponse
|
||||
{
|
||||
$userId = $request->user()->id;
|
||||
[$success, $message, $data] = $this->diseaseRecordService->editDiseaseRecord($recordId, $request->validated(), $userId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('Disease record updated successfully.', $data);
|
||||
}
|
||||
|
||||
public function deleteDiseaseRecord(DeleteDiseaseRecordRequest $request, $diseaseId, $recordId): JsonResponse
|
||||
{
|
||||
$userId = $request->user()->id;
|
||||
[$success, $message] = $this->diseaseRecordService->deleteDiseaseRecord($recordId, $userId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message);
|
||||
}
|
||||
|
||||
public function getDiseaseRecords(IndexDiseaseRecordRequest $request, $diseaseId): JsonResponse
|
||||
{
|
||||
[$success, $message, $data] = $this->diseaseRecordService->getDiseaseRecords($diseaseId, $request->all());
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse('Disease records retrieved successfully.', $data);
|
||||
}
|
||||
|
||||
|
||||
public function getDiseaseRecordDetails(ShowDiseaseRecordRequest $request, $diseaseId, $recordId): JsonResponse
|
||||
{
|
||||
[$success, $message, $data] = $this->diseaseRecordService->getDiseaseRecordDetails($diseaseId, $recordId);
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::failedResponse($message, $data);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Disease;
|
||||
use App\Models\DiseaseRecord;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use App\Services\FileStorageService;
|
||||
use App\Http\Requests\IndexDiseaseRecordRequest;
|
||||
use App\Http\Requests\ShowDiseaseRecordRequest;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class DiseaseRecordExportController extends Controller
|
||||
{
|
||||
protected $fileStorage;
|
||||
|
||||
public function __construct(FileStorageService $fileStorage)
|
||||
{
|
||||
$this->fileStorage = $fileStorage;
|
||||
$this->middleware(['auth:sanctum', 'checkDiseaseAccess']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all disease records to CSV
|
||||
*/
|
||||
public function exportToCsv(IndexDiseaseRecordRequest $request, $diseaseId)
|
||||
{
|
||||
// Validate disease exists
|
||||
$disease = Disease::findOrFail($diseaseId);
|
||||
|
||||
// Get all columns from schema
|
||||
$columns = collect($disease->schema['columns'])
|
||||
->pluck('name')
|
||||
->toArray();
|
||||
|
||||
// Generate filename
|
||||
$filename = sprintf(
|
||||
'disease-records-%s-%s.csv',
|
||||
$disease->name,
|
||||
now()->format('Y-m-d-His')
|
||||
);
|
||||
|
||||
return $this->generateCsvResponse($disease, $columns, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export single record to CSV
|
||||
*/
|
||||
public function exportSingleRecord(ShowDiseaseRecordRequest $request, $diseaseId, $recordId)
|
||||
{
|
||||
$disease = Disease::findOrFail($diseaseId);
|
||||
$record = DiseaseRecord::where('disease_id', $diseaseId)
|
||||
->where('id', $recordId)
|
||||
->firstOrFail();
|
||||
|
||||
$columns = collect($disease->schema['columns'])
|
||||
->pluck('name')
|
||||
->toArray();
|
||||
|
||||
$filename = sprintf(
|
||||
'disease-record-%s-%d-%s.csv',
|
||||
$disease->name,
|
||||
$recordId,
|
||||
now()->format('Y-m-d-His')
|
||||
);
|
||||
|
||||
return $this->generateCsvResponse($disease, $columns, $filename, $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CSV response for both single and multiple records
|
||||
*/
|
||||
private function generateCsvResponse($disease, $columns, $filename, $singleRecord = null)
|
||||
{
|
||||
return new StreamedResponse(function () use ($disease, $columns, $singleRecord) {
|
||||
$handle = fopen('php://output', 'w');
|
||||
|
||||
// Write headers
|
||||
fputcsv($handle, [...$columns, 'created_at', 'updated_at']);
|
||||
|
||||
if ($singleRecord) {
|
||||
// Write single record
|
||||
$this->writeRecordToCsv($handle, $singleRecord, $columns);
|
||||
} else {
|
||||
// Write all records
|
||||
DiseaseRecord::where('disease_id', $disease->id)
|
||||
->chunk(100, function ($records) use ($handle, $columns) {
|
||||
foreach ($records as $record) {
|
||||
$this->writeRecordToCsv($handle, $record, $columns);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}, 200, [
|
||||
'Content-Type' => 'text/csv',
|
||||
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
|
||||
'Cache-Control' => 'no-cache, no-store, must-revalidate',
|
||||
'Pragma' => 'no-cache',
|
||||
'Expires' => '0',
|
||||
]);
|
||||
}
|
||||
|
||||
private function generateSignedFileUrl($path)
|
||||
{
|
||||
// Remove any leading slashes
|
||||
$path = ltrim($path, '/');
|
||||
|
||||
return URL::temporarySignedRoute(
|
||||
'files.download.record',
|
||||
now()->addHours(24), // URLs valid for 24 hours
|
||||
['path' => $path]
|
||||
);
|
||||
}
|
||||
|
||||
private function generatePublicFileUrl($path)
|
||||
{
|
||||
$domain = env('APP_URL');
|
||||
return $domain . '/storage/public/' . $path;
|
||||
}
|
||||
/**
|
||||
* Write a single record to CSV
|
||||
*/
|
||||
private function writeRecordToCsv($handle, $record, $columns)
|
||||
{
|
||||
$row = [];
|
||||
foreach ($columns as $column) {
|
||||
$value = $record->data[$column] ?? '';
|
||||
|
||||
// Handle file paths
|
||||
if (is_array($value)) {
|
||||
// Convert array of file paths to public URLs
|
||||
$urls = array_map(
|
||||
fn($path) => $this->generatePublicFileUrl($path),
|
||||
$value
|
||||
);
|
||||
$value = implode(' | ', $urls);
|
||||
} elseif (is_string($value) && str_contains($value, 'diseases/records/')) {
|
||||
// Convert single file path to public URL
|
||||
$value = $this->generatePublicFileUrl($value);
|
||||
}
|
||||
|
||||
$row[] = $value;
|
||||
}
|
||||
|
||||
// Add timestamps
|
||||
$row[] = $record->created_at->format('Y-m-d H:i:s');
|
||||
$row[] = $record->updated_at->format('Y-m-d H:i:s');
|
||||
|
||||
fputcsv($handle, $row);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\FileStorageService;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\DiseaseRecord;
|
||||
use App\Models\Disease;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class FileController extends Controller
|
||||
{
|
||||
protected $fileStorage;
|
||||
|
||||
public function __construct(FileStorageService $fileStorage)
|
||||
{
|
||||
$this->fileStorage = $fileStorage;
|
||||
$this->middleware(['auth:sanctum', 'checkDiseaseAccess'])->only(['previewFile']);
|
||||
// $this->middleware('signed')->only(['downloadRecord']); // Add signed middleware for downloads
|
||||
}
|
||||
|
||||
public function previewFile(Request $request, string $path)
|
||||
{
|
||||
try {
|
||||
$path = $this->sanitizePath($path);
|
||||
$storagePath = storage_path('app/public/' . $path);
|
||||
|
||||
if (!file_exists($storagePath)) {
|
||||
Log::error('File not found', ['path' => $path]);
|
||||
abort(404, 'File not found');
|
||||
}
|
||||
|
||||
// Determine MIME type
|
||||
$mimeType = mime_content_type($storagePath);
|
||||
|
||||
// Only allow audio files for preview (extendable later)
|
||||
if (!str_starts_with($mimeType, 'audio/')) {
|
||||
abort(415, 'Unsupported media type for inline preview');
|
||||
}
|
||||
|
||||
// Stream audio file
|
||||
return response()->file($storagePath, [
|
||||
'Content-Type' => $mimeType,
|
||||
'Content-Disposition' => 'inline',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('File preview failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'path' => $path,
|
||||
'user_id' => $request->user()->id ?? null,
|
||||
]);
|
||||
abort(500, 'Failed to preview file');
|
||||
}
|
||||
}
|
||||
|
||||
public function downloadRecord(Request $request, string $path)
|
||||
{
|
||||
try {
|
||||
if (!$request->hasValidSignature()) {
|
||||
abort(401, 'Invalid signature');
|
||||
}
|
||||
|
||||
// Clean up the path to match storage structure
|
||||
$path = $this->sanitizePath($path);
|
||||
|
||||
// Determine the full storage path
|
||||
$storagePath = storage_path('app/public/' . $path);
|
||||
|
||||
if (!file_exists($storagePath)) {
|
||||
Log::error('File not found', [
|
||||
'path' => $path,
|
||||
'full_path' => $storagePath
|
||||
]);
|
||||
abort(404, 'File not found');
|
||||
}
|
||||
|
||||
// Find record containing this file path
|
||||
$record = $this->findRecordByPath($path);
|
||||
if (!$record) {
|
||||
abort(404, 'Associated record not found');
|
||||
}
|
||||
|
||||
// Log download attempt
|
||||
Log::info('File download initiated via signed URL', [
|
||||
'path' => $path,
|
||||
'disease_id' => $record->disease_id,
|
||||
'record_id' => $record->id
|
||||
]);
|
||||
|
||||
return $this->fileStorage->streamFile('public/' . $path);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('File download failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'path' => $path ?? 'undefined'
|
||||
]);
|
||||
|
||||
abort(500, 'Failed to download file: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function sanitizePath(string $path): string
|
||||
{
|
||||
// Remove any directory traversal attempts and extra slashes
|
||||
$path = str_replace(['..', '//'], ['', '/'], $path);
|
||||
|
||||
// Remove /api/files/records if present at the start
|
||||
$path = preg_replace('/^\/?(api\/files\/records\/)?/', '', $path);
|
||||
|
||||
return trim($path, '/');
|
||||
}
|
||||
|
||||
private function findRecordByPath(string $path): ?DiseaseRecord
|
||||
{
|
||||
// First find all diseases that have file fields
|
||||
$diseasesWithFiles = Disease::whereRaw("jsonb_path_exists(schema->'columns',
|
||||
'$.** ? (@.type == \"file\")')")
|
||||
->get();
|
||||
|
||||
if ($diseasesWithFiles->isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get all file field names from the schemas
|
||||
$fileFields = [];
|
||||
foreach ($diseasesWithFiles as $disease) {
|
||||
$columns = $disease->schema['columns'] ?? [];
|
||||
foreach ($columns as $column) {
|
||||
if (($column['type'] ?? '') === 'file') {
|
||||
$fileFields[$disease->id][] = [
|
||||
'name' => $column['name'],
|
||||
'multiple' => $column['multiple'] ?? false
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build query based on discovered file fields
|
||||
return DiseaseRecord::where(function ($query) use ($path, $fileFields) {
|
||||
foreach ($fileFields as $diseaseId => $fields) {
|
||||
foreach ($fields as $field) {
|
||||
if ($field['multiple']) {
|
||||
// Handle array fields using ? operator
|
||||
$query->orWhere(function ($q) use ($path, $diseaseId, $field) {
|
||||
$q->where('disease_id', $diseaseId)
|
||||
->whereRaw("data->? ?? ?", [$field['name'], $path]);
|
||||
});
|
||||
} else {
|
||||
// Handle single file fields
|
||||
$query->orWhere(function ($q) use ($path, $diseaseId, $field) {
|
||||
$q->where('disease_id', $diseaseId)
|
||||
->whereRaw("data->>? = ?", [$field['name'], $path]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})->first();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Helpers\ResponseJson;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Services\LogActionService;
|
||||
|
||||
class LogActionController extends Controller
|
||||
{
|
||||
protected LogActionService $logActionService;
|
||||
|
||||
public function __construct(LogActionService $logActinoService)
|
||||
{
|
||||
$this->logActionService = $logActinoService;
|
||||
}
|
||||
|
||||
public function getLogActions(Request $request){
|
||||
|
||||
[$success, $message, $logs] = $this->logActionService->getLogs($request->all());
|
||||
|
||||
if (!$success) {
|
||||
return ResponseJson::errorResponse($message);
|
||||
}
|
||||
|
||||
return ResponseJson::successResponse($message, $logs);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user