Files
wms-app/app/include_header.php
T

106 lines
5.5 KiB
PHP

<?php
// Output buffering must be active before the first byte of HTML below, so that
// header() calls made later in the page still work — notably the
// not-logged-in redirect in include_topbar.php, which runs *after* this file
// has already emitted <!DOCTYPE html>. Without a buffer that redirect depends
// entirely on php.ini's output_buffering: it is on for the dev stack but off
// in production, where every protected page answered 200 with a half-rendered
// body instead of sending the browser to the login form. session.php starts a
// buffer for the same reason.
if (ob_get_level() === 0) {
ob_start();
}
// Never render PHP notices/warnings into the page: they leak absolute server
// paths to anonymous visitors and corrupt the markup. Errors still reach the
// server log. This mirrors the policy db_auth.php already applies to the JSON
// API routes, and keeps the app safe even where php.ini has display_errors on.
ini_set('display_errors', '0');
ini_set('log_errors', '1');
// Apply the configured application timezone. Pages that only require config.php
// (no dbconn.php) still call date() for default values such as "today", so they
// need this too or they render a UTC date.
require_once __DIR__ . '/assets/utils/timezone.php';
// Security headers (CSP, nosniff, framing, referrer) — emitted before any HTML output.
require_once __DIR__ . '/assets/utils/page_headers.php';
send_page_security_headers();
// Self-hosted libraries (assets/vendor/, exact versions in assets/vendor/VERSIONS.json):
// the app no longer depends on third-party CDNs being up or unchanged.
$vendor_url = $server_url . 'assets/vendor/';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>BRN WMS</title>
<meta name="csrf-token" content="<?= htmlspecialchars($_SESSION['csrf_token'] ?? '') ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" sizes="180x180" href="<?php echo $server_url?>assets/images/favicon.png">
<link rel="icon" type="image/png" sizes="32x32" href="<?php echo $server_url?>assets/images/favicon32.png">
<link rel="icon" type="image/png" sizes="16x16" href="<?php echo $server_url?>assets/images/favicon32.png">
<link rel="manifest" href="<?php echo $server_url?>assets/site.webmanifest">
<!-- jquery -->
<script src="<?php echo $vendor_url?>jquery/3.7.1/jquery.min.js"></script>
<!-- popper (must be before bootstrap) -->
<script src="<?php echo $vendor_url?>popper/2.11.8/popper.min.js"></script>
<!-- bootstrap -->
<script src="<?php echo $vendor_url?>bootstrap/5.3.8/bootstrap.min.js"></script>
<!-- Disable the standalone Bootstrap's dropdown toggle — main.js bundles Bootstrap+Popper and
handles dropdown events. This copy stays for window.bootstrap (Modal API). -->
<script>bootstrap.Dropdown.prototype.toggle = function() {};</script>
<!-- bootbox -->
<script src="<?php echo $vendor_url?>bootbox/4.4.0/bootbox.min.js"></script>
<!-- overlay loader -->
<script src="<?php echo $vendor_url?>loadingoverlay/2.1.7/loadingoverlay.min.js"></script>
<!-- bootstrap css -->
<link href="<?php echo $vendor_url?>bootstrap/5.3.8/bootstrap.min.css" rel="stylesheet">
<!-- flatpickr date (custom.js initialises .flatpickr inputs on load, so not deferred) -->
<link rel="stylesheet" href="<?php echo $vendor_url?>flatpickr/4.6.13/flatpickr.min.css">
<script src="<?php echo $vendor_url?>flatpickr/4.6.13/flatpickr.min.js"></script>
<!-- flatpickr monthSelect plugin -->
<link rel="stylesheet" href="<?php echo $vendor_url?>flatpickr/4.6.13/plugins/monthSelect/style.css">
<script src="<?php echo $vendor_url?>flatpickr/4.6.13/plugins/monthSelect/index.js"></script>
<!-- autocomplete -->
<link rel="stylesheet" href="<?php echo $vendor_url?>jquery-ui/1.14.1/jquery-ui.css">
<script src="<?php echo $vendor_url?>jquery-ui/1.14.1/jquery-ui.min.js"></script>
<!-- alasql (only called from functions that run after load) -->
<script defer src="<?php echo $vendor_url?>alasql/4.6.6/alasql.min.js"></script>
<!-- dropzone -->
<script src="<?php echo $vendor_url?>dropzone/5.9.3/dropzone.min.js"></script>
<script>
// Turn off Dropzone's auto-scanner so it doesn't conflict with main.js
Dropzone.autoDiscover = false;
</script>
<!-- apexcharts (only called from functions that run after load) -->
<script defer src="<?php echo $vendor_url?>apexcharts/7.5.1/apexcharts.min.js"></script>
<!-- theme script -->
<link rel="stylesheet" href="<?php echo $server_url?>assets/css/main.css?v=<?php echo @filemtime(__DIR__ . '/assets/css/main.css'); ?>">
<script type="module" src="<?php echo $server_url?>assets/js/main.js?v=<?php echo @filemtime(__DIR__ . '/assets/js/main.js'); ?>"></script>
<link rel="stylesheet" href="<?php echo $server_url?>assets/css/custom.css?v=<?php echo @filemtime(__DIR__ . '/assets/css/custom.css'); ?>">
<script src="<?php echo $server_url?>assets/js/ajax_core.js?v=<?php echo @filemtime(__DIR__ . '/assets/js/ajax_core.js'); ?>"></script>
<script src="<?php echo $server_url?>assets/js/custom.js?v=<?php echo @filemtime(__DIR__ . '/assets/js/custom.js'); ?>"></script>
<script src="<?php echo $server_url?>assets/js/batch_overlay.js?v=<?php echo @filemtime(__DIR__ . '/assets/js/batch_overlay.js'); ?>"></script>
<!-- camera scanner library, loaded lazily by scanner.js when the camera opens -->
<script defer src="<?php echo $vendor_url?>html5-qrcode/2.3.8/html5-qrcode.min.js"></script>
<script src="<?php echo $server_url?>assets/js/scanner.js"></script>
</head>