85 lines
3 KiB
PHP
85 lines
3 KiB
PHP
<?php
|
|
class Invitation {
|
|
private $db;
|
|
|
|
public function __construct() {
|
|
$this->db = new Database();
|
|
}
|
|
|
|
public function create(array $assignedProjects = [], ?string $note = null, int $maxUses = 1, ?string $expiresAt = null): string {
|
|
$token = bin2hex(random_bytes(24)); // 48-char secure hex token
|
|
$projectsJson = json_encode(array_values(array_filter($assignedProjects)));
|
|
|
|
$sql = "INSERT INTO home_invitations (token, assigned_projects, max_uses, uses_count, expires_at, note)
|
|
VALUES (:token, :assigned_projects, :max_uses, 0, :expires_at, :note)";
|
|
$this->db->query($sql);
|
|
$this->db->bind(':token', $token);
|
|
$this->db->bind(':assigned_projects', $projectsJson);
|
|
$this->db->bind(':max_uses', $maxUses);
|
|
$this->db->bind(':expires_at', $expiresAt);
|
|
$this->db->bind(':note', $note);
|
|
$this->db->execute();
|
|
|
|
return $token;
|
|
}
|
|
|
|
public function getByToken(string $token): ?array {
|
|
$sql = "SELECT * FROM home_invitations WHERE LOWER(token) = LOWER(:token)";
|
|
$this->db->query($sql);
|
|
$this->db->bind(':token', $token);
|
|
$invitation = $this->db->single();
|
|
|
|
if (!$invitation) {
|
|
return null;
|
|
}
|
|
|
|
// Check uses count
|
|
if ($invitation['max_uses'] > 0 && $invitation['uses_count'] >= $invitation['max_uses']) {
|
|
return null;
|
|
}
|
|
|
|
// Check expiration
|
|
if (!empty($invitation['expires_at'])) {
|
|
$now = new DateTime();
|
|
$expires = new DateTime($invitation['expires_at']);
|
|
if ($now > $expires) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
$invitation['assigned_projects'] = json_decode($invitation['assigned_projects'] ?? '[]', true) ?? [];
|
|
return $invitation;
|
|
}
|
|
|
|
public function recordUse(string $token): bool {
|
|
$sql = "UPDATE home_invitations SET uses_count = uses_count + 1 WHERE LOWER(token) = LOWER(:token)";
|
|
$this->db->query($sql);
|
|
$this->db->bind(':token', $token);
|
|
return $this->db->execute();
|
|
}
|
|
|
|
public function getAll(): array {
|
|
$sql = "SELECT * FROM home_invitations ORDER BY id DESC";
|
|
$this->db->query($sql);
|
|
$invitations = $this->db->resultSet();
|
|
|
|
foreach ($invitations as &$inv) {
|
|
$inv['assigned_projects'] = json_decode($inv['assigned_projects'] ?? '[]', true) ?? [];
|
|
$isExpired = false;
|
|
if (!empty($inv['expires_at'])) {
|
|
$isExpired = (new DateTime()) > (new DateTime($inv['expires_at']));
|
|
}
|
|
$isDepleted = ($inv['max_uses'] > 0 && $inv['uses_count'] >= $inv['max_uses']);
|
|
$inv['is_valid'] = (!$isExpired && !$isDepleted);
|
|
}
|
|
|
|
return $invitations;
|
|
}
|
|
|
|
public function delete(int $id): bool {
|
|
$sql = "DELETE FROM home_invitations WHERE id = :id";
|
|
$this->db->query($sql);
|
|
$this->db->bind(':id', $id);
|
|
return $this->db->execute();
|
|
}
|
|
}
|