---
title: "Check-in pri vstupe — Events for Laravel | Roundly"
description: "Neuhádnuteľné šifrované kódy a QR bez cache, skenovanie s podujatím aj bez neho, odmietnutia, okno, ručný check-in a výmena kódu."
url: https://roundly-consulting.com/sk/open-source/navody/events-for-laravel/check-in-pri-vstupe
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Events for Laravel](https://roundly-consulting.com/sk/open-source/navody/events-for-laravel.md)

# Check-in pri vstupe

## Kódy

Prechodom do going dostane každé RSVP kód pre check-in: EV1- a za ním 32 znakov base32 — 160 náhodných bitov z [Crypto for Laravel](https://roundly-consulting.com/sk/open-source/navody/crypto-for-laravel.md) —, uložený šifrovane s indexom SHA-256, vyhľadávaný podľa hashu a nikdy hromadne nedešifrovaný. Odchodom zo stavu going sa zneplatní. Kód je na modeli skrytý a nikdy sa neobjaví v zoznamoch správcov, doménových udalostiach, logoch ani v about.

```php
use RoundlyConsulting\Qr\DataTransferObjects\QrOptions;

$rsvp->checkInCode();                                    // EV1-… — for the attendee's own ticket page
$rsvp->checkInQr(new QrOptions(size: 320, margin: 2));   // an inline SVG, never cached
Events::rsvps()->qr($rsvp);                              // the same image
Events::rsvps()->findByCode($scannerInput);              // the RSVP behind a code, or a URL containing one
Events::rsvps()->by($organizer)->rotateCode($rsvp);      // a new code; the old one stops working
```

QR je inline SVG z [QR for Laravel](https://roundly-consulting.com/sk/open-source/navody/qr-for-laravel.md) s citlivosťou Secret, takže sa nikdy neuloží do cache, nech sú voľby akékoľvek; Svg je Htmlable, Responsable aj Stringable (toDataUri() pre značku img). Jeho obsahom je events.check\_in.url s {code}, ak je nastavené — fotoaparát telefónu potom otvorí vašu aplikáciu pre vstup —, inak samotný kód. Vstup zo skenera sa oreže a prevedie na veľké písmená a použije sa prvý kód EV1-… v ňom, takže sa prečíta aj obsah s URL či prípona zo skenera. Na kódy pre check-in nikdy nepoužívajte Blade komponent x-qr-code.

```blade
{{-- the attendee's ticket page --}}
{{ $rsvp->checkInQr() }}
<p>{{ $rsvp->checkInCode() }}</p>
```

JSON API poskytne ten istý obrázok jeho vlastníkovi na GET /events/{event}/rsvp/qr.svg s Cache-Control: no-store.

## Pri vstupe

```php
$result = Events::for($event)->by($doorStaff)->checkIn($scannedCode, guests: 2);   // scoped to this event
$result->firstCheckIn;    // false on a repeat scan ("already in since 20:04")
$result->checkedInAt;     // CarbonImmutable (UTC) of the first check-in
$result->guests;          // the party's guests checked in so far
$result->method;          // CheckInMethod::Code (CheckInMethod::Manual by hand)
$result->attendee;        // the attendee model
$result->rsvp;            // the RSVP (checked_in_by records the staff member)

$result = Events::checkIn($scannedCode, by: $gateStaff);   // unscoped: a festival gate scanning several events
```

- Check-in robia len správcovia (oprávnenie checkIn). Skenovanie bez podujatia nájde podujatie kódu a policy overí tam; kto nie je správca, dostane rovnakú odpoveď ako pri neznámom kóde, takže nič neprezradí.
- V kontroléri pri vstupe vždy uveďte pracovníka cez by(). Handle bez by() je dôveryhodné PHP a policy preskočí — skopírovaný do kontroléra by dovolil ktorémukoľvek prihlásenému používateľovi urobiť check-in komukoľvek.
- Skenovanie je idempotentné aj pri súbežnosti: na kód pripadne práve jeden firstCheckIn (aktualizácia porovnaj a nastav). Hostia, ktorí prídu neskôr, zvýšia checked\_in\_guests pri opakovanom skenovaní.
- Zápis navyše vyžaduje, aby RSVP bolo stále going a stále malo naskenovaný kód: účastník, ktorý počas skenovania odmietne, je odobratý alebo má vymenený kód, sa odmietne. Po check-ine už účastník odísť nemôže, takže skenovanie a odmietnutie súperiace o jedno RSVP majú práve jedného víťaza.
- Účastník sa určí skôr, než sa čokoľvek zapíše: soft-deleted účet si ponechá RSVP aj miesto, takže jeho vstupenka prejde; účastník, ktorého riadok už neexistuje, skenovanie odmietne a nič sa nezapíše.
- Okno sa otvára events.check\_in.opens\_before (PT3H) pred začiatkom a zatvára events.check\_in.closes\_after (PT2H) po skončení; ignoreWindow: true ho preskočí.

## Odmietnutia

| Výnimka | code | HTTP | Kedy |
| --- | --- | --- | --- |
| `InvalidCheckInCodeException` | `invalid_code` | 404 | Neznámy alebo zneplatnený kód — a pri skenovaní bez podujatia aj niekto, kto nie je správca. |
| `CheckInRefusedException` | `check_in_refused` | 409 | Známy kód, ktorý vstup odmietne; reason() je wrong\_event (ktoré podujatie, sa nikdy neprezradí), not\_going, event\_not\_active (koncept, odložené, zrušené alebo zmazané — ukončené podujatie má vstup otvorený, kým sa okno nezavrie) alebo outside\_window. |
| `RsvpNotFoundException` | `rsvp_not_found` | 404 | Riadok účastníka už neexistuje — nič sa nezapíše. |

```php
use RoundlyConsulting\Events\Exceptions\CheckInRefusedException;
use RoundlyConsulting\Events\Exceptions\InvalidCheckInCodeException;

try {
    $result = Events::for($event)->by($request->user())->checkIn((string) $request->input('code'));
} catch (InvalidCheckInCodeException) {
    // an unknown or revoked code (404 invalid_code)
} catch (CheckInRefusedException $e) {
    $e->reason();   // wrong_event, not_going, event_not_active or outside_window
}
```

## Ručne

```php
Events::for($event)->by($organizer)->attendees()->checkIn($user, guests: 1);   // ignores the window
Events::for($event)->by($organizer)->attendees()->undoCheckIn($user);
Events::for($event)->by($organizer)->attendees()->checkedIn();                // by check-in time
```

Spustia sa AttendeeCheckedIn(CheckInResult) a CheckInUndone a RSVP po check-ine zostáva going — odmietnuť ho už nemožno. Obe operácie zamknú riadok RSVP vo vlastnej transakcii, takže medzi čítanie a zápis sa nedostane odmietnutie ani odobratie a dve zrušenia ohlásia jedno CheckInUndone.

## Uniknutý kód

Ak unikne snímka obrazovky so vstupenkou, Events::rsvps()->rotateCode($rsvp) okamžite vydá nový kód; starý prestane fungovať aj uprostred skenovania.

## Vlastný formát kódu

Pre podpísaný formát overiteľný aj offline naviažte v service provideri Contracts\\CheckInCodes — issue(Rsvp $rsvp): string, extract(string $input): ?string a hash(string $code): string. Predvolený Support\\RandomCheckInCodes je naviazaný cez bindIf, takže vyhrá ten váš:

```php
// AppServiceProvider::register()
$this->app->bind(\RoundlyConsulting\Events\Contracts\CheckInCodes::class, App\Events\SignedCheckInCodes::class);
```

## 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 kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## 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.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/events-for-laravel.md)
