| 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();
require_once dirname(__DIR__).'/includes/polana_v12_pages.php';
$webroot=dirname(__DIR__);$target=$webroot.'/includes/functions.php';
$backdir=$webroot.'/storage/v12-backup';$manifest=$backdir.'/active.json';
$error='';$info='';
function p12_patch_functions(string $src): string {
if(str_contains($src,'/* POLANA_V12_SERVER_I18N */'))throw new RuntimeException('V12 jest już zainstalowana.');
$start=strpos($src,'function render_public_head(');
$end=strpos($src,'function render_public_header(',$start===false?0:$start);
if($start===false||$end===false||$end<=$start)throw new RuntimeException('Nie znaleziono publicznego nagłówka.');
$head=substr($src,$start,$end-$start);
if(!str_contains($head,'p11_page_ready('))throw new RuntimeException('Nie znaleziono V11 w nagłówku. Najpierw aktywuj V11.');
$needle='render_global_site_splash_if_needed();';
if(substr_count($head,$needle)!==1)throw new RuntimeException('Nie rozpoznano punktu wejścia strony.');
$inject=$needle."\n /* POLANA_V12_SERVER_I18N */\n require_once __DIR__.'/polana_v12_pages.php';\n p12_boot();";
$head=str_replace($needle,$inject,$head);
return substr($src,0,$start).$head.substr($src,$end);
}
if($_SERVER['REQUEST_METHOD']==='POST'){
verify_csrf();
try{
$action=(string)($_POST['action']??'');
if($action==='install'){
if(is_file($manifest))throw new RuntimeException('Istnieje aktywny manifest V12.');
if(!is_file($target)||!is_readable($target)||!is_writable($target))throw new RuntimeException('Brak dostępu do functions.php');
$current=file_get_contents($target);if($current===false)throw new RuntimeException('Błąd odczytu functions.php');
$next=p12_patch_functions($current);
p12_schema();
if(!is_dir($backdir)&&!mkdir($backdir,0700,true))throw new RuntimeException('Nie można utworzyć folderu kopii.');
file_put_contents($backdir.'/.htaccess',"Require all denied\n",LOCK_EX);
$name='functions_'.date('Ymd_His').'_'.bin2hex(random_bytes(3)).'.php.bak';
$back=$backdir.'/'.$name;
if(file_put_contents($back,$current,LOCK_EX)!==strlen($current))throw new RuntimeException('Błąd tworzenia kopii.');
// Optimistic concurrency check: do not overwrite a file modified by another deployment.
if(hash_file('sha256',$target)!==hash('sha256',$current))throw new RuntimeException('functions.php zmienił się podczas instalacji.');
$tmp=$target.'.v12tmp_'.bin2hex(random_bytes(4));
if(file_put_contents($tmp,$next,LOCK_EX)!==strlen($next))throw new RuntimeException('Błąd zapisu wersji tymczasowej.');
@chmod($tmp,fileperms($target)&0777);
if(!rename($tmp,$target)){@unlink($tmp);throw new RuntimeException('Nie udało się podmienić functions.php.');}
$data=['backup'=>$back,'target'=>$target,'installed_sha256'=>hash('sha256',$next),'original_sha256'=>hash('sha256',$current)];
file_put_contents($manifest,json_encode($data,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES),LOCK_EX);
admin_log('v12_installed','Podstrony i18n');
$info='Zainstalowano V12. Wykonaj skanowanie i testy wersji językowych.';
}elseif($action==='rollback'){
if(!is_file($manifest))throw new RuntimeException('Brak aktywnego manifestu V12.');
$meta=json_decode((string)file_get_contents($manifest),true,512,JSON_THROW_ON_ERROR);
if(!is_file((string)($meta['backup']??'')))throw new RuntimeException('Brak kopii pliku.');
if(hash_file('sha256',$target)!==($meta['installed_sha256']??''))throw new RuntimeException('functions.php był zmieniany od instalacji V12. Nie nadpisuję nowszych zmian!');
if(!copy($meta['backup'],$target))throw new RuntimeException('Nie można przywrócić functions.php.');
unlink($manifest);
$info='Przywrócono wcześniejsze functions.php. Baza tłumaczeń pozostaje nietknięta.';
}else throw new RuntimeException('Błędna operacja');
}catch(Throwable $e){$error=$e->getMessage();error_log('POLANA V12 installer: '.$error);}
}
render_admin_header('Polana V12 — instalacja');
?>
<div style="max-width:850px;margin:25px auto;padding:22px;background:#fff;border:1px solid #ddd;border-radius:12px;color:#232923">
<h1>POLANA V12 — podstrony PL / EN / DE / ES</h1>
<p>Wdraża jedną bezpieczną wstawkę w <code>includes/functions.php</code>, bez podmiany obecnych podstron ani tłumaczeń V9. Tworzy jedną tabelę kolejki w obecnej MariaDB.</p>
<p><b>Wymagana jest wcześniej aktywowana wersja V11</b> (flagi, routing i SEO).</p>
<?php if($error): ?><p style="color:#a22"><b><?=e($error)?></b></p><?php endif; ?>
<?php if($info): ?><p style="color:#17622c"><b><?=e($info)?></b></p><?php endif; ?>
<form method="post" style="margin:16px 0"><?=csrf_field()?> <button name="action" value="install" onclick="return confirm('Wykonać backup i zainstalować V12?')">Zainstaluj V12</button></form>
<form method="post" style="margin:16px 0"><?=csrf_field()?> <button name="action" value="rollback" onclick="return confirm('Wycofać wstawkę V12?')">Rollback V12</button></form>
<p><a href="/admin/polana-v12-podstrony.php">Przejdź do centrum tłumaczeń podstron →</a></p>
<p>Po instalacji i zakończeniu testów usuń ten instalator z serwera. Kopie pozostaną w <code>storage/v12-backup/</code>.</p>
</div>
<?php render_admin_footer(); ?>