<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/functions.inc"; require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages; require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/Parsedown.php"; $Parsedown = new Parsedown(); if (isset($_POST["updateRules"])) { header("Content-Type: text/plain"); if (!isset($_POST['payload'])) { header("Location: /-/rules"); die(); } foreach ($_POST['payload'] as $index => $rule) { if (!isset($rule["name"]) || !isset($rule["content"]) && !is_numeric($index)) { header("Location: /-/rules"); die(); } if (trim($rule["name"]) === "") { unset($_POST["payload"][$index]); continue; } if (!isset($rule["approved"])) $rule["approved"] = []; if (isset($rule["approved"][0])) $rule["approved"][0] = true; else $rule["approved"][0] = false; if (isset($rule["approved"][1])) $rule["approved"][1] = true; else $rule["approved"][1] = false; $_POST["payload"][$index] = $rule; } file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/rules/rules.json", json_encode($_POST["payload"])); file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/rules.json", "{}"); createJob("RefreshCache", []); header("Location: /-/rules"); die(); } require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc'; if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/rules.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/rules.json", "{}"); $cache = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/rules.json"), true); ?> <?php if (!isset($cache["content"])): ob_start(); ?> <br> <div class="container"> <div id="page-content"> <h2>Rules</h2> <p><a onclick="event.target.blur();" href="#" data-bs-toggle="modal" data-bs-target="#editor">Edit rules</a></p> <?php $rules = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/rules/rules.json"), true); $protectorCloudburst = array_values(array_filter(scoreOrderGlobal(), function ($i) { return $i["_system"] === "ynmuc" && $i["_metadata"]["leader"]; })); $protectorRaindrops = array_values(array_filter(scoreOrderGlobal(), function ($i) { return $i["_system"] === "gdapd" && $i["_metadata"]["leader"]; })); ?> <?php foreach (array_values($rules) as $index => $rule): $index++; ?> <h4 style="margin-top: 20px;"> <b>Rule <?= $index ?>: <?= str_replace("<", "<", str_replace(">", ">", $rule["name"])) ?></b> <?php if (in_array(false, $rule["approved"])): ?> <span class="badge bg-warning text-black rounded-pill">Unapproved</span> <?php endif; ?> </h4> <?php if (in_array(false, $rule["approved"])): ?> <div style="margin-top:10px;" class="alert alert-warning"> <b>This rule has not yet been approved.</b> All rules need to be approved by the leaders from both systems. This rule is still missing approval from <?php $list = []; if ($rule["approved"][0] === false) { if ($rule["approved"][1] === false) { array_push($list, ...array_map(function ($i) { return $i["display_name"] ?? $i["name"]; }, $protectorCloudburst)); array_push($list, ...array_map(function ($i) { return $i["display_name"] ?? $i["name"]; }, $protectorRaindrops)); } else { array_push($list, ...array_map(function ($i) { return $i["display_name"] ?? $i["name"]; }, $protectorCloudburst)); } } else if ($rule["approved"][1] === false) { array_push($list, ...array_map(function ($i) { return $i["display_name"] ?? $i["name"]; }, $protectorRaindrops)); } foreach ($list as $index => $item) { echo($item); if ($index < count($list) - 2) { echo(", "); } else if ($index < count($list) - 1) { echo(" and "); } } ?>. </div> <?php endif; ?> <div> <p><?= $Parsedown->text(str_replace("<", "<", str_replace(">", ">", $rule["content"]))) ?></p> </div> </li> <?php $index++; endforeach; ?> </div> </div> <style> .modal-dialog { margin-bottom: 3.5rem; } </style> <div class="modal fade" id="editor"> <div class="modal-dialog modal-xl"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">Rules editor</h4> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> <p>Rules with an empty name are automatically deleted. Buttons to add new rules and save the changes are at the bottom of the list.</p> <hr> <form method="post"> <div id="rules-editor"> <?php $index = 1; foreach ($rules as $rule): ?> <div <?= $index === 1 ? 'id="default-rule"' : '' ?>> <p><b <?= $index === 1 ? 'id="default-rule--number"' : '' ?>>Rule #<?= $index ?>:</b></p> <input <?= $index === 1 ? 'id="default-rule--name"' : '' ?> type="text" placeholder="Rule name" class="form-control" style="margin-bottom:15px;color:white;background:#111;border-color:#222;" name="payload[<?= $index - 1 ?>][name]" value="<?= str_replace('"', """, str_replace("<", "<", str_replace(">", ">", $rule["name"]))) ?>"> <textarea <?= $index === 1 ? 'id="default-rule--content"' : '' ?> name="payload[<?= $index - 1 ?>][content]" rows="10" class="form-control" style="resize: none;color:white;background:#111;border-color:#222;" placeholder="Rule details"><?= str_replace("<", "<", str_replace(">", ">", $rule["content"] ?? "")) ?></textarea> <label style="margin-top:10px;margin-left:5px;"> <input <?= $index === 1 ? 'id="default-rule--approval-1"' : '' ?> <?= ($rule["approved"][0] ?? false) ? "checked" : "" ?> type="checkbox" class="form-check-input" name="payload[<?= $index - 1 ?>][approved][0]"> Approved by <?= implode("/", array_values(array_map(function ($i) { return $i["display_name"] ?? $i["name"]; }, $protectorCloudburst))) ?> </label><br> <label style="margin-left:5px;"> <input <?= $index === 1 ? 'id="default-rule--approval-2"' : '' ?> <?= ($rule["approved"][1] ?? false) ? "checked" : "" ?> type="checkbox" class="form-check-input" name="payload[<?= $index - 1 ?>][approved][1]"> Approved by <?= implode("/", array_values(array_map(function ($i) { return $i["display_name"] ?? $i["name"]; }, $protectorRaindrops))) ?> </label><br> <hr> </div> <?php $index++; endforeach; ?> </div> <input type="submit" value="Save" class="btn btn-primary"> <a onclick="editorNewRule();" class="btn btn-secondary">New rule</a> <input type="hidden" name="updateRules"> </form> </div> </div> </div> </div> <script> window.numberOfRules = <?= count($rules) ?>; Array.from(document.getElementsByClassName("rule-outer")).forEach((el) => { let details = el.children[0]; el.onclick = () => { Array.from(document.getElementsByClassName("rule-outer")).forEach((sel) => { if (el === sel) return; sel.children[0].open = false; sel.classList.remove("open"); }); details.open = !details.open; if (details.open) { el.classList.add("open"); } else { el.classList.remove("open"); } } }) function editorNewRule() { let id = Math.random(36).toString().split(".")[1]; document.getElementById("default-rule").id = "added-" + id + "-1"; document.getElementById("default-rule--number").id = "added-" + id + "-2"; document.getElementById("default-rule--name").id = "added-" + id + "-3"; document.getElementById("default-rule--content").id = "added-" + id + "-4"; document.getElementById("default-rule--approval-1").id = "added-" + id + "-5"; document.getElementById("default-rule--approval-2").id = "added-" + id + "-6"; let child = document.createElement("div"); child.id = "temp-" + id; window.numberOfRules++; document.getElementById("rules-editor").appendChild(child); document.getElementById("temp-" + id).outerHTML = document.getElementById("added-" + id + "-1").outerHTML; document.getElementById("added-" + id + "-1").id = "default-rule"; document.getElementById("added-" + id + "-2").id = "default-rule--number"; document.getElementById("added-" + id + "-3").id = "default-rule--name"; document.getElementById("added-" + id + "-4").id = "default-rule--content"; document.getElementById("added-" + id + "-5").id = "default-rule--approval-1"; document.getElementById("added-" + id + "-6").id = "default-rule--approval-2"; document.getElementById("added-" + id + "-3").name = "payload[" + (numberOfRules - 1) + "][name]"; document.getElementById("added-" + id + "-4").name = "payload[" + (numberOfRules - 1) + "][content]"; document.getElementById("added-" + id + "-5").name = "payload[" + (numberOfRules - 1) + "][approved][0]"; document.getElementById("added-" + id + "-6").name = "payload[" + (numberOfRules - 1) + "][approved][1]"; document.getElementById("added-" + id + "-5").checked = false; document.getElementById("added-" + id + "-6").checked = false; document.getElementById("added-" + id + "-3").value = ""; document.getElementById("added-" + id + "-4").value = ""; document.getElementById("added-" + id + "-2").innerText = "Rule #" + numberOfRules + ":"; } </script> <style> .list-group-item { color: #fff; background-color: #222; border: 1px solid rgba(255, 255, 255, .125); } .list-group-item.disabled { color: #fff; background-color: #222; border-color: rgba(255, 255, 255, .125); opacity: .75; } .rule-outer:hover { background-color: #252525; color: #ddd; } .rule-outer:active, .rule-outer:focus { background-color: #272727; color: #bbb; } .rule-outer.open { background-color: #333; } .rule { list-style: none; pointer-events: none; } .rule-outer { cursor: pointer; } .modal-header { border-bottom: 1px solid #353738; } .modal-content { border: 1px solid rgba(255, 255, 255, .2); background-color: #111; } .btn-close { filter: invert(1); } </style> <?php $cache["content"] = ob_get_contents(); ob_end_clean(); endif; echo($cache["content"]); file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/rules.json", json_encode($cache)); ?> <?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?>