Josh's Changes

This commit is contained in:
2026-04-03 20:43:00 -04:00
parent df06dcc0d7
commit 03825c1048
16 changed files with 216 additions and 54 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ function readJsonBody(): array {
function sendJson(array $payload, int $code = 200): void {
http_response_code($code);
echo json_encode($payload);
echo json_encode($payload, familyHubJsonEncodeShellFlags());
exit;
}
+3 -2
View File
@@ -1,6 +1,7 @@
<?php
require_once __DIR__ . '/persona.php';
require_once __DIR__ . '/utils.php';
const CHORE_SCHEDULE_ONCE = 'once';
const CHORE_SCHEDULE_RECURRING = 'recurring';
@@ -32,11 +33,11 @@ function legacyAssigneeNameToIds(string $name, array $people): array {
if ($name === '') {
return [];
}
$lower = mb_strtolower($name, 'UTF-8');
$lower = familyHubStrLowerUtf8($name);
$ids = [];
foreach ($people as $p) {
$pn = trim((string) ($p['name'] ?? ''));
if ($pn !== '' && mb_strtolower($pn, 'UTF-8') === $lower) {
if ($pn !== '' && familyHubStrLowerUtf8($pn) === $lower) {
$ids[] = (string) $p['id'];
}
}
+3 -1
View File
@@ -1,5 +1,7 @@
<?php
require_once __DIR__ . '/utils.php';
function getDataDirectory(): string {
return __DIR__ . '/../data';
}
@@ -49,7 +51,7 @@ function writeJsonFile(string $filename, $data): bool {
fclose($fp);
return false;
}
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$json = json_encode($data, JSON_PRETTY_PRINT | familyHubJsonEncodeShellFlags());
if ($json === false) {
flock($fp, LOCK_UN);
fclose($fp);
+2
View File
@@ -1,9 +1,11 @@
</main>
<?php if (empty($isCalendarTvView)): ?>
<footer class="bg-light p-3 mt-4">
<div class="container text-center">
<p>Family Hub &copy; <?= date('Y') ?></p>
</div>
</footer>
<?php endif; ?>
<!-- Bootstrap JS from CDN -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
+4 -2
View File
@@ -1,5 +1,7 @@
<?php
require_once __DIR__ . '/utils.php';
/**
* @param mixed $raw
* @return array<int, array<string, mixed>>
@@ -35,8 +37,8 @@ function normalizeCatalogList($raw): array {
}
function groceryCatalogDedupeKey(string $storeId, string $name, string $size): string {
$n = mb_strtolower(trim($name), 'UTF-8');
$s = mb_strtolower(trim($size), 'UTF-8');
$n = familyHubStrLowerUtf8(trim($name));
$s = familyHubStrLowerUtf8(trim($size));
return $storeId . '|' . $n . '|' . $s;
}
+7 -2
View File
@@ -72,7 +72,7 @@
}
$bodyStyle = implode('; ', $bodyStyleParts) . ';';
?>
<body class="family-hub-body <?= htmlspecialchars($headerThemeClass ?? 'header-tone-dark', ENT_QUOTES, 'UTF-8') ?>" style="<?= htmlspecialchars($bodyStyle, ENT_QUOTES, 'UTF-8') ?>">
<body class="family-hub-body <?= htmlspecialchars($headerThemeClass ?? 'header-tone-dark', ENT_QUOTES, 'UTF-8') ?><?= !empty($isCalendarTvView) ? ' calendar-tv-dark' : '' ?>" style="<?= htmlspecialchars($bodyStyle, ENT_QUOTES, 'UTF-8') ?>">
<?php $hideTopHeader = !empty($isCalendarTvView); ?>
<?php if (!$hideTopHeader): ?>
<header class="app-header app-header-with-tabs text-white pt-3 px-3 pb-2 mb-0">
@@ -220,4 +220,9 @@
<script>
window.familyHubApiBase = <?= json_encode($familyHubApiBase, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP) ?>;
</script>
<main class="container py-4">
<?php
$fhMainClasses = !empty($isCalendarTvView)
? 'container-fluid px-0 py-0'
: 'container py-4';
?>
<main class="<?= htmlspecialchars($fhMainClasses, ENT_QUOTES, 'UTF-8') ?>">
+26
View File
@@ -33,3 +33,29 @@ function familyHubWebApiBase(): string {
}
return $sd . '/api';
}
/**
* Bitmask for json_encode so pasted recipe text (or any user string) with malformed UTF-8
* does not make json_encode return false. Without substitution, failed embeds emit an empty
* &lt;script type="application/json"&gt; and the meals UI hits JSON.parse errors.
*
* @return int
*/
function familyHubJsonEncodeShellFlags(): int {
$f = JSON_UNESCAPED_UNICODE;
if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) {
$f |= JSON_INVALID_UTF8_SUBSTITUTE;
}
return $f;
}
/**
* Lowercase for comparisons and keys. Uses mbstring when available; otherwise ASCII-only strtolower
* so grocery/chore code does not fatal on hosts without ext-mbstring.
*/
function familyHubStrLowerUtf8(string $s): string {
if (function_exists('mb_strtolower')) {
return mb_strtolower($s, 'UTF-8');
}
return strtolower($s);
}