Modely a schéma
Sedem tabuliek, sedem modelov. Každý model ukladá časové značky v UTC bez ohľadu na app.timezone. Zapisujte cez fasádu, nikdy cez save() na týchto modeloch — handle udržiava miesta, počítadlá, notifikácie, zámky aj fake v poriadku. Modely slúžia na čítanie, vzťahy a scopes.
Tabuľky
events-migrations publikuje sedem anonymných migrácií len smerom vpred (bez down()), s časovou značkou z publikovania a nikdy nenačítaných automaticky. Morph dvojice sú <name>_type (reťazec) + <name>_id (nakonfigurovaný typ kľúča). Preložiteľné stĺpce a slugy sú na PostgreSQL jsonb a na MySQL json.
| Tabuľka | Konfigurácia | Obsahuje |
|---|---|---|
event_venues | tables.venues | Preložiteľný názov, unikátny slug, morph vlastníka (null = zdieľané), street, city, region, postal_code, country_code (ISO 3166-1 alpha-2), formatted_address, latitude / longitude (decimal 10,7, indexované pre ohraničujúci obdĺžnik), timezone, capacity (informatívna), geocoded_at, súkromné meta. Soft delete. |
events | tables.events | uuid (kľúč routy, kľúč na zdieľanie, UID v kalendári), slug pre každý jazyk, title, description, morph organizátora, venue_id (restrict), šifrovaný online_url, status, visibility, attendance_mode, timezone, starts_at / ends_at (UTC), doors_open_at, previous_starts_at, starts_on / ends_on (miestne dni), all_day, časové značky lifecycle, moved_online_at, capacity, max_guests, príznaky čakacej listiny, okno RSVP, guest_list, show_counts, reminders, počítadlá (seats_taken, going_count, interested_count, waitlist_count), sequence, súkromné meta. Soft delete. |
event_admission_tiers | tables.tiers | event_id (cascade), key (unikátny v rámci podujatia vrátane zmazaných), preložiteľný názov a popis, price + price_currency (null = zadarmo), capacity, seats_taken, obdobie predaja, min_party / max_party, hidden, position. Soft delete. |
event_rsvps | tables.rsvps | event_id (cascade), morph účastníka (jedno RSVP na účastníka a podujatie), tier_id (restrict), status, guests, note, waitlisted_at (poradie vo fronte), held_until, hold_key, payment_reference (unikátny), payment_url, amount, confirmed_at, responded_at, šifrovaný check_in_code + jeho hash (unikátny), checked_in_at, checked_in_guests, check_in_method, morphy checked_in_by / added_by / removed_by, súkromné meta. Bez soft delete — jeho zmazaním je not_going. |
event_hosts | tables.hosts | event_id (cascade), morph spoluorganizátora (unikátny v rámci podujatia), morph added_by, created_at. Odobratie spoluorganizátora zmaže riadok. |
event_invitations | tables.invitations | event_id (cascade), morph pozvaného (unikátny v rámci podujatia), morph invited_by, status, message, token_hash (ukladá sa len hash), responded_at. Bez stĺpca expirácie — odkaz vyprší pri aktuálnom začiatku podujatia. |
event_reminder_deliveries | tables.reminder_deliveries | event_id (cascade), offset, starts_at, dispatched_at, recipients. Unikátne (event_id, offset, starts_at) — vloženie riadku je nárok, vďaka ktorému sa pripomienka pošle raz. |
Tabuľka events má indexy pre zoznamy (visibility, status, starts_at), začiatok, koniec, miestne dni, miesto konania a organizátora. Indexy slugov pre jednotlivé jazyky pokrývajú translatable.locales v čase migrácie; index neskôr pridaného jazyka doplníte cez php artisan sluggable:indexes s názvom triedy modelu podujatia.
Modely
| Model | Konfigurácia | Poznámky |
|---|---|---|
Models\Event | models.event | HasMedia, LifecycleSubject, Sluggable, Taggable, Translatable; skrýva organizer_type, online_url a meta. |
Models\Venue | models.venue | Preložiteľný názov, HasSlug, HasLocation z geolocation (atribút coordinates); skrýva owner_type a meta. |
Models\AdmissionTier | models.tier | Preložiteľný názov a popis; price cez AsMoney z money-for-laravel. |
Models\Rsvp | models.rsvp | Skrýva morph typy, check_in_code, jeho hash, payment_url a meta; amount je Money, check_in_code je šifrovaný. |
Models\EventHost | final | event(), host(), addedBy(). |
Models\EventInvitation | final | event(), invitee(), invitedBy(), isPending(), expiresAt() (aktuálny začiatok podujatia; null, kým je odložené) a $plainToken — nastavený len na inštancii, ktorú vráti send(), nikdy sa neukladá. |
Models\ReminderDelivery | final | event(). |
Model Event
Vzťahy: venue() (vrátane zmazaných miest konania), organizer() (MorphTo; null, keď jeho riadok zanikne), tiers() (podľa position, potom id), rsvps(), hosts() a invitations(). Casty: status na enum stavov nakonfigurovaného životného cyklu; visibility, attendance_mode a guest_list na ich enumy; online_url šifrovane; každá časová značka ako CarbonImmutable v UTC.
| Člen | Vracia | Poznámky |
|---|---|---|
$event->phase | EventPhase | Fáza aktuálneho stavu. |
$event->category / $event->labels | ?Tag / Collection<Tag> | Z pamäte, keď je načítaný vzťah tags. |
$event->poster | ?Media | — |
$event->distance_km | ?float | Nastaví withDistance(). |
posterUrl(string $variant = '') | ?string | Variant, keď je vygenerovaný, inak originál, inak events.poster.fallback_url; nikdy nevyhodí výnimku. |
startsAtLocal() / endsAtLocal() | CarbonImmutable | V časovom pásme podujatia. |
isUpcoming() / isOngoing() / isPast() | bool | — |
seatsLeft() | ?int | null = bez obmedzenia. |
isFull() | bool | — |
tagScope() | ?Model | Organizátor pri events.tags.scope = organizer, inak null. |
toIcs(?Model $viewer = null) | IcsCalendar | = Events::for($event)->ics($viewer). |
toJsonLd() / renderJsonLd() | ?array / HtmlString | Dáta schema.org alebo značka script (prázdna, keď sa negeneruje). |
Query scopes
Každý filter API je jedným z týchto scopes, takže PHP aj HTTP filtrujú rovnako:
| Scope | Čo robí |
|---|---|
visibleTo(?Model $viewer) | View z policy ako dotaz — pozrite Súkromie a oprávnenia. |
listed() | Verejná viditeľnosť. |
published() | Ohlásené: každá fáza okrem Draft. |
active() | Scheduled alebo Rescheduled. |
inPhase(EventPhase ...$phases) | Premietnuté na stavy nakonfigurovaného životného cyklu. |
atVenue(Venue|int ...$venues) | — |
online() · inPerson() · withAttendanceMode(AttendanceMode ...$modes) | inPerson() je offline alebo mixed. |
organizedBy(Model $organizer) | Bez podujatí, ktoré len spoluorganizuje. |
managedBy(Model $user) | Podujatia, ktoré $user spravuje, vrátane konceptov. |
attendedBy(Model $attendee) · interestedBy(Model $attendee) | Podľa stavu RSVP. |
free() | Žiadny typ vstupenky s cenou. |
withSeatsAvailable() | Voľné miesta alebo bez kapacity. |
search(string $term) | Názov alebo popis obsahuje výraz — v ľubovoľnom jazyku, bez ohľadu na veľkosť písmen, so zneškodnenými zástupnými znakmi LIKE; prázdny výraz nepridá nič. |
popular() | Najviac účastníkov ako prvé, potom najbližšie. |
upcoming() · ongoing() · past() · between() · startingBetween() · onLocalDate() | Pozrite Čas a časové pásma. |
inCategory() · labelled() · uncategorized() | Pozrite Kategórie a štítky. |
near() · withDistance() · orderByDistance() | Pozrite Miesta konania a hľadanie v okolí. |
use RoundlyConsulting\Events\Models\Event;
Event::query()->visibleTo($user)->listed()->active()->free()->withSeatsAvailable()
->search('jazz')->popular()->paginate();
Event::query()->managedBy($user)->get(); // the events $user manages, drafts included
Event::query()->organizedBy($team)->upcoming()->get();
Event::query()->atVenue($venue)->inPerson()->get();Route-model binding používa uuid (getRouteKeyName()); chybné uuid je 404 bez dotazu. Binding neuplatňuje žiadne pravidlo viditeľnosti — overte view. Trvalé zmazanie odstráni súbory plagátu (media-library sama nič neodstráni); soft delete ich ponechá.
Venue, AdmissionTier a Rsvp
- Venue — vzťahy owner() a events(), formattedAddress(), atribút coordinates (?Coordinates), scopes ownedBy($owner) a near($point, $km) a k tomu withinRadius() z geolocation (samotný ohraničujúci obdĺžnik).
- AdmissionTier — event() (vrátane zmazaných); isFree(), isOnSale() (práve v období predaja) a seatsLeft(); price je Money alebo null.
- Rsvp — event(), attendee(), tier() (vrátane zmazaných) a checkedInBy(); isGoing(), isHeld(), isWaitlisted(), isInterested(), isCheckedIn(), partySize(), waitlistPosition(), paymentIdempotencyKey() (ev-hold-…), checkInCode() a checkInQr().
Výmena modelu
namespace App\Models;
final class Event extends \RoundlyConsulting\Events\Models\Event
{
// your relations, casts, traits
}
// config/events.php
'models' => ['event' => App\Models\Event::class],Vymeniteľné sú štyri modely — event, venue, tier a rsvp; EventHost, EventInvitation a ReminderDelivery sú final. Balík získava každý model cez toto miesto — vzťahy, dotazy, registráciu policy, typy štítkov aj factories —, takže vzniká a vracia sa vaša podtrieda. Trieda, ktorá nie je podtriedou modelu balíka, vyhodí InvalidConfigurationException z toolkitu s názvom kľúča.
Enumy
| Enum | Hodnoty | Pomocníci |
|---|---|---|
EventStatus | Draft, Scheduled, Postponed, Rescheduled, Cancelled, Completed | Stavy dodaného životného cyklu; phase(), color() (gray, green, amber, blue, red, zinc). |
EventPhase | Draft, Scheduled, Postponed, Rescheduled, Cancelled, Completed | To, čo čítajú všetky pravidlá balíka, nech sú vaše stavy akékoľvek; isTerminal(), isActive(), isPublished(). |
EventVerb | Publish, Unpublish, Postpone, Reschedule, Cancel, Complete | Stavové slovesá handle. |
Visibility | Public, Unlisted, Private | — |
AttendanceMode | Offline, Online, Mixed | schemaOrg(): URL enumerácie schema.org. |
GuestList | Hidden, Attendees, Public | — |
RsvpStatus | Going, Held, Waitlisted, Interested, NotGoing, Expired | takesSeats() (Going, Held); color(). |
RsvpResponse | Going, Interested, NotGoing | Odpoveď účastníka. |
CheckInMethod | Code, Manual | — |
InvitationStatus | Pending, Accepted, Declined, Revoked | — |
EventTagType | Category (events:category), Label (events:label) | — |
EventOperation | Jedna hodnota pre každý zaznamenaný zápis (50) | Pozrite Testovanie. |
Každý enum okrem EventOperation, EventTagType a FindingSeverity používa Helpers z enums-for-laravel: label() (preložený, v angličtine a slovenčine), labels(), values(), options(), toOptions(), fromName(), tryFromName(), is(), isIn(), validationRule() a ďalšie metódy tohto traitu. Slovenské popisy sú napríklad „Čaká na platbu“ pre RsvpStatus::Held, „Osobne aj online“ pre AttendanceMode::Mixed a „Ručne“ pre CheckInMethod::Manual:
use RoundlyConsulting\Events\Enums\RsvpStatus;
RsvpStatus::Waitlisted->label(); // "On the waitlist" ("Na čakacej listine" in sk)
$rsvp->status->takesSeats(); // going or held
$event->phase->isActive(); // RSVPs and check-in runDátové objekty
Každé DTO je final readonly s vlastnosťami v konštruktore. Vstupy:
| DTO | Polia |
|---|---|
CreateEventData | title, organizer, schedule (ScheduleData) a každé pole buildera: description, venue, onlineUrl, attendanceMode, visibility, capacity, maxGuests, waitlist, waitlistAutoPromote, rsvpOpensAt, rsvpClosesAt, guestList, showCounts, reminders, slug, coHosts, tiers (list<TierData>), poster, posterDraft, category, labels, meta, actor. |
ScheduleData | startsAt, endsAt, duration, allDayFrom, allDayThrough, doorsOpenAt, timezone — predvolene všetky null; isAllDay(). |
UpdateEventData | Každé pole podujatia, predvolene Support\NotGiven::Value (bez zmeny); null vymaže pole, ktoré môže byť prázdne; movesStart(). |
VenueData / UpdateVenueData | name, address (AddressData), coordinates, timezone, capacity, owner, geocode, meta, actor / tie isté polia ako NotGiven, pričom address nahradí všetkých šesť stĺpcov adresy. |
AddressData | street, city, region, postalCode, country, formatted |
TierData / UpdateTierData | name, key, price (Money alebo desatinný reťazec), capacity, saleStartsAt, saleEndsAt, minParty (1), maxParty, hidden, position, description / to isté ako NotGiven. |
RsvpRequest | attendee, response (RsvpResponse), tier, guests, note, actor |
EventFeedQuery | category, label, organizer, venue, name (názov kalendára). |
SweepOptions / RepairOptions | limit, chunk (100) / counts, orphans, dryRun, chunk (100) |
Výsledky:
| DTO | Polia |
|---|---|
CheckInResult | rsvp, attendee, firstCheckIn, guests, checkedInAt, method |
EventCounts | going (vrátane hostí), interested, waitlisted, seatsLeft |
PaymentRequest | reference, url, expiresAt — to, čo vráti váš collector |
SweepResult | events, expiredHolds, promoted, reminders, notified |
RepairReport | eventsChecked, countersFixed, orphansReleased, dryRun |
DoctorFinding | severity (FindingSeverity), check, message; toArray() |
PosterVariant | name, width, height — jedna položka events.poster.variants |
Kontrakty
| Kontrakt | Metódy | Predvolené a výmena |
|---|---|---|
Organizer | eventOrganizerName(), eventOrganizerUrl(), allowsEventManagementBy(Model $user), scopeManagingEventsFor(Builder $query, Model $user) | Na vašich modeloch organizátorov; predvolené hodnoty dáva Concerns\OrganizesEvents. |
CollectsAdmissionPayment | request(Rsvp $rsvp, Money $amount): ?PaymentRequest | Payments\NoPaymentCollector; events.payments.collector. |
EventUrls | event(Event $event), invitation(string $token), rsvp(Rsvp $rsvp) — each ?string | Support\TemplateEventUrls; events.urls.resolver. |
CheckInCodes | issue(Rsvp $rsvp), extract(string $input), hash(string $code) | Support\RandomCheckInCodes, naviazaný cez bindIf — vlastný naviažte v service provideri. |
EventLifecycle | transitionFor(EventVerb $verb): ?string | Lifecycle\EventLifecycle; events.lifecycle. |
EventState | phase(): EventPhase | Implementuje ho enum stavov vášho životného cyklu (dodáva sa EventStatus). |
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.