38676-vm/patch_admin_v4.php
Flatlogic Bot 12241ba85d Alpha V1.4
2026-02-26 08:28:54 +00:00

240 lines
16 KiB
PHP

<?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";