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

120 lines
4.1 KiB
PHP

<?php
/**
* Point UNIQUE de détermination du statut d'un objet céleste.
* Basé sur les règles configurées dans l'administration.
*/
function calculateCelestialStatus($planet, $db, $statuses_map) {
$profile_id = $planet['status_profile_id'] ?? null;
// Si pas de profil sur la planète, on prend celui du type d'objet
if (!$profile_id && isset($planet['type'])) {
$stmt = $db->prepare("SELECT status_profile_id FROM celestial_object_types WHERE slug = ?");
$stmt->execute([$planet['type']]);
$profile_id = $stmt->fetchColumn();
}
// Si toujours pas de profil, on retourne le statut actuel (fallback alpha)
if (!$profile_id) {
return $planet['status'];
}
// Récupération des règles du profil par priorité
$stmt = $db->prepare("SELECT r.*, s.slug as status_slug
FROM celestial_object_status_rules r
JOIN celestial_object_statuses s ON r.status_id = s.id
WHERE r.profile_id = ? AND r.is_active = 1
ORDER BY r.priority DESC, r.id ASC");
$stmt->execute([$profile_id]);
$rules = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Préparation des données de l'objet pour l'évaluation
$orbital_controls = $planet['orbital_controls'] ?? [];
$terrestrial_controls = $planet['terrestrial_controls'] ?? [];
$orbital_factions = array_filter($orbital_controls, fn($v) => $v > 0);
$terrestrial_factions = array_filter($terrestrial_controls, fn($v) => $v > 0);
$orb_count = count($orbital_factions);
$terr_count = count($terrestrial_factions);
$orb_dom = null;
if ($orb_count > 0) {
arsort($orbital_factions);
$orb_dom = array_key_first($orbital_factions);
}
$terr_dom = null;
if ($terr_count > 0) {
arsort($terrestrial_factions);
$terr_dom = array_key_first($terrestrial_factions);
}
$is_empty = ($orb_count === 0 && $terr_count === 0);
// Évaluation des règles
foreach ($rules as $rule) {
$match = true;
// Condition Case Vide
if ($rule['is_empty_case'] && !$is_empty) $match = false;
// Condition Nombre Factions Orbite
if ($match && $rule['orbital_count_op']) {
$match = evaluateOperator($orb_count, $rule['orbital_count_op'], $rule['orbital_count_val']);
}
// Condition Nombre Factions Sol
if ($match && $rule['terrestrial_count_op']) {
$match = evaluateOperator($terr_count, $rule['terrestrial_count_op'], $rule['terrestrial_count_val']);
}
// 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 (in_array((string)$orb_dom, $allowed)) $isIn = true;
}
if (!$isIn) $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 (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) {
return $rule['status_slug'];
}
}
// Fallback final
return $planet['status'];
}
function evaluateOperator($val, $op, $target) {
switch ($op) {
case '=': return $val == $target;
case '>': return $val > $target;
case '<': return $val < $target;
case '>=': return $val >= $target;
case '<=': return $val <= $target;
case '!=': return $val != $target;
}
return true;
}