| 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);
/** Optional, reversible one-link navigation patch. No database modifications. */
require_once dirname(__DIR__).'/includes/functions.php';
require_admin_role();
header('Cache-Control: private, no-store');
header('X-Robots-Tag: noindex, nofollow');
$notice='';$error='';
$root=dirname(__DIR__);
$backupDir=dirname($root).'/.polana_menu_v165_backups';
$manifest=$backupDir.'/manifest.json';
$targets=[
'functions'=> $root.'/includes/functions.php',
'content_hub'=> $root.'/admin/polana-centrum-tresci.php',
];
function pm165_inst_e($s):string{return htmlspecialchars((string)$s,ENT_QUOTES|ENT_SUBSTITUTE,'UTF-8');}
function pm165_inst_atomic(string $file,string $content):void{
$tmp=$file.'.pmm165.'.bin2hex(random_bytes(5)).'.tmp';
if(file_put_contents($tmp,$content,LOCK_EX)===false)throw new RuntimeException('Nie można zapisać pliku tymczasowego: '.basename($file));
@chmod($tmp,fileperms($file)&0777);
if(!rename($tmp,$file)){$unused=@unlink($tmp);throw new RuntimeException('Nie można podmienić pliku: '.basename($file));}
}
if(($_SERVER['REQUEST_METHOD']??'GET')==='POST'){
verify_csrf();
try{
$action=(string)($_POST['action']??'');
if($action==='install'){
if(is_file($manifest))throw new RuntimeException('Instalacja jest już zapisana. Najpierw wykonaj rollback albo pozostaw obecną wersję.');
if(!is_file($root.'/admin/polana-menu-centrum.php'))throw new RuntimeException('Najpierw wgraj nowy panel polana-menu-centrum.php.');
if(!is_dir($backupDir) && !mkdir($backupDir,0700,true))throw new RuntimeException('Brak możliwości utworzenia backupu poza WWW. Nowy panel można otworzyć bez instalacji nawigacji.');
$changed=[];$prepared=[];
foreach($targets as $key=>$file){
if(!is_file($file))continue;
$before=file_get_contents($file);
if($before===false)throw new RuntimeException('Nie można odczytać '.basename($file));
$needle='href="/admin/menus.php"';
$replacement='href="/admin/polana-menu-centrum.php"';
if(strpos($before,$replacement)!==false)continue;
if(substr_count($before,$needle)!==1)throw new RuntimeException('Nieznany układ nawigacji '.basename($file).'. Odmowa zmiany.');
if(!is_writable($file))throw new RuntimeException('Brak prawa zapisu '.basename($file).'.');
$after=str_replace($needle,$replacement,$before);
$backup=$backupDir.'/'.$key.'_original.php.bak';
if(file_put_contents($backup,$before,LOCK_EX)===false)throw new RuntimeException('Nie można wykonać kopii '.basename($file));
@chmod($backup,0600);
$prepared[$key]=['path'=>$file,'backup'=>$backup,'after'=>$after,'hash'=>hash('sha256',$after)];
}
if(!$prepared)throw new RuntimeException('Nie znaleziono odnośnika do podmiany lub menu już kieruje do nowego panelu. Niczego nie zmieniono.');
try{
foreach($prepared as $key=>$p){pm165_inst_atomic($p['path'],$p['after']);$changed[]=$key;}
$metadata=[];
foreach($prepared as $key=>$p)$metadata[$key]=['path'=>$p['path'],'backup'=>$p['backup'],'installed_sha256'=>$p['hash']];
$encoded=json_encode($metadata,JSON_THROW_ON_ERROR|JSON_PRETTY_PRINT);
if(file_put_contents($manifest,$encoded,LOCK_EX)===false)throw new RuntimeException('Brak zapisu metadanych rollback.');
@chmod($manifest,0600);
}catch(Throwable $e){
foreach(array_reverse($changed) as $key){$p=$prepared[$key];$old=@file_get_contents($p['backup']);if($old!==false)pm165_inst_atomic($p['path'],$old);}
throw $e;
}
$notice='Przełączono nawigację na nowy panel. Backup jest poza katalogiem WWW.';
}elseif($action==='rollback'){
if(!is_file($manifest))throw new RuntimeException('Brak informacji o instalacji — nie można bezpiecznie cofnąć.');
$data=json_decode((string)file_get_contents($manifest),true,512,JSON_THROW_ON_ERROR);
if(!is_array($data)||!$data)throw new RuntimeException('Nieprawidłowy manifest backupu.');
foreach($data as $entry){
if(!is_array($entry)||!is_file($entry['path']??'')||!is_file($entry['backup']??''))throw new RuntimeException('Brak pliku do cofnięcia.');
if(hash_file('sha256',$entry['path'])!==($entry['installed_sha256']??''))throw new RuntimeException('Plik '.basename($entry['path']).' był zmieniony po instalacji. Automatyczny rollback zatrzymany, aby nie utracić tych zmian.');
}
foreach($data as $entry){$old=file_get_contents($entry['backup']);if($old===false)throw new RuntimeException('Nie można odczytać kopii.');pm165_inst_atomic($entry['path'],$old);}
unlink($manifest);
$notice='Poprzednie linki w nawigacji zostały przywrócone. Nowy panel pozostaje dostępny pod swoim adresem.';
}else throw new RuntimeException('Nieznana akcja.');
}catch(Throwable $e){$error=$e->getMessage();}
}
render_admin_header('V16.5 — instalacja nowego menu');
?>
<main style="max-width:820px;margin:26px auto;padding:18px;background:white;border-radius:18px;color:#233d29">
<h1>Proste menu — instalacja nawigacji V16.5</h1>
<p>Nowy panel menu działa od razu po wgraniu. Tutaj opcjonalnie zmienisz jedynie link „Menu restauracji” w nawigacji i „Centrum treści”. Żadnych zmian bazy ani kasowania funkcji.</p>
<?php if($notice):?><p style="background:#eef9ee;padding:14px"><?=pm165_inst_e($notice)?></p><?php endif;?>
<?php if($error):?><p style="background:#fff1e9;padding:14px"><?=pm165_inst_e($error)?></p><?php endif;?>
<p><a href="/admin/polana-menu-centrum.php">Otwórz nowy panel menu →</a></p>
<p>Backup: <code>../.polana_menu_v165_backups/</code> — katalog nad WWW, jeśli hosting umożliwia zapis.</p>
<form method="post" style="display:inline-block;margin-right:12px"><?=csrf_field()?><button name="action" value="install" style="padding:13px;background:#285234;color:white;border:0;border-radius:9px;cursor:pointer">Włącz proste menu</button></form>
<form method="post" style="display:inline-block"><?=csrf_field()?><button name="action" value="rollback" style="padding:13px;background:#ecefe9;border:0;border-radius:9px;cursor:pointer">Przywróć stare linki</button></form>
<p style="font-size:13px;color:#58695a">Instalator działa tylko przy dokładnie rozpoznanym linku w plikach. Gdy struktura jest inna — przerwie operację bez zgadywania.</p>
</main>
<?php render_admin_footer(); ?>