Project import generated by Copybara.
GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/src/inc/visual.php b/src/inc/visual.php
new file mode 100644
index 0000000..02a3457
--- /dev/null
+++ b/src/inc/visual.php
@@ -0,0 +1,192 @@
+<?php
+class visual {
+ const VIEW_ADMIN = 0;
+ const VIEW_WORKER = 1;
+
+ // Old:
+ /*const YES = "✓";
+ const NO = "✗";*/
+
+ // New:
+ const YES = "✓";
+ const NO = "X";
+
+ public static function snackbar($msg, $timeout = 10000, $printHTML = true) {
+ if ($printHTML) echo '<div class="mdl-snackbar mdl-js-snackbar">
+ <div class="mdl-snackbar__text"></div>
+ <button type="button" class="mdl-snackbar__action"></button>
+ </div>';
+ echo '<script>
+ window.addEventListener("load", function() {
+ var notification = document.querySelector(".mdl-js-snackbar");
+ notification.MaterialSnackbar.showSnackbar(
+ {
+ message: "'.security::htmlsafe($msg).'",
+ timeout: '.(int)$timeout.'
+ }
+ );
+ });
+ </script>';
+ }
+
+ public static function smartSnackbar($msgs, $timeout = 10000, $printHTML = true) {
+ global $_GET;
+
+ if (!isset($_GET["msg"])) return;
+
+ foreach ($msgs as $msg) {
+ if ($_GET["msg"] == $msg[0]) {
+ self::snackbar($msg[1], $timeout, $printHTML);
+ return;
+ }
+ }
+ }
+
+ public static function debugJson($array) {
+ return security::htmlsafe(json_encode($array, JSON_PRETTY_PRINT));
+ }
+
+ public static function includeHead() {
+ include("includes/head.php");
+ }
+
+ public static function includeNav() {
+ global $conf, $mdHeaderRowMore, $mdHeaderMore, $mdHeaderRowBefore;
+
+ $activeView = security::getActiveView();
+ switch ($activeView) {
+ case self::VIEW_ADMIN:
+ include("includes/adminnav.php");
+ break;
+
+ case self::VIEW_WORKER:
+ include("includes/workernav.php");
+ break;
+
+ default:
+ exit();
+ }
+ }
+
+ public static function backBtn($url) {
+ return '<a class="backbtn mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" href="'.$url.'"><i id="auto_backbtn" class="material-icons">arrow_back</i></a><div class="mdl-tooltip" for="auto_backbtn">Atrás</div><div style="width: 16px;"></div>';
+ }
+
+ public static function printDebug($function, $return, $always=false, $notjson=false) {
+ global $conf;
+
+ if ($always || $conf["debug"])
+ echo '<details class="debug margintop">
+ <summary>Debug:</summary>
+ <p><b>'.security::htmlsafe($function).'</b></p>
+ <div class="overflow-wrapper"><pre>'.($notjson ? security::htmlsafe(print_r($return, true)) : self::debugJson($return)).'</pre></div>
+ </details>';
+ }
+
+ public static function renderPagination($rows, $page, $limit = 10, $showLimitLink = false, $alreadyHasParameters = false, $limitChange = false, $highlightedPage = false) {
+ global $_GET;
+
+ $numPages = ($limit == 0 ? 1 : ceil($rows/$limit));
+ if ($numPages > 1) {
+ $currentPage = ((isset($_GET["page"]) && $_GET["page"] <= $numPages && $_GET["page"] >= 1) ? $_GET["page"] : 1);
+
+ echo '<div class="pagination">';
+ for ($i = 1; $i <= $numPages; $i++) {
+ echo ($i != $currentPage ? '<a class="page'.($i == $highlightedPage ? " mdl-color-text--green" : "").'" href="'.security::htmlsafe($page).($alreadyHasParameters ? "&" : "?").'page='.(int)$i.($showLimitLink ? '&limit='.(int)$limit : '').'">'.(int)$i.'</a> ' : '<b class="page">'.(int)$i.'</b> ');
+ }
+ echo '</div>';
+ }
+
+ if ($limitChange !== false) {
+ ?>
+ <div class="limit-change-container">Ver <select id="limit-change">
+ <?php
+ if (isset($limitChange["options"])) {
+ if (!in_array($limit, $limitChange["options"])) {
+ echo "<option value=\"".(int)$limit."\" selected>".(int)$limit."</option>";
+ }
+ foreach ($limitChange["options"] as $option) {
+ echo "<option value=\"".(int)$option."\"".($option == $limit ? " selected" : "").">".(int)$option."</option>";
+ }
+ }
+ ?>
+ </select> <?=security::htmlsafe($limitChange["elementName"])?> por página.</div>
+ <?php
+ }
+ }
+
+ public static function padNum($num, $length) {
+ return str_pad($num, $length, "0", STR_PAD_LEFT);
+ }
+
+ public static function isMDColor() {
+ global $conf;
+
+ return (($conf["backgroundColor"][0] ?? "") != "#");
+ }
+
+ public static function printBodyTag() {
+ global $conf;
+
+ $conf["backgroundColorIsDark"];
+ echo "<body ".(!visual::isMDColor() ? "style=\"background-color: ".security::htmlsafe($conf["backgroundColor"]).";\"" : "")."class=\"".(visual::isMDColor() ? "mdl-color--".security::htmlsafe($conf["backgroundColor"]) : "").($conf["backgroundColorIsDark"] ? " dark-background" : "")."\">";
+ }
+
+ // WARNING: We will not sanitize $msg, so sanitize it before calling this function!
+ public static function addTooltip($id, $msg) {
+ global $_tooltips;
+
+ if (!isset($_tooltips)) $_tooltips = "";
+ $_tooltips .= '<div class="mdl-tooltip" for="'.security::htmlsafe($id).'">'.$msg.'</div>';
+ }
+
+ public static function renderTooltips() {
+ global $_tooltips;
+
+ echo ($_tooltips ?? "");
+ }
+
+ private static function addMsgToUrl($url, $msg = false) {
+ if ($msg === false) return $url;
+ return $url.(preg_match("/\?/", $url) == 1 ? "&" : "?")."msg=".urlencode($msg);
+ }
+
+ public static function getContinueUrl($defaultUrl, $msg = false, $method = "GET") {
+ global $_GET, $_POST;
+
+ $url = "";
+
+ switch ($method) {
+ case "GET":
+ if (!isset($_GET["continue"])) return self::addMsgToUrl($defaultUrl, $msg);
+ $url = (string)$_GET["continue"];
+ break;
+
+ case "POST":
+ if (!isset($_POST["continue"])) return self::addMsgToUrl($defaultUrl, $msg);
+ $url = (string)$_POST["continue"];
+ break;
+
+ default:
+ return self::addMsgToUrl($defaultUrl, $msg);
+ }
+
+ if (!preg_match("/^[^\/\\\\]*$/", $url)) return self::addMsgToUrl($defaultUrl, $msg);
+
+ if ($msg !== false) $url = self::addMsgToUrl($url, $msg);
+
+ return $url;
+ }
+
+ public static function addContinueInput($url = false) {
+ global $_GET, $_POST;
+
+ if ($url === false) {
+ if (isset($_GET["continue"])) $url = $_GET["continue"];
+ elseif (isset($_POST["continue"])) $url = $_POST["continue"];
+ else return;
+ }
+
+ echo '<input type="hidden" name="continue" value="'.security::htmlsafe($url).'">';
+ }
+}