DONE: layout letter with letterhead and footer, notification for newly...
This commit is contained in:
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\BaseCrudController;
|
||||
use App\Models\Document;
|
||||
use App\Services\ActivityLogger;
|
||||
use App\Services\DocumentService;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Modules\Activity\Entities\Activity;
|
||||
use Modules\Activity\Http\Requests\ActivityRequest;
|
||||
use Modules\Activity\Http\Requests\UploadActivityDocumentRequest;
|
||||
use Modules\Activity\Http\Requests\UploadActivityGalleryImageRequest;
|
||||
use Modules\Activity\Repositories\Contracts\ActivityRepositoryInterface;
|
||||
use Modules\Activity\Services\ActivityService;
|
||||
use Modules\Activity\Transformers\ActivityListResource;
|
||||
use Modules\Activity\Transformers\ActivityResource;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class ActivityController extends BaseCrudController
|
||||
{
|
||||
protected $modelClass = Activity::class;
|
||||
|
||||
protected $resourceClass = ActivityResource::class;
|
||||
|
||||
protected $requestClass = ActivityRequest::class;
|
||||
|
||||
protected $resourceName = 'activity';
|
||||
|
||||
protected $resourceNamePlural = 'activities';
|
||||
|
||||
public function __construct(ActivityRepositoryInterface $repository, protected ActivityService $activityService, protected DocumentService $documentService)
|
||||
{
|
||||
parent::__construct($repository);
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$this->authorize('viewAny', $this->modelClass);
|
||||
|
||||
try {
|
||||
$perPage = $request->get('per_page', 10) ?? 10;
|
||||
$perPage = min($perPage, 1000);
|
||||
$search = (string) ($request->get('search', '') ?? '');
|
||||
$sortBy = (string) ($request->get('sort_by', 'start_datetime') ?? 'start_datetime');
|
||||
$sortOrder = (string) ($request->get('sort_order', 'desc') ?? 'desc');
|
||||
|
||||
$items = $this->getIndexData($request, $perPage, $search, $sortBy, $sortOrder);
|
||||
|
||||
if ($items instanceof LengthAwarePaginator) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => ActivityListResource::collection($items->items()),
|
||||
'pagination' => [
|
||||
'current_page' => $items->currentPage(),
|
||||
'per_page' => $items->perPage(),
|
||||
'total' => $items->total(),
|
||||
'last_page' => $items->lastPage(),
|
||||
'from' => $items->firstItem(),
|
||||
'to' => $items->lastItem(),
|
||||
'has_more_pages' => $items->hasMorePages(),
|
||||
],
|
||||
'message' => $this->getSuccessMessage('index'),
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => ActivityListResource::collection($items),
|
||||
'message' => $this->getSuccessMessage('index'),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error fetching {$this->resourceNamePlural}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse($this->getErrorMessage('index'), 500);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getIndexData(Request $request, int $perPage = 10, string $search = '', string $sortBy = 'start_datetime', string $sortOrder = 'desc')
|
||||
{
|
||||
if ($perPage > 0) {
|
||||
return $this->repository->getIndexPaginated($perPage, $search, $sortBy, $sortOrder);
|
||||
}
|
||||
|
||||
return $this->repository->all($search);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$this->authorize('create', $this->modelClass);
|
||||
|
||||
try {
|
||||
$validated = $this->validateRequest($request);
|
||||
$documents = collect($request->file('documents', []))
|
||||
->filter()
|
||||
->all();
|
||||
$galleryImages = collect($request->file('gallery', []))
|
||||
->filter()
|
||||
->all();
|
||||
|
||||
$activity = $this->activityService->create(
|
||||
$this->prepareStoreData(collect($validated)->except(['documents', 'gallery'])->all()),
|
||||
$documents,
|
||||
$galleryImages,
|
||||
);
|
||||
|
||||
ActivityLogger::log("Created {$this->resourceName}: {$this->getItemName($activity)}", $activity);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => new $this->resourceClass($activity),
|
||||
'message' => $this->getSuccessMessage('store'),
|
||||
], 201);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error creating {$this->resourceName}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse($this->getErrorMessage('store').': '.$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
$this->authorize('update', $this->modelClass);
|
||||
|
||||
try {
|
||||
$activity = $this->repository->findById($id);
|
||||
|
||||
if (! $activity) {
|
||||
return $this->errorResponse($this->getNotFoundMessage(), 404);
|
||||
}
|
||||
|
||||
$validated = $this->validateRequest($request);
|
||||
$documents = collect($request->file('documents', []))
|
||||
->filter()
|
||||
->all();
|
||||
$galleryImages = collect($request->file('gallery', []))
|
||||
->filter()
|
||||
->all();
|
||||
|
||||
$activity = $this->activityService->update(
|
||||
$activity,
|
||||
$this->prepareUpdateData(collect($validated)->except(['documents', 'gallery'])->all(), $activity),
|
||||
$documents,
|
||||
$galleryImages,
|
||||
);
|
||||
|
||||
ActivityLogger::log("Updated {$this->resourceName}: {$this->getItemName($activity)}", $activity);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => new $this->resourceClass($activity),
|
||||
'message' => $this->getSuccessMessage('update'),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error updating {$this->resourceName}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse($this->getErrorMessage('update').': '.$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadShowRelations($item)
|
||||
{
|
||||
return $this->repository->findByIdWithRelations($item->id) ?? $item;
|
||||
}
|
||||
|
||||
protected function getItemName($item): string
|
||||
{
|
||||
return $item->title ?? $item->id;
|
||||
}
|
||||
|
||||
protected function checkDependencies($activity): ?JsonResponse
|
||||
{
|
||||
if ($activity->reports()->count() > 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Aktiviti tidak boleh dipadam kerana masih mempunyai laporan.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function uploadDocument(
|
||||
UploadActivityDocumentRequest $request,
|
||||
Activity $activity
|
||||
): JsonResponse {
|
||||
$this->authorize('update', $this->modelClass);
|
||||
|
||||
try {
|
||||
$activity = $this->activityService->uploadDocument(
|
||||
$activity,
|
||||
$request->file('file'),
|
||||
$request->validated('type', 'general'),
|
||||
$request->validated('description'),
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Dokumen berjaya dimuat naik.',
|
||||
'data' => new ActivityResource($activity),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error uploading document for {$this->resourceName}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse('Gagal memuat naik dokumen: '.$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadGalleryImage(UploadActivityGalleryImageRequest $request, Activity $activity): JsonResponse {
|
||||
$this->authorize('update', $this->modelClass);
|
||||
|
||||
try {
|
||||
$activity = $this->activityService->uploadGalleryImage(
|
||||
$activity,
|
||||
$request->file('file'),
|
||||
$request->validated('description'),
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Imej galeri berjaya dimuat naik.',
|
||||
'data' => new ActivityResource($activity),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error uploading gallery image for {$this->resourceName}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse('Gagal memuat naik imej galeri: '.$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function downloadDocument(Activity $activity, string $documentId): StreamedResponse
|
||||
{
|
||||
$this->authorize('view', $this->modelClass);
|
||||
|
||||
$document = $activity->documents()
|
||||
->where('type', '!=', Activity::GALLERY_DOCUMENT_TYPE)
|
||||
->findOrFail($documentId);
|
||||
|
||||
return $this->documentService->downloadDocument($document->id);
|
||||
}
|
||||
|
||||
public function serveGalleryImage(Activity $activity, string $imageId): BinaryFileResponse
|
||||
{
|
||||
$this->authorize('view', $this->modelClass);
|
||||
|
||||
$document = $activity->galleryImages()->findOrFail($imageId);
|
||||
|
||||
$disk = Storage::disk(Document::STORAGE_DISK);
|
||||
|
||||
if (! $disk->exists($document->path)) {
|
||||
abort(404, 'File not found');
|
||||
}
|
||||
|
||||
return response()->file($disk->path($document->path), [
|
||||
'Content-Type' => $document->mime_type ?? 'application/octet-stream',
|
||||
'Content-Disposition' => 'inline; filename="'.$document->name.'"',
|
||||
]);
|
||||
}
|
||||
|
||||
public function deleteDocument(Activity $activity, string $documentId): JsonResponse
|
||||
{
|
||||
$this->authorize('update', $this->modelClass);
|
||||
|
||||
try {
|
||||
$activity->documents()
|
||||
->where('type', '!=', Activity::GALLERY_DOCUMENT_TYPE)
|
||||
->findOrFail($documentId);
|
||||
|
||||
$activity->deleteDocument($documentId);
|
||||
$activity = $this->repository->findByIdWithRelations($activity->id);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Dokumen berjaya dipadam.',
|
||||
'data' => new ActivityResource($activity),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error deleting document for {$this->resourceName}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse('Gagal memadam dokumen: '.$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteGalleryImage(Activity $activity, string $imageId): JsonResponse
|
||||
{
|
||||
$this->authorize('update', $this->modelClass);
|
||||
|
||||
try {
|
||||
$activity->galleryImages()->findOrFail($imageId);
|
||||
$activity->deleteDocument($imageId);
|
||||
$activity = $this->repository->findByIdWithRelations($activity->id);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Imej galeri berjaya dipadam.',
|
||||
'data' => new ActivityResource($activity),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error deleting gallery image for {$this->resourceName}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse('Gagal memadam imej galeri: '.$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
$this->authorize('deleteAny', $this->modelClass);
|
||||
|
||||
try {
|
||||
$activity = $this->repository->findByIdWithRelations($id);
|
||||
|
||||
if (! $activity) {
|
||||
return $this->errorResponse($this->getNotFoundMessage(), 404);
|
||||
}
|
||||
|
||||
$dependencyCheck = $this->checkDependencies($activity);
|
||||
if ($dependencyCheck !== null) {
|
||||
return $dependencyCheck;
|
||||
}
|
||||
|
||||
$activity->documents->each(
|
||||
fn ($document) => $this->documentService->deleteDocument($document->id)
|
||||
);
|
||||
|
||||
$this->repository->delete($id);
|
||||
|
||||
ActivityLogger::log("Deleted {$this->resourceName}: {$this->getItemName($activity)}", $activity);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => $this->getSuccessMessage('destroy'),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error deleting {$this->resourceName}: ".$e->getMessage());
|
||||
|
||||
return $this->errorResponse($this->getErrorMessage('destroy').': '.$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\BaseCrudController;
|
||||
use Modules\Activity\Entities\ActivityReport;
|
||||
use Modules\Activity\Http\Requests\ActivityReportRequest;
|
||||
use Modules\Activity\Repositories\Contracts\ActivityReportRepositoryInterface;
|
||||
use Modules\Activity\Transformers\ActivityReportResource;
|
||||
|
||||
class ActivityReportController extends BaseCrudController
|
||||
{
|
||||
protected $modelClass = ActivityReport::class;
|
||||
|
||||
protected $resourceClass = ActivityReportResource::class;
|
||||
|
||||
protected $requestClass = ActivityReportRequest::class;
|
||||
|
||||
protected $resourceName = 'activity report';
|
||||
|
||||
protected $resourceNamePlural = 'activity reports';
|
||||
|
||||
public function __construct(
|
||||
ActivityReportRepositoryInterface $repository,
|
||||
) {
|
||||
parent::__construct($repository);
|
||||
}
|
||||
|
||||
protected function prepareStoreData(array $validated): array
|
||||
{
|
||||
return array_merge($validated, [
|
||||
'prepared_by' => auth()->id(),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getItemName($item): string
|
||||
{
|
||||
return $item->activity?->title ?? $item->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\BaseCrudController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class ActivityTypeController extends BaseCrudController
|
||||
{
|
||||
protected $modelClass = \Modules\Activity\Entities\ActivityType::class;
|
||||
|
||||
protected $resourceClass = \Modules\Activity\Transformers\ActivityTypeResource::class;
|
||||
|
||||
protected $requestClass = \Modules\Activity\Http\Requests\ActivityTypeRequest::class;
|
||||
|
||||
protected $resourceName = 'activity type';
|
||||
|
||||
protected $resourceNamePlural = 'activity types';
|
||||
|
||||
public function __construct(
|
||||
\Modules\Activity\Repositories\Contracts\ActivityTypeRepositoryInterface $repository,
|
||||
) {
|
||||
parent::__construct($repository);
|
||||
}
|
||||
|
||||
protected function getItemName($item): string
|
||||
{
|
||||
return $item->name ?? $item->id;
|
||||
}
|
||||
|
||||
protected function checkDependencies($activityType): ?JsonResponse
|
||||
{
|
||||
if ($activityType->activities()->count() > 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Jenis aktiviti tidak boleh dipadam kerana masih digunakan oleh aktiviti.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ActivityReportRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
$isCreate = $this->isMethod('POST');
|
||||
$isUpdate = $this->isMethod('PUT') || $this->isMethod('PATCH');
|
||||
|
||||
if (! $isCreate && ! $isUpdate) {
|
||||
return [
|
||||
'activity_id' => 'nullable|uuid|exists:activities,id',
|
||||
'report_text' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'activity_id' => 'required|uuid|exists:activities,id',
|
||||
'report_text' => 'required|string',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'activity_id.required' => 'Aktiviti diperlukan.',
|
||||
'activity_id.exists' => 'Aktiviti tidak sah.',
|
||||
'report_text.required' => 'Laporan diperlukan.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class ActivityRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
$isCreate = $this->isMethod('POST');
|
||||
$isUpdate = $this->isMethod('PUT') || $this->isMethod('PATCH');
|
||||
|
||||
if (! $isCreate && ! $isUpdate) {
|
||||
return [
|
||||
'activity_type_id' => 'nullable|uuid|exists:activity_types,id',
|
||||
'title' => 'nullable|string|max:255',
|
||||
'reference_number' => 'nullable|string|max:255',
|
||||
'description' => 'nullable|string',
|
||||
'start_datetime' => 'nullable|date',
|
||||
'end_datetime' => 'nullable|date|after_or_equal:start_datetime',
|
||||
'organizer' => 'nullable|string|max:255',
|
||||
'location' => 'nullable|string|max:255',
|
||||
'is_active' => 'nullable|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
$referenceRule = Rule::unique('activities', 'reference_number');
|
||||
|
||||
if ($isUpdate) {
|
||||
$referenceRule = $referenceRule->ignore($this->route('activity'));
|
||||
}
|
||||
|
||||
return [
|
||||
'activity_type_id' => 'required|uuid|exists:activity_types,id',
|
||||
'title' => 'required|string|max:255',
|
||||
'reference_number' => ['nullable', 'string', 'max:255', $referenceRule],
|
||||
'description' => 'nullable|string',
|
||||
'start_datetime' => 'nullable|date',
|
||||
'end_datetime' => 'nullable|date|after_or_equal:start_datetime',
|
||||
'organizer' => 'nullable|string|max:255',
|
||||
'location' => 'nullable|string|max:255',
|
||||
'is_active' => 'required|boolean',
|
||||
'documents' => 'nullable|array',
|
||||
'documents.*' => 'file|mimes:pdf,jpg,jpeg,png,doc,docx|max:10240',
|
||||
'gallery' => 'nullable|array',
|
||||
'gallery.*' => 'file|mimes:jpg,jpeg,png,webp,gif|max:10240',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'activity_type_id.required' => 'Jenis aktiviti diperlukan.',
|
||||
'activity_type_id.exists' => 'Jenis aktiviti tidak sah.',
|
||||
'title.required' => 'Tajuk aktiviti diperlukan.',
|
||||
'title.max' => 'Tajuk aktiviti tidak boleh melebihi 255 aksara.',
|
||||
'reference_number.unique' => 'Nombor rujukan sudah wujud.',
|
||||
'end_datetime.after_or_equal' => 'Tarikh tamat mestilah selepas atau sama dengan tarikh mula.',
|
||||
'is_active.required' => 'Status aktif diperlukan.',
|
||||
'is_active.boolean' => 'Status aktif tidak sah.',
|
||||
'documents.*.file' => 'Dokumen mestilah fail yang sah.',
|
||||
'documents.*.mimes' => 'Format dokumen tidak disokong.',
|
||||
'documents.*.max' => 'Saiz dokumen melebihi had maksimum 10MB.',
|
||||
'gallery.*.file' => 'Imej galeri mestilah fail yang sah.',
|
||||
'gallery.*.mimes' => 'Format imej galeri tidak disokong. Gunakan jpg, jpeg, png, webp atau gif.',
|
||||
'gallery.*.max' => 'Saiz imej galeri melebihi had maksimum 10MB.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class ActivityTypeRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
$isCreate = $this->isMethod('POST');
|
||||
$isUpdate = $this->isMethod('PUT') || $this->isMethod('PATCH');
|
||||
|
||||
if (! $isCreate && ! $isUpdate) {
|
||||
return [
|
||||
'name' => 'nullable|string|max:255',
|
||||
'code' => 'nullable|string|max:255',
|
||||
];
|
||||
}
|
||||
|
||||
$codeRule = Rule::unique('activity_types', 'code');
|
||||
|
||||
if ($isUpdate) {
|
||||
$codeRule = $codeRule->ignore($this->route('activity_type'));
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'code' => ['nullable', 'string', 'max:255', $codeRule],
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => 'Nama jenis aktiviti diperlukan.',
|
||||
'name.max' => 'Nama jenis aktiviti tidak boleh melebihi 255 aksara.',
|
||||
'code.max' => 'Kod jenis aktiviti tidak boleh melebihi 255 aksara.',
|
||||
'code.unique' => 'Kod jenis aktiviti sudah wujud.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Activity\Entities\Activity;
|
||||
|
||||
class UploadActivityDocumentRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'type' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'max:255',
|
||||
Rule::notIn([Activity::GALLERY_DOCUMENT_TYPE]),
|
||||
],
|
||||
'description' => 'nullable|string|max:1000',
|
||||
'file' => 'required|file|mimes:pdf,jpg,jpeg,png,doc,docx|max:10240',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'type.not_in' => 'Imej galeri mesti dimuat naik melalui endpoint galeri aktiviti.',
|
||||
'file.required' => 'Fail diperlukan.',
|
||||
'file.mimes' => 'Format fail tidak disokong.',
|
||||
'file.max' => 'Saiz fail melebihi had maksimum 10MB.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Activity\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UploadActivityGalleryImageRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'file' => 'required|file|mimes:jpg,jpeg,png,webp,gif|max:10240',
|
||||
'description' => 'nullable|string|max:1000',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'file.required' => 'Imej diperlukan.',
|
||||
'file.mimes' => 'Format imej tidak disokong. Gunakan jpg, jpeg, png, webp atau gif.',
|
||||
'file.max' => 'Saiz imej melebihi had maksimum 10MB.',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user