diff --git a/db/scitemcustom.php b/db/scitemcustom.php index bc144ef..2647f25 100644 --- a/db/scitemcustom.php +++ b/db/scitemcustom.php @@ -2,6 +2,38 @@ require_once __DIR__ . '/config.php'; +function scitemcustom_column_exists(PDO $db, string $table, string $column): bool +{ + $stmt = $db->query("SHOW COLUMNS FROM `{$table}` LIKE " . $db->quote($column)); + + return (bool) $stmt->fetch(); +} + +function scitemcustom_index_exists(PDO $db, string $table, string $index): bool +{ + $stmt = $db->query("SHOW INDEX FROM `{$table}` WHERE Key_name = " . $db->quote($index)); + + return (bool) $stmt->fetch(); +} + +function scitemcustom_foreign_key_exists(PDO $db, string $table, string $constraint): bool +{ + $stmt = $db->prepare( + "SELECT COUNT(*) + FROM information_schema.TABLE_CONSTRAINTS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = :table_name + AND CONSTRAINT_NAME = :constraint_name + AND CONSTRAINT_TYPE = 'FOREIGN KEY'" + ); + $stmt->execute([ + 'table_name' => $table, + 'constraint_name' => $constraint, + ]); + + return (int) $stmt->fetchColumn() > 0; +} + function scitemcustom_bootstrap(): void { static $scitemcustom_bootstrap_done = false; @@ -15,11 +47,17 @@ function scitemcustom_bootstrap(): void $db->exec( "CREATE TABLE IF NOT EXISTS tbl_scitemcustom ( cl_scitemcustom_id INT(11) NOT NULL AUTO_INCREMENT, + cl_scitemcustom_owner_auth_id INT UNSIGNED NOT NULL, cl_scitemcustom_obj_id INT(10) UNSIGNED NOT NULL, cl_scitemcustom_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (cl_scitemcustom_id), - UNIQUE KEY uq_scitemcustom_obj (cl_scitemcustom_obj_id), + UNIQUE KEY uq_scitemcustom_owner_obj (cl_scitemcustom_owner_auth_id, cl_scitemcustom_obj_id), + KEY idx_scitemcustom_owner (cl_scitemcustom_owner_auth_id), KEY idx_scitemcustom_obj (cl_scitemcustom_obj_id), + CONSTRAINT fk_scitemcustom_owner_auth FOREIGN KEY (cl_scitemcustom_owner_auth_id) + REFERENCES tbl_auth (cl_auth_id) + ON DELETE CASCADE + ON UPDATE CASCADE, CONSTRAINT fk_scitemcustom_obj FOREIGN KEY (cl_scitemcustom_obj_id) REFERENCES tbl_scobjs (cl_scobjs_id) ON DELETE CASCADE @@ -27,6 +65,41 @@ function scitemcustom_bootstrap(): void ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" ); + if (!scitemcustom_column_exists($db, 'tbl_scitemcustom', 'cl_scitemcustom_owner_auth_id')) { + $db->exec( + 'ALTER TABLE tbl_scitemcustom + ADD COLUMN cl_scitemcustom_owner_auth_id INT UNSIGNED NULL AFTER cl_scitemcustom_id' + ); + } + + if (scitemcustom_index_exists($db, 'tbl_scitemcustom', 'uq_scitemcustom_obj')) { + $db->exec('ALTER TABLE tbl_scitemcustom DROP INDEX uq_scitemcustom_obj'); + } + + if (!scitemcustom_index_exists($db, 'tbl_scitemcustom', 'idx_scitemcustom_owner')) { + $db->exec( + 'ALTER TABLE tbl_scitemcustom + ADD INDEX idx_scitemcustom_owner (cl_scitemcustom_owner_auth_id)' + ); + } + + if (!scitemcustom_index_exists($db, 'tbl_scitemcustom', 'uq_scitemcustom_owner_obj')) { + $db->exec( + 'ALTER TABLE tbl_scitemcustom + ADD UNIQUE KEY uq_scitemcustom_owner_obj (cl_scitemcustom_owner_auth_id, cl_scitemcustom_obj_id)' + ); + } + + if (!scitemcustom_foreign_key_exists($db, 'tbl_scitemcustom', 'fk_scitemcustom_owner_auth')) { + $db->exec( + 'ALTER TABLE tbl_scitemcustom + ADD CONSTRAINT fk_scitemcustom_owner_auth FOREIGN KEY (cl_scitemcustom_owner_auth_id) + REFERENCES tbl_auth (cl_auth_id) + ON DELETE CASCADE + ON UPDATE CASCADE' + ); + } + $db->exec( "CREATE TABLE IF NOT EXISTS tbl_scitemcustomstat ( cl_scitemcustomstat_id INT(11) NOT NULL AUTO_INCREMENT, diff --git a/scitemcustom.php b/scitemcustom.php index fb9d8ea..acf7466 100644 --- a/scitemcustom.php +++ b/scitemcustom.php @@ -46,6 +46,24 @@ function scitemcustom_preview(string $sign, $value, string $unit): string return ($sign === '-' ? '-' : '+') . scitemcustom_display_value($value) . $unit; } +function scitemcustom_current_owner_auth_id(PDO $db): int +{ + $session_user = isset($_SESSION['user']) ? trim((string) $_SESSION['user']) : ''; + if ($session_user === '') { + return 0; + } + + $stmt_owner = $db->prepare( + 'SELECT cl_auth_id + FROM tbl_auth + WHERE cl_auth_user = :user + LIMIT 1' + ); + $stmt_owner->execute(['user' => $session_user]); + + return (int) $stmt_owner->fetchColumn(); +} + $flash = auth_flash_get(); $flash_type = $flash['type'] ?? ''; $flash_message = $flash['message'] ?? ''; @@ -53,6 +71,13 @@ $flash_message = $flash['message'] ?? ''; $db = db(); $csrf_token = auth_csrf_token(); $allowed_signs = ['+', '-']; +$current_owner_auth_id = scitemcustom_current_owner_auth_id($db); + +if ($current_owner_auth_id <= 0) { + auth_flash_set('error', 'Utilisateur introuvable. Merci de vous reconnecter.'); + header('Location: logout.php'); + exit; +} if ($_SERVER['REQUEST_METHOD'] === 'POST') { $submitted_csrf = $_POST['csrf_token'] ?? ''; @@ -75,8 +100,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!$stmt_check->fetch()) { auth_flash_set('error', 'Objet introuvable.'); } else { - $stmt_insert = $db->prepare('INSERT INTO tbl_scitemcustom (cl_scitemcustom_obj_id) VALUES (:obj_id)'); - $stmt_insert->execute(['obj_id' => $obj_id]); + $stmt_insert = $db->prepare( + 'INSERT INTO tbl_scitemcustom (cl_scitemcustom_owner_auth_id, cl_scitemcustom_obj_id) + VALUES (:owner_auth_id, :obj_id)' + ); + $stmt_insert->execute([ + 'owner_auth_id' => $current_owner_auth_id, + 'obj_id' => $obj_id, + ]); auth_flash_set('success', 'Objet ajouté dans Item Custom.'); } } catch (PDOException $e) { @@ -96,12 +127,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $itemcustom_id = (int) ($_POST['itemcustom_id'] ?? 0); if ($itemcustom_id > 0) { try { - $stmt_delete_children = $db->prepare('DELETE FROM tbl_scitemcustomstat WHERE cl_scitemcustomstat_itemcustom_id = :id'); - $stmt_delete_children->execute(['id' => $itemcustom_id]); + $stmt_delete = $db->prepare( + 'DELETE FROM tbl_scitemcustom + WHERE cl_scitemcustom_id = :id + AND cl_scitemcustom_owner_auth_id = :owner_auth_id' + ); + $stmt_delete->execute([ + 'id' => $itemcustom_id, + 'owner_auth_id' => $current_owner_auth_id, + ]); - $stmt_delete = $db->prepare('DELETE FROM tbl_scitemcustom WHERE cl_scitemcustom_id = :id'); - $stmt_delete->execute(['id' => $itemcustom_id]); - auth_flash_set('success', 'Objet Item Custom supprimé.'); + if ($stmt_delete->rowCount() > 0) { + auth_flash_set('success', 'Objet Item Custom supprimé.'); + } else { + auth_flash_set('error', 'Objet introuvable ou non autorisé.'); + } } catch (PDOException $e) { auth_flash_set('error', 'Erreur lors de la suppression : ' . $e->getMessage()); } @@ -125,11 +165,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { 'SELECT c.cl_scitemcustom_id, s.cl_scstatsitem_id FROM tbl_scitemcustom c JOIN tbl_scstatsitem s ON s.cl_scstatsitem_id = :stat_id - WHERE c.cl_scitemcustom_id = :itemcustom_id' + WHERE c.cl_scitemcustom_id = :itemcustom_id + AND c.cl_scitemcustom_owner_auth_id = :owner_auth_id' ); $stmt_check->execute([ 'itemcustom_id' => $itemcustom_id, 'stat_id' => $stat_id, + 'owner_auth_id' => $current_owner_auth_id, ]); if (!$stmt_check->fetch()) { @@ -175,19 +217,28 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } else { try { $stmt_update = $db->prepare( - 'UPDATE tbl_scitemcustomstat - SET cl_scitemcustomstat_stat_id = :stat_id, - cl_scitemcustomstat_sign = :sign, - cl_scitemcustomstat_value = :value - WHERE cl_scitemcustomstat_id = :id' + 'UPDATE tbl_scitemcustomstat cs + JOIN tbl_scitemcustom c ON c.cl_scitemcustom_id = cs.cl_scitemcustomstat_itemcustom_id + JOIN tbl_scstatsitem s ON s.cl_scstatsitem_id = :stat_id + SET cs.cl_scitemcustomstat_stat_id = :stat_id, + cs.cl_scitemcustomstat_sign = :sign, + cs.cl_scitemcustomstat_value = :value + WHERE cs.cl_scitemcustomstat_id = :id + AND c.cl_scitemcustom_owner_auth_id = :owner_auth_id' ); $stmt_update->execute([ 'stat_id' => $stat_id, 'sign' => $sign, 'value' => $value, 'id' => $custom_stat_id, + 'owner_auth_id' => $current_owner_auth_id, ]); - auth_flash_set('success', 'Statistique mise à jour.'); + + if ($stmt_update->rowCount() > 0) { + auth_flash_set('success', 'Statistique mise à jour.'); + } else { + auth_flash_set('error', 'Statistique introuvable ou non autorisée.'); + } } catch (PDOException $e) { if ((string) $e->getCode() === '23000') { auth_flash_set('error', 'Cette statistique est déjà configurée pour cet objet.'); @@ -205,9 +256,23 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $custom_stat_id = (int) ($_POST['custom_stat_id'] ?? 0); if ($custom_stat_id > 0) { try { - $stmt_delete = $db->prepare('DELETE FROM tbl_scitemcustomstat WHERE cl_scitemcustomstat_id = :id'); - $stmt_delete->execute(['id' => $custom_stat_id]); - auth_flash_set('success', 'Statistique supprimée de l\'objet.'); + $stmt_delete = $db->prepare( + 'DELETE cs + FROM tbl_scitemcustomstat cs + JOIN tbl_scitemcustom c ON c.cl_scitemcustom_id = cs.cl_scitemcustomstat_itemcustom_id + WHERE cs.cl_scitemcustomstat_id = :id + AND c.cl_scitemcustom_owner_auth_id = :owner_auth_id' + ); + $stmt_delete->execute([ + 'id' => $custom_stat_id, + 'owner_auth_id' => $current_owner_auth_id, + ]); + + if ($stmt_delete->rowCount() > 0) { + auth_flash_set('success', 'Statistique supprimée de l\'objet.'); + } else { + auth_flash_set('error', 'Statistique introuvable ou non autorisée.'); + } } catch (PDOException $e) { auth_flash_set('error', 'Erreur lors de la suppression : ' . $e->getMessage()); } @@ -225,11 +290,18 @@ if ($search !== '') { "SELECT * FROM tbl_scobjs WHERE (cl_scobjs_name LIKE :search OR cl_scobjs_type LIKE :search OR cl_scobjs_subtype LIKE :search OR cl_scobjs_uuid LIKE :search) - AND cl_scobjs_id NOT IN (SELECT cl_scitemcustom_obj_id FROM tbl_scitemcustom) + AND cl_scobjs_id NOT IN ( + SELECT cl_scitemcustom_obj_id + FROM tbl_scitemcustom + WHERE cl_scitemcustom_owner_auth_id = :owner_auth_id + ) ORDER BY cl_scobjs_name ASC LIMIT 15" ); - $stmt_search->execute(['search' => '%' . $search . '%']); + $stmt_search->execute([ + 'search' => '%' . $search . '%', + 'owner_auth_id' => $current_owner_auth_id, + ]); $search_results = $stmt_search->fetchAll(); } @@ -243,16 +315,21 @@ foreach ($stats_catalog as $stat_catalog_row) { $sql_custom_items = "SELECT c.*, o.cl_scobjs_name, o.cl_scobjs_uuid, o.cl_scobjs_type, o.cl_scobjs_subtype, o.cl_scobjs_rarity FROM tbl_scitemcustom c JOIN tbl_scobjs o ON o.cl_scobjs_id = c.cl_scitemcustom_obj_id + WHERE c.cl_scitemcustom_owner_auth_id = :owner_auth_id ORDER BY o.cl_scobjs_name ASC, c.cl_scitemcustom_id ASC"; -$stmt_custom_items = $db->query($sql_custom_items); +$stmt_custom_items = $db->prepare($sql_custom_items); +$stmt_custom_items->execute(['owner_auth_id' => $current_owner_auth_id]); $custom_items = $stmt_custom_items->fetchAll(); -$stmt_custom_stats = $db->query( +$stmt_custom_stats = $db->prepare( "SELECT cs.*, st.cl_scstatsitem_name, st.cl_scstatsitem_unit FROM tbl_scitemcustomstat cs + JOIN tbl_scitemcustom c ON c.cl_scitemcustom_id = cs.cl_scitemcustomstat_itemcustom_id JOIN tbl_scstatsitem st ON st.cl_scstatsitem_id = cs.cl_scitemcustomstat_stat_id + WHERE c.cl_scitemcustom_owner_auth_id = :owner_auth_id ORDER BY cs.cl_scitemcustomstat_itemcustom_id ASC, st.cl_scstatsitem_name ASC, cs.cl_scitemcustomstat_id ASC" ); +$stmt_custom_stats->execute(['owner_auth_id' => $current_owner_auth_id]); $custom_stats_rows = $stmt_custom_stats->fetchAll(); $custom_stats_by_item = []; foreach ($custom_stats_rows as $custom_stat_row) { @@ -813,7 +890,6 @@ $current_session_user = $_SESSION['user'] ?? '';
| ID | Statistique | Signe | Valeur | @@ -825,12 +901,11 @@ $current_session_user = $_SESSION['user'] ?? '';|||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Aucune statistique configurée pour cet objet. | +Aucune statistique configurée pour cet objet. | |||||||||||
| # | ||||||||||||