RSVP a čakacia listina
$rsvp = Events::for($event)->rsvp($user)->going(); // the event's single on-sale tier, or none
$rsvp = Events::for($event)->rsvp($user)->going('vip', guests: 2, note: 'Wheelchair access');
$rsvp = Events::for($event)->rsvp($user)->by($user)->interested(); // by() checks the rsvp policy
$rsvp = Events::for($event)->rsvp($user)->notGoing();
$user->rsvp($event)->going(); // AttendsEvents: the same call, through the managergoing() vráti Rsvp — prečítajte jeho stav. Na účastníka a podujatie existuje jedno RSVP a nová odpoveď ho zmení. Poznámka (cez API ≤ 500 znakov) sa uloží s RSVP a vidí ju účastník aj správcovia; zopakovanie tej istej odpovede s novou poznámkou poznámku uloží.
| Stav | Berie miesta | Význam |
|---|---|---|
going | áno | Potvrdené miesto — vydá sa kód pre check-in. |
held | áno | Platené miesto čakajúce na platbu. |
waitlisted | nie | Čaká na miesta, v poradí. |
interested | nie | Sleduje podujatie. |
not_going | nie | Odmietol. |
expired | nie | Rezervácia, ktorá vypršala. |
$rsvp->status; // RsvpStatus: Going, Held, Waitlisted, Interested, NotGoing, Expired
$rsvp->isGoing(); // also isHeld(), isWaitlisted(), isInterested(), isCheckedIn()
$rsvp->partySize(); // 1 + guests
$rsvp->waitlistPosition(); // 1-based, or null
$user->isGoingTo($event);
$user->rsvpFor($event)?->waitlistPosition();
$user->attendingEvents()->upcoming()->get();
$user->interestingEvents()->get();
Event::query()->attendedBy($user)->get();Kedy môže účastník odpovedať
- Koncept prijíma testovacie odpovede len od svojich správcov.
- Zrušené a ukončené podujatia neprijímajú nič (RsvpClosedException).
- Odložené podujatie prijíma len interested a not going.
- Naplánované alebo presunuté podujatie sa pri začiatku uzavrie a going prijíma len v okne RSVP (rsvp_opens_at … rsvp_closes_at, inak do začiatku).
- Súkromné podujatie vyžaduje pozvánku (InvitationRequiredException, 403); odpoveď going ju prijme.
Hostia a limity skupiny
guests sú ďalší ľudia v jednom RSVP, skupina je teda 1 + guests: najviac max_guests podujatia, alebo namiesto toho limity perRsvp(min:, max:) typu vstupenky (InvalidGuestCountException). Viac hostí potrebuje voľné miesta; menej hostí miesta uvoľní a posunie čakaciu listinu.
- Odpoveď, ktorá neuvedie typ vstupenky, si pri RSVP v stave going, held či waitlisted ponechá ten, ktorý má — aj žiadny: miesto obsadené predtým, ako podujatie malo typy vstupeniek, zostáva pri zmenách skupiny bezplatným miestom.
- Typ vstupenky, ktorý RSVP má, patrí účastníkovi: nikdy sa neoveruje, akoby bol zvolený nanovo, takže jeho predaj mohol skončiť alebo ho správca mohol prideliť ako skrytý, a účastník aj tak zmenší skupinu či zopakuje odpoveď. Uvedenie iného typu RSVP presunie podľa bežných pravidiel.
- Skupinu na platenom mieste mení len správca: pri RSVP v stave going na type s cenou ju vlastná odpoveď účastníka zmeniť nemôže (invalid_rsvp_transition, 409). Zmena skupiny rezervovaného RSVP vytvorí novú rezerváciu s novou sumou.
- Hostia po check-ine si miesta ponechajú: skupinu po check-ine nemožno zmenšiť pod počet hostí, ktorí už prešli vstupom.
Kapacita a súbežnosť
Miesta sa počítajú na podujatí (capacity, null = bez obmedzenia) a na každom type vstupenky. Každé rozhodnutie o mieste najprv zamkne riadok podujatia, potom riadky jeho typov vstupeniek vzostupne podľa id a potom riadky RSVP — najprv zámok, potom čítanie —, takže ani pri REPEATABLE READ v MySQL nemôžu dve požiadavky vidieť to isté posledné miesto. Lifecycle aj tags berú riadok podujatia tiež ako prvý, takže vnorené zápisy nikdy neobrátia poradie. Každý zápis beží v transaction($callback, 3) z Laravelu: deadlock alebo stratené spojenie sa zopakuje od čerstvého riadku, najviac trikrát; vo vašej vlastnej transakcii sa zápisy vnoria ako savepointy a opakovanie je na vás. Štyridsať súbežných going() na 25 miest dá vždy 25 going a 15 na čakacej listine.
Počítadlá — seats_taken, going_count, interested_count, waitlist_count a seats_taken každého typu vstupenky — sa menia v tej istej transakcii a events:repair --counts ich prepočíta:
$counts = Events::for($event)->by($organizer)->counts(); // viewCounts, read fresh from the row
$counts->going; // guests included
$counts->interested;
$counts->waitlisted;
$counts->seatsLeft; // null = unlimited
$event->seatsLeft();
$event->isFull();Čakacia listina
So zapnutou čakacou listinou plné podujatie alebo typ vstupenky zaradí na listinu namiesto odmietnutia (bez nej EventFullException alebo TierSoldOutException):
- Prvá vhodná podľa poradia: keď sa uvoľnia miesta, posunie sa najstaršia skupina z listiny, ktorá sa zmestí; skupina príliš veľká na voľné miesta si ponechá poradie a menšia za ňou môže ísť skôr.
- Bez predbiehania: kým by sa na voľné miesta zmestila skupina z listiny pre ten istý typ vstupenky, nováčik sa zaradí na listinu namiesto toho, aby miesta obsadil.
- Automatické posúvanie (waitlist_auto_promote, predvolene zapnuté) sa zastaví events.waitlist.stop_promoting_before (PT1H) pred začiatkom a pri zrušení. Posunutá skupina na platenom type je rezervovaná na events.payments.promotion_hold a správu s odkazom dostane od úlohy platby, keď checkout existuje.
- Každé uvoľnenie posúva v tej istej transakcii — aj prepadnutá rezervácia, ktorú cestou uvoľní webhook platby, potvrdenie pri vstupe alebo zmena od správcu. Miesta uvoľnené počas odloženia sa posunú pri presune termínu; opätovné zapnutie waitlist_auto_promote obsadí voľné miesta hneď.
$waitlist = Events::for($event)->by($organizer)->waitlist();
$waitlist->all(); // in order (waitlisted_at, then id) — viewWaitlist
$waitlist->position($user); // 1-based or null — the actor's own, else viewWaitlist
$waitlist->promote(limit: 5); // a manager's manual move-up — manageAttendeesNástroje správcov
$attendees = Events::for($event)->by($organizer)->attendees(); // manageAttendees
$attendees->add($user, tier: 'vip', guests: 1, overCapacity: true); // comp seats past capacity, explicitly
$attendees->changeTier($user, 'floor');
$attendees->changeGuests($user, 2);
$attendees->confirm($user, $reference); // a held seat, by hand
$attendees->release($user); // a held seat, given back
$attendees->remove($user);
$attendees->find($user); $attendees->going(); $attendees->interested(); $attendees->checkedIn();Každá metóda prijme model účastníka alebo jeho Rsvp; RSVP iného podujatia sa odmietne. S by($actor) zápisy overujú manageAttendees (checkIn a undoCheckIn overujú checkIn) a rovnako aj čítania: going() overí viewAttendees — rozhoduje guest_list podujatia —, interested() viewInterested, checkedIn() checkIn a find() dovolí aktérovi prečítať jeho vlastné RSVP a cudzie len s manageAttendees. Bez aktéra sa nič neoveruje. Čestné miesto z add() je hneď going na akomkoľvek type vstupenky, aj skrytom, a nad kapacitu len s overCapacity: true. changeTier() a changeGuests() najprv uvoľnia prepadnuté rezervácie; pri rezervovanom RSVP vytvoria novú rezerváciu s novou sumou, ktorej checkout sa vyžiada cez front.
Zmazaní účastníci
AttendsEvents uvoľní RSVP trvalo zmazaného účastníka — miesta sa vrátia, čakacia listina sa posunie, riadky sa odstránia. Soft delete ich ponechá aj s miestami, takže taká vstupenka stále prejde check-inom. Hromadné mazanie nespúšťa udalosti modelu: potom spustite events:repair --orphans. Trvalé zmazanie účastníka vo vašej vlastnej transakcii drží každé jeho podujatie zamknuté až do commitu; dve také mazania naraz môžu na dvoch spoločných podujatiach skončiť deadlockom a opakovanie je úlohou vašej transakcie (DB::transaction($callback, 3)).
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.