This commit is contained in:
Flatlogic Bot 2026-04-08 19:11:06 +00:00
parent a785e059e9
commit e464a95e35
2 changed files with 173 additions and 25 deletions

View File

@ -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,

View File

@ -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'] ?? '';
<table class="modern-table">
<thead>
<tr>
<th style="width:70px;">ID</th>
<th>Statistique</th>
<th style="width:110px;">Signe</th>
<th style="width:140px;">Valeur</th>
@ -825,12 +901,11 @@ $current_session_user = $_SESSION['user'] ?? '';
<tbody>
<?php if (empty($item_stats)): ?>
<tr>
<td colspan="7" class="empty-state">Aucune statistique configurée pour cet objet.</td>
<td colspan="6" class="empty-state">Aucune statistique configurée pour cet objet.</td>
</tr>
<?php else: ?>
<?php foreach ($item_stats as $item_stat): ?>
<tr>
<td>#<?php echo (int) $item_stat['cl_scitemcustomstat_id']; ?></td>
<td>
<form method="post">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8'); ?>">