generateUniqueToken(); $payload = [ 'event_id' => $event->id, 'token' => $tokenValue, 'label' => Arr::get($attributes, 'label'), 'usage_limit' => Arr::get($attributes, 'usage_limit'), 'metadata' => Arr::get($attributes, 'metadata', []), ]; if ($expiresAt = Arr::get($attributes, 'expires_at')) { $payload['expires_at'] = $expiresAt instanceof Carbon ? $expiresAt : Carbon::parse($expiresAt); } if ($createdBy = Arr::get($attributes, 'created_by')) { $payload['created_by'] = $createdBy; } return EventJoinToken::create($payload); }); } public function revoke(EventJoinToken $joinToken, ?string $reason = null): EventJoinToken { $joinToken->revoked_at = now(); if ($reason) { $metadata = $joinToken->metadata ?? []; $metadata['revoked_reason'] = $reason; $joinToken->metadata = $metadata; } $joinToken->save(); return $joinToken; } public function incrementUsage(EventJoinToken $joinToken): void { $joinToken->increment('usage_count'); } public function findActiveToken(string $token): ?EventJoinToken { return EventJoinToken::query() ->where('token', $token) ->whereNull('revoked_at') ->where(function ($query) { $query->whereNull('expires_at') ->orWhere('expires_at', '>', now()); }) ->where(function ($query) { $query->whereNull('usage_limit') ->orWhereColumn('usage_limit', '>', 'usage_count'); }) ->first(); } protected function generateUniqueToken(int $length = 48): string { do { $token = Str::random($length); } while (EventJoinToken::where('token', $token)->exists()); return $token; } }