Add online menu management, modernized and hardened

Adds a public menu page (menu.php) and an admin CRUD interface
(admin/menu.php + admin/menu.js) backed by new menu_categories and
menu_items tables, replacing the "menu lives on Facebook" placeholder
on the homepage.

The admin JS/PHP came out of an AI-assisted pass that used outdated
JS (var, .then() chains, string-built HTML) and had some rough edges
security-wise, so this also:

- Rewrites the admin JS to modern ES (const/let, async/await,
  template literals, dataset API) and splits it out of admin/menu.php
  into admin/menu.js for proper separation of concerns
- Adds declare(strict_types=1) and PHP 8 match-based action dispatch
  in place of an if-chain
- Validates category_id/item_id/category_id server-side before use,
  so a bad ID returns a clean JSON error instead of an uncaught
  PDOException or a null item breaking the client
- Rejects non-string POST fields instead of crashing trim() on them
- Replaces the category-save handler's full-page location.reload()
  with in-place DOM updates (panel insert/update, resort by
  sort_order, keep the item modal's category dropdown in sync), so
  every admin action is now AJAX with no reload
- Sets data-name/data-desc via dataset assignment rather than string-
  interpolating them into an HTML attribute, closing a stored-XSS
  path through the category name/description fields

Removes seed-menu.php, a leftover stub with no working code left in
it after the AI's one-time seeding run.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
David DyerandClaude Sonnet 5 committed 2026-08-30 21:35:22 -04:00
1 parent 21ad6c31cf
commit f1bbf59548
8 files changed
+1382 -27

No files matched your search

+12 -12
View File
@@ -46,7 +46,7 @@ $siteUrl = rtrim(SITE_URL, '/');
<header class="site">
<div class="container nav-inner">
<a class="brand" href="#main">
<a class="brand" href="./">
<img class="knot" src="./assets/knot.png" alt="">
<span>THE OLD FITZ</span>
</a>
@@ -54,7 +54,7 @@ $siteUrl = rtrim(SITE_URL, '/');
<a href="#about">About</a>
<a href="#visit">Hours &amp; Visit</a>
<a href="#music">Live Music</a>
<a href="#menu">Menu</a>
<a href="menu.php">Menu</a>
<a href="#contact">Contact</a>
</nav>
<a class="nav-cta" href="https://www.google.com/maps/search/?api=1&amp;query=100+N+Washington+St+Marion+IN" target="_blank" rel="noopener">Get Directions</a>
@@ -62,9 +62,9 @@ $siteUrl = rtrim(SITE_URL, '/');
</header>
<?php
$bannerAnnouncements = array_filter($activeAnnouncements, function($a) {
return !empty($a['show_banner']);
});
$bannerAnnouncements = array_filter($activeAnnouncements, function ($a) {
return !empty($a['show_banner']);
});
?>
<?php if (!empty($bannerAnnouncements)): ?>
<?php foreach ($bannerAnnouncements as $banner): ?>
@@ -135,9 +135,9 @@ $siteUrl = rtrim(SITE_URL, '/');
<div class="card reveal">
<h3>On Tap Thu–Sat</h3>
<?php
$hoursAnnouncements = array_filter($activeAnnouncements, function($a) {
return !empty($a['show_in_hours']);
});
$hoursAnnouncements = array_filter($activeAnnouncements, function ($a) {
return !empty($a['show_in_hours']);
});
?>
<?php foreach ($hoursAnnouncements as $hoursNotice): ?>
<div class="hours-alert alert-<?= htmlspecialchars($hoursNotice['type']) ?>">
@@ -220,10 +220,10 @@ $siteUrl = rtrim(SITE_URL, '/');
<p class="eyebrow">The Menu</p>
<h2>Pub food and a full bar, Thursday through Saturday.</h2>
</div>
<p class="body reveal">The current menu lives behind the bar and gets posted on our Facebook page. Stop in, or send us a message and we'll get you sorted before you arrive.</p>
<p class="body reveal">We serve traditional Irish staples, shareable plates, and hearty comfort food until 9 PM, with bar snacks staying out later. Explore our full kitchen menu or check Facebook for weekend chalkboard features.</p>
<div class="hero-ctas reveal">
<a class="btn btn-primary" href="https://www.facebook.com/profile.php?id=100086635646712" target="_blank" rel="noopener">See Menu Updates on Facebook</a>
<a class="btn btn-outline" href="mailto:info@theoldfitzpub.com">Email a Question</a>
<a class="btn btn-primary" href="menu.php">Explore Full Menu →</a>
<a class="btn btn-outline" href="https://www.facebook.com/profile.php?id=100086635646712" target="_blank" rel="noopener">Daily Specials on Facebook</a>
</div>
</div>
</section>
@@ -295,4 +295,4 @@ $siteUrl = rtrim(SITE_URL, '/');
</script>
</body>
</html>
</html>