Plan Your Visit landing page for visit.waterschurch.org
Next.js 16 static export + PHP 8 API for cPanel/Apache hosting. - Location-aware campus finder (IP estimate, optional precise location, ZIP search) - Three-step Plan Your Visit form with separate email/SMS consent - PHP API: validation, anti-spam, rate limiting, SQLite lead store, Mailchimp and Sinch Engage adapters, idempotent retries via cron - Attribution capture (utm_*, gclid/gbraid/wbraid, fbclid, ttclid, twclid) and consent-aware analytics hooks - Vitest and PHP test suites, cPanel deployment script and docs Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Reads the shared campus configuration (config/campuses.json). The build
|
||||
* copies it to api/config/campuses.json; in local development we fall back to
|
||||
* the repo copy.
|
||||
*/
|
||||
final class Campuses
|
||||
{
|
||||
/** @var array<string,array<string,mixed>>|null */
|
||||
private static ?array $byId = null;
|
||||
|
||||
/** @return array<string,array<string,mixed>> */
|
||||
public static function all(): array
|
||||
{
|
||||
if (self::$byId !== null) {
|
||||
return self::$byId;
|
||||
}
|
||||
$candidates = [
|
||||
dirname(__DIR__) . '/config/campuses.json',
|
||||
dirname(__DIR__, 3) . '/config/campuses.json',
|
||||
];
|
||||
foreach ($candidates as $file) {
|
||||
if (is_readable($file)) {
|
||||
$data = json_decode((string)file_get_contents($file), true);
|
||||
if (is_array($data) && isset($data['campuses'])) {
|
||||
$out = [];
|
||||
foreach ($data['campuses'] as $c) {
|
||||
$out[$c['id']] = $c;
|
||||
}
|
||||
return self::$byId = $out;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException('campuses.json not found');
|
||||
}
|
||||
|
||||
/** @return array<string,mixed>|null */
|
||||
public static function get(string $id): ?array
|
||||
{
|
||||
return self::all()[$id] ?? null;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public static function openIds(): array
|
||||
{
|
||||
return array_keys(array_filter(self::all(), static fn($c) => ($c['status'] ?? 'open') === 'open'));
|
||||
}
|
||||
|
||||
/** "Sunday 9:30 AM" style summary of the first service day. */
|
||||
public static function timesSummary(array $campus): string
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($campus['serviceTimes'] ?? [] as $st) {
|
||||
$parts[] = $st['day'] . ' ' . implode(', ', $st['times']);
|
||||
}
|
||||
return implode(' · ', $parts);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user