You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
12 KiB
PHP

<?php
/*
* Copyright 2019 Netsyms Technologies.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
require_once __DIR__ . "/../lib/required_public.php";
$publicsettings = json_decode(file_get_contents(__DIR__ . "/../custom/public.json"), true);
if (!empty($_GET["format"]) && strtolower($_GET["format"]) == "json") {
include __DIR__ . "/api.php";
exit();
}
function getSearchBox(bool $searchagain = false): string {
global $publicsettings, $Strings;
if (isset($_GET["embed"])) {
return "";
}
$html = '<p>' . ($searchagain ? $publicsettings["Look up another device prompt"] : $publicsettings["Search box prompt"]) . '</p><form method="GET">'
. '<input type="text" name="id" class="form-control" placeholder="' . ($searchagain ? $publicsettings["ID number search box placeholder"] : $Strings->get("Number", false)) . '" required />'
. '<button type="submit" class="btn btn-primary btn-block mt-2">' . $Strings->get("Get Info", false) . '</button>'
. '</form>';
return $html;
}
/**
* Output a Bootstrap card div with the given header HTML and body HTML.
* @param string $header
* @param (string|array) $body string or array of strings
*/
function printCard($header, $body) {
echo '<div class="card">';
echo ' <h3 class="card-header d-flex">';
echo ' <div>';
echo ' ' . $header;
echo ' </div>';
echo ' </h3>';
if (is_array($body)) {
foreach ($body as $b) {
if (empty($b)) {
continue;
}
echo ' <div class="card-body">';
echo $b;
echo ' </div>';
}
} else {
echo $body;
}
echo "<div>";
}
?>
<!DOCTYPE html>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $SETTINGS["branding"]["publictitle"]; ?></title>
<link href="../static/css/bootstrap.min.css" rel="stylesheet">
<link href="../static/css/material-color/material-color.min.css" rel="stylesheet">
<link href="../static/css/fontawesome-all.min.css" rel="stylesheet">
<?php
// Allow setting the page background to match the style of a parent frame
if (isset($_GET["backgroundcolor"]) && !empty($_GET["backgroundcolor"]) && preg_match("/^[a-z0-9#\-]+$/i", $_GET["backgroundcolor"])) {
?>
<style nonce="<?php echo $SECURE_NONCE; ?>">
html,body {
background-color: <?php echo $_GET["backgroundcolor"]; ?>;
}
</style>
<?php
}
?>
<div class="container mt-4">
<div class="row justify-content-center">
<div class="<?php if (!isset($_GET["embed"])) { ?>col-12 col-md-8<?php } else { ?>col-12<?php } ?>">
<?php
if (!empty($_GET["id"]) && strpos($_GET["id"], "68") === 0 && !CheckDigit::validateS10($_GET["id"])) {
// Made a typo in the machine ID
printCard('<i class="fas fa-desktop"></i> ' . $Strings->get("Device Info", false), [
'<p class="text-danger"><code>' . htmlspecialchars($_GET['id']) . '</code> is not valid. Please try re-typing it.</p>',
getSearchBox()
]);
} else if (empty($_GET["id"]) || (!Machine::exists($_GET["id"]) && !Machine::serialExists($_GET["id"]) && !Component::exists($_GET["id"]))) {
// try package tracking query
$trackingok = false;
if (!empty($_GET["id"]) && preg_match("/^[a-z0-9]{10,}$/", $_GET["id"])) {
$trkresp = json_decode(file_get_contents("https://apis.netsyms.net/packagehelper/track.php?code=$_GET[id]"), true);
if ($trkresp["status"] == "OK" && $trkresp["current"]["status"] != "UNKNOWN" && $trkresp["service"]["id"] != null) {
$trackingok = true;
function trackingStatusToNiceString($status) {
switch ($status) {
case "UNKNOWN":
return "Unknown";
case "PRE_TRANSIT":
return "Pre-transit";
case "TRANSIT":
return "In Transit";
case "DELIVERED":
return "Delivered";
case "RETURNED":
return "Returned";
case "FAILURE":
return "Failure";
default:
return $status;
}
}
$html = '<div class="row">
<div class="col-12 mb-3">
<div class="list-group">
<div class="list-group-item">
<b>Tracking code:</b> <span style="font-family: \'Ubuntu Mono\', monospace;">' . $trkresp["code"] . '</span>
</div>
<div class="list-group-item">
<b>Current status:</b> ' . trackingStatusToNiceString($trkresp["current"]["status"]) . ": " . $trkresp["current"]["details"]
. '</div>
<div class="list-group-item">
<b>Last updated:</b> ' . date($SETTINGS["datetime_format"], $trkresp["current"]["date"])
. '</div>
<div class="list-group-item">
<b>Last location:</b> ' . implode(" ", $trkresp["current"]["location"])
. '</div>
<div class="list-group-item">
<b>Carrier:</b> ' . $trkresp["carrier"]["name"] .
'</div>
</div>
</div>
<div class="col-12 mb-3">
<h6>History:</h6>
<div class="list-group">';
foreach ($trkresp["history"] as $his) {
$html .= '<div class="list-group-item">';
$html .= '<b>' . trackingStatusToNiceString($his["status"]) . ":</b> " . $his["details"] . '<br>';
$html .= date($SETTINGS["datetime_format"], $his["date"]) . '<br>';
$html .= implode(" ", $his["location"]);
$html .= '</div>';
}
$html .= '</div>
</div>
</div>';
printCard('<i class="fas fa-box"></i> ' . $Strings->get("Tracking Info", false), [
$html,
getSearchBox()
]);
}
}
if (!$trackingok) {
$body = [];
if (!empty($_GET["id"])) {
$body[] = '<p class="text-danger">' . str_replace("{id}", htmlspecialchars($_GET['id']), $publicsettings["No device with ID error"]) . "</p>";
}
$body[] = getSearchBox();
printCard('<i class="fas fa-desktop"></i> ' . $Strings->get("Device Info", false), $body);
}
} else {
if (Component::exists($_GET["id"])) {
$component = new Component($_GET["id"]);
$mid = $component->getMachineID();
if (!empty($mid) && Machine::exists($mid)) {
$machine = new Machine($mid);
} else {
// component exists but isn't attached to a machine
$html = '<div class="alert alert-info">
<i class="fas fa-info-circle"></i> ' . $publicsettings["Component exist but isn't attached to a machine"]
. '</div>
<div class="row">
<div class="col-12 mb-3">
<div class="list-group">
<div class="list-group-item">'
. $component->toHTML(true)
. '</div></div></div></div>';
printCard('<i class="fas fa-memory"></i> ' . $Strings->get("Component", false) . ' #' . $component->getID(), [$html, getSearchBox()]);
}
} else {
if (Machine::exists($_GET["id"])) {
$machine = new Machine($_GET['id']);
} else {
$machine = new Machine(Machine::getIDFromSerial($_GET['id']));
}
$eventshtml = "";
$history = $machine->getEvents();
$events = [];
foreach ($history as $h) {
$events[] = $h;
}
if (count($events) > 0) {
$eventshtml = '<div class="col-sm-6 mb-3">
<h6>Events:</h6>
<div class="list-group">';
foreach ($history as $h) {
$eventshtml .= '<div class="list-group-item">'
. $h->toHTML(true)
. '</div>';
}
$eventshtml .= '</div></div>';
}
$componentshtml = "";
$components = $machine->getComponents();
if (count($components) > 0) {
$componentshtml = '<div class="col-sm-6 mb-3"><h6>Components:</h6><div class="list-group">';
foreach ($components as $c) {
$componentshtml .= '<div class = "list-group-item">'
. $c->toHTML(true)
. '</div>';
}
$componentshtml .= '</div></div>';
}
$body = [
'<div class="row"><div class="col-12 mb-3">'
. $machine->toHTMLListGroup(true)
. '</div>'
. $eventshtml
. $componentshtml
. "</div>",
getSearchBox(true)
];
printCard('<i class="' . $machine->getIcon() . '"></i> ' . $machine->getTypeLabel() . ' Info', $body);
}
}
?>
</div>
</div>
</div>
<?php
// Send message to parent frame with our height so they can adjust the iframe
if (isset($_GET["embed"])) {
?>
<script nonce="<?php echo $SECURE_NONCE; ?>">
window.addEventListener("load", function () {
// https://stackoverflow.com/questions/1145850/how-to-get-height-of-entire-document-with-javascript
var body = document.body,
html = document.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
parent.window.postMessage(height + "px", "*");
});
</script>
<?php
}
?>