PHP 7.4.33
Preview: SlotRepository.php Size: 11.43 KB
/var/www/multi-event-cfp.bitkit.dk/httpdocs/app/Repositories/SlotRepository.php
<?php

namespace App\Repositories;

use App\Models\Event;
use App\Models\Slot;
use App\Models\SlotUser;
use App\Models\Session;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Jobs\SendPublishedSessionSlotAbstractOrPresentationChangeEmail;
use App\Jobs\SendSessionCreatedMail;
use App\Lib\EmailSetupHelper;

class SlotRepository extends Repository
{
    protected $emailSetup;
    const KEY_TO_SLOT_USERS = "session_create_slot_users";
    public function __construct($event = null)
    {
        $this->for($event);
        $this->emailSetup = new EmailSetupHelper();
    }

    public function model(): ?Slot
    {
        return new Slot();
    }

    public function query($as = null)
    {
        $model = $this->model();
        return $model->newQuery();
    }

    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 scope($arguments, $callback = null)
    {
        $query = $this->query()
            ->select($this->selectColumns());

        //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);
    }

    public function applyScope(Builder $query, $arguments): Builder
    {
        $this->applyEventScope($query, $arguments);

        $this->applySessionScope($query, $arguments);

        $this->applySlotUserScope($query, $arguments);

        $this->applyOrder($query, $arguments);

        $this->applySearch($query, $arguments);

        return $query;
    }

    public function applySearch(Builder $query, $arguments): Builder
    {
        $columns = [
            'id' => 'slots.id',
            'identifier' => 'identifier',
            'session_id' => 'session_id',
            'start_date' => 'slots.start_date',
            'end_date' => 'slots.end_date',
            'duration' => 'slots.duration',
            'type' => 'slots.type',
            'slot_users' => 'slot_users',
            'room' => 'room',

        ];
        $search = $arguments->search;
        $search = strtolower($search);

        foreach ($columns as $column) {
            $query->orHaving(DB::raw("lower($column)"), 'like', "%{$search}%");
        }

        return $query;
    }

    public function applyOrder(Builder $query, $arguments): Builder
    {
        $columns = [
            'id' => 'slots.id',
            'title' => 'slots.title',
            'identifier' => 'slots.identifier',
            'session_id' => 'slots.session_id',
            'start_date' => 'slots.start_date',
            'end_date' => 'slots.end_date',
            'duration' => 'slots.duration',
            'type' => 'slots.type',
            'slot_users' => 'slot_users',
            'room' => 'room'
        ];

        $sorts = json_decode($arguments->sort, true) ?? [];
        foreach ($sorts as $sort => $method) {
            if (array_key_exists($sort, $columns)) {
                $query->orderBy($sort, $method);
            }
        }

        return $query;
    }

    public function applySessionScope(Builder $query, $arguments): Builder
    {
        $query->join('sessions', 'slots.session_id', '=', 'sessions.id')
            ->addSelect(['sessions.room as room']);
        return $query;
    }

    public function applySlotUserScope(Builder $query, $arguments): Builder
    {
        $query->leftJoin('slot_users as su', 'slots.id', '=', 'su.slot_id')
            ->leftJoin('users as u', 'su.user_id', '=', 'u.id')
            ->addSelect([
                DB::raw("
                concat('[',
                GROUP_CONCAT(
                    DISTINCT(
                        IF(
                        u.id is not null,
                        JSON_OBJECT(
                            'name',
                            concat(u.first_name, ' ', u.last_name),
                            'role',
                            su.role
                        ),
                        NULL )
                    )
                ), ']'
                ) as slot_users")
            ])->groupBy('slots.id');

        return $query;
    }

    public function applyEventScope(Builder $query, $arguments): Builder
    {
        if ($arguments->event) {
            $query->where('slots.event_id', '=', $arguments->event->id);
        }

        return $query;
    }

    public function selectColumns(): array
    {
        return [
            'slots.id',
            'slots.event_id',
            'slots.session_id',
            'slots.presentation_id',
            'slots.abstract_id',
            'slots.start_date',
            'slots.end_date',
            'slots.duration',
            'slots.title',
            'slots.type',
            'slots.reserved',
            'slots.exclude_from_website',
            'slots.identifier',
            'slots.break_slot',
            'slots.featured_by',
            'slots.sponsored_by'
        ];
    }

    public function getSlotCount(Event $event): int
    {
        return $event->slots()
            ->count();
    }
    public function updateRelatedSlots($abstract, $presentation)
    {
        if ($abstract && $abstract->exists) {
            // update dependent slots
            $this->updateSlots($abstract, 'Abstract');
        }

        if ($presentation && $presentation->exists) {
            // update dependent slots
            $this->updateSlots($presentation, 'Presentation');
        }
    }

    public function updateSlots($entity, $type)
    {
        if ($entity && $entity->exists) {
            $slots = Slot::where("{$type}_id", $entity->id)->get();

            foreach ($slots as $slot) {
                // update slot title
                $this->updateSlotTitle($slot, $entity, $type);
                // update slot users
                $this->updateSlotUsers($slot, $entity, $type);
            }
        }
    }

    public function updateSlotTitle($slot, $entity, $type)
    {
        $currentSlotTitle = $slot->title;

        // Get the updated title from the entity data
        $updatedTitleField = collect($entity->data)->firstWhere('field_id', 'title');
        $updatedTitle = $updatedTitleField ? $updatedTitleField['value'] : $entity->id;

        $formSettings = $slot->event->form_settings->toArray();
        $titleEnabled = false;
        // Use array_column to extract 'field_id' values
        $fieldIds = array_column($formSettings, 'field_id');
        // Check if 'title' is present in the extracted 'field_id' values
        $key = array_search('title', $fieldIds);

        if ($key !== false) {
            // Check if 'enabled' is set to true
            $titleEnabled = isset($formSettings[$key]['enabled']) && $formSettings[$key]['enabled'];
        }

        // Check if the old title is different from the new title
        if ($currentSlotTitle !== $updatedTitle && ($titleEnabled || $type == 'Presentation')) {
            // Update the slot title with the new title
            $slot->title = $updatedTitle;
            // Update the track title
            $slot->abstract_presentation_track['title'] = $updatedTitle;
            $slot->save();
            // handle slot changes
            $this->handleSlotChanges($slot, $entity, $type);
        }

    }

    public function updateSlotUsers($slot, $entity, $type)
    {
        $currentSpeakers = SlotUser::where('slot_id', '=', $slot->id)->pluck('user_id')->toArray();
        $trackSpeakers = $slot->abstract_presentation_track['speakers'];
        $updatedSpeakers = ($type === 'Abstract')
            ? $entity->users('abstract_presenter')->pluck('id')->toArray()
            : $entity->presenters->pluck('id')->toArray();

        // Identify new speakers to add
        $newSpeakers = array_diff($updatedSpeakers, $trackSpeakers);
        // Identify speakers to remove
        $removedSpeakers = array_diff($trackSpeakers, $updatedSpeakers);

        // Check if there are changes in slot users
        if (!empty($newSpeakers) || !empty($removedSpeakers)) {
            // slot user changed or not
            $slotUserChanged = false;
            // Combine existing speakers and new speakers
            //$finalSpeakers = array_merge($trackSpeakers, $newSpeakers);
            // Add new speakers to the slot users
            foreach ($newSpeakers as $newSpeaker) {
                // Check if the user ID is not already in the list of track speakers
                if (!in_array($newSpeaker, $currentSpeakers)) {
                    $this->addSlotUser($slot, $newSpeaker);
                    $slotUserChanged = true;
                }
            }

            // Remove speakers from the slot users
            foreach ($removedSpeakers as $removedSpeaker) {
                $this->removeSlotUser($slot, $removedSpeaker);
                $slotUserChanged = true;
            }

            // Update the abstract/presentation track speakers
            $slot->abstract_presentation_track['speakers'] = $updatedSpeakers;
            $slot->save();
            if ($slotUserChanged) {
                // handle slot changes
                $this->handleSlotChanges($slot, $entity, $type);
            }

        }
    }

    private function addSlotUser($slot, $userId)
    {
        // add new slot user
        $slotUser = new SlotUser();
        $slotUser->event_id = $slot->event_id;
        $slotUser->slot_id = $slot->id;
        $slotUser->user_id = $userId;
        $slotUser->role = 'Speaker';
        // add order based on count
        $slotUser->order = SlotUser::where('slot_id', $slot->id)->count() + 1;
        $slotUser->save();
        // Session
        $session = Session::find($slot->session_id);
        // email slot content
        $emailSlotContents = $this->emailSetup->getEmailData($session->event->id, self::KEY_TO_SLOT_USERS);
        // send user added to session mail
        dispatch(new SendSessionCreatedMail($session, $slotUser->user, 'added to slot', $slot, $emailSlotContents));
    }

    private function removeSlotUser($slot, $userId)
    {
        $slotUser = SlotUser::where('slot_id', $slot->id)
            ->where('user_id', $userId)
            ->first();

        if ($slotUser) {
            // delete slot user
            $slotUser->delete();
            // re order remaining slot user
            $this->reorderRemainingSlotUsers($slot);
        }
    }

    private function reorderRemainingSlotUsers($slot)
    {
        // Retrieve all slot users for the given slot
        $slotUsers = SlotUser::where('slot_id', $slot->id)
            ->orderBy('order')
            ->get();

        // Reassign order values
        foreach ($slotUsers as $index => $slotUser) {
            $slotUser->order = $index + 1;
            $slotUser->save();
        }
    }

    public function handleSlotChanges($slot, $entity, $type)
    {
        // Session
        $session = Session::find($slot->session_id);

        if ($session->published_status) {
            // published session slots abstract or presentation change email
            dispatch(new SendPublishedSessionSlotAbstractOrPresentationChangeEmail($session, $entity, $type));
            // Set published_status to false if there are changes
            $session->published_status = false;
            $session->save();
        }
    }
}

Directory Contents

Dirs: 0 × Files: 17
Name Size Perms Modified Actions
75.27 KB lrw-rw-r-- 2026-04-30 09:24:04
Edit Download
1.21 KB lrw-rw-r-- 2025-04-21 06:11:52
Edit Download
65 B lrw-r--r-- 2024-02-09 12:37:30
Edit Download
8.53 KB lrw-rw-r-- 2025-03-03 05:39:26
Edit Download
4.14 KB lrw-rw-r-- 2025-10-28 05:24:52
Edit Download
8.53 KB lrw-rw-r-- 2025-10-28 05:24:35
Edit Download
37.58 KB lrw-rw-r-- 2026-04-07 05:00:51
Edit Download
8.71 KB lrw-r--r-- 2024-02-09 12:37:30
Edit Download
59.48 KB lrwxrwxr-x 2026-04-30 09:24:03
Edit Download
4.78 KB lrw-r--r-- 2024-02-09 12:37:30
Edit Download
10.79 KB lrw-rw-r-- 2025-04-21 06:11:52
Edit Download
11.37 KB lrw-rw-r-- 2024-07-24 04:42:48
Edit Download
72.51 KB lrw-rw-r-- 2026-04-22 04:31:21
Edit Download
11.43 KB lrw-rw-r-- 2024-09-20 05:02:14
Edit Download
6.57 KB lrw-rw-r-- 2026-03-31 07:16:20
Edit Download
4.26 KB lrw-r--r-- 2024-02-09 12:37:30
Edit Download
128.96 KB lrw-rw-r-- 2026-05-07 09:06:13
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).