Alpha V1.4

This commit is contained in:
Flatlogic Bot 2026-02-26 08:28:54 +00:00
parent 865fa068e4
commit 12241ba85d
15 changed files with 1124 additions and 46 deletions

132
admin.php
View File

@ -170,8 +170,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
$orbital_count_val = $_POST['orbital_count_val'] !== '' ? (int)$_POST['orbital_count_val'] : null;
$terrestrial_count_op = $_POST['terrestrial_count_op'] ?: null;
$terrestrial_count_val = $_POST['terrestrial_count_val'] !== '' ? (int)$_POST['terrestrial_count_val'] : null;
$orbital_dominance = $_POST['orbital_dominance'] ?: null;
$terrestrial_dominance = $_POST['terrestrial_dominance'] ?: null;
$orbital_dominance = isset($_POST['orbital_dominance']) ? implode(',', (array)$_POST['orbital_dominance']) : null;
$terrestrial_dominance = isset($_POST['terrestrial_dominance']) ? implode(',', (array)$_POST['terrestrial_dominance']) : null;
$is_empty_case = isset($_POST['is_empty_case']) ? 1 : 0;
if ($id > 0) {
@ -551,6 +551,19 @@ if ($tab === 'users') {
/* Color picker custom style */
.color-group { display: flex; gap: 5px; }
.color-picker-input { width: 45px !important; height: 34px !important; padding: 2px !important; border: 1px solid #334155 !important; background: #0f172a !important; cursor: pointer; }
/* Multi-select dropdown */
.ms-container { position: relative; width: 100%; }
.ms-display {
background: #0f172a; border: 1px solid #334155; color: #fff; padding: 8px; cursor: pointer; min-height: 34px; box-sizing: border-box; font-size: 12px; display: flex; align-items: center; justify-content: space-between;
}
.ms-display:after { content: '▼'; font-size: 8px; color: #8c92a3; }
.ms-dropdown {
position: absolute; top: 100%; left: 0; right: 0; background: #1a202c; border: 1px solid #334155; z-index: 1000; display: none; max-height: 200px; overflow-y: auto; padding: 5px;
}
.ms-item { padding: 5px 8px; cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 11px; }
.ms-item:hover { background: #2d3545; }
.ms-item input { width: auto !important; }
</style>
</head>
<body>
@ -955,29 +968,35 @@ if ($tab === 'users') {
</div>
</div>
<div style="display: flex; gap: 15px; align-items: center; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold;">FACTION DOMINANTE :</div>
<div style="display: flex; gap: 15px; align-items: flex-start; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold; padding-top: 5px;">FILTRE DOMINANCE :</div>
<!-- Orbite -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">En Orbite</label>
<select name="orbital_dominance" id="rule_orb_dom">
<option value="">-</option>
<option value="ANY">N'importe laquelle</option>
<option value="NONE">Aucune (Vide)</option>
<?php foreach($factions_list as $f): if($f['name'] !== 'Aucune'): ?>
<option value="<?php echo $f['id']; ?>"><?php echo htmlspecialchars($f['name']); ?></option>
<?php endif; endforeach; ?>
</select>
<div class="ms-container" id="ms_orb">
<div class="ms-display" onclick="toggleMS('ms_orb_list')">Toutes / Peu importe</div>
<div class="ms-dropdown" id="ms_orb_list">
<label class="ms-item"><input type="checkbox" value="none" onchange="updateMSLabel('ms_orb')"> Aucune (Vide)</label>
<?php foreach($factions_list as $f): if($f['name'] !== 'Aucune'): ?>
<label class="ms-item"><input type="checkbox" value="<?php echo $f['id']; ?>" name="orbital_dominance[]" onchange="updateMSLabel('ms_orb')"> <?php echo htmlspecialchars($f['name']); ?></label>
<?php endif; endforeach; ?>
</div>
</div>
</div>
<!-- Sol -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">Au Sol</label>
<select name="terrestrial_dominance" id="rule_terr_dom">
<option value="">-</option>
<option value="ANY">N'importe laquelle</option>
<option value="NONE">Aucune (Vide)</option>
<?php foreach($factions_list as $f): if($f['name'] !== 'Aucune'): ?>
<option value="<?php echo $f['id']; ?>"><?php echo htmlspecialchars($f['name']); ?></option>
<?php endif; endforeach; ?>
</select>
<div class="ms-container" id="ms_terr">
<div class="ms-display" onclick="toggleMS('ms_terr_list')">Toutes / Peu importe</div>
<div class="ms-dropdown" id="ms_terr_list">
<label class="ms-item"><input type="checkbox" value="none" onchange="updateMSLabel('ms_terr')"> Aucune (Vide)</label>
<?php foreach($factions_list as $f): if($f['name'] !== 'Aucune'): ?>
<label class="ms-item"><input type="checkbox" value="<?php echo $f['id']; ?>" name="terrestrial_dominance[]" onchange="updateMSLabel('ms_terr')"> <?php echo htmlspecialchars($f['name']); ?></label>
<?php endif; endforeach; ?>
</div>
</div>
</div>
</div>
@ -1007,8 +1026,8 @@ if ($tab === 'users') {
if($r['is_empty_case']) $conds[] = "Case Vide";
if($r['orbital_count_op']) $conds[] = "Orbital Factions " . $r['orbital_count_op'] . " " . $r['orbital_count_val'];
if($r['terrestrial_count_op']) $conds[] = "Ground Factions " . $r['terrestrial_count_op'] . " " . $r['terrestrial_count_val'];
if($r['orbital_dominance']) $conds[] = "Orbital Dom: " . $r['orbital_dominance'];
if($r['terrestrial_dominance']) $conds[] = "Ground Dom: " . $r['terrestrial_dominance'];
if($r['orbital_dominance']) $conds[] = "Orbital IN (" . $r['orbital_dominance'] . ")";
if($r['terrestrial_dominance']) $conds[] = "Ground IN (" . $r['terrestrial_dominance'] . ")";
echo !empty($conds) ? implode(' AND ', $conds) : '<em>Toujours vrai</em>';
?>
</small>
@ -1290,7 +1309,28 @@ if ($tab === 'users') {
document.getElementById('log_id').value = 0;
document.getElementById('logForm').reset();
}
</script>
function toggleMS(id) {
const d = document.getElementById(id);
d.style.display = d.style.display === 'block' ? 'none' : 'block';
}
function updateMSLabel(containerId) {
const container = document.getElementById(containerId);
const checkboxes = container.querySelectorAll('input[type="checkbox"]:checked');
const display = container.querySelector('.ms-display');
if (checkboxes.length === 0) {
display.innerText = "Toutes / Peu importe";
} else {
const labels = Array.from(checkboxes).map(cb => cb.parentElement.innerText.trim());
display.innerText = labels.join(', ');
}
}
document.addEventListener('click', function(e) {
if (!e.target.closest('.ms-container')) {
document.querySelectorAll('.ms-dropdown').forEach(d => d.style.display = 'none');
}
});
</script>
<?php elseif ($tab === 'lootboxes'): ?>
<h3 style="color: #88c0d0;">Système de Lootboxes</h3>
@ -1484,12 +1524,29 @@ function editStatus(data) {
document.getElementById('rule_orb_val').value = data.orbital_count_val !== null ? data.orbital_count_val : "";
document.getElementById('rule_terr_op').value = data.terrestrial_count_op || "";
document.getElementById('rule_terr_val').value = data.terrestrial_count_val !== null ? data.terrestrial_count_val : "";
document.getElementById('rule_orb_dom').value = data.orbital_dominance || "";
document.getElementById('rule_terr_dom').value = data.terrestrial_dominance || "";
// Set multi-selects
const orbVals = (data.orbital_dominance || "").split(",");
document.querySelectorAll('#ms_orb_list input').forEach(cb => {
cb.checked = orbVals.includes(cb.value);
});
updateMSLabel('ms_orb');
const terrVals = (data.terrestrial_dominance || "").split(",");
document.querySelectorAll('#ms_terr_list input').forEach(cb => {
cb.checked = terrVals.includes(cb.value);
});
updateMSLabel('ms_terr');
document.getElementById('rule_empty').checked = data.is_empty_case == 1;
window.scrollTo(0,0);
}
function resetRuleForm() { document.getElementById('ruleForm').reset(); document.getElementById('rule_id').value = 0; }
function resetRuleForm() {
document.getElementById('ruleForm').reset();
document.getElementById('rule_id').value = 0;
updateMSLabel('ms_orb');
updateMSLabel('ms_terr');
}
function editSettlementType(data) {
document.getElementById('set_t_id').value = data.id;
@ -1651,6 +1708,27 @@ function editStatus(data) {
if (document.getElementById('items_container').children.length === 0) addItemRow();
};
<?php endif; ?>
</script>
function toggleMS(id) {
const d = document.getElementById(id);
d.style.display = d.style.display === 'block' ? 'none' : 'block';
}
function updateMSLabel(containerId) {
const container = document.getElementById(containerId);
const checkboxes = container.querySelectorAll('input[type="checkbox"]:checked');
const display = container.querySelector('.ms-display');
if (checkboxes.length === 0) {
display.innerText = "Toutes / Peu importe";
} else {
const labels = Array.from(checkboxes).map(cb => cb.parentElement.innerText.trim());
display.innerText = labels.join(', ');
}
}
document.addEventListener('click', function(e) {
if (!e.target.closest('.ms-container')) {
document.querySelectorAll('.ms-dropdown').forEach(d => d.style.display = 'none');
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<?php
require_once __DIR__ . '/config.php';
$db = db();
try {
// Ensuring the columns can hold multiple IDs
$db->exec("ALTER TABLE celestial_object_status_rules MODIFY COLUMN orbital_dominance TEXT NULL");
$db->exec("ALTER TABLE celestial_object_status_rules MODIFY COLUMN terrestrial_dominance TEXT NULL");
// Migration: ensure we handle ANY and IN/NOT IN appropriately
// Actually, I'll just use these two columns to store comma-separated IDs now.
echo "Columns modified successfully.\n";
} catch (PDOException $e) {
echo "Error: " . $e->getMessage() . "\n";
}

13
fix_admin_table.php Normal file
View File

@ -0,0 +1,13 @@
<?php
$content = file_get_contents('admin.php');
// Fix double div from previous patch if any
$content = str_replace(" </div>\n </div>\n </div>\n </div>", " </div>\n </div>", $content);
// Correct table display logic
$content = preg_replace('/if(\$r[\'orbital_dominance_mode\'].*?Orbital.*?;/s', 'if(!empty($r[\'orbital_dominant_factions\'])) $conds[] = "Orbital IN (" . $r[\'orbital_dominant_factions\'] . ")";', $content);
$content = preg_replace('/if(\$r[\'terrestrial_dominance_mode\'].*?Ground.*?;/s', 'if(!empty($r[\'ground_dominant_factions\'])) $conds[] = "Ground IN (" . $r[\'ground_dominant_factions\'] . ")";', $content);
file_put_contents('admin.php', $content);
echo "admin.php table logic fixed.\n";

14
fix_admin_table_v2.php Normal file
View File

@ -0,0 +1,14 @@
<?php
$content = file_get_contents('admin.php');
$oldOrb = 'if($r[\'orbital_dominance_mode\'] !== \'ANY\') $conds[] = "Orbital " . $r[\'orbital_dominance_mode\'] . " [...]"';
$newOrb = 'if(!empty($r[\'orbital_dominant_factions\'])) $conds[] = "Orbital IN (" . $r[\'orbital_dominant_factions\'] . ")"';
$content = str_replace($oldOrb, $newOrb, $content);
$oldTerr = 'if($r[\'terrestrial_dominance_mode\'] !== \'ANY\') $conds[] = "Ground " . $r[\'terrestrial_dominance_mode\'] . " [...]"';
$newTerr = 'if(!empty($r[\'ground_dominant_factions\'])) $conds[] = "Ground IN (" . $r[\'ground_dominant_factions\'] . ")"';
$content = str_replace($oldTerr, $newTerr, $content);
file_put_contents('admin.php', $content);
echo "admin.php table logic fixed via str_replace.\n";

View File

@ -58,10 +58,6 @@ function calculateCelestialStatus($planet, $db, $statuses_map) {
// Condition Case Vide
if ($rule['is_empty_case'] && !$is_empty) $match = false;
if ($match && !$rule['is_empty_case'] && $is_empty && ($rule['orbital_count_op'] || $rule['terrestrial_count_op'] || $rule['orbital_dominance'] || $rule['terrestrial_dominance'])) {
// Si la règle n'est pas "case vide" mais qu'on a d'autres conditions et que c'est vide, ça ne matchera probablement pas
// Sauf si les conditions acceptent 0. On laisse la suite gérer.
}
// Condition Nombre Factions Orbite
if ($match && $rule['orbital_count_op']) {
@ -73,26 +69,33 @@ function calculateCelestialStatus($planet, $db, $statuses_map) {
$match = evaluateOperator($terr_count, $rule['terrestrial_count_op'], $rule['terrestrial_count_val']);
}
// Condition Dominance Orbite
if ($match && $rule['orbital_dominance']) {
if ($rule['orbital_dominance'] === 'ANY') {
if (!$orb_dom) $match = false;
} elseif ($rule['orbital_dominance'] === 'NONE') {
if ($orb_dom) $match = false;
// Condition Dominance Orbite (Multi-select)
if ($match && !empty($rule['orbital_dominant_factions'])) {
$allowed = explode(',', $rule['orbital_dominant_factions']);
$isIn = false;
if (!$orb_dom) {
if (in_array('none', $allowed)) $isIn = true;
} else {
if ($orb_dom != $rule['orbital_dominance']) $match = false;
if (in_array((string)$orb_dom, $allowed)) $isIn = true;
}
if (!$isIn) $match = false;
}
// Condition Dominance Sol
if ($match && $rule['terrestrial_dominance']) {
if ($rule['terrestrial_dominance'] === 'ANY') {
if (!$terr_dom) $match = false;
} elseif ($rule['terrestrial_dominance'] === 'NONE') {
if ($terr_dom) $match = false;
// Condition Dominance Sol (Multi-select)
if ($match && !empty($rule['ground_dominant_factions'])) {
$allowed = explode(',', $rule['ground_dominant_factions']);
$isIn = false;
if (!$terr_dom) {
if (in_array('none', $allowed)) $isIn = true;
} else {
if ($terr_dom != $rule['terrestrial_dominance']) $match = false;
if (in_array((string)$terr_dom, $allowed)) $isIn = true;
}
if (!$isIn) $match = false;
}
// Condition Croisée
if ($match && ($rule['dominance_diff_required'] ?? 0)) {
if ($orb_dom == $terr_dom) $match = false;
}
if ($match) {
@ -114,4 +117,4 @@ function evaluateOperator($val, $op, $target) {
case '!=': return $val != $target;
}
return true;
}
}

285
patch_admin_minimal.php Normal file
View File

@ -0,0 +1,285 @@
<?php
$admin_path = 'admin.php';
$content = file_get_contents($admin_path);
// 1. Add CSS
$css = <<<'EOD'
/* Multi-select Dropdown */
.multi-select-dropdown { position: relative; width: 100%; }
.multi-select-btn { width: 100%; padding: 8px 10px; background: #0f172a; border: 1px solid #334155; border-radius: 4px; color: #eceff4; text-align: left; cursor: pointer; font-size: 13px; display: flex; justify-content: space-between; align-items: center; box-sizing: border-box; }
.multi-select-menu { position: absolute; top: 100%; left: 0; right: 0; z-index: 1000; background: #1e293b; border: 1px solid #334155; border-radius: 4px; margin-top: 5px; display: none; max-height: 250px; overflow-y: auto; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); }
.multi-select-menu.show { display: block; }
.multi-select-header { padding: 8px 10px; border-bottom: 1px solid #334155; display: flex; gap: 10px; background: #0f172a; position: sticky; top: 0; z-index: 10; }
.multi-select-header button { background: none; border: none; color: #88c0d0; font-size: 10px; cursor: pointer; padding: 0; text-transform: uppercase; font-weight: bold; }
.multi-select-header button:hover { text-decoration: underline; }
.multi-select-option { padding: 6px 10px; display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 12px; }
.multi-select-option:hover { background: #334155; }
.multi-select-option input { width: auto !important; margin: 0; cursor: pointer; }
EOD;
if (strpos($content, '/* Multi-select Dropdown */') === false) {
$content = str_replace('</style>', $css . ' </style>', $content);
}
// 2. Update POST Handler
$new_rule_handler = <<<'EOD'
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_status_rule') {
$id = (int)$_POST['id'];
$name = $_POST['name'];
$status_id = (int)$_POST['status_id'];
$profile_id = (int)$_POST['profile_id'];
$priority = (int)$_POST['priority'];
$orbital_count_op = $_POST['orbital_count_op'] ?: null;
$orbital_count_val = $_POST['orbital_count_val'] !== '' ? (int)$_POST['orbital_count_val'] : null;
$terrestrial_count_op = $_POST['terrestrial_count_op'] ?: null;
$terrestrial_count_val = $_POST['terrestrial_count_val'] !== '' ? (int)$_POST['terrestrial_count_val'] : null;
// Multi-select Factions logic
$orb_factions = $_POST['orbital_dominant_factions'] ?? [];
$terr_factions = $_POST['ground_dominant_factions'] ?? [];
// If "any" is in the list, we clear the list to mean "no filter"
if (in_array('any', $orb_factions)) $orb_factions = [];
if (in_array('any', $terr_factions)) $terr_factions = [];
$orbital_dominance = !empty($orb_factions) ? implode(',', $orb_factions) : null;
$terrestrial_dominance = !empty($terr_factions) ? implode(',', $terr_factions) : null;
$is_empty_case = isset($_POST['is_empty_case']) ? 1 : 0;
// V2 Compat
$orbital_dominance_mode = $orbital_dominance ? 'IN' : 'ANY';
$terrestrial_dominance_mode = $terrestrial_dominance ? 'IN' : 'ANY';
$orbital_dominance_factions = $orbital_dominance;
$terrestrial_dominance_factions = $terrestrial_dominance;
$orbital_dominance_include_none = (is_array($orb_factions) && in_array('none', $orb_factions)) ? 1 : 0;
$orbital_dominance_include_player = (is_array($orb_factions) && in_array('2', $orb_factions)) ? 1 : 0;
$terrestrial_dominance_include_none = (is_array($terr_factions) && in_array('none', $terr_factions)) ? 1 : 0;
$terrestrial_dominance_include_player = (is_array($terr_factions) && in_array('2', $terr_factions)) ? 1 : 0;
$dominance_diff_required = 0;
if ($id > 0) {
$stmt = $db->prepare("UPDATE celestial_object_status_rules SET name = ?, status_id = ?, profile_id = ?, priority = ?, orbital_count_op = ?, orbital_count_val = ?, terrestrial_count_op = ?, terrestrial_count_val = ?, orbital_dominance = ?, terrestrial_dominance = ?, is_empty_case = ?, orbital_dominance_mode = ?, orbital_dominance_factions = ?, orbital_dominance_include_none = ?, orbital_dominance_include_player = ?, terrestrial_dominance_mode = ?, terrestrial_dominance_factions = ?, terrestrial_dominance_include_none = ?, terrestrial_dominance_include_player = ?, dominance_diff_required = ? WHERE id = ?");
$stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominance, $terrestrial_dominance, $is_empty_case, $orbital_dominance_mode, $orbital_dominance_factions, $orbital_dominance_include_none, $orbital_dominance_include_player, $terrestrial_dominance_mode, $terrestrial_dominance_factions, $terrestrial_dominance_include_none, $terrestrial_dominance_include_player, $dominance_diff_required, $id]);
} else {
$stmt = $db->prepare("INSERT INTO celestial_object_status_rules (name, status_id, profile_id, priority, orbital_count_op, orbital_count_val, terrestrial_count_op, terrestrial_count_val, orbital_dominance, terrestrial_dominance, is_empty_case, orbital_dominance_mode, orbital_dominance_factions, orbital_dominance_include_none, orbital_dominance_include_player, terrestrial_dominance_mode, terrestrial_dominance_factions, terrestrial_dominance_include_none, terrestrial_dominance_include_player, dominance_diff_required) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominance, $terrestrial_dominance, $is_empty_case, $orbital_dominance_mode, $orbital_dominance_factions, $orbital_dominance_include_none, $orbital_dominance_include_player, $terrestrial_dominance_mode, $terrestrial_dominance_factions, $terrestrial_dominance_include_none, $terrestrial_dominance_include_player, $dominance_diff_required]);
}
header("Location: admin.php?tab=statuses&success=1");
exit;
EOD;
$content = preg_replace('/if \(\$_SERVER\[\'REQUEST_METHOD\'\] === \'POST\' && isset\(\$_POST\[\'action\'\]\) && \$_POST\[\'action\'\] === \'upsert_status_rule\'\) \{.*?header\(\"Location: admin\.php\?tab=statuses&success=1\"\);\n exit;/s', $new_rule_handler, $content);
// 3. Update UI Form
$new_ui = <<<'EOD'
<div style="display: flex; gap: 15px; align-items: flex-start; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold; padding-top: 5px;">FACTION DOMINANTE :</div>
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">En Orbite</label>
<div class="multi-select-dropdown" id="orb_dom_container">
<div class="multi-select-btn" id="orb-factions-btn" onclick="toggleMultiSelect('orb-factions')">
N'importe laquelle <i class="fa-solid fa-chevron-down"></i>
</div>
<div class="multi-select-menu" id="orb-factions-menu">
<div class="multi-select-header">
<button type="button" onclick="selectAllMultiSelect('orb-factions', true)">Tout sélectionner</button>
<button type="button" onclick="selectAllMultiSelect('orb-factions', false)">Tout désélectionner</button>
</div>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="orbital_dominant_factions[]" value="any" class="orb-factions-checkbox any-option" data-label="N'importe laquelle" onchange="handleAnyOption('orb-factions', this)">
<span>N'importe laquelle</span>
</div>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="orbital_dominant_factions[]" value="none" class="orb-factions-checkbox" data-label="Aucune (Vide)" onchange="updateMultiSelectDisplay('orb-factions')">
<span>Aucune (Vide)</span>
</div>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="orbital_dominant_factions[]" value="2" class="orb-factions-checkbox" data-label="Joueur (Terrien)" onchange="updateMultiSelectDisplay('orb-factions')">
<span>Joueur (Terrien)</span>
</div>
<hr style="border: 0; border-top: 1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f): if($f['id'] > 2): ?>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="orbital_dominant_factions[]" value="<?php echo $f['id']; ?>" class="orb-factions-checkbox" data-label="<?php echo htmlspecialchars($f['name']); ?>" onchange="updateMultiSelectDisplay('orb-factions')">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</div>
<?php endif; endforeach; ?>
</div>
</div>
</div>
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">Au Sol</label>
<div class="multi-select-dropdown" id="terr_dom_container">
<div class="multi-select-btn" id="terr-factions-btn" onclick="toggleMultiSelect('terr-factions')">
N'importe laquelle <i class="fa-solid fa-chevron-down"></i>
</div>
<div class="multi-select-menu" id="terr-factions-menu">
<div class="multi-select-header">
<button type="button" onclick="selectAllMultiSelect('terr-factions', true)">Tout sélectionner</button>
<button type="button" onclick="selectAllMultiSelect('terr-factions', false)">Tout désélectionner</button>
</div>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="ground_dominant_factions[]" value="any" class="terr-factions-checkbox any-option" data-label="N'importe laquelle" onchange="handleAnyOption('terr-factions', this)">
<span>N'importe laquelle</span>
</div>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="ground_dominant_factions[]" value="none" class="terr-factions-checkbox" data-label="Aucune (Vide)" onchange="updateMultiSelectDisplay('terr-factions')">
<span>Aucune (Vide)</span>
</div>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="ground_dominant_factions[]" value="2" class="terr-factions-checkbox" data-label="Joueur (Terrien)" onchange="updateMultiSelectDisplay('terr-factions')">
<span>Joueur (Terrien)</span>
</div>
<hr style="border: 0; border-top: 1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f): if($f['id'] > 2): ?>
<div class="multi-select-option" onclick="toggleCheckbox(event, this)">
<input type="checkbox" name="ground_dominant_factions[]" value="<?php echo $f['id']; ?>" class="terr-factions-checkbox" data-label="<?php echo htmlspecialchars($f['name']); ?>" onchange="updateMultiSelectDisplay('terr-factions')">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</div>
<?php endif; endforeach; ?>
</div>
</div>
</div>
</div>
<div style="display: flex; align-items: center; gap: 20px; padding-top: 10px; border-top: 1px solid #334155;">
<div style="display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="is_empty_case" id="rule_empty" style="width: auto;">
<label for="rule_empty" style="margin-bottom: 0; color: #ebcb8b; font-size: 11px;">Cas "CASE VIDE"</label>
</div>
</div>
EOD;
// Need to match exactly the old UI to replace it
$old_ui_regex = '/<div style="display: flex; gap: 15px; align-items: flex-start; margin-bottom: 10px;">.*?FILTRE DOMINANCE :.*?Cas \"CASE VIDE\".*?<\/div>.*?<\/div>/s';
// Actually, I'll use str_replace for blocks I know are there
// I'll read admin.php around the UI block to be 100% sure of the string.
$js_additions = <<<'EOD'
function toggleMultiSelect(id) {
const menu = document.getElementById(id + '-menu');
if(!menu) return;
menu.classList.toggle('show');
const closer = function(e) {
if (!e.target.closest('.multi-select-dropdown')) {
menu.classList.remove('show');
document.removeEventListener('click', closer);
}
};
setTimeout(() => document.addEventListener('click', closer), 0);
}
function toggleCheckbox(e, element) {
if (e.target.tagName === 'INPUT') return;
const cb = element.querySelector('input[type="checkbox"]');
if(cb) {
cb.checked = !cb.checked;
cb.dispatchEvent(new Event('change'));
}
}
function handleAnyOption(id, anyCb) {
if (anyCb.checked) {
document.querySelectorAll('.' + id + '-checkbox:not(.any-option)').forEach(cb => cb.checked = false);
}
updateMultiSelectDisplay(id);
}
function updateMultiSelectDisplay(id) {
const checkboxes = document.querySelectorAll('.' + id + '-checkbox');
const btn = document.getElementById(id + '-btn');
if(!btn) return;
const anyOption = document.querySelector('.' + id + '-checkbox.any-option');
const selected = [];
let hasSelection = false;
checkboxes.forEach(cb => {
if (cb.checked && !cb.classList.contains('any-option')) {
selected.push(cb.dataset.label);
hasSelection = true;
}
});
if (hasSelection && anyOption) anyOption.checked = false;
if (selected.length === 0) {
btn.innerHTML = 'N\'importe laquelle <i class="fa-solid fa-chevron-down"></i>';
} else {
if (selected.length > 2) {
btn.innerHTML = selected.length + ' sélectionné(s) <i class="fa-solid fa-chevron-down"></i>';
} else {
btn.innerHTML = selected.join(', ') + ' <i class="fa-solid fa-chevron-down"></i>';
}
}
}
function selectAllMultiSelect(id, selectAll) {
document.querySelectorAll('.' + id + '-checkbox').forEach(cb => {
if (cb.classList.contains('any-option')) {
cb.checked = !selectAll;
} else {
cb.checked = selectAll;
}
});
updateMultiSelectDisplay(id);
}
EOD;
if (strpos($content, 'function toggleMultiSelect') === false) {
$content = str_replace('// --- LOOTBOX SYSTEM ---', $js_additions . "\n\n" . ' // --- LOOTBOX SYSTEM ---', $content);
}
// Re-do the editRule replacement more carefully
$content = preg_replace('/document\.getElementById\(\'rule_orb_op\'\)\.value = data\.orbital_count_op \|\| \"\";.*document\.getElementById\(\'rule_empty\'\)\.checked = data\.is_empty_case == 1;/s',
'document.getElementById(\'rule_orb_op\').value = data.orbital_count_op || "";
document.getElementById(\'rule_orb_val\').value = data.orbital_count_val !== null ? data.orbital_count_val : "";
document.getElementById(\'rule_terr_op\').value = data.terrestrial_count_op || "";
document.getElementById(\'rule_terr_val\').value = data.terrestrial_count_val !== null ? data.terrestrial_count_val : "";
// Populate Multi-selects
const orbVals = (data.orbital_dominance || "").split(",");
document.querySelectorAll(\'.orb-factions-checkbox\').forEach(cb => {
cb.checked = orbVals.includes(cb.value);
});
const anyOrb = document.querySelector(\'.orb-factions-checkbox.any-option\');
if (anyOrb && (orbVals.length === 0 || orbVals[0] === "")) anyOrb.checked = true;
updateMultiSelectDisplay(\'orb-factions\');
const terrVals = (data.terrestrial_dominance || "").split(",");
document.querySelectorAll(\'.terr-factions-checkbox\').forEach(cb => {
cb.checked = terrVals.includes(cb.value);
});
const anyTerr = document.querySelector(\'.terr-factions-checkbox.any-option\');
if (anyTerr && (terrVals.length === 0 || terrVals[0] === "")) anyTerr.checked = true;
updateMultiSelectDisplay(\'terr-factions\');
document.getElementById(\'rule_empty\').checked = data.is_empty_case == 1;', $content);
$content = str_replace('document.getElementById(\'ruleForm\').reset(); document.getElementById(\'rule_id\').value = 0;',
'document.getElementById(\'ruleForm\').reset();
document.getElementById(\'rule_id\').value = 0;
selectAllMultiSelect(\'orb-factions\', false);
selectAllMultiSelect(\'terr-factions\', false);
const anyOrbForm = document.querySelector(\'.orb-factions-checkbox.any-option\');
if(anyOrbForm) anyOrbForm.checked = true;
const anyTerrForm = document.querySelector(\'.terr-factions-checkbox.any-option\');
if(anyTerrForm) anyTerrForm.checked = true;
updateMultiSelectDisplay(\'orb-factions\');
updateMultiSelectDisplay(\'terr-factions\');', $content);
// Final UI swap (Manual block replace to be safe)
// I'll search for specific markers in UI
$start_marker = '<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold; padding-top: 5px;">FILTRE DOMINANCE :</div>';
$end_marker = '<label for="rule_diff" style="margin-bottom: 0; color: #a3be8c; font-size: 11px;">Dominante orbite Dominante sol</label>
</div>
</div>';
// Find the parent containers
// I'll just use the preg_replace on handler and table as they worked.
// For UI I will use a very specific string replace of the whole block.
file_put_contents($admin_path, $content);
echo "Admin patched successfully.";

240
patch_admin_v4.php Normal file
View File

@ -0,0 +1,240 @@
<?php
require_once 'db/config.php';
$db = db();
// Update Handler
$handler_code = <<<'PHP'
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_status_rule') {
$id = (int)$_POST['id'];
$name = $_POST['name'];
$status_id = (int)$_POST['status_id'];
$profile_id = (int)$_POST['profile_id'];
$priority = (int)$_POST['priority'];
$orbital_count_op = $_POST['orbital_count_op'] ?: null;
$orbital_count_val = $_POST['orbital_count_val'] !== '' ? (int)$_POST['orbital_count_val'] : null;
$terrestrial_count_op = $_POST['terrestrial_count_op'] ?: null;
$terrestrial_count_val = $_POST['terrestrial_count_val'] !== '' ? (int)$_POST['terrestrial_count_val'] : null;
// Multi-select Factions logic
$orb_factions = $_POST['orbital_dominant_factions'] ?? [];
$terr_factions = $_POST['ground_dominant_factions'] ?? [];
// If "any" is in the list, we clear the list to mean "no filter"
if (in_array('any', $orb_factions)) $orb_factions = [];
if (in_array('any', $terr_factions)) $terr_factions = [];
$orbital_dominant_factions = !empty($orb_factions) ? implode(',', $orb_factions) : null;
$ground_dominant_factions = !empty($terr_factions) ? implode(',', $terr_factions) : null;
$is_empty_case = isset($_POST['is_empty_case']) ? 1 : 0;
$dominance_diff_required = isset($_POST['dominance_diff_required']) ? 1 : 0;
if ($id > 0) {
$stmt = $db->prepare("UPDATE celestial_object_status_rules SET name = ?, status_id = ?, profile_id = ?, priority = ?, orbital_count_op = ?, orbital_count_val = ?, terrestrial_count_op = ?, terrestrial_count_val = ?, orbital_dominant_factions = ?, ground_dominant_factions = ?, is_empty_case = ?, dominance_diff_required = ? WHERE id = ?");
$stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominant_factions, $ground_dominant_factions, $is_empty_case, $dominance_diff_required, $id]);
} else {
$stmt = $db->prepare("INSERT INTO celestial_object_status_rules (name, status_id, profile_id, priority, orbital_count_op, orbital_count_val, terrestrial_count_op, terrestrial_count_val, orbital_dominant_factions, ground_dominant_factions, is_empty_case, dominance_diff_required) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominant_factions, $ground_dominant_factions, $is_empty_case, $dominance_diff_required]);
}
header("Location: admin.php?tab=statuses&success=1");
exit;
}
PHP;
// Update UI
$new_ui = <<<'HTML'
<div style="display: flex; gap: 15px; align-items: flex-start; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold; padding-top: 5px;">FILTRE DOMINANCE :</div>
<!-- ORBITAL MULTI-SELECT -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">En Orbite</label>
<div class="multi-select-dropdown" id="orb_ms">
<div class="multi-select-btn" id="orb_btn" onclick="toggleMS('orb')">N'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i></div>
<div class="multi-select-menu" id="orb_menu">
<div class="multi-select-header">
<button type="button" onclick="msAll('orb', true)">Tout sélectionner</button>
<button type="button" onclick="msAll('orb', false)">Tout désélectionner</button>
</div>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="any" id="orb_any" checked onchange="handleMSChange(this, 'orb', true)">
<span>N'importe laquelle</span>
</label>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="none" class="orb-cb" data-name="Aucune" onchange="handleMSChange(this, 'orb', false)">
<span>Aucune (Vide)</span>
</label>
<hr style="border:0; border-top:1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f): ?>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="<?php echo $f['id']; ?>" class="orb-cb" data-name="<?php echo htmlspecialchars($f['name']); ?>" onchange="handleMSChange(this, 'orb', false)">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
<!-- GROUND MULTI-SELECT -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">Au Sol</label>
<div class="multi-select-dropdown" id="terr_ms">
<div class="multi-select-btn" id="terr_btn" onclick="toggleMS('terr')">N'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i></div>
<div class="multi-select-menu" id="terr_menu">
<div class="multi-select-header">
<button type="button" onclick="msAll('terr', true)">Tout sélectionner</button>
<button type="button" onclick="msAll('terr', false)">Tout désélectionner</button>
</div>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="any" id="terr_any" checked onchange="handleMSChange(this, 'terr', true)">
<span>N'importe laquelle</span>
</label>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="none" class="terr-cb" data-name="Aucune" onchange="handleMSChange(this, 'terr', false)">
<span>Aucune (Vide)</span>
</label>
<hr style="border:0; border-top:1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f): ?>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="<?php echo $f['id']; ?>" class="terr-cb" data-name="<?php echo htmlspecialchars($f['name']); ?>" onchange="handleMSChange(this, 'terr', false)">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
HTML;
// Update JS
$js_code = <<<'JS'
function toggleMS(id) {
const menu = document.getElementById(id + '_menu');
const isVisible = menu.classList.contains('show');
document.querySelectorAll('.multi-select-menu').forEach(m => m.classList.remove('show'));
if (!isVisible) menu.classList.add('show');
}
document.addEventListener('click', function(e) {
if (!e.target.closest('.multi-select-dropdown')) {
document.querySelectorAll('.multi-select-menu').forEach(m => m.classList.remove('show'));
}
});
function updateMSLabel(prefix) {
const any = document.getElementById(prefix + '_any');
const cbs = document.querySelectorAll('.' + prefix + '-cb:checked');
const btn = document.getElementById(prefix + '_btn');
if (any && any.checked) {
btn.innerHTML = 'N\'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i>';
} else if (cbs.length === 0) {
if(any) any.checked = true;
btn.innerHTML = 'N\'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i>';
} else {
const names = Array.from(cbs).map(c => c.dataset.name);
if (names.length > 2) btn.innerHTML = names.length + ' sélectionnés <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i>';
else btn.innerHTML = names.join(', ') + ' <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i>';
}
}
function handleMSChange(cb, prefix, isAny) {
const any = document.getElementById(prefix + '_any');
const others = document.querySelectorAll('.' + prefix + '-cb');
if (isAny && cb.checked) {
others.forEach(o => o.checked = false);
} else if (!isAny && cb.checked) {
if(any) any.checked = false;
}
updateMSLabel(prefix);
}
function msAll(prefix, state) {
const any = document.getElementById(prefix + '_any');
const others = document.querySelectorAll('.' + prefix + '-cb');
if (state) {
if(any) any.checked = false;
others.forEach(o => o.checked = true);
} else {
others.forEach(o => o.checked = false);
if(any) any.checked = true;
}
updateMSLabel(prefix);
}
function editRule(data) {
document.getElementById('rule_id').value = data.id;
document.getElementById('rule_name').value = data.name;
document.getElementById('rule_profile_id').value = data.profile_id || "";
document.getElementById('rule_status_id').value = data.status_id;
document.getElementById('rule_priority').value = data.priority || 0;
document.getElementById('rule_orb_op').value = data.orbital_count_op || "";
document.getElementById('rule_orb_val').value = data.orbital_count_val !== null ? data.orbital_count_val : "";
document.getElementById('rule_terr_op').value = data.terrestrial_count_op || "";
document.getElementById('rule_terr_val').value = data.terrestrial_count_val !== null ? data.terrestrial_count_val : "";
// Orbital Multi-select
const orbFactions = (data.orbital_dominant_factions || "").split(',').filter(x => x);
msAll('orb', false);
if (orbFactions.length === 0) {
document.getElementById('orb_any').checked = true;
} else {
document.getElementById('orb_any').checked = false;
orbFactions.forEach(val => {
const cb = document.querySelector(`.orb-cb[value="${val}"]`);
if(cb) cb.checked = true;
});
}
updateMSLabel('orb');
// Ground Multi-select
const terrFactions = (data.ground_dominant_factions || "").split(',').filter(x => x);
msAll('terr', false);
if (terrFactions.length === 0) {
document.getElementById('terr_any').checked = true;
} else {
document.getElementById('terr_any').checked = false;
terrFactions.forEach(val => {
const cb = document.querySelector(`.terr-cb[value="${val}"]`);
if(cb) cb.checked = true;
});
}
updateMSLabel('terr');
document.getElementById('rule_empty').checked = data.is_empty_case == 1;
document.getElementById('rule_diff').checked = data.dominance_diff_required == 1;
window.scrollTo(0,0);
}
function resetRuleForm() {
document.getElementById('ruleForm').reset();
document.getElementById('rule_id').value = 0;
msAll('orb', false);
msAll('terr', false);
}
JS;
// Apply changes to admin.php
$content = file_get_contents('admin.php');
// Handler
$content = preg_replace('/if \(\$_SERVER\[\'REQUEST_METHOD\'\] === \'POST\' && isset\(\$_POST\[\'action\'\]\) && \$_POST\[\'action\'\] === \'upsert_status_rule\'\) \{.*?header\(\"Location: admin\.php\?tab=statuses&success=1\"\);\n exit;/s', $handler_code, $content);
// UI
$content = preg_replace('/<div style=\"display: flex; gap: 15px; align-items: flex-start; margin-bottom: 10px;\">.*?FILTRE DOMINANCE :.*?Cas \"CASE VIDE\".*?<\/div>.*?<\/div>/s', $new_ui . "\n" . ' <div style="display: flex; align-items: center; gap: 20px; padding-top: 10px; border-top: 1px solid #334155;">
<div style="display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="is_empty_case" id="rule_empty" style="width: auto;">
<label for="rule_empty" style="margin-bottom: 0; color: #ebcb8b; font-size: 11px;">Cas "CASE VIDE"</label>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="dominance_diff_required" id="rule_diff" style="width: auto;">
<label for="rule_diff" style="margin-bottom: 0; color: #a3be8c; font-size: 11px;">Dominante orbite Dominante sol</label>
</div>
</div>
</div>', $content);
// JS
$content = preg_replace('/function editRule\(data\) \{.*?function resetSettlementTypeForm\(\) \{.*?\}/s', $js_code . "\n\n function editSettlementType(data) {\n document.getElementById('set_t_id').value = data.id;\n document.getElementById('set_t_name').value = data.name;\n document.getElementById('set_t_slug').value = data.slug;\n document.getElementById('set_t_desc').value = data.description;\n window.scrollTo(0,0);\n }\n function resetSettlementTypeForm() { document.getElementById('settlementTypeForm').reset(); document.getElementById('set_t_id').value = 0; }", $content);
// Table Display - use preg_quote for exact matches or simplified regex
$content = preg_replace('/if\(\$r\[\'orbital_dominance_mode\'\] !== \'ANY\'\) \$conds\[\] = \"Orbital \" \. \$r\[\'orbital_dominance_mode\'\] \. \" \\\[\.\.\.\\\]\";/s', 'if($r[\'orbital_dominant_factions\']) $conds[] = "Orbital IN (" . $r[\'orbital_dominant_factions\'] . ")";', $content);
$content = preg_replace('/if\(\$r\[\'terrestrial_dominance_mode\'\] !== \'ANY\'\) \$conds\[\] = \"Ground \" \. \$r\[\'terrestrial_dominance_mode\'\] \. \" \\\[\.\.\.\\\]\";/s', 'if($r[\'ground_dominant_factions\']) $conds[] = "Ground IN (" . $r[\'ground_dominant_factions\'] . ")";', $content);
file_put_contents('admin.php', $content);
echo "admin.php updated.\n";

24
patch_css.php Normal file
View File

@ -0,0 +1,24 @@
<?php
$file = 'admin.php';
$content = file_get_contents($file);
$css = "
/* Multi-select dropdown */
.ms-container { position: relative; width: 100%; }
.ms-display {
background: #0f172a; border: 1px solid #334155; color: #fff; padding: 8px; cursor: pointer; min-height: 34px; box-sizing: border-box; font-size: 12px; display: flex; align-items: center; justify-content: space-between;
}
.ms-display:after { content: '▼'; font-size: 8px; color: #8c92a3; }
.ms-dropdown {
position: absolute; top: 100%; left: 0; right: 0; background: #1a202c; border: 1px solid #334155; z-index: 1000; display: none; max-height: 200px; overflow-y: auto; padding: 5px;
}
.ms-item { padding: 5px 8px; cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 11px; }
.ms-item:hover { background: #2d3545; }
.ms-item input { width: auto !important; }
</style>";
$content = str_replace(' </style>', $css, $content);
file_put_contents($file, $content);
echo "CSS patched";
?>

17
patch_handler_v2.php Normal file
View File

@ -0,0 +1,17 @@
<?php
$file = 'admin.php';
$content = file_get_contents($file);
$oldLogic = ' $orbital_dominance = $_POST[\'orbital_dominance\'] ?: null;
$terrestrial_dominance = $_POST[\'terrestrial_dominance\'] ?: null;';
$newLogic = <<<'EOD'
$orbital_dominance = isset($_POST['orbital_dominance']) ? implode(',', (array)$_POST['orbital_dominance']) : null;
$terrestrial_dominance = isset($_POST['terrestrial_dominance']) ? implode(',', (array)$_POST['terrestrial_dominance']) : null;
EOD;
$content = str_replace($oldLogic, $newLogic, $content);
file_put_contents($file, $content);
echo "Handler patched";
?>

61
patch_js.php Normal file
View File

@ -0,0 +1,61 @@
<?php
$content = file_get_contents('admin.php');
$newJs = <<<'JS'
function editRule(data) {
document.getElementById('rule_id').value = data.id;
document.getElementById('rule_name').value = data.name;
document.getElementById('rule_profile_id').value = data.profile_id || "";
document.getElementById('rule_status_id').value = data.status_id;
document.getElementById('rule_priority').value = data.priority || 0;
document.getElementById('rule_orb_op').value = data.orbital_count_op || "";
document.getElementById('rule_orb_val').value = data.orbital_count_val !== null ? data.orbital_count_val : "";
document.getElementById('rule_terr_op').value = data.terrestrial_count_op || "";
document.getElementById('rule_terr_val').value = data.terrestrial_count_val !== null ? data.terrestrial_count_val : "";
// Orbital Multi-select
const orbFactions = (data.orbital_dominant_factions || "").split(',').filter(x => x);
msAll('orb', false);
if (orbFactions.length === 0) {
document.getElementById('orb_any').checked = true;
} else {
document.getElementById('orb_any').checked = false;
orbFactions.forEach(val => {
const cb = document.querySelector(`.orb-cb[value="${val}"]`);
if(cb) cb.checked = true;
});
}
updateMSLabel('orb');
// Ground Multi-select
const terrFactions = (data.ground_dominant_factions || "").split(',').filter(x => x);
msAll('terr', false);
if (terrFactions.length === 0) {
document.getElementById('terr_any').checked = true;
} else {
document.getElementById('terr_any').checked = false;
terrFactions.forEach(val => {
const cb = document.querySelector(`.terr-cb[value="${val}"]`);
if(cb) cb.checked = true;
});
}
updateMSLabel('terr');
document.getElementById('rule_empty').checked = data.is_empty_case == 1;
if(document.getElementById('rule_diff')) document.getElementById('rule_diff').checked = data.dominance_diff_required == 1;
window.scrollTo(0,0);
}
function resetRuleForm() {
document.getElementById('ruleForm').reset();
document.getElementById('rule_id').value = 0;
msAll('orb', false);
msAll('terr', false);
}
JS;
$content = preg_replace('/function editRule\(data\) \{.*?function resetRuleForm\(\)\{.*?\}/s', $newJs, $content);
file_put_contents('admin.php', $content);
echo "editRule and resetRuleForm updated.\n";

32
patch_js_v2.php Normal file
View File

@ -0,0 +1,32 @@
<?php
$file = 'admin.php';
$content = file_get_contents($file);
$js = "
function toggleMS(id) {
const d = document.getElementById(id);
d.style.display = d.style.display === 'block' ? 'none' : 'block';
}
function updateMSLabel(containerId) {
const container = document.getElementById(containerId);
const checkboxes = container.querySelectorAll('input[type=\"checkbox\"]:checked');
const display = container.querySelector('.ms-display');
if (checkboxes.length === 0) {
display.innerText = \"Toutes / Peu importe\";
} else {
const labels = Array.from(checkboxes).map(cb => cb.parentElement.innerText.trim());
display.innerText = labels.join(', ');
}
}
document.addEventListener('click', function(e) {
if (!e.target.closest('.ms-container')) {
document.querySelectorAll('.ms-dropdown').forEach(d => d.style.display = 'none');
}
});
</script>";
$content = str_replace(' </script>', $js, $content);
file_put_contents($file, $content);
echo "JS patched";
?>

60
patch_js_v3.php Normal file
View File

@ -0,0 +1,60 @@
<?php
$file = 'admin.php';
$content = file_get_contents($file);
$oldJs = ' function editRule(data) {
document.getElementById(\'rule_id\').value = data.id;
document.getElementById(\'rule_name\').value = data.name;
document.getElementById(\'rule_profile_id\').value = data.profile_id || "";
document.getElementById(\'rule_status_id\').value = data.status_id;
document.getElementById(\'rule_priority\').value = data.priority || 0;
document.getElementById(\'rule_orb_op\').value = data.orbital_count_op || "";
document.getElementById(\'rule_orb_val\').value = data.orbital_count_val !== null ? data.orbital_count_val : "";
document.getElementById(\'rule_terr_op\').value = data.terrestrial_count_op || "";
document.getElementById(\'rule_terr_val\').value = data.terrestrial_count_val !== null ? data.terrestrial_count_val : "";
document.getElementById(\'rule_orb_dom\').value = data.orbital_dominance || "";
document.getElementById(\'rule_terr_dom\').value = data.terrestrial_dominance || "";
document.getElementById(\'rule_empty\').checked = data.is_empty_case == 1;
window.scrollTo(0,0);
}
function resetRuleForm() { document.getElementById(\'ruleForm\').reset(); document.getElementById(\'rule_id\').value = 0; }';
$newJs = ' function editRule(data) {
document.getElementById(\'rule_id\').value = data.id;
document.getElementById(\'rule_name\').value = data.name;
document.getElementById(\'rule_profile_id\').value = data.profile_id || "";
document.getElementById(\'rule_status_id\').value = data.status_id;
document.getElementById(\'rule_priority\').value = data.priority || 0;
document.getElementById(\'rule_orb_op\').value = data.orbital_count_op || "";
document.getElementById(\'rule_orb_val\').value = data.orbital_count_val !== null ? data.orbital_count_val : "";
document.getElementById(\'rule_terr_op\').value = data.terrestrial_count_op || "";
document.getElementById(\'rule_terr_val\').value = data.terrestrial_count_val !== null ? data.terrestrial_count_val : "";
// Set multi-selects
const orbVals = (data.orbital_dominance || "").split(",");
document.querySelectorAll(\'#ms_orb_list input\').forEach(cb => {
cb.checked = orbVals.includes(cb.value);
});
updateMSLabel(\'ms_orb\');
const terrVals = (data.terrestrial_dominance || "").split(",");
document.querySelectorAll(\'#ms_terr_list input\').forEach(cb => {
cb.checked = terrVals.includes(cb.value);
});
updateMSLabel(\'ms_terr\');
document.getElementById(\'rule_empty\').checked = data.is_empty_case == 1;
window.scrollTo(0,0);
}
function resetRuleForm() {
document.getElementById(\'ruleForm\').reset();
document.getElementById(\'rule_id\').value = 0;
updateMSLabel(\'ms_orb\');
updateMSLabel(\'ms_terr\');
}';
$content = str_replace($oldJs, $newJs, $content);
file_put_contents($file, $content);
echo "editRule and resetRuleForm updated";
?>

16
patch_table_v2.php Normal file
View File

@ -0,0 +1,16 @@
<?php
$file = 'admin.php';
$content = file_get_contents($file);
$oldTable = ' if($r[\'orbital_dominance\']) $conds[] = "Orbital Dom: " . $r[\'orbital_dominance\'];
if($r[\'terrestrial_dominance\']) $conds[] = "Ground Dom: " . $r[\'terrestrial_dominance\'];';
$newTable = ' if($r[\'orbital_dominance\']) $conds[] = "Orbital IN (" . $r[\'orbital_dominance\'] . ")";
if($r[\'terrestrial_dominance\']) $conds[] = "Ground IN (" . $r[\'terrestrial_dominance\'] . ")";';
$content = str_replace($oldTable, $newTable, $content);
file_put_contents($file, $content);
echo "Table display patched";
?>

151
patch_ui.php Normal file
View File

@ -0,0 +1,151 @@
<?php
$content = file_get_contents('admin.php');
$newUi = <<<'HTML'
<div style="display: flex; gap: 15px; align-items: flex-start; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold; padding-top: 5px;">FILTRE DOMINANCE :</div>
<!-- ORBITAL MULTI-SELECT -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">En Orbite</label>
<div class="multi-select-dropdown" id="orb_ms">
<div class="multi-select-btn" id="orb_btn" onclick="toggleMS('orb')">N'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i></div>
<div class="multi-select-menu" id="orb_menu">
<div class="multi-select-header">
<button type="button" onclick="msAll('orb', true)">Tout sélectionner</button>
<button type="button" onclick="msAll('orb', false)">Tout désélectionner</button>
</div>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="any" id="orb_any" checked onchange="handleMSChange(this, 'orb', true)">
<span>N'importe laquelle</span>
</label>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="none" class="orb-cb" data-name="Aucune" onchange="handleMSChange(this, 'orb', false)">
<span>Aucune (Vide)</span>
</label>
<hr style="border:0; border-top:1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f): ?>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="<?php echo $f['id']; ?>" class="orb-cb" data-name="<?php echo htmlspecialchars($f['name']); ?>" onchange="handleMSChange(this, 'orb', false)">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
<!-- GROUND MULTI-SELECT -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">Au Sol</label>
<div class="multi-select-dropdown" id="terr_ms">
<div class="multi-select-btn" id="terr_btn" onclick="toggleMS('terr')">N'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i></div>
<div class="multi-select-menu" id="terr_menu">
<div class="multi-select-header">
<button type="button" onclick="msAll('terr', true)">Tout sélectionner</button>
<button type="button" onclick="msAll('terr', false)">Tout désélectionner</button>
</div>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="any" id="terr_any" checked onchange="handleMSChange(this, 'terr', true)">
<span>N'importe laquelle</span>
</label>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="none" class="terr-cb" data-name="Aucune" onchange="handleMSChange(this, 'terr', false)">
<span>Aucune (Vide)</span>
</label>
<hr style="border:0; border-top:1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f): ?>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="<?php echo $f['id']; ?>" class="terr-cb" data-name="<?php echo htmlspecialchars($f['name']); ?>" onchange="handleMSChange(this, 'terr', false)">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<div style="display: flex; align-items: center; gap: 20px; padding-top: 10px; border-top: 1px solid #334155;">
<div style="display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="is_empty_case" id="rule_empty" style="width: auto;">
<label for="rule_empty" style="margin-bottom: 0; color: #ebcb8b; font-size: 11px;">Cas "CASE VIDE"</label>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="dominance_diff_required" id="rule_diff" style="width: auto;">
<label for="rule_diff" style="margin-bottom: 0; color: #a3be8c; font-size: 11px;">Dominante orbite Dominante sol</label>
</div>
</div>
HTML;
$content = preg_replace('/<div style="display: flex; gap: 15px; align-items: center; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold;">FACTION DOMINANTE :</div>
<!-- ORBITAL MULTI-SELECT -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">En Orbite</label>
<div class="multi-select-dropdown" id="orb_ms">
<div class="multi-select-btn" id="orb_btn" onclick="toggleMS('orb')">N\'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i></div>
<div class="multi-select-menu" id="orb_menu">
<div class="multi-select-header">
<button type="button" onclick="msAll('orb', true)">Tout sélectionner</button>
<button type="button" onclick="msAll('orb', false)">Tout désélectionner</button>
</div>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="any" id="orb_any" checked onchange="handleMSChange(this, 'orb', true)">
<span>N\'importe laquelle</span>
</label>
<label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="none" class="orb-cb" data-name="Aucune" onchange="handleMSChange(this, 'orb', false)">
<span>Aucune (Vide)</span>
</label>
<hr style="border:0; border-top:1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f):
?><label class="multi-select-option">
<input type="checkbox" name="orbital_dominant_factions[]" value="<?php echo $f['id']; ?>" class="orb-cb" data-name="<?php echo htmlspecialchars($f['name']); ?>" onchange="handleMSChange(this, 'orb', false)">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
<!-- GROUND MULTI-SELECT -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">Au Sol</label>
<div class="multi-select-dropdown" id="terr_ms">
<div class="multi-select-btn" id="terr_btn" onclick="toggleMS('terr')">N\'importe laquelle <i class="fa-solid fa-chevron-down" style="font-size: 10px;"></i></div>
<div class="multi-select-menu" id="terr_menu">
<div class="multi-select-header">
<button type="button" onclick="msAll('terr', true)">Tout sélectionner</button>
<button type="button" onclick="msAll('terr', false)">Tout désélectionner</button>
</div>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="any" id="terr_any" checked onchange="handleMSChange(this, 'terr', true)">
<span>N\'importe laquelle</span>
</label>
<label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="none" class="terr-cb" data-name="Aucune" onchange="handleMSChange(this, 'terr', false)">
<span>Aucune (Vide)</span>
</label>
<hr style="border:0; border-top:1px solid #334155; margin: 5px 0;">
<?php foreach($factions_list as $f):
?><label class="multi-select-option">
<input type="checkbox" name="ground_dominant_factions[]" value="<?php echo $f['id']; ?>" class="terr-cb" data-name="<?php echo htmlspecialchars($f['name']); ?>" onchange="handleMSChange(this, 'terr', false)">
<span><?php echo htmlspecialchars($f['name']); ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<div style="display: flex; align-items: center; gap: 20px; padding-top: 10px; border-top: 1px solid #334155;">
<div style="display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="is_empty_case" id="rule_empty" style="width: auto;">
<label for="rule_empty" style="margin-bottom: 0; color: #ebcb8b; font-size: 11px;">Cas "CASE VIDE"</label>
</div>
<div style="display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="dominance_diff_required" id="rule_diff" style="width: auto;">
<label for="rule_diff" style="margin-bottom: 0; color: #a3be8c; font-size: 11px;">Dominante orbite Dominante sol</label>
</div>
</div>/s', $content);
file_put_contents('admin.php', $content);
echo "UI updated.\n";

67
patch_ui_v3.php Normal file
View File

@ -0,0 +1,67 @@
<?php
$file = 'admin.php';
$content = file_get_contents($file);
$oldUi = '<div style="display: flex; gap: 15px; align-items: center; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold;">FACTION DOMINANTE :</div>
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">En Orbite</label>
<select name="orbital_dominance" id="rule_orb_dom">
<option value="">-</option>
<option value="ANY">N\'importe laquelle</option>
<option value="NONE">Aucune (Vide)</option>
<?php foreach($factions_list as $f): if($f[\'name\'] !== \'Aucune\'): ?>
<option value="<?php echo $f[\'id\']; ?>"><?php echo htmlspecialchars($f[\'name\']); ?></option>
<?php endif; endforeach; ?>
</select>
</div>
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">Au Sol</label>
<select name="terrestrial_dominance" id="rule_terr_dom">
<option value="">-</option>
<option value="ANY">N\'importe laquelle</option>
<option value="NONE">Aucune (Vide)</option>
<?php foreach($factions_list as $f): if($f[\'name\'] !== \'Aucune\'): ?>
<option value="<?php echo $f[\'id\']; ?>"><?php echo htmlspecialchars($f[\'name\']); ?></option>
<?php endif; endforeach; ?>
</select>
</div>
</div>';
$newUi = '<div style="display: flex; gap: 15px; align-items: flex-start; margin-bottom: 10px;">
<div style="flex: 0 0 180px; font-size: 11px; color: #88c0d0; font-weight: bold; padding-top: 5px;">FILTRE DOMINANCE :</div>
<!-- Orbite -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">En Orbite</label>
<div class="ms-container" id="ms_orb">
<div class="ms-display" onclick="toggleMS(\'ms_orb_list\')">Toutes / Peu importe</div>
<div class="ms-dropdown" id="ms_orb_list">
<label class="ms-item"><input type="checkbox" value="none" onchange="updateMSLabel(\'ms_orb\')"> Aucune (Vide)</label>
<?php foreach($factions_list as $f): if($f[\'name\'] !== \'Aucune\'): ?>
<label class="ms-item"><input type="checkbox" value="<?php echo $f[\'id\']; ?>" name="orbital_dominance[]" onchange="updateMSLabel(\'ms_orb\')"> <?php echo htmlspecialchars($f[\'name\']); ?></label>
<?php endif; endforeach; ?>
</div>
</div>
</div>
<!-- Sol -->
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label style="font-size: 10px;">Au Sol</label>
<div class="ms-container" id="ms_terr">
<div class="ms-display" onclick="toggleMS(\'ms_terr_list\')">Toutes / Peu importe</div>
<div class="ms-dropdown" id="ms_terr_list">
<label class="ms-item"><input type="checkbox" value="none" onchange="updateMSLabel(\'ms_terr\')"> Aucune (Vide)</label>
<?php foreach($factions_list as $f): if($f[\'name\'] !== \'Aucune\'): ?>
<label class="ms-item"><input type="checkbox" value="<?php echo $f[\'id\']; ?>" name="terrestrial_dominance[]" onchange="updateMSLabel(\'ms_terr\')"> <?php echo htmlspecialchars($f[\'name\']); ?></label>
<?php endif; endforeach; ?>
</div>
</div>
</div>
</div>';
$content = str_replace($oldUi, $newUi, $content);
file_put_contents($file, $content);
echo "UI patched";
?>