| Server IP : 188.114.96.3 / Your IP : 216.73.216.143 Web Server : Apache System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64 User : ( 3194769) PHP Version : 8.5.12 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /polana/includes/ |
Upload File : |
<?php
declare(strict_types=1);
/* Public localization: reviewed translations only; no runtime remote MT. */
require_once __DIR__.'/polana_site_translations.php';
function polana_lang(): string
{
return (($_GET['lang'] ?? '') === 'en' || preg_match('~^/en(?:/|$)~', parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/')) ? 'en' : 'pl';
}
function polana_menu_type(string $type): string
{
return in_array($type, ['food','soft','wine'], true) ? $type : 'food';
}
function polana_types(): array
{
return ['food'=>['pl'=>'Dania', 'en'=>'Food'], 'soft'=>['pl'=>'Napoje bezalkoholowe','en'=>'Soft drinks'], 'wine'=>['pl'=>'Wina','en'=>'Wines']];
}
function polana_type_label(string $type, ?string $lang = null): string
{
return polana_types()[polana_menu_type($type)][$lang ?? polana_lang()];
}
function polana_schema_ready(): bool
{
static $ready = null;
if ($ready !== null) return $ready;
try {
$cols = db()->query("SHOW COLUMNS FROM menus LIKE 'menu_type'")->fetchAll();
return $ready = (count($cols) > 0);
} catch (Throwable $e) {
return $ready = false;
}
}
function polana_menu_value(array $row, string $field): string
{
if (polana_lang() === 'en' && !empty($row[$field.'_en'])) {
return trim((string)$row[$field.'_en']);
}
if (polana_lang() === 'en' && in_array($field, ['description', 'ingredients', 'allergens'], true)) {
// Do not present Polish allergen information as an English translation.
return '';
}
if (polana_lang() === 'en' && $field === 'name' && isset($row['menu_id'])) {
$categories = [
'Przed zupą' => 'Starters', 'Zupa' => 'Soups', 'Zupy' => 'Soups',
'Dania główne' => 'Main courses', 'Dania' => 'Dishes', 'Desery' => 'Desserts',
'Słodkie zakończenie' => 'Sweet endings', 'Sałatki' => 'Salads',
'Napoje' => 'Drinks', 'Napoje zimne' => 'Cold drinks', 'Napoje gorące' => 'Hot drinks',
'Wina białe' => 'White wines', 'Wina czerwone' => 'Red wines', 'Wina musujące' => 'Sparkling wines',
];
return $categories[(string)($row[$field] ?? '')] ?? (string)($row[$field] ?? '');
}
return (string)($row[$field] ?? '');
}
function polana_routes(): array
{
return [
'/' => '/', '/menu'=>'/menu', '/menu-seo'=>'/menu-seo', '/menu-druk'=>'/menu-druk',
'/menu-karta.svg'=>'/menu-karta.svg', '/andrzej-polan'=>'/chef', '/kontakt'=>'/contact',
'/rezerwacja'=>'/reservation', '/polityka-prywatnosci'=>'/privacy', '/alergeny'=>'/allergens',
'/galeria'=>'/gallery', '/blog'=>'/blog', '/wspolpraca'=>'/cooperation',
'/opinie'=>'/reviews', '/opinia'=>'/review', '/newsletter.php'=>'/newsletter', '/404'=>'/404',
];
}
function polana_local_path(string $path, ?string $lang = null): string
{
$lang = $lang ?? polana_lang();
$parsed = parse_url($path);
if ($parsed === false) return $path;
$route = $parsed['path'] ?? '/';
$route = '/' . trim($route, '/');
if ($route === '//') $route = '/';
if (str_starts_with($route, '/en/')) {
$route = substr($route, 3);
} elseif ($route === '/en') {
$route = '/';
}
$mapping = polana_routes();
$reversed = array_flip($mapping);
$plPath = $reversed[$route] ?? $route;
if (preg_match('~^/blog/([a-z0-9-]+)/?$~', $route)) $plPath = $route;
$known = array_key_exists($plPath, $mapping) || (bool)preg_match('~^/blog/[a-z0-9-]+/?$~', $plPath);
// Keep unknown endpoints on their original route; never fabricate /en/admin or /en/api handlers.
$localized = ($lang === 'en' && $known) ? '/en' . ($mapping[$plPath] ?? $plPath) : $plPath;
if ($localized === '/en/') $localized = '/en/';
return $localized . (isset($parsed['query']) ? '?' . $parsed['query'] : '') . (isset($parsed['fragment']) ? '#' . $parsed['fragment'] : '');
}
function polana_switch_url(string $to): string
{
$url = (string)($_SERVER['REQUEST_URI'] ?? '/');
// Preserve menu kind/QR while removing internal rewrite language parameter.
$parsed = parse_url($url);
$query = [];
if (!empty($parsed['query'])) parse_str($parsed['query'], $query);
unset($query['lang']);
$new = polana_local_path($parsed['path'] ?? '/', $to);
return $new . ($query ? '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986) : '');
}
function polana_english_strings(): array
{
return require __DIR__.'/polana_en_dictionary.php';
}
function polana_translate_text(string $s): string
{
static $normalized = null;
if ($normalized === null) {
$normalized = [];
foreach (polana_english_strings() as $pl => $en) {
$normalized[preg_replace('/\s+/u', ' ', trim($pl))] = $en;
}
}
$leading = preg_match('/^\s*/u', $s, $m) ? $m[0] : '';
$trailing = preg_match('/\s*$/u', $s, $m) ? $m[0] : '';
$key = preg_replace('/\s+/u', ' ', trim($s));
$published = polana_site_translation_published('dictionary', $key);
if ($published !== null) return $leading . $published . $trailing;
return isset($normalized[$key]) ? $leading . $normalized[$key] . $trailing : $s;
}
function polana_translate_public_html(string $html): string
{
if (polana_lang() !== 'en') return $html;
// Do not alter CSS/JS, whose strings sometimes match Polish UI labels.
$chunks = preg_split('~(<(?:script|style)\b[^>]*>.*?</(?:script|style)>)~is', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
if (!is_array($chunks)) return $html;
foreach ($chunks as $i => $piece) {
if (preg_match('~^<(?:script|style)\b~i', $piece)) continue;
$piece = preg_replace_callback('~(?<=>)[^<>]+(?=<)~u', static function ($m) {
$translated = polana_translate_text($m[0]);
return $translated === $m[0] ? $m[0] : htmlspecialchars($translated, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
}, $piece) ?? $piece;
$piece = preg_replace_callback('~\b(title|alt|aria-label|placeholder|content)=("|\')(.*?)\2~u', static function ($m) {
$translated = polana_translate_text($m[3]);
return $m[1] . '=' . $m[2] . ($translated === $m[3] ? $m[3] : htmlspecialchars($translated, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')) . $m[2];
}, $piece) ?? $piece;
// Process complete tags: the Polish language-switch link must remain Polish.
$piece = preg_replace_callback('~<(?:a|form)\b[^>]*>~iu', static function ($match) {
$tag = $match[0];
if (preg_match('~\bhreflang=("|\')pl\1~i', $tag)) return $tag;
return preg_replace_callback('~\b(href|action)=("|\')(/(?!admin/|assets/|uploads/|pracownik/|tipy/|api/|manifest|service-worker|sitemap|robots)[^"\']*)\2~u', static function ($m) {
return $m[1] . '=' . $m[2] . polana_local_path($m[3], 'en') . $m[2];
}, $tag) ?? $tag;
}, $piece) ?? $piece;
$chunks[$i] = $piece;
}
return implode('', $chunks);
}
/**
* After DNS cutover, legacy absolute hyperlinks entered by editors in HTML
* are rewritten at render time to the new host, without mutating the DB.
* External websites/domains and relative links are deliberately untouched.
*/
function polana_rewrite_legacy_public_links(string $html): string
{
$origin = rtrim(site_url(), '/');
if ($origin !== 'https://mojapolanasmakow.pl') return $html;
$pattern = <<<'REGEX'
~(\b(?:href|src|action|poster|content)\s*=\s*)(["'])((?:https?:)?//)(?:www\.)?polanasmakow\.pl(?=/|\?|#|["'])([^"']*)\2~i
REGEX;
return preg_replace_callback($pattern, static function (array $m) use ($origin): string {
return $m[1] . $m[2] . $origin . $m[4] . $m[2];
}, $html) ?? $html;
}
function polana_start_public_link_buffer(): void
{
static $started = false;
if ($started || rtrim(site_url(), '/') !== 'https://mojapolanasmakow.pl') return;
$started = true;
ob_start('polana_rewrite_legacy_public_links');
}
function polana_start_translation_buffer(): void
{
polana_start_public_link_buffer();
static $started = false;
if ($started || polana_lang() !== 'en') return;
$started = true;
ob_start('polana_translate_public_html');
}
function polana_menu_tabs(string $selected, string $path = '/menu'): void
{
echo '<nav class="polana-kind-tabs" aria-label="' . (polana_lang() === 'en' ? 'Menu sections' : 'Rodzaje kart') . '">';
foreach (polana_types() as $type => $labels) {
$url = polana_local_path($path, polana_lang()) . '?kind=' . rawurlencode($type);
$active = $selected === $type ? ' active' : '';
echo '<a class="' . trim($active) . '" href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '">' . htmlspecialchars($labels[polana_lang()], ENT_QUOTES, 'UTF-8') . '</a>';
}
echo '</nav>';
}