403Webshell
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 :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /polana/admin/polana-menu-seo-v191.php
<?php
declare(strict_types=1);
/**
 * POLANA MENU SEO V19.1
 * Surgical installer: adds one visual H1 to the active public menu rendering.
 * Does not touch QR/SVG, reservations, database, redirects or calendar.
 * Copy to /admin/polana-menu-seo-v191.php (authenticated admin only).
 */
require_once dirname(__DIR__) . '/includes/functions.php';
require_admin_role();
header('Cache-Control: private, no-store');
header('X-Robots-Tag: noindex, nofollow');

const PM191_TAG = 'POLANA_MENU_SEO_V191';
const PM191_REL = 'menu.php';
const PM191_VERSION = '19.1';

function pm191_e($value): string { return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
function pm191_root(): string {
    $root=realpath(dirname(__DIR__));
    if ($root===false || !is_file($root.'/menu.php')) throw new RuntimeException('Nie znaleziono aktywnego katalogu witryny.');
    return $root;
}
function pm191_read(string $path): string {
    if (!is_file($path) || is_link($path)) throw new RuntimeException('Nieprawidłowy plik źródłowy.');
    $value=@file_get_contents($path);
    if (!is_string($value)) throw new RuntimeException('Brak możliwości odczytu pliku.');
    return $value;
}
function pm191_patch(string $before): string {
    if (str_contains($before, PM191_TAG)) throw new RuntimeException('Plik zawiera znacznik V19.1. Instalacja nie nadpisuje istniejącej poprawki.');
    $needle='            <?php p15_menu_tabs($menuType); ?>';
    if (substr_count($before,$needle)!==1) throw new RuntimeException('menu.php ma inną strukturę niż zatwierdzony wariant. Instalacja wstrzymana.');
    // One visible, localized H1 per menu variant; independent of availability of database items.
    $insertion=<<<'CODE'
            <!-- POLANA_MENU_SEO_V191: H1 for normal menu (including wine and drinks) -->
            <?php
            $pm191Lang = p15_menu_lang();
            $pm191Headings = [
                'pl' => [
                    'food' => 'Menu restauracji Andrzeja Polana w Krakowie',
                    'wine' => 'Karta win – Moja Polana Smaków w Krakowie',
                    'soft' => 'Karta napojów – Moja Polana Smaków w Krakowie',
                ],
                'en' => [
                    'food' => 'Restaurant menu by Andrzej Polan in Krakow',
                    'wine' => 'Wine list – Moja Polana Smaków, Krakow',
                    'soft' => 'Drinks menu – Moja Polana Smaków, Krakow',
                ],
                'de' => [
                    'food' => 'Speisekarte von Andrzej Polan in Krakau',
                    'wine' => 'Weinkarte – Moja Polana Smaków, Krakau',
                    'soft' => 'Getränkekarte – Moja Polana Smaków, Krakau',
                ],
                'es' => [
                    'food' => 'Menú del restaurante de Andrzej Polan en Cracovia',
                    'wine' => 'Carta de vinos – Moja Polana Smaków, Cracovia',
                    'soft' => 'Carta de bebidas – Moja Polana Smaków, Cracovia',
                ],
            ];
            $pm191Heading = $pm191Headings[$pm191Lang][$menuType]
                ?? $pm191Headings['pl'][$menuType]
                ?? $pm191Headings['pl']['food'];
            ?>
            <h1 class="menu-v191-heading"><?= e($pm191Heading) ?></h1>
            <?php p15_menu_tabs($menuType); ?>
CODE;
    $new = str_replace($needle,$insertion,$before);
    $cssNeedle='    .menu-v18-head p{';
    if (substr_count($new,$cssNeedle)!==1) throw new RuntimeException('Nie rozpoznano stylów menu.php; bez zmian.');
    $css="    /* POLANA_MENU_SEO_V191: responsive SEO H1, shown in the normal menu. */\n".
         "    .menu-v18-head .menu-v191-heading{font-size:clamp(24px,4.1vw,39px);line-height:1.16;\n".
         "        font-weight:800;letter-spacing:-.02em;max-width:740px;margin:12px auto 18px;\n".
         "        text-align:center;color:#1c281d;text-wrap:balance;}\n";
    $new = str_replace($cssNeedle,$css.$cssNeedle,$new);
    if (substr_count($new, '<h1 class="menu-v191-heading">')!==1) throw new RuntimeException('Nie można bezpiecznie wstawić H1.');
    return $new;
}
function pm191_private(string $root): string {
    $candidates=[];
    $helper=$root.'/includes/polana_backup_v182.php';
    if (is_file($helper)) {
        try {
            require_once $helper;
            if (function_exists('pbk_private')) $candidates[]=pbk_private();
        } catch (Throwable $ignored) { }
    }
    $candidates[]=dirname($root).'/.polana-private-ops';
    $documentRoot=realpath((string)($_SERVER['DOCUMENT_ROOT']??''));
    foreach($candidates as $candidate) {
        if (!is_string($candidate)||$candidate==='')continue;
        if (!is_dir($candidate)&&!@mkdir($candidate,0700,true))continue;
        $real=realpath($candidate);
        if ($real===false||!is_writable($real))continue;
        if ($real===$root||str_starts_with($real.'/', $root.'/'))continue;
        if ($documentRoot!==false&&($real===$documentRoot||str_starts_with($real.'/', $documentRoot.'/')))continue;
        $folder=$real.'/polana-menu-seo-v191';
        if (!is_dir($folder)&&!@mkdir($folder,0700,true))continue;
        $actual=realpath($folder);
        if ($actual!==false && is_writable($actual)) { @chmod($actual,0700);return $actual; }
    }
    throw new RuntimeException('Brak prywatnego, zapisywalnego katalogu backupu poza WWW. Instalacja zablokowana.');
}
function pm191_atomic(string $path,string $value): void {
    if (!is_file($path)||is_link($path))throw new RuntimeException('Nieprawidłowy plik do zapisania.');
    $tmp=@tempnam(dirname($path),'.pm191-');
    if ($tmp===false)throw new RuntimeException('Brak możliwości utworzenia pliku tymczasowego.');
    try {
        $n=@file_put_contents($tmp,$value,LOCK_EX);
        if ($n===false||$n!==strlen($value))throw new RuntimeException('Niepełny zapis pliku tymczasowego.');
        @chmod($tmp,fileperms($path)&0777);
        if (!@rename($tmp,$path))throw new RuntimeException('Nie udało się atomowo podmienić menu.php.');
    } finally {if(is_file($tmp))@unlink($tmp);}
}
function pm191_json(string $path,array $manifest): void {
    $data=json_encode($manifest,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR);
    $tmp=@tempnam(dirname($path),'.pm191-json-');
    if ($tmp===false)throw new RuntimeException('Nie można przygotować manifestu.');
    try {
        if (@file_put_contents($tmp,$data,LOCK_EX)!==strlen($data))throw new RuntimeException('Niepełny zapis manifestu.');
        @chmod($tmp,0600);
        if (!@rename($tmp,$path))throw new RuntimeException('Błąd zapisu manifestu.');
    } finally {if (is_file($tmp))@unlink($tmp);}
}
function pm191_load(string $path): ?array {
    if (!is_file($path))return null;
    $data=json_decode(pm191_read($path),true);
    if (!is_array($data)||($data['version']??'')!==PM191_VERSION)throw new RuntimeException('Manifest V19.1 jest uszkodzony.');
    return $data;
}
function pm191_lock(string $folder) {
    $fp=@fopen($folder.'/install.lock','c+');
    if ($fp===false||!flock($fp,LOCK_EX|LOCK_NB))throw new RuntimeException('Inna operacja V19.1 trwa.');
    return $fp;
}
function pm191_install(string $root,string $folder): string {
    $lock=pm191_lock($folder);
    $file=$root.'/'.PM191_REL;
    $before='';$wrote=false;$backup='';$manifest='';
    try {
        if (is_file($folder.'/active.json'))throw new RuntimeException('Instalacja jest już aktywna. Nie nadpisujemy jej.');
        $before=pm191_read($file);
        $after=pm191_patch($before);
        if (!is_writable($file)||!is_writable(dirname($file)))throw new RuntimeException('Brak prawa zapisu do menu.php.');
        $stamp=date('Ymd-His').'-'.bin2hex(random_bytes(4));
        $backup=$folder.'/'.$stamp;
        if (!@mkdir($backup,0700))throw new RuntimeException('Nie można utworzyć katalogu kopii.');
        $original=$backup.'/menu.php.original';
        if (@file_put_contents($original,$before,LOCK_EX)!==strlen($before))throw new RuntimeException('Nie można zapisać kopii źródłowej.');
        @chmod($original,0600);
        if (hash_file('sha256',$original)!==hash('sha256',$before))throw new RuntimeException('Weryfikacja SHA256 kopii nie powiodła się.');
        $manifest=['version'=>PM191_VERSION,'created_at'=>date('c'),'backup_dir'=>$stamp,
           'before_sha256'=>hash('sha256',$before),'after_sha256'=>hash('sha256',$after)];
        pm191_json($backup.'/manifest.json',$manifest);
        // Revalidate on a busy shared host so that foreign changes are not overwritten.
        if (hash_file('sha256',$file)!==$manifest['before_sha256'])throw new RuntimeException('menu.php zmienił się podczas przygotowania instalacji; nic nie nadpisano.');
        pm191_atomic($file,$after);$wrote=true;
        if (hash_file('sha256',$file)!==$manifest['after_sha256'])throw new RuntimeException('Kontrola zapisu po instalacji nie powiodła się.');
        pm191_json($folder.'/active.json',$manifest);
        try {admin_log('polana_menu_seo_v191_install','H1 menu food/wine/soft');}catch(Throwable $ignored){}
        return 'Zainstalowano V19.1. Zmieniono wyłącznie menu.php; backup w prywatnym katalogu: '.$stamp.'.';
    } catch(Throwable $e) {
        if($wrote) {
            try {pm191_atomic($file,$before);}catch(Throwable $restoreError){error_log('POLANA V19.1 CRITICAL AUTO RESTORE: '.$restoreError->getMessage());}
        }
        throw new RuntimeException('Instalacja przerwana: '.$e->getMessage());
    } finally {flock($lock,LOCK_UN);fclose($lock);}
}
function pm191_rollback(string $root,string $folder): string {
    $lock=pm191_lock($folder);
    $file=$root.'/'.PM191_REL;
    try {
        $m=pm191_load($folder.'/active.json');
        if ($m===null)throw new RuntimeException('Brak aktywnej instalacji V19.1.');
        $current=pm191_read($file);
        if (hash('sha256',$current)!==($m['after_sha256']??''))throw new RuntimeException('menu.php został zmieniony od instalacji. Rollback zablokowany, żeby nie skasować nowszych zmian.');
        $stamp=(string)($m['backup_dir']??'');
        if (!preg_match('/^\d{8}-\d{6}-[a-f0-9]{8}$/',$stamp))throw new RuntimeException('Nieprawidłowa ścieżka kopii.');
        $original=pm191_read($folder.'/'.$stamp.'/menu.php.original');
        if (hash('sha256',$original)!==($m['before_sha256']??''))throw new RuntimeException('Kopia backupu jest uszkodzona.');
        pm191_atomic($file,$original);
        try {pm191_json($folder.'/'.$stamp.'/rollback.json',['rolled_back_at'=>date('c'),'version'=>PM191_VERSION]);}catch(Throwable $ignored){}
        // Successful file restore takes priority. If unlink is blocked, status will clearly show a stale manifest.
        if (!@unlink($folder.'/active.json'))throw new RuntimeException('Plik menu.php cofnięto, ale nie można usunąć manifestu active.json. Zgłoś administratorowi.');
        try {admin_log('polana_menu_seo_v191_rollback','Przywrócono menu.php');}catch(Throwable $ignored){}
        return 'Rollback V19.1 zakończony. Przywrócono wcześniejszy menu.php. V19.0 i inne moduły bez zmian.';
    } finally {flock($lock,LOCK_UN);fclose($lock);}
}

$root=pm191_root();$error='';$notice='';$private=null;$active=null;$status='';
try {
    $private=pm191_private($root);
    if (($_SERVER['REQUEST_METHOD']??'GET')==='POST') {
        verify_csrf();
        $action=(string)($_POST['action']??'');
        if ($action==='install') $notice=pm191_install($root,$private);
        elseif ($action==='rollback') $notice=pm191_rollback($root,$private);
        else throw new RuntimeException('Nieznana operacja.');
    }
    $active=pm191_load($private.'/active.json');
    $current=pm191_read($root.'/menu.php');
    if ($active!==null) {
        $status=hash('sha256',$current)===($active['after_sha256']??'')?'AKTYWNA / zgodna':'UWAGA: plik został zmieniony po instalacji';
    }elseif(str_contains($current,PM191_TAG)){
        $status='Znacznik V19.1 obecny bez aktywnego manifestu — sprawdź ręcznie';
    } else {
        pm191_patch($current);
        $status='GOTOWE — źródło zgodne z V18.8 (bez zapisu)';
    }
} catch(Throwable $e){$error=$e->getMessage();}
render_admin_header('POLANA MENU SEO V19.1 — H1 menu');
?>
<style>
.pm191{max-width:900px;margin:20px auto 60px;padding:0 16px}.pm191 section{padding:20px;border:1px solid #dde2db;border-radius:14px;margin:15px 0;background:#fff}.pm191 h1{font-size:30px}.pm191 h2{font-size:21px}.pm191 p{line-height:1.6}.pm191 .ok{background:#e9f7e9;padding:13px;border-radius:9px}.pm191 .err{background:#fff0ee;padding:13px;color:#922c1f;border-radius:9px}.pm191 button{border:0;border-radius:9px;background:#204f34;color:#fff;padding:12px 20px;cursor:pointer;font-weight:700}.pm191 button.danger{background:#9d2b2b}.pm191 button:disabled{opacity:.5;cursor:not-allowed}.pm191 a{text-decoration:underline;color:#20543c}.pm191 small{color:#555}
</style>
<div class="pm191">
<h1>POLANA SEO V19.1 — nagłówki menu</h1>
<p>Naprawiamy brak H1 na <a href="/menu" target="_blank" rel="noopener">/menu</a> i <a href="/menu?kind=wine" target="_blank" rel="noopener">/menu?kind=wine</a> oraz wersji z napojami. Bez zmian w bazie, formularzach, SVG, kalendarzu i przekierowaniach.</p>
<section>
<h2>Stan instalacji</h2>
<p><strong><?= pm191_e($status?:'Weryfikacja niedostępna') ?></strong></p>
<?php if($notice):?><p class="ok"><?=pm191_e($notice)?></p><?php endif;?>
<?php if($error):?><p class="err"><?=pm191_e($error)?></p><?php endif;?>
<p><small>Źródło: menu.php · prywatny backup poza WWW · sprawdzanie SHA256 · instalacja z kontrolą CSRF</small></p>
<?php if(!$error && $active===null):?><form method="post"><?=csrf_field()?><input type="hidden" name="action" value="install"><button type="submit">Zainstaluj V19.1 z backupem</button></form><?php endif;?>
<?php if(!$error && $active!==null):?><form method="post"><?=csrf_field()?><input type="hidden" name="action" value="rollback"><button type="submit" class="danger" <?=str_starts_with($status,'AKTYWNA')?'':'disabled'?>>Rollback V19.1</button></form><?php endif;?>
</section>
<section><h2>Oczekiwane nagłówki</h2>
<ul><li>/menu — Menu restauracji Andrzeja Polana w Krakowie</li>
<li>/menu?kind=wine — Karta win – Moja Polana Smaków w Krakowie</li>
<li>/menu?kind=soft — Karta napojów – Moja Polana Smaków w Krakowie</li></ul>
<p><a href="/admin/polana-seo-audyt-v190.php">Otwórz audyt SEO V19.0</a> · <a href="/admin/polana-seo-v190.php">Otwórz SEO V19.0</a></p>
</section>
</div>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit