81 lines
2.2 KiB
PHP
81 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Photobooth;
|
|
|
|
use App\Models\Event;
|
|
use App\Models\PhotoboothConnectCode;
|
|
|
|
class PhotoboothConnectCodeService
|
|
{
|
|
public function create(Event $event, ?int $expiresInMinutes = null): array
|
|
{
|
|
$length = (int) config('photobooth.connect_code.length', 6);
|
|
$length = max(4, min(8, $length));
|
|
|
|
$expiresInMinutes = $expiresInMinutes ?: (int) config('photobooth.connect_code.expires_minutes', 10);
|
|
$expiresInMinutes = max(1, min(120, $expiresInMinutes));
|
|
|
|
$code = null;
|
|
$hash = null;
|
|
$max = (10 ** $length) - 1;
|
|
|
|
for ($attempts = 0; $attempts < 5; $attempts++) {
|
|
$candidate = str_pad((string) random_int(0, $max), $length, '0', STR_PAD_LEFT);
|
|
$candidateHash = hash('sha256', $candidate);
|
|
|
|
$exists = PhotoboothConnectCode::query()
|
|
->where('code_hash', $candidateHash)
|
|
->whereNull('redeemed_at')
|
|
->where('expires_at', '>=', now())
|
|
->exists();
|
|
|
|
if (! $exists) {
|
|
$code = $candidate;
|
|
$hash = $candidateHash;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (! $code || ! $hash) {
|
|
$code = str_pad((string) random_int(0, $max), $length, '0', STR_PAD_LEFT);
|
|
$hash = hash('sha256', $code);
|
|
}
|
|
|
|
$expiresAt = now()->addMinutes($expiresInMinutes);
|
|
|
|
$record = PhotoboothConnectCode::query()->create([
|
|
'event_id' => $event->getKey(),
|
|
'code_hash' => $hash,
|
|
'expires_at' => $expiresAt,
|
|
]);
|
|
|
|
return [
|
|
'code' => $code,
|
|
'record' => $record,
|
|
'expires_at' => $expiresAt,
|
|
];
|
|
}
|
|
|
|
public function redeem(string $code): ?PhotoboothConnectCode
|
|
{
|
|
$hash = hash('sha256', $code);
|
|
|
|
/** @var PhotoboothConnectCode|null $record */
|
|
$record = PhotoboothConnectCode::query()
|
|
->where('code_hash', $hash)
|
|
->whereNull('redeemed_at')
|
|
->where('expires_at', '>=', now())
|
|
->first();
|
|
|
|
if (! $record) {
|
|
return null;
|
|
}
|
|
|
|
$record->forceFill([
|
|
'redeemed_at' => now(),
|
|
])->save();
|
|
|
|
return $record;
|
|
}
|
|
}
|