Files
flixcooks-website/helpers.php
T

132 lines
3.6 KiB
PHP

<?php
// Shared helper functions for the FlixCooks food blog.
function load_recipes(): array {
$path = __DIR__ . '/data/recipes.json';
if (!file_exists($path)) {
return [];
}
$json = file_get_contents($path);
$data = json_decode($json, true);
if (!is_array($data)) {
return [];
}
foreach ($data as &$recipe) {
if (!empty($recipe['hero']) && is_string($recipe['hero'])) {
$recipe['hero'] = normalize_asset_path($recipe['hero']);
}
}
unset($recipe);
return $data;
}
function save_recipes(array $recipes): bool {
$path = __DIR__ . '/data/recipes.json';
$json = json_encode($recipes, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
return (bool) file_put_contents($path, $json);
}
function slugify(string $text): string {
$text = strtolower($text);
$text = preg_replace('~[^a-z0-9]+~', '-', $text);
$text = trim($text, '-');
return $text ?: uniqid('recipe-');
}
function find_recipe_by_slug(array $recipes, string $slug): ?array {
foreach ($recipes as $recipe) {
if (($recipe['slug'] ?? '') === $slug) {
return $recipe;
}
}
return null;
}
function localize_recipe(array $recipe, string $lang): array {
$localized = $recipe;
$i18n = $recipe['i18n'][$lang] ?? ($recipe['i18n']['en'] ?? []);
foreach ($i18n as $key => $value) {
$localized[$key] = $value;
}
return $localized;
}
function localize_recipes(array $recipes, string $lang): array {
return array_map(function ($recipe) use ($lang) {
return localize_recipe($recipe, $lang);
}, $recipes);
}
function filter_recipes(array $recipes, ?string $query = null, ?string $tag = null, string $lang = 'en'): array {
$query = $query ? strtolower($query) : null;
$tag = $tag ? strtolower($tag) : null;
$localized = localize_recipes($recipes, $lang);
return array_values(array_filter($localized, function ($recipe) use ($query, $tag) {
$matchesQuery = true;
if ($query) {
$haystack = strtolower(($recipe['title'] ?? '') . ' ' . ($recipe['description'] ?? ''));
$matchesQuery = strpos($haystack, $query) !== false;
}
$matchesTag = true;
if ($tag) {
$tags = array_map('strtolower', $recipe['tags'] ?? []);
$matchesTag = in_array($tag, $tags, true);
}
return $matchesQuery && $matchesTag;
}));
}
function format_minutes(int $minutes): string {
if ($minutes < 60) {
return $minutes . ' min';
}
$hours = intdiv($minutes, 60);
$mins = $minutes % 60;
return $hours . ' hr' . ($hours > 1 ? 's ' : ' ') . ($mins ? $mins . ' min' : '');
}
function e(?string $value): string {
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
function normalize_asset_path(string $path): string {
if (!str_starts_with($path, '/assets/')) {
return $path;
}
$absolute = __DIR__ . $path;
if (file_exists($absolute)) {
return $path;
}
$dir = dirname($absolute);
$target = basename($absolute);
if (!is_dir($dir)) {
return $path;
}
foreach (scandir($dir) ?: [] as $entry) {
if (strcasecmp($entry, $target) === 0) {
return rtrim(dirname($path), '/') . '/' . $entry;
}
}
return $path;
}
/**
* Build a URL to the current path with a specific language parameter, preserving other query params.
*/
function lang_url(string $lang): string {
$params = $_GET;
$params['lang'] = $lang;
$path = strtok($_SERVER['REQUEST_URI'], '?') ?: '/';
return $path . '?' . http_build_query($params);
}