BLUE
PHP 7.4.33
Path:
/var/www/multi-event-cfp.bitkit.dk/httpdocs/app/Repositories
Run
Logout
Edit File
Size: 59.48 KB
Close
/var/www/multi-event-cfp.bitkit.dk/httpdocs/app/Repositories/PresentationRepository.php
Text
Base64
<?php namespace App\Repositories; use App\Jobs\SendPresentationSubmittedMails; use App\Jobs\SendSpeakerTerms; use App\Models\Abstracts; use Illuminate\Support\Facades\Log; use App\Models\EventUser; use App\Models\Presentation; use App\Models\PresentationComment; use App\Models\PresentationReview; use App\Models\Presenter; use App\Models\User; use App\Models\Event; use URL; use ZipArchive; use App\Rules\PresentationDataRule; use Exception; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Validator; use App\Jobs\SendPresentationEditStatusChangeMail; use App\Jobs\SendPresentationStatusChangeMail; use App\Jobs\SendAssignReviewerMail; use App\Jobs\SendReviewerApprovedMail; use App\Jobs\SendPresentationDownloadLinkEmail; use App\Models\Slot; use Illuminate\Support\Str; use PhpParser\Node\Expr\AssignOp\Concat; class PresentationRepository extends Repository { public $fileName; protected $presentaionFields = ["submission_status", "assigned_status", "written_paper_status", "reviewer_assigned_status"]; public function __construct($event = null) { $this->for($event); } public function model(): Presentation { return new Presentation; } public function query($as = null) { $model = $this->model(); return $model->newQuery(); } public function createOrUpdate(Request $request, Abstracts $abstract = null): Presentation { $presentationId = $request->get('id'); $invitationResponse = $request->get('invitation_response'); $submissionStatusValue = $request->get('submission_status'); $input = $request->input(); if ($presentationId || $invitationResponse || $submissionStatusValue == "Draft") { $role = $request->get('role'); $event = $request->get('event'); $submissionStatus = $request->get('submission_status', 'Draft'); $presentersOnly = $request->get('presenter_only', false) == 'true'; if ($role != 'event_submitter' && $role != 'event_admin') validationErrorResponse(['Access denied']); if (!$presentationId) { if ($abstract) { $presentation = Presentation::whereEventId($event->id) ->whereAbstractId($abstract->id) ->first(); if ($presentation) validationErrorResponse(['Presentation already exists']); } $presentation = new Presentation([ 'user_id' => $abstract->user_id ?? authUser()->id, 'submission_status' => $submissionStatus, 'event_id' => $event->id, 'abstract_id' => $abstract->id ?? null, 'type' => $abstract ? 'abstract' : 'presentation', 'presentation_type' => $abstract->presentation_type ?? null ]); $presentation->save(); if ($abstract) { $presenters = $abstract->users('abstract_presenter')->pluck('id')->toArray(); $presentation->presenters()->attach($presenters, ['event_id' => $presentation->event_id]); $presentationPresenters = Presenter::wherePresentationId($presentation->id)->get(); $eventUsers = []; foreach ($presentationPresenters as $presentationPresenter) { $eventUser = getEventUser($event->id, $presentationPresenter->user_id); $eventUsers[] = $eventUser; $this->markAsConfirmedSpeaker($eventUser, 'Abstract', $event->id); } if (!empty($eventUsers) && !$abstract->presentation_tc_status) dispatch(new SendSpeakerTerms($eventUsers)); } else { // managing presenters in presentation if (isset($input['presenters'])) { $presenters = json_decode($input['presenters'] ?? "[]", true); } else { $user = authUser(); $userData = json_decode($user, true); $presenters[] = $userData; // $presentationRequestCount = $request->get('presentation_request_count') ? $request->get('presentation_request_count') : null; // if ($presentationRequestCount || $presentationRequestCount == 0) { // // event user // $eventUser = EventUser::whereEventId($event->id) // ->whereUserId($user->id) // ->first(); // if ($eventUser) { // // create presentation request without abstract count // $eventUser->presentation_request_count = $presentationRequestCount; // // save // $eventUser->save(); // } // } } $files = $request->allFiles(); $removedUsers = json_decode($input['removed_presenters'] ?? "[]", true); $this->managePresenters($presentation, $presenters, $files, $removedUsers, $request); } } else { $validator = Validator::make($input, [ 'data' => ['required', new PresentationDataRule()] ]); if ($validator->fails() && $submissionStatus == 'Submitted') validationErrorResponse($validator->errors()); $presentation = Presentation::find($presentationId); if (!$presentersOnly) { $data = json_decode($input['data'] ?? false, true); //$writtenPaperData = ($input['written_paper_data'] ?? false) ? json_decode($input['written_paper_data'], true) : []; $data = $this->handlePresentationFiles($request, $presentation, $data); //$writtenPaperData = $this->handleWrittenPaperFiles($request, $presentation, $writtenPaperData); $presentation->data = $data; //$presentation->written_paper_data = $writtenPaperData; $presentation->submission_status = $submissionStatus; $presentation->save(); } else { // managing presenters in presentation $presenters = json_decode($input['presenters'], true); $files = $request->allFiles(); $removedUsers = json_decode($input['removed_presenters'], true); $this->managePresenters($presentation, $presenters, $files, $removedUsers, $request); } } //send email if submitted to admins and submitter and presenters. if ($presentation->submission_status == 'Submitted') { if($role == 'event_submitter'){ $presentation->submission_date = date('Y-m-d H:i:s', time()); $presentation->save(); } dispatch(new SendPresentationSubmittedMails($presentation)); } if ($presentation->submission_status == 'Submitted') { // update related slots $slotRepository = new SlotRepository(); $slotRepository->updateRelatedSlots(null,$presentation); } return $presentation; } } public function writtenPaper(Request $request) { $presentationId = $request->get('id'); $input = $request->input(); $role = $request->get('role'); $writtenPaperStatus = $request->get('written_paper_status', 'Draft'); // Allow both submitters and admins to edit written papers if ($role != 'event_submitter' && $role != 'event_admin') validationErrorResponse(['Access denied']); if ($presentationId) { $presentation = Presentation::find($presentationId); $writtenPaperData = ($input['written_paper_data'] ?? false) ? json_decode($input['written_paper_data'], true) : []; $writtenPaperData = $this->handleWrittenPaperFiles($request, $presentation, $writtenPaperData); $presentation->written_paper_data = $writtenPaperData; $presentation->written_paper_status = $writtenPaperStatus; $presentation->save(); return $presentation; } } public function markAsConfirmedSpeaker(EventUser $eventUser, $via = 'Abstract', $eventId): EventUser { if (!$eventUser->confirmed_speaker) { $eventUser->confirmed_speaker = true; $eventUser->speaker_added_via = $via; if ($eventUser->confirmed_speaker) { $lastConfirmedSpeakerOrder = EventUser::where('event_id', $eventId) ->where('confirmed_speaker', 1) ->whereNotNull('confirmed_speaker') ->max('order'); // Set the order for the new confirmed speaker $eventUser->order = $lastConfirmedSpeakerOrder + 1; } $eventUser->save(); } return $eventUser; } public function handleWrittenPaperFiles(Request $request, Presentation $presentation, $writtenPaperData) { $removedFiles = $request->get('removed_files'); $removedFiles = json_decode($removedFiles, true); //handling uploaded files if ($request->hasFile('written_paper_files')) { $files = $request->file('written_paper_files'); $fileContents = []; foreach ($files as $file) { $fileObj = $presentation->saveFile( $file, null, "{$presentation->id}/files/", "presentation.written_paper.file", null, false ); $fileContents[] = $fileObj->getFileObject(); } $fileField = getField($writtenPaperData, 'written_paper_files'); $fileField = array_shift($fileField); $fileFieldValue = $fileField['value']; $fileFieldValue = array_values(array_filter(array_merge($fileFieldValue, $fileContents))); $writtenPaperData = updateField($writtenPaperData, 'written_paper_files', 'value', $fileFieldValue); } //handling removed files if (isset($removedFiles['written_paper_files'])) { $fileIds = $removedFiles['written_paper_files']; foreach ($fileIds as $fileId) { $this->deleteFile($fileId); } } return $writtenPaperData; } public function handlePresentationFiles(Request $request, Presentation $presentation, $data) { $removedFiles = $request->get('removed_files'); $removedFiles = json_decode($removedFiles, true); //handling uploaded files if ($request->hasFile('presentation_files')) { $files = $request->file('presentation_files'); $fileContents = []; foreach ($files as $file) { $fileObj = $presentation->saveFile( $file, null, "{$presentation->id}/files/", "presentation.file", null, false ); $fileContents[] = $fileObj->getFileObject(); } $fileField = getField($data, 'presentation_files'); $fileField = array_shift($fileField); $fileFieldValue = $fileField['value']; $fileFieldValue = array_values(array_filter(array_merge($fileFieldValue, $fileContents))); $data = updateField($data, 'presentation_files', 'value', $fileFieldValue); } //handling removed files if (isset($removedFiles['presentation_files'])) { $fileIds = $removedFiles['presentation_files']; foreach ($fileIds as $fileId) { $this->deleteFile($fileId); } } return $data; } public function selectColumns(): array { return [ 'presentations.id', 'presentations.user_id', 'presentations.event_id', 'presentations.abstract_id', 'presentations.data', 'presentations.type', 'presentations.presentation_type', 'presentations.submission_status', 'presentations.submission_date', 'presentations.written_paper_data', 'presentations.written_paper_status', 'presentations.created_at', 'presentations.updated_at', ]; } public function applyEventScope(Builder $query, $arguments): Builder { if ($arguments->event) { $query->where('presentations.event_id', '=', $arguments->event->id); } return $query; } public function applyUserScope(Builder $query, $arguments): Builder { if ($arguments->role == 'event_submitter') { $query->where(function ($query) use ($arguments) { $query->where('presentations.user_id', '=', $arguments->event_user->user_id) ->orWhereIn( 'presentations.id', function ($query) use ($arguments) { $query->select('presenters.presentation_id') ->from('presenters') ->where('presenters.user_id', '=', $arguments->event_user->user_id); } ); })->groupBy('presentations.id'); } if ($arguments->role == 'event_admin') { $query->leftJoin('presentation_reviews as pr', 'pr.presentation_id', '=', 'presentations.id') ->leftJoin('users as reviewers', 'reviewers.id', '=', 'pr.reviewer_id') ->addSelect([ DB::raw(" concat('[', GROUP_CONCAT( DISTINCT( IF( reviewers.id is not null, JSON_OBJECT( 'name', concat(reviewers.first_name, ' ', reviewers.last_name), 'email', reviewers.email, 'status', pr.status, 'do_not_send_emails', reviewers.do_not_send_emails, 'cc_emails', reviewers.cc_emails ), NULL ) ) ), ']' ) as reviewers") ])->groupBy('presentations.id'); } if ($arguments->role == 'event_reviewer') { $query->join('presentation_reviews as pr', function ($join) use ($arguments) { $join->on('pr.presentation_id', '=', 'presentations.id') ->where('pr.reviewer_id', '=', authUser()->id) ->where('pr.event_id', '=', $arguments->event->id); })->addSelect([ 'pr.status as review_status' ])->groupBy('presentations.id'); } return $query; } public function applyOrder(Builder $query, $arguments): Builder { if (!$arguments->sort) return $query; $columns = [ 'id' => 'presentations.id', 'user_id' => 'presentations.user_id', 'event_id' => 'presentations.event_id', 'abstract_id' => 'presentations.abstract_id', 'type' => 'presentations.type', 'presentation_type' => 'presentations.presentation_type', 'submission_status' => 'presentations.submission_status', 'selection_status' => 'abstract.selection_status', 'written_paper_status' => 'presentations.written_paper_status', 'submission_date' => 'presentations.submission_date', 'created_at' => 'presentations.created_at', 'updated_at' => 'presentations.updated_at', 'presenters' => 'presenters', 'reviewers' => 'reviewers', 'submitter' => 'submitter' ]; $sorts = json_decode($arguments->sort, true); // form settings $formSettings = collect($arguments->event->form_settings->toArray()); // pluck all fields $dataFields = $formSettings->pluck('field_id')->toArray(); foreach ($sorts as $sort => $method) { if (array_key_exists($sort, $columns)) $query->orderBy($sort, $method); // checking sort in field array else if (in_array($sort, $dataFields)) { $key = array_search($sort, $dataFields); $query->orderByRaw("JSON_EXTRACT(abstract.data, '$[$key].value') $method"); } } //todo: add reviewer, presenter and submitter sort return $query; } public function applyTab(Builder $query, $arguments): Builder { if (!($arguments->tab)) return $query; // tab filter $filter = json_decode($arguments->tab); // filtering with reviewers assigned or not if (isset($filter->assigned)) { if ($filter->assigned) $query->whereNotNull('reviewers.id'); else $query->whereNull('reviewers.id'); } return $query; } public function applyFilter(Builder $query, $arguments): Builder { if (!($arguments->filter)) return $query; // for filtering $filter = json_decode($arguments->filter); // filter with category $formSettings = collect($arguments->event->form_settings->toArray()); $dataFields = $formSettings->pluck('field_id')->toArray(); if ($filter->category ?? false) { $key = array_search('category', $dataFields); $values = $filter->category; $query->where(function ($query) use ($values, $key) { foreach ($values as $value) { // $query->orWhereRaw(DB::raw("JSON_EXTRACT(abstract.data, '$[$key].value') = ?"), [$value]); $query->orWhereJsonContains('abstract.data', [ ['field_id' => 'category', 'value' => $value] ]); } }); } // filter with subcategory if ($filter->subcategory ?? false) { $key = array_search('subcategory', $dataFields); $values = $filter->subcategory; $query->where(function ($query) use ($values, $key) { foreach ($values as $value) { //$query->whereRaw(DB::raw("JSON_EXTRACT(abstract.data, '$[$key].value') = ?"), [$value]); $query->orWhereJsonContains('abstract.data', [ ['field_id' => 'subcategory', 'value' => $value] ]); } }); } // filter with company name if ($filter->company ?? false) { $values = $filter->company; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere('presenters.company', '=', $value); } }); } // filter with submission status if ($filter->submission_status ?? false) { $values = $filter->submission_status; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere('presentations.submission_status', '=', $value); } }); } // filter with written paper status if ($filter->written_paper_status ?? false) { $values = $filter->written_paper_status; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere('presentations.written_paper_status', '=', $value); if ($value === 'draft') { $query->orWhereNull('presentations.written_paper_status') ->orWhere('presentations.written_paper_status', '=', ''); } } }); } // assign status if (isset($filter->assigned_status)) { if (count($filter->assigned_status) == 1 && $filter->assigned_status[0] == "Assigned") { $query->where('pr.presentation_id', '>', 0); } else if (count($filter->assigned_status) == 1 && $filter->assigned_status[0] == "Un-Assigned") { $query->whereNull('pr.presentation_id'); } } // filter with presentation type if ($filter->presentation_type ?? false) { $values = $filter->presentation_type; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere('presentations.presentation_type', '=', $value); } }); } // filter with Abstract ID if ($filter->abstractId ?? false) { $values = $filter->abstractId; $query->where(function ($query) use ($values) { foreach ($values as $value) { if ($value == 'Not Set') { $query->orWhere('presentations.abstract_id', '=', null); } else { $query->orWhere('presentations.abstract_id', '=', $value); } } }); } // filter with selection Status if ($filter->selection_status ?? false) { $values = $filter->selection_status; $query->where(function ($query) use ($values) { foreach ($values as $value) { if ($value == 'Not Set') { $query->orWhere('abstract.selection_status', '=', null); } else { $query->orWhere('abstract.selection_status', '=', $value); } } }); } // filter with presenter name if ($filter->presenter ?? false) { $values = $filter->presenter; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere(DB::raw("CONCAT(presenters.first_name, ' ', presenters.last_name)"), '=', $value); } }); } // filter with submitter name if ($filter->submitter ?? false) { $values = $filter->submitter; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere(DB::raw("CONCAT(user.first_name, ' ', user.last_name)"), '=', $value); } }); } // filter with Assigned Reviewer Name if ($filter->reviewer ?? false) { $values = $filter->reviewer; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere(DB::raw("CONCAT(reviewers.first_name, ' ', reviewers.last_name)"), '=', $value); } }); } // filter with Assigned Reviewer status if ($filter->reviewer_assigned_status ?? false) { $values = $filter->reviewer_assigned_status; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere('pr.status', '=', $value); } }); } // filter submission date if (isset($filter->start_date) || isset($filter->end_date)) { $startDate = isset($filter->start_date) ? $filter->start_date : null; $endDate = isset($filter->end_date) ? $filter->end_date : null; if (!$endDate) { $query->where(function ($query) use ($startDate) { $query->orWhereDate(DB::raw('DATE(presentations.submission_date)'), '=', $startDate); }); } else if (!$startDate) { $query->where(function ($query) use ($endDate) { $query->orWhereDate(DB::raw('DATE(presentations.submission_date)'), '=', $endDate); }); } else { $query->where(function ($query) use ($startDate, $endDate) { $query->orWhereBetween('presentations.submission_date', [$startDate, $endDate]); $query->orWhereDate(DB::raw('DATE(presentations.submission_date)'), '=', $startDate); }); } } // filter sessions if ($filter->sessions ?? false) { $values = $filter->sessions; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere('session.title', '=', $value); } }); } // filter slots if ($filter->slots ?? false) { $values = $filter->slots; $query->where(function ($query) use ($values) { foreach ($values as $value) { $query->orWhere('slot.title', '=', $value); } }); } return $query; } public function applySearch(Builder $query, $arguments): Builder { if ($arguments->search) { $columns = [ 'id' => 'presentations.id', 'abstract_id' => 'presentations.abstract_id', 'submission_status' => 'presentations.submission_status' ]; $search = strtolower($arguments->search); $query->where(function ($query) use ($arguments, $search, $columns) { foreach ($columns as $column) { $query->orWhere(DB::raw("lower($column)"), 'like', "%{$search}%"); } //user name $query->orWhereRaw(DB::raw("lower(CONCAT(user.first_name, ' ', user.last_name)) like ?"), ["%{$search}%"]); // presenter name $query->orWhereRaw(DB::raw("lower(CONCAT(presenters.first_name, ' ', presenters.last_name)) like ?"), ["%{$search}%"]); // presenter company $query->orWhereRaw(DB::raw("lower(presenters.company) like ?"), ["%{$search}%"]); // presentation abstract category search // form settings $formSettings = collect($arguments->event->form_settings->toArray()); // pluck all fields $dataFields = $formSettings->pluck('field_id')->toArray(); // key $key = array_search('category', $dataFields); //$query->orWhereRaw(DB::raw("lower(JSON_EXTRACT(abstract.data, '$[$key].value')) like ? "), ["%{$search}%"]); $query->orWhereRaw(DB::raw("lower(JSON_EXTRACT(abstract.data, '$[*].value')) like ? "), ["%{$search}%"]); // user selection status $query->orWhereRaw(DB::raw("lower(abstract.selection_status) like ?"), ["%{$search}%"]); // session title search $query->orWhereRaw(DB::raw("lower(session.title) like ?"), ["%{$search}%"]); // slot title search $query->orWhereRaw(DB::raw("lower(slot.title) like ?"), ["%{$search}%"]); $filter = json_decode($arguments->filter); if (isset($filter->assigned)) { if ($filter->assigned) { $query->orWhereRaw(DB::raw("lower(CONCAT(reviewers.first_name, ' ', reviewers.last_name)) like ?"), ["%{$search}%"]); $query->orWhereRaw(DB::raw("lower(pr.status) like ?"), ["%{$search}%"]); } } }); } return $query; } public function applyScope(Builder $query, $arguments): Builder { $this->applyEventScope($query, $arguments); $this->applyUserScope($query, $arguments); $this->applyOrder($query, $arguments); $this->applyTab($query, $arguments); $this->applyFilter($query, $arguments); $this->applySearch($query, $arguments); return $query; } /** * @throws Exception */ public function scope($arguments, $callback = null): Builder { $query = $this->query() ->select($this->selectColumns()); //joining user to presentation $query->leftJoin('users as user', 'user.id', '=', 'presentations.user_id'); $query->addSelect([DB::raw( "JSON_OBJECT( 'id',user.id, 'first_name',user.first_name, 'last_name',user.last_name, 'do_not_send_emails',user.do_not_send_emails, 'cc_emails',user.cc_emails, 'email',user.email ) as user, concat(user.first_name, ' ', user.last_name) as submitter" )]); //joining abstract to presentation $query->leftJoin('abstracts as abstract', 'abstract.id', '=', 'presentations.abstract_id'); $query->addSelect([DB::raw( "JSON_OBJECT( 'id',abstract.id, 'data',abstract.data, 'submission_status',abstract.submission_status, 'selection_status',abstract.selection_status ) as abstract" ) ]); //joining slots to presentation $query->leftJoin('slots as slot', 'slot.presentation_id', '=', 'presentations.id')-> leftJoin('sessions as session', 'slot.session_id', '=', 'session.id') ->addSelect([ DB::raw(" JSON_ARRAYAGG( JSON_OBJECT( 'title', slot.title, 'slot_id', slot.id, 'session_id', session.id, 'session_title', session.title )) AS slotsArray") ]) ->groupBy('presentations.id'); //joining presenters to presentation $query->leftJoin('presenters as p', 'p.presentation_id', '=', 'presentations.id') ->leftJoin('users as presenters', 'presenters.id', '=', 'p.user_id') ->addSelect([ DB::raw("GROUP_CONCAT(DISTINCT(concat(presenters.first_name, ' ', presenters.last_name))) as presenters") ])->addSelect([ DB::raw(" concat('[', GROUP_CONCAT( DISTINCT( IF( presenters.id is not null, JSON_OBJECT( 'name', concat(presenters.first_name, ' ', presenters.last_name), 'company', presenters.company, 'do_not_send_emails', presenters.do_not_send_emails, 'cc_emails', presenters.cc_emails, 'email', presenters.email ), NULL ) ) ), ']' ) as presentersArray") ])->groupBy('presentations.id'); //applying different scopes based on the arguments $this->applyScope($query, $arguments); //resolve if there is any callback functions available return $this->resolve($query, $arguments, $callback); } /** * @throws Exception */ public function listing(Request $request, $paginate) { //building arguments $arguments = $this->arguments($request); //building query $query = $this->scope($arguments); return ($paginate && $arguments->paging != 'All') ? $query->paginate($arguments->paging, ['*'], 'page', $arguments->page) : $query->get(); } public function fetchPresentation($id, $eventId = null) { if (!$eventId) return Presentation::with(['user', 'abstract', 'presenters', 'reviews.reviewer'])->find($id); else return Presentation::with(['user', 'abstract', 'presenters', 'reviews.reviewer'])->where('event_id', '=', $eventId) ->find($id); } public function getCommentRepository(): PresentationCommentRepository { return new PresentationCommentRepository(); } public function managePresenters(Presentation $presentation, $presenters, $files, $removedUsers = [], $request): Presentation { $this->removerPresentersFromPresentation($presentation, $removedUsers); $userRepository = new UserRepository(); //add/edit presenters in the presentation foreach ($presenters as $key => $person) { $user = User::find($person['id'] ?? null); $isEdit = true; if (!$user) { $validator = Validator::make($person, [ 'first_name' => ['required', 'string', 'max:255'], 'last_name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], ]); if ($validator->fails()) validationErrorResponse($validator->errors()); $user = new User(); $user->password = Hash::make(randomStringGenerator(8)); $user->valid = true; $user->email = $person['email']; $user->created_by = authUser()->id; $user->new_user = true; $user->save(); $user->assignRole('user'); $isEdit = false; } else { $user->new_user = false; $user->save(); } $eventUser = getEventUser($presentation->event->id, $user->id); if (!$eventUser) { $eventUser = $userRepository->attachUserToEvent($presentation->event, $user, 'event_submitter'); // type $eventUser->type = "strategic"; // user added via $eventUser->user_added_via = "Presentation"; // save $eventUser->save(); } if ($presentation->abstract_id) { $abstract = Abstracts::find($presentation->abstract_id); $abstractPresenters = $abstract->users('abstract_presenter')->pluck('id'); $speakerType = $abstractPresenters->contains($user->id) ? 'Abstract' : 'Presentation'; } else { $speakerType = 'Presentation'; } $this->markAsConfirmedSpeaker($eventUser, $speakerType, $presentation->event->id); unset($person['pivot']); unset($person['id']); unset($person['checkboxes']); unset($person['login_email_count']); unset($person['valid']); unset($person['forgot_password']); unset($person['avatar']); unset($person['company_logo']); $user->fill($person); //keep changes field lists $changes = $user->getDirty(); // Track modification if users table data changed if (!empty($changes)) { $userRepository->trackUserModification($user, authUser()->id, $presentation->event_id); $userRepository->trackVipMarkedBy($user, $changes); } $user->save(); $removeAvatar = false; $removeCompanyLogo = false; $removeUserSecondaryImage = false; if (isset($request->get('avatar')[$key])) { if ($request->get('avatar')[$key] === "null" && $user->avatar) { $removeAvatar = true; } } if (isset($request->get('company_logo')[$key])) { if ($request->get('company_logo')[$key] === "null" && $user->company_logo) { $removeCompanyLogo = true; } } if (isset($request->get('user_secondary_image')[$key])) { if ($request->get('user_secondary_image')[$key] === "null" && $user->user_secondary_image) { $removeUserSecondaryImage = true; } } if ($isEdit) { // image files $imageFiles = [ 'avatar' => isset($files['avatar'][$key]) ? $files['avatar'][$key] : null, 'company_logo' => isset($files['company_logo'][$key]) ? $files['company_logo'][$key] : null, ]; // Get the changed fields using the common function $changeFields = $userRepository->getChangedFields($changes, $imageFiles, $removeAvatar, $removeCompanyLogo); // verification changes for change fields if ($changeFields) { // published session status changing $userRepository->publishedSessionStatusUpdate($user); $userRepository->userVerificationFieldsChanges($changeFields, $user); } } $presentersId = $presentation->presenters()->pluck('user_id')->toArray(); if (!in_array($user->id, $presentersId)) { $presentation->presenters()->attach($user, ['event_id' => $presentation->event_id]); // event $event = $request->get('event'); // general settings $generalSettings = $event->general_settings; // terms and condition $termsAndConditionStatus = $generalSettings['speaker_terms_prefill']['terms_and_condition_status']; if (!$termsAndConditionStatus) { dispatch(new SendSpeakerTerms([$eventUser])); } } $userRepository->removeUserImages($user, $removeAvatar, $removeCompanyLogo, $removeUserSecondaryImage); //handling user images $userFiles = []; if (isset($files['avatar'][$key])) $userFiles['avatar'] = $files['avatar'][$key]; if (isset($files['company_logo'][$key])) $userFiles['company_logo'] = $files['company_logo'][$key]; if (isset($files['user_secondary_image'][$key])) $userFiles['user_secondary_image'] = $files['user_secondary_image'][$key]; $userRepository->updateUserImages($userFiles, $user, authUser()->id, $presentation->event_id); } if ($presentation->submission_status == 'Submitted'){ // update related slots $slotRepository = new SlotRepository(); $slotRepository->updateRelatedSlots(null,$presentation); } return $presentation; } // adding selected files in zip file public function addingToZip(object $presentations, Request $request) { // Delete older files $this->deleteOlderZipFiles(); // Create a new ZipArchive instance and open or create the ZIP file $zip = new ZipArchive; $zipName = 'presentationFiles' . time() . '.zip'; $zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE); // Get the selected presentation type from the request $presentationType = $request['presentation_type']; foreach ($presentations as $presentation) { $this->addPresentationToZip($presentation, $zip, $presentationType); // Reset the file name for the next iteration $this->fileName = null; } // Close the ZIP archive $zip->close(); // Set the file path $filepath = public_path($zipName); if (file_exists($filepath)) { // maximum size $maximumSizeInMB = 50; // Check if the file size is too large $fileSize = filesize($zipName); if ($fileSize > $maximumSizeInMB * 1024 * 1024) { // Handle large file size return $this->handleLargeFileSize($zipName, $request); } } // Return a response with the ZIP file for download or an error message return file_exists($filepath) ? $this->returnZipFileResponse($filepath, $zipName) : response(['status' => false, 'message' => "File not found"]); } public function deleteOlderZipFiles() { // public folder path $publicPath = public_path(); // Get a list of all files in the public folder $publicFiles = scandir($publicPath); // delete zip files older than 1 hour $expirationTime = now()->subHour()->timestamp; foreach ($publicFiles as $file) { $filePath = $publicPath . '/' . $file; if (is_file($filePath) && pathinfo($filePath, PATHINFO_EXTENSION) === 'zip') { $fileModificationTime = filemtime($filePath); if ($fileModificationTime < $expirationTime) { // Delete the zip file unlink($filePath); } } } } private function addPresentationToZip($presentation, $zip, $presentationType) { // Extract and format submitter name $submitterName = ''; if ($presentation->user_id) { $submitter = User::whereId($presentation->user_id)->first(); if ($submitter) { $submitterName = removeSpecialCharacters(substr($submitter->name, 0, 30)); $submitterCompany = removeSpecialCharacters(substr($submitter->company, 0, 30)); $this->fileName = $submitterName . ($submitterCompany ? '_' . $submitterCompany : ''); } } // Zip presentation files if available if ($presentation->data && $this->shouldZipPresentationFiles($presentationType)) { $presentationData = json_decode(json_encode($presentation->data), true); $this->filesToZip($presentationData, 'presentation_files', $zip, $presentation); } // Zip written paper files if available if ($presentation->written_paper_data && $this->shouldZipWrittenPaperFiles($presentationType)) { $writtenPaperData = json_decode(json_encode($presentation->written_paper_data), true); $this->filesToZip($writtenPaperData, 'written_paper_files', $zip, $presentation); } } private function shouldZipPresentationFiles($presentationType) { return array_search('Presentation Files', array_column($presentationType['option'], 'value')) !== false; } private function shouldZipWrittenPaperFiles($presentationType) { return array_search('Written Paper Files', array_column($presentationType['option'], 'value')) !== false; } private function handleLargeFileSize($zipName, $request) { // Generate a temporary URL for the file with an expiration time $expiration = now()->addHours(1); $temporaryUrl = URL::temporarySignedRoute( 'downloadPresentationZip', $expiration, ['filename' => $zipName] ); // Send an email to the user with the temporary download link $userEmail = $request->user()->email; // event $event = $request->get('event'); // send email to user with download link $this->sendPresentationDownloadLinkEmail($event, $userEmail, $temporaryUrl); // Return the temporary URL to the user return response()->json([ 'status' => true, 'temporary_url' => urldecode($temporaryUrl), 'message' => "File is too large for direct download. We've emailed you a download link, Please use that link to download the file. ", ]); } public function sendPresentationDownloadLinkEmail($event, $userEmail, $temporaryUrl) { SendPresentationDownloadLinkEmail::dispatch($event, $userEmail, $temporaryUrl); } private function returnZipFileResponse($filepath, $zipName) { return response()->download($filepath, $zipName, ['Content-Type: application/zip', 'Content-Length: ' . filesize($filepath)])->deleteFileAfterSend(true); } public function filesToZip($data, $field, $zip, $presentation) { // attachment field $attachmentFields = array_values( array_filter( $data, fn($presentationFile) => $presentationFile['field_id'] == $field ) ); if (isset($attachmentFields[0]['value']) && is_array($attachmentFields[0]['value'])) { foreach ($attachmentFields[0]['value'] as $attachmentField) { if (isset($attachmentField['file_id'])) { $file = \App\Models\File::whereId($attachmentField['file_id'])->first(); if ($file) { // file path $filePath = $file->filepath . $file->save_name; $filePath = storage_path() . "/app/" . $filePath; $savedFileName = $file->filename; if (strlen($savedFileName) > 30) { $savedFileName = substr($savedFileName, 0, 30); $savedFileName = removeSpecialCharacters($savedFileName); } $name = $this->fileName . '_' . $savedFileName . '_' . $presentation->id . '.' . $file->extension; if (file_exists($filePath)) { // add file to zip $zip->addFile($filePath, $name); } } } } } } public function removerPresentersFromPresentation(Presentation $presentation, $users) { foreach ($users as $user) { if ($user) { $presentationUser = getPresentationPresenter($presentation->id, $user); if ($presentationUser) { $presentationUser->delete(); } } } } public function assignReviewer(Presentation $presentation, $reviewerId): PresentationReview { $reviewerEventUser = getEventUser($presentation->event_id, $reviewerId); if (!$reviewerEventUser->hasRole('event_reviewer')) validationErrorResponse(['User not a reviewer']); $review = PresentationReview::wherePresentationId($presentation->id) ->whereReviewerId($reviewerId) ->first(); if ($review) validationErrorResponse(['Reviewer already assigned']); $review = new PresentationReview([ 'presentation_id' => $presentation->id, 'event_id' => $presentation->event->id, 'reviewer_id' => $reviewerId, 'status' => 'Under Review', ]); $review->save(); $review->refresh(); // disable mail for Egyps // requirement from the client $disableSlug = 'egyps-2023'; if ($review->presentation->event->slug_name !== $disableSlug) { //mail to reviewer dispatch(new SendAssignReviewerMail($review)); } return $review; } public function removeReviewer(Presentation $presentation, $reviewerId) { $review = PresentationReview::wherePresentationId($presentation->id) ->whereReviewerId($reviewerId) ->first(); if (!$review) validationErrorResponse(['Reviewer not found']); $review->delete(); return true; } // remove presenter from presentation public function removePresenter(Presentation $presentation, $presenterId) { $presenter = Presenter::wherePresentationId($presentation->id) ->whereUserId($presenterId) ->first(); if (!$presenter) validationErrorResponse(['Presenter not found']); $presenter->delete(); // update related slots if ($presentation->submission_status == 'Submitted') { $slotRepository = new SlotRepository(); $slotRepository->updateRelatedSlots(null,$presentation); } return true; } public function handleWrittenPaperEditRequest(Presentation $presentation, $status): Presentation { switch ($status) { case 'change': $status = $presentation->written_paper_status === 'Draft' ? 'Submitted' : 'Draft'; $presentation->written_paper_status = $status; $presentation->save(); break; default: validationErrorResponse(['Invalid status']); } return $presentation; } public function handleEditRequest(Presentation $presentation, $status) { switch ($status) { case 'accept': $presentation->submission_status = 'Draft'; $presentation->edit_request = false; $presentation->save(); $generalSettings = $presentation->event->general_settings; $requestToEdit = $generalSettings['presentation_templates']['request_to_edit']; if ($requestToEdit) { //mail to submitter dispatch(new SendPresentationEditStatusChangeMail($presentation, $status)); } break; case 'reject': $presentation->edit_request = false; $presentation->save(); //mail to submitter dispatch(new SendPresentationEditStatusChangeMail($presentation, $status)); break; case 'change': $status = $presentation->submission_status === 'Draft' ? 'Submitted' : 'Draft'; if ($status == "Submitted") { $data = $presentation->data; if (!$data) validationErrorResponse(['Required fields are missing']); $data = $data->toArray(); $fileField = getField($data, 'presentation_files')[0]; $titleField = getField($data, 'title')[0]; if (empty($fileField['value']) && empty($titleField['value'])) { validationErrorResponse(['Required fields are missing']); } } $presentation->submission_status = $status; $presentation->edit_request = false; $presentation->save(); //mail to submitter dispatch(new SendPresentationStatusChangeMail($presentation)); break; default: validationErrorResponse(['Invalid status']); } return $presentation; } public function handleReviewerApprovedRequest($comment, Presentation $presentation) { $user = authUser(); $presentationReview = PresentationReview::wherePresentationId($presentation->id) ->whereReviewerId($user->id) ->first(); if (!$presentationReview) return response([ 'status' => false, 'message' => 'reviewer not found' ]); $presentationReview->status = "Approved"; $presentationReview->approved_date = date('Y-m-d H:i:s', time()); $presentationReview->comment = $comment; $presentationReview->save(); //mail to admins dispatch(new SendReviewerApprovedMail($presentationReview)); return $this->fetchPresentation($presentation->id, $presentation->event->id); } public function getPresentationCount(Request $request): array { $event = $request->get('event'); $eventPresentations = Presentation::whereEventId($event->id) ->get(); $eventPresentationsCount = $eventPresentations->count(); $assignedPresentations = Presentation::where('presentations.event_id', '=', $event->id) ->join('presentation_reviews as pr', 'pr.presentation_id', '=', 'presentations.id') ->groupBy('presentations.id') ->get(); $assignedPresentationsCount = $assignedPresentations->count(); $unAssignedCount = $eventPresentationsCount - $assignedPresentationsCount; $eventPresentationsSubmitted = Presentation::whereEventId($event->id) ->where('submission_status', '=', 'Submitted')->get(); $eventPresentationsSubmittedCount = $eventPresentationsSubmitted->count(); $eventPresentationsDraftCount = $eventPresentationsCount - $eventPresentationsSubmittedCount; return [ 'assigned' => $assignedPresentationsCount, 'unassigned' => $unAssignedCount, 'submitted' => $eventPresentationsSubmittedCount, 'draft' => $eventPresentationsDraftCount, 'total' => $eventPresentationsCount ]; } public function deletePresentation(Presentation $presentation): bool { $slotCount = Slot::wherePresentationId($presentation->id) ->count(); if ($slotCount > 0) { return false; } //delete presentation comments $presentationComments = PresentationComment::wherePresentationId($presentation->id) ->get(); foreach ($presentationComments as $presentationComment) { $this->getCommentRepository()->deletePresentationComment($presentationComment); } //detach presenters from presentation $presentation->presenters()->detach(); //delete presentation reviews $presentation->reviews()->delete(); //delete files in presentation $data = $presentation->data; if ($data) { $presentationFiles = getField($data, 'presentation_files')[0]; $files = $presentationFiles['value']; if (is_array($files)) foreach ($files as $file) { $fileId = $file['file_id']; $this->deleteFile($fileId); } } //delete directory Storage::deleteDirectory('private/media/presentations/' . $presentation->id); if ($presentation->abstract_id) { Abstracts::whereId($presentation->abstract_id) ->update([ 'presentation_invite' => null ]); } $presentation->delete(); return true; } /** * getScheduleMailData() * * @return array */ public function getScheduleMailData(object $data): array { $filter = json_decode($data->filter, 1); $to = []; $email = []; // storing recipients if (isset($filter['recipients'])) { foreach ($filter['recipients'] as $recipients) { $to[] = $recipients['email']; } } $formatedFilter = []; // getting all users if there is no user selected if (!isset($filter['users']) || count($filter['users']) <= 0) { $filter['users'] = $this->getAllUsersByEmailType('Presentation'); } foreach ($this->presentaionFields as $fields) { $arrayColumn = (isset($filter[$fields])) ? $filter[$fields] : []; $formatedFilter[$fields] = array_column($arrayColumn, 'value'); } $event = Event::find($data->event_id); $request = new Request(); $request->replace([ 'paging' => 'all', 'sort' => '{}', 'filter' => json_encode($formatedFilter), 'role' => 'event_admin', 'event' => $event, ]); $result = $this->listing($request, false); $eventRepo = new EventRepository(); //getting users emails foreach ($result as $key => $res) { $body = $this->replaceMacros($res, $data, $event->event_name); $bcc = []; foreach ($filter['users'] as $user) { switch ($user['value']) { case "Submitters": $mails = getUsersEmails([json_decode(json_encode($res->user))]); $bcc = [...$bcc, ...$mails['emails']]; break; case "Presenters": if ($res->presentersArray) $mails = getUsersEmails(json_decode(json_encode($res->presentersArray))); $bcc = [...$bcc, ...$mails['emails']]; break; case "Reviewers": if ($res->reviewers) $mails = getUsersEmails(json_decode(json_encode($res->reviewers))); $bcc = [...$bcc, ...$mails['emails']]; break; } } $bcc = array_unique($bcc); $email[] = [ 'to' => $to, 'bcc' => $bcc, 'subject' => $data->subject, 'body' => $body, 'attachments' => $data->attachments, 'event' => $event, 'event_id' => $data->event_id, 'id' => $data->id, ]; } return $email; } /** * Replace macros * * @return string */ public function replaceMacros($row, object $data, string $event_name): string { $variables = config('schedule_mail_settings')->Presentation->variables; $submittedStatus = $row->submission_status; $writtenPaperStatus = $row->written_paper_status; $submittedDate = $row->submission_date; $presentationId = $row->id; $body = $data->body; $body = Str::replace("{submission_status}", $submittedStatus, $body); $body = Str::replace("{written_paper_status}", $writtenPaperStatus, $body); $body = Str::replace("{presentation_id}", $presentationId, $body); $body = Str::replace("{submission_date}", $submittedDate, $body); $body = Str::replace("{event_name}", $event_name, $body); return $body; } }
Save
Close
Exit & Reset
Text mode: syntax highlighting auto-detects file type.
Directory Contents
Dirs: 0 × Files: 17
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
AbstractsRepository.php
75.27 KB
lrw-rw-r--
2026-04-30 09:24:04
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
AmendSpeakerTermsRepository.php
1.21 KB
lrw-rw-r--
2025-04-21 06:11:52
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ApiRepository.php
65 B
lrw-r--r--
2024-02-09 12:37:30
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
AuthRepository.php
8.53 KB
lrw-rw-r--
2025-03-03 05:39:26
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
EmailLogRepository.php
4.14 KB
lrw-rw-r--
2025-10-28 05:24:52
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
EmailRepository.php
8.53 KB
lrw-rw-r--
2025-10-28 05:24:35
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
EventRepository.php
37.58 KB
lrw-rw-r--
2026-04-07 05:00:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
PresentationCommentRepository.php
8.71 KB
lrw-r--r--
2024-02-09 12:37:30
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
PresentationRepository.php
59.48 KB
lrwxrwxr-x
2026-04-30 09:24:03
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Repository.php
4.78 KB
lrw-r--r--
2024-02-09 12:37:30
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ScheduleEmailRepository.php
10.79 KB
lrw-rw-r--
2025-04-21 06:11:52
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ScoreRepository.php
11.37 KB
lrw-rw-r--
2024-07-24 04:42:48
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
SessionRepository.php
72.51 KB
lrw-rw-r--
2026-04-22 04:31:21
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
SlotRepository.php
11.43 KB
lrw-rw-r--
2024-09-20 05:02:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
SpeakerNotesRepository.php
6.57 KB
lrw-rw-r--
2026-03-31 07:16:20
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
SystemEmailRepository.php
4.26 KB
lrw-r--r--
2024-02-09 12:37:30
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
UserRepository.php
128.96 KB
lrw-rw-r--
2026-05-07 09:06:13
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).