Static-turned-PHP site for a pub in Marion, Indiana, with: - Hero section with tiled brick-texture background - Live-capable stat card (Facebook followers/reviews via Graph API, with graceful fallback to config.php constants when no token is set) - Open Graph / Twitter Card meta tags for social sharing - robots.txt config.php is gitignored (holds a Facebook Page Access Token once generated); config.sample.php is the tracked template — copy it to config.php and fill in values to run this locally or in deployment.
95 lines
3.1 KiB
PHP
95 lines
3.1 KiB
PHP
<?php
|
|
/**
|
|
* Pulls "recommend %", review count, and follower count from The Old
|
|
* Fitz's Facebook Page via the Graph API, cached to a local JSON file so
|
|
* we don't hit Facebook on every page load. Falls back to the numbers in
|
|
* config.php whenever there's no access token yet, or the API call fails
|
|
* for any reason — the homepage never breaks because of this.
|
|
*
|
|
* Known limitation: Facebook's newer thumbs-up/down "recommendation"
|
|
* system (the "X% recommend (Y reviews)" wording used on the Page today)
|
|
* doesn't have a confirmed, stable Graph API field the way star ratings
|
|
* do. This code requests overall_star_rating/rating_count and converts
|
|
* a star rating to a percentage if Facebook returns one; if the Page's
|
|
* review data isn't exposed that way, recommend_pct/review_count will
|
|
* silently stay at the config.php fallback while followers_count still
|
|
* goes live. That's expected, not a bug — Meta's review-related API
|
|
* access has gotten more restricted over time.
|
|
*/
|
|
|
|
function fritz_facebook_stats(): array {
|
|
$fallback = [
|
|
'recommend_pct' => FB_FALLBACK_RECOMMEND_PCT,
|
|
'review_count' => FB_FALLBACK_REVIEW_COUNT,
|
|
'followers' => FB_FALLBACK_FOLLOWERS,
|
|
'source' => 'fallback',
|
|
'fetched_at' => null,
|
|
];
|
|
|
|
if (FB_PAGE_ACCESS_TOKEN === '') {
|
|
return $fallback;
|
|
}
|
|
|
|
$cacheFile = __DIR__ . '/../cache/facebook-stats.json';
|
|
|
|
if (is_file($cacheFile)) {
|
|
$cached = json_decode((string) file_get_contents($cacheFile), true);
|
|
if (is_array($cached) && (time() - ($cached['fetched_at'] ?? 0)) < FB_STATS_CACHE_TTL) {
|
|
$cached['source'] = 'cache';
|
|
return $cached;
|
|
}
|
|
}
|
|
|
|
$fresh = fritz_fetch_facebook_stats($fallback);
|
|
$fresh['fetched_at'] = time();
|
|
|
|
$cacheDir = dirname($cacheFile);
|
|
if (!is_dir($cacheDir)) {
|
|
@mkdir($cacheDir, 0775, true);
|
|
}
|
|
@file_put_contents($cacheFile, json_encode($fresh));
|
|
|
|
return $fresh;
|
|
}
|
|
|
|
function fritz_fetch_facebook_stats(array $fallback): array {
|
|
if (!function_exists('curl_init')) {
|
|
return $fallback;
|
|
}
|
|
|
|
$url = sprintf(
|
|
'https://graph.facebook.com/v21.0/%s?fields=followers_count,overall_star_rating,rating_count&access_token=%s',
|
|
FB_PAGE_ID,
|
|
urlencode(FB_PAGE_ACCESS_TOKEN)
|
|
);
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 5,
|
|
]);
|
|
$body = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($body === false || $httpCode !== 200) {
|
|
return $fallback;
|
|
}
|
|
|
|
$data = json_decode($body, true);
|
|
if (!is_array($data) || isset($data['error'])) {
|
|
return $fallback;
|
|
}
|
|
|
|
$recommendPct = isset($data['overall_star_rating'])
|
|
? (int) round(($data['overall_star_rating'] / 5) * 100)
|
|
: $fallback['recommend_pct'];
|
|
|
|
return [
|
|
'recommend_pct' => $recommendPct,
|
|
'review_count' => $data['rating_count'] ?? $fallback['review_count'],
|
|
'followers' => $data['followers_count'] ?? $fallback['followers'],
|
|
'source' => 'live',
|
|
];
|
|
}
|