| 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/admin/ |
Upload File : |
<?php
declare(strict_types=1);
require_once dirname(__DIR__).'/includes/functions.php';
require_admin_role();
$root=dirname(__DIR__);
$dir=$root.'/storage/polana-v15-backups';
$manifest=$dir.'/manifest.json';
$error='';$notice='';
function p15_patch_file(string $src,string $name):string {
if(str_contains($src,'POLANA_V15_MENU_PUBLIC'))return $src;
$line="require_once __DIR__ . '/includes/functions.php';";
if(substr_count($src,$line)!==1)throw new RuntimeException("Nierozpoznany include w $name — bez zmian");
$src=str_replace($line,$line."\n/* POLANA_V15_MENU_PUBLIC */\nrequire_once __DIR__ . '/includes/polana_v15_menu.php';",$src);
$src=preg_replace('/\bpolana_menu_value\s*\(/','p15_menu_text(',$src);
$src=preg_replace('/\bpolana_lang\s*\(\s*\)/','p15_menu_lang()',$src);
$src=preg_replace('/\bpolana_type_label\s*\(/','p15_menu_type_label(',$src);
$src=preg_replace('/\bpolana_menu_tabs\s*\(/','p15_menu_tabs(',$src);
$src=preg_replace('/\bactive_menu\s*\(\s*\$menuType\s*\)/','p15_active_menu($menuType)',$src);
// Explicitly transport locale and kind to SVG/print/text routes. Prevent EN fallback after DE/ES flag switch.
$src=preg_replace_callback('~<\?=\s*e\(polana_local_path\(\'(/menu-karta\.svg|/alergeny|/menu-seo|/menu-druk|/menu)\'\)\)\s*\?>\?kind=<\?=\s*e\(\$menuType\)\s*\?>~',
static fn($m)=>"<?= e(p15_menu_url('".$m[1]."',\$menuType)) ?>",$src);
$src=str_replace("site_url(polana_local_path('/menu-seo') . '?kind=' . \$menuType)","site_url(p15_menu_url('/menu-seo',\$menuType))",$src);
if($name==='menu-seo.php'){
$src=str_replace("\$menuSchema, 'index,follow'","\$menuSchema, p15_menu_complete(\$categories) ? 'index,follow' : 'noindex,follow'",$src);
}
if($name==='menu.php'){
$src=str_replace('<span class="eyebrow">Aktualna karta</span>','<span class="eyebrow"><?= e(p15_menu_ui(\'Aktualna karta\')) ?></span>',$src);
foreach(['Pokaż menu','Składniki i alergeny','Wersja tekstowa menu','Drukuj / zapisz PDF','Menu restauracji','Zamknij'] as $label){
// Only text node contents, never arbitrary code or hrefs.
$src=str_replace('>'.$label.'<','><?= e(p15_menu_ui(\''.$label.'\')) ?><',$src);
}
}
if($name==='menu-druk.php'){
$src=str_replace("polana_ui('Drukuj / zapisz jako PDF')","p15_menu_ui('Drukuj / zapisz PDF')",$src);
$src=str_replace("polana_ui('Wróć do menu')","p15_menu_ui('Wróć do menu')",$src);
$src=str_replace('Machine translation / missing names — review before publication.',
'Some menu translations need review before printing.',$src);
}
if($name==='alergeny.php'){
$src=str_replace('<strong>Składniki:</strong>','<strong><?= e(p15_menu_ui(\'Składniki:\')) ?></strong>',$src);
$src=str_replace('<strong>Alergeny:</strong>','<strong><?= e(p15_menu_ui(\'Alergeny:\')) ?></strong>',$src);
}
return $src;
}
if(($_SERVER['REQUEST_METHOD']??'')==='POST'){
verify_csrf();
try{
$action=(string)($_POST['action']??'');
if(!in_array($action,['install','rollback'],true))throw new RuntimeException('Nieprawidłowa akcja');
if($action==='rollback'){
if(!is_file($manifest))throw new RuntimeException('Nie ma manifestu V15');
$data=json_decode((string)file_get_contents($manifest),true,512,JSON_THROW_ON_ERROR);
foreach($data['files'] as $r){
$file=$root.'/'.$r['name'];$backup=$dir.'/'.$r['backup'];
if(!is_file($file)||!is_file($backup))throw new RuntimeException('Brak pliku lub backupu '.$r['name']);
if(hash_file('sha256',$file)!==$r['installed_sha'])throw new RuntimeException('Plik '.$r['name'].' zmieniono po V15 — rollback ręczny, aby nie utracić zmian');
}
foreach($data['files'] as $r){
if(file_put_contents($root.'/'.$r['name'],file_get_contents($dir.'/'.$r['backup']),LOCK_EX)===false)throw new RuntimeException('Rollback niekompletny');
}
unlink($manifest);$notice='Przywrócono pięć plików menu sprzed V15.';
}else{
if(is_file($manifest))throw new RuntimeException('V15 już zainstalowana. Zamiast ponownej instalacji skorzystaj z panelu menu.');
$names=['menu.php','menu-karta.php','menu-seo.php','menu-druk.php','alergeny.php'];
$patches=[];
foreach($names as $name){
$path=$root.'/'.$name;
if(!is_file($path)||!is_readable($path)||!is_writable($path)||is_link($path))throw new RuntimeException('Brak dostępu do '.$name);
$before=file_get_contents($path);
if($before===false)throw new RuntimeException('Nie można odczytać '.$name);
$after=p15_patch_file($before,$name);
if($after===$before)throw new RuntimeException('Brak zmian lub V15 już obecna w '.$name);
if(!str_contains($after,'POLANA_V15_MENU_PUBLIC'))throw new RuntimeException('Nie rozpoznano miejsca integracji '.$name);
$patches[]=['name'=>$name,'original'=>$before,'content'=>$after];
}
if(!is_dir($dir)&&!mkdir($dir,0700,true))throw new RuntimeException('Nie można stworzyć katalogu backupu');
$data=['files'=>[]];$done=[];
try{
foreach($patches as $r){
$backup=$r['name'].'-'.date('YmdHis').'.bak';
if(file_put_contents($dir.'/'.$backup,$r['original'],LOCK_EX)===false)throw new RuntimeException('Backup nieudany');
$data['files'][]=['name'=>$r['name'],'backup'=>$backup,'installed_sha'=>hash('sha256',$r['content'])];
}
foreach($patches as $r){
$temp=$root.'/'.$r['name'].'.v15tmp';
if(file_put_contents($temp,$r['content'],LOCK_EX)===false)throw new RuntimeException('Brak możliwości zapisu '.$r['name']);
@chmod($temp,fileperms($root.'/'.$r['name']) & 0777);
if(!rename($temp,$root.'/'.$r['name']))throw new RuntimeException('Podmiana pliku nieudana '.$r['name']);
$done[]=$r;
}
if(file_put_contents($manifest,json_encode($data,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE),LOCK_EX)===false)throw new RuntimeException('Nie można zapisać manifestu');
$notice='V15 aktywna. Przetestuj /en/menu, /de/menu, /es/menu i uruchom panel kolejek.';
}catch(Throwable $e){
foreach($done as $r)file_put_contents($root.'/'.$r['name'],$r['original'],LOCK_EX);
throw $e;
}
}
}catch(Throwable $e){$error=$e->getMessage();error_log('Polana V15 installer: '.$e->getMessage());}
}
render_admin_header('Polana V15 — Menu i języki');
?>
<main style="max-width:900px;margin:30px auto;padding:16px">
<h1>V15 — Naprawa języków menu</h1>
<p>Ujednolica wybór PL / EN / DE / ES i oddzielne karty Dania / Napoje / Wina. Nie dotyka bloga ani tłumaczeń w bazie.</p>
<p>Przed instalacją wykonaj backup bazy i katalogu strony. Instalator robi też lokalną kopię 5 plików i obsługuje rollback.</p>
<?php if($error):?><p style="color:#a11"><?=e($error)?></p><?php endif;?>
<?php if($notice):?><p style="color:#175e28"><?=e($notice)?></p><?php endif;?>
<p>Stan: <?=is_file($manifest)?'Zainstalowano':'Nie zainstalowano'?></p>
<form method="post" style="display:flex;gap:15px;flex-wrap:wrap">
<?=csrf_field()?><button name="action" value="install" type="submit">Instaluj V15</button>
<button name="action" value="rollback" type="submit" onclick="return confirm('Przywrócić poprzednie pliki menu?')">Rollback V15</button></form>
<p><a href="/admin/polana-v15-menu.php">Centrum języków menu</a></p>
</main>
<?php render_admin_footer(); ?>