philippurbschat.de/home/app/models/Invitation.php

98 lines
3.5 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 $recipientEmail = null): string {
$token = bin2hex(random_bytes(24)); // 48-char secure hex token
$projectsJson = json_encode(array_values(array_filter($assignedProjects)));
$cleanEmail = !empty($recipientEmail) ? strtolower(trim($recipientEmail)) : null;
$sql = "INSERT INTO home_invitations (token, recipient_email, assigned_projects, max_uses, uses_count, expires_at, note)
VALUES (:token, :recipient_email, :assigned_projects, :max_uses, 0, :expires_at, :note)";
$this->db->query($sql);
$this->db->bind(':token', $token);
$this->db->bind(':recipient_email', $cleanEmail);
$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 getById(int $id): ?array {
$sql = "SELECT * FROM home_invitations WHERE id = :id";
$this->db->query($sql);
$this->db->bind(':id', $id);
$inv = $this->db->single();
if ($inv) {
$inv['assigned_projects'] = User::parseProjects($inv['assigned_projects'] ?? []);
}
return $inv ?: null;
}
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'] = User::parseProjects($invitation['assigned_projects'] ?? []);
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'] = User::parseProjects($inv['assigned_projects'] ?? []);
$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();
}
}