File "LessonTopicController.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/Controllers/LessonTopicController.php
File size: 21.67 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Http\Controllers;
use App\Models\LessonCommon;
use App\Models\Students;
use App\Repositories\ClassSection\ClassSectionInterface;
use App\Repositories\ClassSubject\ClassSubjectInterface;
use App\Repositories\Files\FilesInterface;
use App\Repositories\Lessons\LessonsInterface;
use App\Repositories\Student\StudentInterface;
use App\Repositories\Subject\SubjectInterface;
use App\Repositories\SubjectTeacher\SubjectTeacherInterface;
use App\Repositories\Topics\TopicsInterface;
use App\Repositories\Semester\SemesterInterface;
use App\Repositories\StudentSubject\StudentSubjectInterface;
use App\Rules\DynamicMimes;
use App\Rules\MaxFileSize;
use App\Rules\uniqueTopicInLesson;
use App\Rules\YouTubeUrl;
use App\Services\BootstrapTableService;
use App\Services\CachingService;
use App\Services\ResponseService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Throwable;
use App\Jobs\BulkNotificationsJobv3_0_0;
use App\Models\ClassSubject;
use App\Models\LessonTopicClass;
use App\Repositories\SessionYear\SessionYearInterface;
use App\Services\LessonNotificationService;
class LessonTopicController extends Controller
{
private LessonsInterface $lesson;
private TopicsInterface $topic;
private FilesInterface $files;
private ClassSectionInterface $classSection;
private SubjectTeacherInterface $subjectTeacher;
private StudentInterface $student;
private SubjectInterface $subject;
private CachingService $cache;
private ClassSubjectInterface $class_subjects;
private SemesterInterface $semester;
private SessionYearInterface $sessionYear;
private StudentSubjectInterface $studentSubject;
private LessonNotificationService $lessonNotificationService;
public function __construct(LessonsInterface $lesson, TopicsInterface $topic, FilesInterface $files, ClassSectionInterface $classSection, SubjectTeacherInterface $subjectTeacher, StudentInterface $student, SubjectInterface $subject, CachingService $cache, ClassSubjectInterface $class_subjects, SemesterInterface $semester, SessionYearInterface $sessionYear, StudentSubjectInterface $studentSubject, LessonNotificationService $lessonNotificationService)
{
$this->lesson = $lesson;
$this->topic = $topic;
$this->files = $files;
$this->classSection = $classSection;
$this->subjectTeacher = $subjectTeacher;
$this->cache = $cache;
$this->student = $student;
$this->subject = $subject;
$this->class_subjects = $class_subjects;
$this->semester = $semester;
$this->sessionYear = $sessionYear;
$this->studentSubject = $studentSubject;
$this->lessonNotificationService = $lessonNotificationService;
}
public function index()
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenRedirect('topic-list');
$sessionYear = $this->cache->getDefaultSessionYear();
$class_section = $this->classSection->builder()->with('class', 'class.stream', 'class.shift', 'section', 'medium')->get();
$subjectTeachers = $this->subjectTeacher->builder()->with('subject:id,name,type')->get();
$lessons = $this->lesson->builder()->with([
'lesson_commons' => function ($q) {
$q->whereHas('syllabus.class_subject', function ($q) {
$q->whereNull('deleted_at');
})->with('syllabus');
}
])->get();
$semesters = $this->semester->builder()->get();
$sessionYears = $this->sessionYear->builder()->get();
return response(view('lessons.topic', compact('class_section', 'subjectTeachers', 'lessons', 'semesters', 'sessionYears')));
}
public function store(Request $request)
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenRedirect('topic-create');
$file_upload_size_limit = $this->cache->getSystemSettings('file_upload_size_limit');
$validator = Validator::make($request->all(), [
'class_section_id' => 'required|array',
'class_section_id.*' => 'numeric',
'subject_id' => 'required|numeric',
'lesson_id' => 'required|numeric',
'name' => ['required', new uniqueTopicInLesson($request->lesson_id)],
'description' => 'required',
'file_data' => 'nullable|array',
'file_data.*.type' => 'required|in:file_upload,youtube_link,video_upload,other_link',
'file_data.*.name' => 'required_with:file_data.*.type',
'file_data.*.thumbnail' => 'required_if:file_data.*.type,youtube_link,video_upload,other_link',
'file_data.*.link' => ['nullable', 'required_if:file_data.*.type,youtube_link,other_link', new YouTubeUrl],
'file_data.*.file' => [
'nullable',
'required_if:file_data.*.type,file_upload,video_upload',
new DynamicMimes(),
new MaxFileSize($file_upload_size_limit),
],
]);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
DB::beginTransaction();
/* ================= TOPIC CREATE ================= */
$topics = $this->topic->create([
'lesson_id' => $request->lesson_id,
'name' => $request->name,
'description' => $request->description,
'school_id' => Auth::user()->school_id,
]);
// Store lesson topic classes
$lessonTopicClasses = [];
foreach ($request->class_section_id ?? [] as $class_section_id) {
$lessonTopicClasses[] = [
'lesson_topic_id' => $topics->id,
'class_section_id' => $class_section_id,
'school_id' => Auth::user()->school_id,
];
}
if (!empty($lessonTopicClasses)) {
LessonTopicClass::upsert($lessonTopicClasses, ['lesson_topic_id', 'class_section_id'], ['school_id']);
}
$topics = $topics->load('lesson_topic_class', 'lesson.lesson_commons.syllabus');
/* ================= FILES (UNCHANGED) ================= */
if (!empty($request->file_data)) {
$lessonTopicFileData = [];
foreach ($request->file_data as $file) {
if (!empty($file['type'])) {
$lessonTopicFileData[] = $this->prepareFileData($file);
}
$file_type = $file['type'];
if ($file_type == "youtube_link") {
$file_type = "other_link";
}
}
if ($lessonTopicFileData) {
$lessonFile = $this->files->model();
$lessonModelAssociate = $lessonFile->modal()->associate($topics);
foreach ($lessonTopicFileData as &$fileData) {
$fileData['modal_type'] = $lessonModelAssociate->modal_type;
$fileData['modal_id'] = $topics->id;
}
$this->files->createBulk($lessonTopicFileData);
}
}
DB::commit();
/* ================== PUSH NOTIFICATIONS ================== */
$sectionIds = $topics->lesson_topic_class->pluck('class_section_id')->toArray();
$subject_id = $topics->lesson->lesson_commons->first()->syllabus->subject_id;
$this->lessonNotificationService->send($topics->lesson, $sectionIds, (int)$subject_id, 'created');
ResponseService::successResponse('Data Stored Successfully');
} catch (Throwable $e) {
if (Str::contains($e->getMessage(), ['does not exist', 'file_get_contents'])) {
DB::commit();
ResponseService::warningResponse("Data Stored successfully. But App push notification not send.");
} else {
DB::rollBack();
ResponseService::logErrorResponse($e, "Lesson Topic Controller -> Store Method");
ResponseService::errorResponse();
}
}
}
private function prepareFileData($file)
{
if ($file['type']) {
$tempFileData = [
'file_name' => $file['name']
];
// If File Upload
if ($file['type'] == "file_upload") {
// Add Type And File Url to TempDataArray and make Thumbnail data null
$tempFileData['type'] = 1;
$tempFileData['file_thumbnail'] = null;
$tempFileData['file_url'] = $file['file'];
} elseif ($file['type'] == "youtube_link") {
// Add Type , Thumbnail and Link to TempDataArray
$tempFileData['type'] = 2;
$tempFileData['file_thumbnail'] = $file['thumbnail'];
$tempFileData['file_url'] = $file['link'];
} elseif ($file['type'] == "video_upload") {
// Add Type , File Thumbnail and File URL to TempDataArray
$tempFileData['type'] = 3;
$tempFileData['file_thumbnail'] = $file['thumbnail'];
$tempFileData['file_url'] = $file['file'];
} elseif ($file['type'] == "other_link") {
// Add Type , File Thumbnail and File URL to TempDataArray
$tempFileData['type'] = 4;
$tempFileData['file_thumbnail'] = $file['thumbnail'];
$tempFileData['file_url'] = $file['link'];
}
}
return $tempFileData;
}
public function show()
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenRedirect('topic-list');
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'DESC');
$search = request('search');
$sql = $this->topic->builder()
->has('lesson')
->with(
[
'file',
'lesson',
'lesson.file',
'lesson.lesson_commons' => function ($q) {
$q->whereHas('syllabus.class_subject', function ($q) {
$q->whereNull('deleted_at');
});
},
'lesson.lesson_commons.syllabus.class_subject' => function ($q) {
$q->whereNull('deleted_at');
},
'lesson.lesson_commons.syllabus.subject'
]
)->with(['lesson_topic_class' => function ($q) {
$q->with(['class_section' => function ($q) {
$q->whereNull('deleted_at')
->with('class.stream', 'section', 'medium');
}]);
}])
->where(function ($query) use ($search) {
$query->when($search, function ($query) use ($search) {
$query->where(function ($query) use ($search) {
$query->where('id', 'LIKE', "%$search%")
->orWhere('name', 'LIKE', "%$search%")
->orWhere('description', 'LIKE', "%$search%")
->orWhereHas('lesson_topic_class.class_section.class', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})
->orWhereHas('lesson.lesson_commons.syllabus.subject', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
})
->orWhereHas('lesson', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%");
});
});
});
})
->when(request('class_subject_id') != null, function ($query) {
$class_subject_id = request('class_subject_id');
$query->whereHas('lesson.lesson_commons.syllabus.class_subject', function ($q) use ($class_subject_id) {
$q->where('class_subjects.subject_id', $class_subject_id);
});
})
->when(request('class_section_id') != null, function ($query) {
$class_section_id = request('class_section_id');
$query->whereHas('lesson_topic_class', function ($q) use ($class_section_id) {
$q->where('class_section_id', $class_section_id);
});
})
->when(request('lesson_id') != null, function ($query) {
$lesson_id = request('lesson_id');
$query->whereHas('lesson', function ($q) use ($lesson_id) {
$q->where('id', $lesson_id);
});
});
$total = $sql->count();
if ($offset >= $total && $total > 0) {
$lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset
$offset = $lastPage;
}
$sql->orderBy($sort, $order)->skip($offset)->take($limit);
$res = $sql->get();
$bulkData = array();
$bulkData['total'] = $total;
$rows = array();
$no = 1;
foreach ($res as $row) {
$row = (object) $row;
$classSections = '';
foreach ($row->lesson_topic_class as $lessonTopicClass) {
// $classSections .= '<li>' . $lessonCommon->class_section->full_name . '</li> ';
if ($lessonTopicClass->class_section) {
$classSections .= '<li>' . $lessonTopicClass->class_section->full_name . '</li> ';
}
}
// Get Subject Name
$subject = $row->lesson->lesson_commons->first()?->syllabus?->subject;
$subjectName = $subject ? $subject->name . ' - ' . $subject->type : null;
// $operate = BootstrapTableService::button(route('lesson-topic.edit', $row->id), ['btn-gradient-primary'], ['title' => 'Edit'], ['fa fa-edit']);
$operate = BootstrapTableService::button('fa fa-edit', route('lesson-topic.edit', $row->id), ['btn-gradient-primary'], ['title' => 'Edit']);
$operate .= BootstrapTableService::deleteButton(route('lesson-topic.destroy', $row->id));
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
// $tempRow['class_section_with_medium'] = $lessonTopicCommons;
$tempRow['class_section_with_medium'] = '<ol>' . $classSections . '</ol>';
$tempRow['subject_with_name'] = $subjectName;
$tempRow['operate'] = $operate;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
public function edit($id)
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenRedirect('topic-edit');
$class_section = $this->classSection->builder()->with('class', 'class.stream', 'class.shift', 'section', 'medium')->get();
$subjectTeachers = $this->subjectTeacher->builder()->with('subject:id,name,type')->get();
$lessons = $this->lesson->builder()->with('lesson_commons.syllabus.class_subject.subject')->get();
$topic = $this->topic->builder()->with('file', 'lesson.lesson_commons.syllabus.subject', 'lesson_topic_class.class_section')->where('id', $id)->first();
return response(view('lessons.edit_topic', compact('class_section', 'subjectTeachers', 'lessons', 'topic')));
}
public function update($id, Request $request)
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenRedirect('topic-edit');
$file_upload_size_limit = $this->cache->getSystemSettings('file_upload_size_limit');
$validator = Validator::make($request->all(), [
'class_section_id' => 'required|array',
'class_section_id*' => 'required|numeric',
'class_subject_id' => 'required|numeric',
'lesson_id' => 'required|numeric',
'name' => ['required', new uniqueTopicInLesson($request->lesson_id, $id)],
'description' => 'required',
'file_data' => 'nullable|array',
'file_data.*.type' => 'required|in:file_upload,youtube_link,video_upload,other_link',
'file_data.*.name' => 'required_with:file_data.*.type',
'file_data.*.link' => ['nullable', 'required_if:file_data.*.type,youtube_link', new YouTubeUrl],
'file_data.*.file' => ['nullable', new DynamicMimes, new MaxFileSize($file_upload_size_limit)],
]);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
};
try {
DB::beginTransaction();
/* ---------------- UPDATE TOPIC (UNCHANGED) ---------------- */
$data = $request->all();
$data['class_section_id'] = $request->class_section_id[0];
$topic = $this->topic->update($id, $data);
$topics = $topic->load('lesson_topic_class', 'lesson.lesson_commons.syllabus');
/* ---------------- FILE UPDATE (UNCHANGED) ---------------- */
if ($request->file_data) {
foreach ($request->file_data as $file) {
if (!$file['type'])
continue;
$topicFile = $this->files->model();
$assoc = $topicFile->modal()->associate($topic);
$fileData = [
'id' => $file['id'] ?? null,
'modal_type' => $assoc->modal_type,
'modal_id' => $assoc->modal_id,
'file_name' => $file['name'],
'created_at' => now(),
'updated_at' => now(),
];
switch ($file['type']) {
case 'file_upload':
$fileData += ['type' => 1, 'file_url' => $file['file'] ?? null];
break;
case 'youtube_link':
$fileData += ['type' => 2, 'file_url' => $file['link'], 'file_thumbnail' => $file['thumbnail'] ?? null];
break;
case 'video_upload':
$fileData += ['type' => 3, 'file_url' => $file['file'] ?? null, 'file_thumbnail' => $file['thumbnail'] ?? null];
break;
case 'other_link':
$fileData += ['type' => 4, 'file_url' => $file['link'], 'file_thumbnail' => $file['thumbnail'] ?? null];
break;
}
$this->files->updateOrCreate(['id' => $file['id']], $fileData);
$file_type = $file['type'];
if ($file_type == "youtube_link") {
$file_type = "other_link";
}
}
}
DB::commit();
/* ================= FIXED NOTIFICATIONS ================= */
$sectionIds = $topics->lesson_topic_class->pluck('class_section_id')->toArray();
$subject_id = $topics->lesson->lesson_commons->first()->syllabus->subject_id;
$this->lessonNotificationService->send($topics->lesson, $sectionIds, (int)$subject_id, 'updated');
ResponseService::successResponse('Data Updated Successfully');
} catch (Throwable $e) {
if (Str::contains($e->getMessage(), ['does not exist', 'file_get_contents'])) {
DB::commit();
ResponseService::warningResponse("Data Stored successfully. But App push notification not send.");
} else {
DB::rollBack();
ResponseService::logErrorResponse($e, "Lesson Topic Controller -> Update Method");
ResponseService::errorResponse();
}
}
}
public function destroy($id)
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenSendJson('topic-delete');
try {
DB::beginTransaction();
$this->topic->deleteById($id);
DB::commit();
ResponseService::successResponse('Data Deleted Successfully');
} catch (Throwable $e) {
DB::rollBack();
ResponseService::logErrorResponse($e, "Lesson Topic Controller -> Delete Method");
ResponseService::errorResponse();
}
}
public function restore(int $id)
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenSendJson('topic-delete');
try {
$this->topic->findOnlyTrashedById($id)->restore();
ResponseService::successResponse("Data Restored Successfully");
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
public function trash($id)
{
ResponseService::noFeatureThenRedirect('Lesson Management');
ResponseService::noPermissionThenSendJson('topic-delete');
try {
$this->topic->findOnlyTrashedById($id)->forceDelete();
ResponseService::successResponse("Data Deleted Permanently");
} catch (Throwable $e) {
ResponseService::logErrorResponse($e);
ResponseService::errorResponse();
}
}
}