| 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);
/** Instalator: modyfikuje wyłącznie admin/menus.php; kopia w pliku PHP blokującym odczyt przez HTTP. */
require_once dirname(__DIR__).'/includes/functions.php';
require_admin_role();
$path=__DIR__.'/menus.php';
$marker='TKLM_WORD_V5_LINKS';
$message='';$status='';
function tklm_v5_inject(string $text): array {
if(str_contains($text,'TKLM_WORD_V5_LINKS')) return ['already', $text];
if(!preg_match_all('~Word\s*PL[^<]{0,80}</a>~iu',$text,$matches,PREG_OFFSET_CAPTURE)) return ['no_anchor',$text];
if(count($matches[0])!==1) return ['ambiguous',$text];
[$match,$offset]=$matches[0][0]; $position=$offset+strlen($match);
// Wstrzykniecie tylko do sekcji HTML, nie do literału PHP lub JS.
$cursor=0;$inline=false;
foreach(token_get_all($text, TOKEN_PARSE) as $tok) {
$segment=is_array($tok)?$tok[1]:$tok;
if($cursor<=$position-1 && $position-1<$cursor+strlen($segment)) {
$inline=is_array($tok) && $tok[0]===T_INLINE_HTML;
break;
}
$cursor+=strlen($segment);
}
if(!$inline) return ['not_html',$text];
$inject="
<?php /* TKLM_WORD_V5_LINKS */ require_once dirname(__DIR__).'/includes/tklm_word_v5.php'; echo tklm_v5_word_buttons((int)(\$menu['id'] ?? \$m['id'] ?? \$row['id'] ?? 0)); ?>";
$updated=substr($text,0,$position).$inject.substr($text,$position);
token_get_all($updated,TOKEN_PARSE);
return ['ok',$updated];
}
if($_SERVER['REQUEST_METHOD']==='POST') {
verify_csrf();
if(($_POST['action']??'')==='install') {
try {
if(!is_file($path) || !is_readable($path)) throw new RuntimeException('Brak admin/menus.php.');
$original=file_get_contents($path);if($original===false)throw new RuntimeException('Nie można odczytać menus.php');
[$status,$modified]=tklm_v5_inject($original);
if($status==='already') {$message='Przyciski już dodane — nic nie zmieniam.';}
elseif($status!=='ok') throw new RuntimeException('Brak bezpiecznego miejsca na przyciski ('.$status.'). Użyj samodzielnej strony tklm-word-jezyki.php — nie nadpisuję menus.php.');
else {
$backdir=__DIR__.'/_tklm_word_v5_backups';
if(!is_dir($backdir) && !mkdir($backdir,0700,true))throw new RuntimeException('Nie można utworzyć katalogu kopii.');
$backup=$backdir.'/menus_'.date('Ymd_His').'_'.bin2hex(random_bytes(4)).'.php';
$guard="<?php http_response_code(404); exit; __halt_compiler();
";
if(file_put_contents($backup,$guard.$original,LOCK_EX)===false)throw new RuntimeException('Nie zapisano kopii źródłowej.');
chmod($backup,0600);
if(!is_writable($path))throw new RuntimeException('Brak prawa zapisu menus.php. Kopia jest gotowa. Pobierz zmianę przez FTP.');
$before=hash_file('sha256',$path);
if($before!==hash('sha256',$original))throw new RuntimeException('Plik zmienił się podczas przygotowania — przerwano.');
if(file_put_contents($path,$modified,LOCK_EX)===false)throw new RuntimeException('Błąd zapisu menus.php');
if(file_get_contents($path)!==$modified){ file_put_contents($path,$original,LOCK_EX);throw new RuntimeException('Weryfikacja zapisu nie przeszła; przywrócono kopię.'); }
$message='Gotowe. Przyciski dodano po Word PL. Backup: '.basename($backup);$status='ok';
}
} catch(Throwable $e){$status='error';$message=$e->getMessage();}
}
}
render_admin_header('TKLM Word — języki V5');
?>
<div class="form-card" style="max-width:940px">
<h1>TKLM Word — przyciski EN/DE/ES</h1>
<p>PL pozostaje bez zmian. EN/DE/ES pojawiają się tylko przy zapisanych tłumaczeniach; niekompletne wersje są oznaczone jako robocze.</p>
<?php if($message):?><p style="padding:12px;border:1px solid #aaa"><strong><?=e($status)?></strong>: <?=e($message)?></p><?php endif;?>
<p>Zakres instalacji: tylko <code>admin/menus.php</code>. Nie modyfikuje SQL, API, kluczy, rezerwacji ani plików eksportu V4.</p>
<form method="post"><?=csrf_field()?><input type="hidden" name="action" value="install"><button class="btn btn-primary">Dodaj przyciski do listy kart</button></form>
<p style="margin-top:20px"><a href="/admin/tklm-word-jezyki.php?menu_id=12">Otwórz eksport dla karty #12 (działa bez zmian listy)</a></p>
<p><small>Po wdrożeniu usuń przez FTP plik instalatora. Kopie zapisane jako osłonięte pliki PHP.</small></p>
</div>
<?php render_admin_footer(); ?>