File "SubjectController.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/Controllers/SubjectController.php
File size: 9.17 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Http\Controllers;
use App\Repositories\Medium\MediumInterface;
use App\Repositories\Subject\SubjectInterface;
use App\Rules\uniqueForSchool;
use App\Services\BootstrapTableService;
use App\Services\ResponseService;
use App\Services\CachingService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Models\ClassSubject;
use App\Rules\MaxFileSize;
use Throwable;
class SubjectController extends Controller
{
private MediumInterface $medium;
private SubjectInterface $subject;
private CachingService $cache;
public function __construct(MediumInterface $medium, SubjectInterface $subject, CachingService $cache)
{
$this->medium = $medium;
$this->subject = $subject;
$this->cache = $cache;
}
public function index()
{
ResponseService::noPermissionThenRedirect('subject-list');
$mediums = $this->medium->builder()->orderBy('id', 'DESC')->get();
return response(view('subjects.index', compact('mediums')));
}
public function show(Request $request)
{
ResponseService::noPermissionThenRedirect('subject-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'DESC');
$search = $_GET['search'];
$showDeleted = $request->show_deleted;
$sql = $this->subject->builder()->with('medium')
->where(function ($query) use ($search) {
$query->when($search, function ($q) use ($search) {
$q->where('id', 'LIKE', "%$search%")
->orwhere('name', 'LIKE', "%$search%")
->orwhere('code', 'LIKE', "%$search%")
->orwhere('type', 'LIKE', "%$search%")->Owner();
});
})
->when(!empty($showDeleted), function ($q) {
$q->onlyTrashed()->Owner();
});
if (!empty($_GET['medium_id'])) {
$sql = $sql->where('medium_id', $_GET['medium_id']);
}
$total = $sql->count();
if ($offset >= $total && $total > 0) {
$lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset
$offset = $lastPage;
}
$sql = $sql->orderBy($sort, $order)->skip($offset)->take($limit);
$res = $sql->get();
$bulkData = array();
$bulkData['total'] = $total;
$rows = array();
$no = 1;
foreach ($res as $row) {
if ($request->show_deleted) {
//Show Restore and Hard Delete Buttons
$operate = BootstrapTableService::restoreButton(route('subjects.restore', $row->id));
$operate .= BootstrapTableService::trashButton(route('subjects.trash', $row->id));
} else {
//Show Edit and Soft Delete Buttons
$operate = BootstrapTableService::editButton(route('subjects.update', $row->id));
$operate .= BootstrapTableService::deleteButton(route('subjects.destroy', $row->id));
}
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
$tempRow['type'] = trans($row->type);
$tempRow['eng_type'] = $row->type;
$tempRow['created_at'] = $row->created_at;
$tempRow['updated_at'] = $row->updated_at;
$tempRow['operate'] = $operate;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
public function store(Request $request)
{
ResponseService::noPermissionThenSendJson('subject-create');
$file_upload_size_limit = $this->cache->getSystemSettings('file_upload_size_limit');
$supportedImageTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg+xml'];
$fileMimeType = $request->file('image')->getMimeType();
if (!in_array($fileMimeType, $supportedImageTypes)) {
ResponseService::errorResponse('The image must be a file of type: jpg, jpeg, png, svg.');
}
$validator = Validator::make($request->all(), [
'medium_id' => 'required|numeric',
'type' => 'required|in:Practical,Theory',
'name' => [
'required',
new uniqueForSchool('subjects', ['name' => $request->name, 'medium_id' => $request->medium_id, 'type' => $request->type])
],
'bg_color' => 'required|not_in:transparent',
// 'code' => 'nullable|unique:subjects,code',
'code' => [
'nullable',
new uniqueForSchool('subjects', ['code' => $request->code, 'medium_id' => $request->medium_id, 'type' => $request->type])
],
'image' => ['required', 'mimetypes:image/jpeg,image/png,image/svg+xml', new MaxFileSize($file_upload_size_limit)],
])->setAttributeNames(['bg_color' => 'Background Color']);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
$this->subject->create($request->all());
ResponseService::successResponse('Data Stored Successfully');
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function update(Request $request, $id)
{
ResponseService::noPermissionThenSendJson('subject-edit');
$file_upload_size_limit = $this->cache->getSystemSettings('file_upload_size_limit');
if ($request->hasFile('image')) {
$supportedImageTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg+xml'];
$fileMimeType = $request->file('image')->getMimeType();
if (!in_array($fileMimeType, $supportedImageTypes)) {
ResponseService::errorResponse('The image must be a file of type: jpg, jpeg, png, svg.');
}
}
$validator = Validator::make($request->all(), [
'medium_id' => 'required|numeric',
'name' => [
'required',
new uniqueForSchool('subjects', ['name' => $request->name, 'medium_id' => $request->medium_id, 'type' => $request->type], $id)
],
'code' => [
'nullable',
new uniqueForSchool('subjects', ['code' => $request->code, 'medium_id' => $request->medium_id, 'type' => $request->type], $id)
],
'type' => 'required|in:Practical,Theory',
'bg_color' => 'required|not_in:transparent',
'image' => ['nullable', 'mimetypes:image/jpeg,image/png,image/svg+xml', new MaxFileSize($file_upload_size_limit)],
])->setAttributeNames(['bg_color' => 'Background Color']);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
$this->subject->update($id, $request->all());
ResponseService::successResponse('Data Updated Successfully');
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function destroy($id)
{
ResponseService::noPermissionThenSendJson('subject-delete');
try {
// Safety Check: Prevent deletion if subject is assigned to any class in any session
if (ClassSubject::where('subject_id', $id)->exists()) {
return ResponseService::errorResponse("Cannot delete this subject because it is assigned to classes in one or more academic sessions. Please remove it from all classes first.");
}
$this->subject->deleteById($id);
ResponseService::successResponse('Data Deleted Successfully');
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function restore(int $id)
{
ResponseService::noPermissionThenSendJson('subject-delete');
try {
$this->subject->findOnlyTrashedById($id)->restore();
ResponseService::successResponse("Data Restored Successfully");
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function trash($id)
{
ResponseService::noPermissionThenSendJson('subject-delete');
try {
// Safety Check: Prevent permanent deletion if subject is assigned to any class in any session
if (ClassSubject::where('subject_id', $id)->exists()) {
return ResponseService::errorResponse("Cannot delete this subject permanently because it is assigned to classes in one or more academic sessions. Please remove it from all classes first.");
}
$this->subject->findOnlyTrashedById($id)->forceDelete();
ResponseService::successResponse("Data Deleted Permanently");
} catch (Throwable $e) {
ResponseService::logErrorResponse($e, "Subject Controller -> Trash Method", 'cannot_delete_because_data_is_associated_with_other_data');
ResponseService::errorResponse();
}
}
}