Aucune fiche sélectionnée
Ajouter un objet
Recherche interactive inspirée de la page objets perso : base d’objets + objets personnalisés, avec quantité et info libre.
Objets de la fiche
prepare( 'SELECT cl_auth_id FROM tbl_auth WHERE cl_auth_user = :user LIMIT 1' ); $stmt->execute(['user' => $session_user]); return (int) $stmt->fetchColumn(); } function scmanutention_redirect(int $sheet_id = 0, string $anchor = ''): void { $location = 'scmanutention.php'; if ($sheet_id > 0) { $location .= '?sheet=' . $sheet_id; } if ($anchor !== '') { $location .= '#' . rawurlencode(ltrim($anchor, '#')); } header('Location: ' . $location); exit; } function scmanutention_rarity_class(string $rarity): string { $rarity = strtoupper(trim($rarity)); return in_array($rarity, ['L', 'E', 'R', 'U', 'C'], true) ? 'rarity-' . $rarity : ''; } function scmanutention_item_name(array $item_row): string { $is_custom = ($item_row['cl_scmanutentionitem_source'] ?? '') === 'custom'; return (string) ($is_custom ? ($item_row['cl_scmanutentionitem_custom_name'] ?? '') : ($item_row['cl_scmanutentionitem_base_name'] ?? '')); } function scmanutention_item_type(array $item_row): string { $is_custom = ($item_row['cl_scmanutentionitem_source'] ?? '') === 'custom'; return (string) ($is_custom ? ($item_row['cl_scmanutentionitem_custom_type'] ?? '') : ($item_row['cl_scmanutentionitem_base_type'] ?? '')); } function scmanutention_item_subtype(array $item_row): string { $is_custom = ($item_row['cl_scmanutentionitem_source'] ?? '') === 'custom'; return (string) ($is_custom ? ($item_row['cl_scmanutentionitem_custom_subtype'] ?? '') : ($item_row['cl_scmanutentionitem_base_subtype'] ?? '')); } function scmanutention_item_uuid(array $item_row): string { $is_custom = ($item_row['cl_scmanutentionitem_source'] ?? '') === 'custom'; return (string) ($is_custom ? ($item_row['cl_scmanutentionitem_custom_uuid'] ?? '') : ($item_row['cl_scmanutentionitem_base_uuid'] ?? '')); } function scmanutention_item_rarity(array $item_row): string { $is_custom = ($item_row['cl_scmanutentionitem_source'] ?? '') === 'custom'; return (string) ($is_custom ? ($item_row['cl_scmanutentionitem_custom_rarity'] ?? '') : ($item_row['cl_scmanutentionitem_base_rarity'] ?? '')); } function scmanutention_format_stat_preview(array $stat_row): string { $sign = (string) ($stat_row['cl_scitemcustomstat_sign'] ?? ''); $prefix = $sign === '-' ? '-' : ($sign === '+' ? '+' : ''); $value = (float) ($stat_row['cl_scitemcustomstat_value'] ?? 0); $formatted = number_format($value, 2, '.', ''); $formatted = rtrim(rtrim($formatted, '0'), '.'); if ($formatted === '') { $formatted = '0'; } $unit = trim((string) ($stat_row['cl_scstatsitem_unit'] ?? '')); return trim((string) ($stat_row['cl_scstatsitem_name'] ?? '') . ' : ' . $prefix . $formatted . ($unit !== '' ? ' ' . $unit : '')); } $flash = auth_flash_get(); $flash_type = $flash['type'] ?? ''; $flash_message = $flash['message'] ?? ''; $db = db(); $csrf_token = auth_csrf_token(); $current_owner_auth_id = scmanutention_current_owner_auth_id($db); $current_role_label = auth_role_label(auth_current_role()); $current_session_user = auth_current_user(); 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'] === 'GET' && (string) ($_GET['ajax'] ?? '') === 'item_suggestions') { header('Content-Type: application/json; charset=utf-8'); $query = trim((string) ($_GET['q'] ?? '')); $suggestion_rows = scmanutention_search_available_items($db, $current_owner_auth_id, $query, 14); $suggestion_custom_ids = []; foreach ($suggestion_rows as $row) { if (((string) ($row['result_source'] ?? '')) === 'custom' && !empty($row['result_scitemcustom_id'])) { $suggestion_custom_ids[] = (int) $row['result_scitemcustom_id']; } } $suggestion_stats_map = scmanutention_fetch_custom_stats_preview_map($db, $suggestion_custom_ids); $items = array_map(static function (array $row) use ($suggestion_stats_map): array { $custom_id = (int) ($row['result_scitemcustom_id'] ?? 0); $custom_stats = $custom_id > 0 ? ($suggestion_stats_map[$custom_id] ?? []) : []; $stats_preview = array_map('scmanutention_format_stat_preview', array_slice($custom_stats, 0, 4)); return [ 'key' => (string) $row['result_key'], 'source' => (string) $row['result_source'], 'sourceLabel' => ((string) $row['result_source']) === 'custom' ? 'Objet perso' : 'Base d\'objets', 'scobjs_id' => (int) ($row['result_scobjs_id'] ?? 0), 'scitemcustom_id' => $custom_id, 'name' => (string) ($row['result_name'] ?? ''), 'type' => (string) ($row['result_type'] ?? ''), 'subtype' => (string) ($row['result_subtype'] ?? ''), 'uuid' => (string) ($row['result_uuid'] ?? ''), 'rarity' => (string) ($row['result_rarity'] ?? ''), 'statsPreview' => $stats_preview, 'statsPreviewMore' => max(0, count($custom_stats) - count($stats_preview)), ]; }, $suggestion_rows); echo json_encode(['items' => $items], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } $selected_sheet_id = isset($_GET['sheet']) ? (int) $_GET['sheet'] : 0; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $csrf = isset($_POST['csrf_token']) ? (string) $_POST['csrf_token'] : null; if (!auth_validate_csrf($csrf)) { auth_flash_set('error', 'Jeton CSRF invalide.'); scmanutention_redirect($selected_sheet_id); } $action = trim((string) ($_POST['action'] ?? '')); if ($action === 'create_sheet') { $title = scmanutention_clean_text($_POST['title'] ?? ''); $type = scmanutention_clean_text($_POST['type'] ?? ''); $subtype = scmanutention_clean_text($_POST['subtype'] ?? ''); $description = scmanutention_clean_text($_POST['description'] ?? ''); $share_enabled = isset($_POST['share_enabled']) ? 1 : 0; if ($title === '') { auth_flash_set('error', 'Le nom de la fiche est obligatoire.'); scmanutention_redirect(); } $stmt = $db->prepare( 'INSERT INTO tbl_scmanutentions ( cl_scmanutention_owner_auth_id, cl_scmanutention_title, cl_scmanutention_type, cl_scmanutention_subtype, cl_scmanutention_description, cl_scmanutention_share_token, cl_scmanutention_share_enabled ) VALUES ( :owner_auth_id, :title, :type, :subtype, :description, :share_token, :share_enabled )' ); $stmt->execute([ 'owner_auth_id' => $current_owner_auth_id, 'title' => $title, 'type' => $type, 'subtype' => $subtype, 'description' => $description !== '' ? $description : null, 'share_token' => scmanutention_generate_share_token(), 'share_enabled' => $share_enabled, ]); $new_sheet_id = (int) $db->lastInsertId(); auth_flash_set('success', 'Fiche créée avec succès.'); scmanutention_redirect($new_sheet_id, 'sheet-settings'); } if ($action === 'update_sheet') { $sheet_id = (int) ($_POST['sheet_id'] ?? 0); $sheet = scmanutention_find_owned_sheet($db, $sheet_id, $current_owner_auth_id); if (!$sheet) { auth_flash_set('error', 'Fiche introuvable.'); scmanutention_redirect(); } $title = scmanutention_clean_text($_POST['title'] ?? ''); $type = scmanutention_clean_text($_POST['type'] ?? ''); $subtype = scmanutention_clean_text($_POST['subtype'] ?? ''); $description = scmanutention_clean_text($_POST['description'] ?? ''); $share_enabled = isset($_POST['share_enabled']) ? 1 : 0; if ($title === '') { auth_flash_set('error', 'Le nom de la fiche est obligatoire.'); scmanutention_redirect($sheet_id, 'sheet-settings'); } $stmt = $db->prepare( 'UPDATE tbl_scmanutentions SET cl_scmanutention_title = :title, cl_scmanutention_type = :type, cl_scmanutention_subtype = :subtype, cl_scmanutention_description = :description, cl_scmanutention_share_enabled = :share_enabled WHERE cl_scmanutention_id = :sheet_id' ); $stmt->execute([ 'title' => $title, 'type' => $type, 'subtype' => $subtype, 'description' => $description !== '' ? $description : null, 'share_enabled' => $share_enabled, 'sheet_id' => $sheet_id, ]); auth_flash_set('success', 'Fiche mise à jour.'); scmanutention_redirect($sheet_id, 'sheet-settings'); } if ($action === 'regenerate_share') { $sheet_id = (int) ($_POST['sheet_id'] ?? 0); $sheet = scmanutention_find_owned_sheet($db, $sheet_id, $current_owner_auth_id); if (!$sheet) { auth_flash_set('error', 'Fiche introuvable.'); scmanutention_redirect(); } $stmt = $db->prepare( 'UPDATE tbl_scmanutentions SET cl_scmanutention_share_token = :share_token WHERE cl_scmanutention_id = :sheet_id' ); $stmt->execute([ 'share_token' => scmanutention_generate_share_token(), 'sheet_id' => $sheet_id, ]); auth_flash_set('success', 'Lien public régénéré.'); scmanutention_redirect($sheet_id, 'sheet-settings'); } if ($action === 'delete_sheet') { $sheet_id = (int) ($_POST['sheet_id'] ?? 0); $sheet = scmanutention_find_owned_sheet($db, $sheet_id, $current_owner_auth_id); if (!$sheet) { auth_flash_set('error', 'Fiche introuvable.'); scmanutention_redirect(); } $stmt = $db->prepare('DELETE FROM tbl_scmanutentions WHERE cl_scmanutention_id = :sheet_id'); $stmt->execute(['sheet_id' => $sheet_id]); auth_flash_set('success', 'Fiche supprimée.'); scmanutention_redirect(); } if ($action === 'add_item') { $sheet_id = (int) ($_POST['sheet_id'] ?? 0); $sheet = scmanutention_find_owned_sheet($db, $sheet_id, $current_owner_auth_id); if (!$sheet) { auth_flash_set('error', 'Fiche introuvable.'); scmanutention_redirect(); } $source = trim((string) ($_POST['item_source'] ?? '')); $scobjs_id = (int) ($_POST['item_scobjs_id'] ?? 0); $scitemcustom_id = (int) ($_POST['item_scitemcustom_id'] ?? 0); $quantity = scmanutention_normalize_quantity($_POST['quantity'] ?? 1); $extra_info = scmanutention_clean_text($_POST['extra_info'] ?? ''); $item_reference = scmanutention_validate_item_reference($db, $current_owner_auth_id, $source, $scobjs_id, $scitemcustom_id); if (!$item_reference) { auth_flash_set('error', 'Objet invalide ou inaccessible.'); scmanutention_redirect($sheet_id, 'item-add-card'); } $stmt = $db->prepare( 'INSERT INTO tbl_scmanutentionitems ( cl_scmanutentionitem_manutention_id, cl_scmanutentionitem_source, cl_scmanutentionitem_scobjs_id, cl_scmanutentionitem_scitemcustom_id, cl_scmanutentionitem_quantity, cl_scmanutentionitem_extra_info, cl_scmanutentionitem_sort_order ) VALUES ( :sheet_id, :source, :scobjs_id, :scitemcustom_id, :quantity, :extra_info, :sort_order )' ); $stmt->execute([ 'sheet_id' => $sheet_id, 'source' => $item_reference['source'], 'scobjs_id' => $item_reference['scobjs_id'] > 0 ? $item_reference['scobjs_id'] : null, 'scitemcustom_id' => $item_reference['scitemcustom_id'] > 0 ? $item_reference['scitemcustom_id'] : null, 'quantity' => $quantity, 'extra_info' => $extra_info !== '' ? $extra_info : null, 'sort_order' => scmanutention_next_item_sort_order($db, $sheet_id), ]); auth_flash_set('success', 'Objet ajouté à la fiche.'); scmanutention_redirect($sheet_id, 'sheet-items'); } if ($action === 'update_item') { $item_id = (int) ($_POST['item_id'] ?? 0); $item_row = scmanutention_find_owned_item($db, $item_id, $current_owner_auth_id); if (!$item_row) { auth_flash_set('error', 'Ligne introuvable.'); scmanutention_redirect($selected_sheet_id); } $sheet_id = (int) $item_row['cl_scmanutentionitem_manutention_id']; $source = trim((string) ($_POST['item_source'] ?? '')); $scobjs_id = (int) ($_POST['item_scobjs_id'] ?? 0); $scitemcustom_id = (int) ($_POST['item_scitemcustom_id'] ?? 0); $quantity = scmanutention_normalize_quantity($_POST['quantity'] ?? 1); $extra_info = scmanutention_clean_text($_POST['extra_info'] ?? ''); $item_reference = scmanutention_validate_item_reference($db, $current_owner_auth_id, $source, $scobjs_id, $scitemcustom_id); if (!$item_reference) { auth_flash_set('error', 'Objet invalide ou inaccessible.'); scmanutention_redirect($sheet_id, 'manutention-item-' . $item_id); } $stmt = $db->prepare( 'UPDATE tbl_scmanutentionitems SET cl_scmanutentionitem_source = :source, cl_scmanutentionitem_scobjs_id = :scobjs_id, cl_scmanutentionitem_scitemcustom_id = :scitemcustom_id, cl_scmanutentionitem_quantity = :quantity, cl_scmanutentionitem_extra_info = :extra_info WHERE cl_scmanutentionitem_id = :item_id' ); $stmt->execute([ 'source' => $item_reference['source'], 'scobjs_id' => $item_reference['scobjs_id'] > 0 ? $item_reference['scobjs_id'] : null, 'scitemcustom_id' => $item_reference['scitemcustom_id'] > 0 ? $item_reference['scitemcustom_id'] : null, 'quantity' => $quantity, 'extra_info' => $extra_info !== '' ? $extra_info : null, 'item_id' => $item_id, ]); auth_flash_set('success', 'Ligne mise à jour.'); scmanutention_redirect($sheet_id, 'manutention-item-' . $item_id); } if ($action === 'delete_item') { $item_id = (int) ($_POST['item_id'] ?? 0); $item_row = scmanutention_find_owned_item($db, $item_id, $current_owner_auth_id); if (!$item_row) { auth_flash_set('error', 'Ligne introuvable.'); scmanutention_redirect($selected_sheet_id); } $sheet_id = (int) $item_row['cl_scmanutentionitem_manutention_id']; $stmt = $db->prepare('DELETE FROM tbl_scmanutentionitems WHERE cl_scmanutentionitem_id = :item_id'); $stmt->execute(['item_id' => $item_id]); scmanutention_reindex_items($db, $sheet_id); auth_flash_set('success', 'Ligne supprimée.'); scmanutention_redirect($sheet_id, 'sheet-items'); } auth_flash_set('error', 'Action inconnue.'); scmanutention_redirect($selected_sheet_id); } $stmt_sheets = $db->prepare( 'SELECT m.*, COUNT(mi.cl_scmanutentionitem_id) AS cl_item_total FROM tbl_scmanutentions m LEFT JOIN tbl_scmanutentionitems mi ON mi.cl_scmanutentionitem_manutention_id = m.cl_scmanutention_id WHERE m.cl_scmanutention_owner_auth_id = :owner_auth_id GROUP BY m.cl_scmanutention_id ORDER BY m.cl_scmanutention_updated_at DESC, m.cl_scmanutention_id DESC' ); $stmt_sheets->execute(['owner_auth_id' => $current_owner_auth_id]); $sheets = $stmt_sheets->fetchAll() ?: []; if ($selected_sheet_id <= 0 && !empty($sheets)) { $selected_sheet_id = (int) $sheets[0]['cl_scmanutention_id']; } $selected_sheet = $selected_sheet_id > 0 ? scmanutention_find_owned_sheet($db, $selected_sheet_id, $current_owner_auth_id) : null; $selected_items = $selected_sheet ? scmanutention_fetch_items($db, (int) $selected_sheet['cl_scmanutention_id']) : []; $custom_stats_map = scmanutention_fetch_custom_stats_map($db, $selected_items); $page_access_widget = auth_render_page_access_widget('scmanutention.php', 'Manutention'); ?>
Recherche interactive inspirée de la page objets perso : base d’objets + objets personnalisés, avec quantité et info libre.