Josh's Changes
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 © <?= 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>
|
||||
|
||||
@@ -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
@@ -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') ?>">
|
||||
|
||||
@@ -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
|
||||
* <script type="application/json"> 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user