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-v1811-backup-kontrola.php
<?php
declare(strict_types=1);
require_once dirname(__DIR__).'/includes/polana_backup_v1811.php';
require_admin_role();
header('Cache-Control: private, no-store, max-age=0');
header('X-Robots-Tag: noindex,nofollow');
header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: no-referrer');
function p1811_h(mixed $value): string {return htmlspecialchars((string)$value,ENT_QUOTES|ENT_SUBSTITUTE,'UTF-8');}
$notice='';$error='';
try {
    if (($_SERVER['REQUEST_METHOD']??'GET')==='POST') {
        verify_csrf();
        $action=(string)($_POST['action']??'');
        $cfg=pbk_cfg();
        if ($action==='probe') {
            $notice=p1811_drive_probe($cfg);
        } elseif ($action==='send_sql') {
            $files=glob(pbk_private().'/daily/polana-sql-*.sql.gz.pbackup')?:[];
            rsort($files,SORT_STRING);
            if (!$files) throw new RuntimeException('Brak lokalnej kopii SQL. Wykonaj kopię w głównym panelu.');
            $r=p1811_send_verified($files[0],$cfg);
            $notice='Kopia '.basename($files[0]).' znajduje się na Drive: potwierdzono rozmiar, MD5 i integralność lokalnego archiwum.';
        } elseif ($action==='enqueue') {
            $j=p1811_enqueue_manual();
            $notice='Zlecono kompletną kopię. Zaczekaj do najbliższego uruchomienia CRON; przed aktualizacją upewnij się, że status to ZAKOŃCZONO.';
        } elseif ($action==='verify') {
            $kind=(string)($_POST['kind']??'');
            $name=(string)($_POST['filename']??'');
            if (!in_array($kind,['daily','weekly','fullsql'],true) ||
                !preg_match('/^polana-(?:sql|strona)-\d{4}-\d{2}-\d{2}(?:-\d{6})?\.(?:sql\.gz|tar)\.pbackup$/D',$name))
                throw new RuntimeException('Niedozwolona nazwa kopii.');
            $path=pbk_private().'/'.$kind.'/'.$name;
            $r=p1811_verify_existing($path,$cfg);
            $notice='Potwierdzono obecność na Drive: '.basename($path).' (rozmiar, suma kontrolna MD5).';
        } elseif ($action==='download') {
            $kind=(string)($_POST['kind']??'');
            $name=(string)($_POST['filename']??'');
            if (!in_array($kind,['daily','weekly','fullsql'],true) ||
                !preg_match('/^polana-(?:sql|strona)-\d{4}-\d{2}-\d{2}(?:-\d{6})?\.(?:sql\.gz|tar)\.pbackup$/D',$name))
                throw new RuntimeException('Niedozwolona nazwa kopii.');
            $path=pbk_private().'/'.$kind.'/'.$name;
            if (!is_file($path)||is_link($path)) throw new RuntimeException('Nie znaleziono archiwum.');
            if (session_status()===PHP_SESSION_ACTIVE) session_write_close();
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="'.$name.'"');
            header('Content-Length: '.filesize($path));
            readfile($path); exit;
        } else throw new RuntimeException('Nieznana operacja.');
    }
} catch (Throwable $e) {$error=$e->getMessage();}
$cfg=[];$jobManual=[];$jobQuarter=[];$cron=[];$recent=[];
try {
    $cfg=pbk_cfg();
    $jobManual=p1811_read('manual');$jobQuarter=p1811_read('quarter');$cron=p1811_read('cron');
    foreach(['weekly','fullsql','daily'] as $kind) {
        $dir=pbk_private().'/'.$kind;
        foreach (glob($dir.'/*.pbackup')?:[] as $file) {
            $recent[]=['name'=>basename($file),'file'=>$file,'kind'=>$kind,'status'=>pbk_status($file),'size'=>filesize($file)];
        }
    }
    usort($recent,static fn($a,$b)=>strcmp($b['name'],$a['name']));
} catch (Throwable $e) {$error=$error?:$e->getMessage();}
render_admin_header('POLANA — Google Drive i pełne kopie');
?>
<style>
.b1811{max-width:1130px;margin:20px auto 60px;padding:0 16px;color:#24372e}.b1811 *{box-sizing:border-box}.b1811 h1{font-size:clamp(24px,3vw,34px)}.b1811 section{padding:20px;background:#fff;border:1px solid #dce7de;border-radius:15px;margin:18px 0}.b1811 h2{font-size:20px;margin:4px 0 14px}.b1811 .cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.b1811 button,.b1811 .link{border:0;background:#194c35;color:white;border-radius:9px;padding:10px 14px;cursor:pointer;font:inherit;font-size:14px;font-weight:700;display:inline-block;text-decoration:none;margin:4px}.b1811 button.alt,.b1811 .link.alt{background:#e8f0e8;color:#194c35}.b1811 .note{padding:11px 13px;background:#eef6ec;border-radius:9px}.b1811 .warning{padding:11px 13px;background:#fff3e5;border:1px solid #e8cd96;border-radius:9px}.b1811 .error{padding:11px 13px;background:#fee9e6;border-radius:9px}.b1811 code{overflow-wrap:anywhere}.b1811 table{width:100%;border-collapse:collapse;font-size:13px}.b1811 td,.b1811 th{text-align:left;border-bottom:1px solid #e3eee5;padding:10px;vertical-align:top}.b1811 .scroll{overflow:auto}.b1811 p{line-height:1.6}.b1811 form{display:inline}.b1811 .muted{color:#5c7568;font-size:13px}@media(max-width:680px){.b1811 section{padding:15px}.b1811 .cols{grid-template-columns:1fr}}
</style>
<main class="b1811">
<h1>Pełne kopie POLANA i Google Drive</h1>
<p>V18.11 — jeden zestaw OAuth, sprawdzanie rzeczywistego przesłania kopii, SQL codziennie i pełna struktura strony + punktowy SQL raz na kwartał oraz przed dużymi zmianami.</p>
<?php if($notice):?><p class="note" role="status"><?=p1811_h($notice)?></p><?php endif;?>
<?php if($error):?><p class="error" role="alert"><?=p1811_h($error)?></p><?php endif;?>
<div class="cols">
<section><h2>1. Prawdziwy test Google Drive</h2>
<p>Połączenie OAuth: <b><?=!empty($cfg['drive_refresh_token'])?'połączone':'niepołączone'?></b>. Wysyłka backupów: <b><?=!empty($cfg['drive_enabled'])?'włączona':'WYŁĄCZONA'?></b>.</p>
<p>Test przesyła niewielki zaszyfrowany plik, sprawdza jego rozmiar i sumę MD5 w Google Drive, a następnie usuwa próbkę.</p>
<form method="post"><?=csrf_field()?><input type="hidden" name="action" value="probe"><button type="submit">Wyślij i sprawdź plik testowy</button></form>
<form method="post"><?=csrf_field()?><input type="hidden" name="action" value="send_sql"><button class="alt" type="submit">Wyślij / sprawdź ostatni SQL</button></form>
<p class="muted">Przycisk testowy nie potwierdza jeszcze, że istnieje pełna kopia strony — sprawdź jej status w tabeli poniżej.</p>
</section>
<section><h2>2. Pełna kopia na żądanie</h2>
<p>Archiwum plików witryny z zachowaniem ścieżek, wraz z osobnym zaszyfrowanym SQL wykonanym w tej samej operacji.</p>
<form method="post" onsubmit="return confirm('Zlecić nową pełną kopię przed aktualizacją? Zadanie wykona najbliższy CRON — odczekaj potwierdzenie!')"><?=csrf_field()?><input type="hidden" name="action" value="enqueue"><button type="submit">Zleć pełną kopię przed aktualizacją</button></form>
<p><b>Status:</b> <?=p1811_h($jobManual['status']??'brak zlecenia')?><?php if(!empty($jobManual['completed_at'])):?> · <?=p1811_h($jobManual['completed_at'])?><?php endif;?></p>
<?php if(!empty($jobManual['last_error'])):?><p class="warning"><?=p1811_h($jobManual['last_error'])?></p><?php endif;?>
<p class="warning"><b>Nie rozpoczynaj aktualizacji, dopóki status nie będzie „done” i kopie nie będą potwierdzone na Drive.</b></p>
</section></div>
<section><h2>3. Harmonogram — jeden CRON</h2>
<p>SQL: codziennie po 03:15. Pełne pliki + SQL: automatycznie w każdym kwartale, a także po zleceniu z panelu. Aby szybciej obsługiwać zlecenia przed aktualizacją, CRON powinien uruchamiać kontrolę co godzinę.</p>
<p><b>Zamień</b> dotychczasowy CRON V18.2 na:</p>
<p><code>15 * * * * /SCIEZKA/DO/PHP <?=p1811_h(pbk_root())?>/cron/polana-backup-v1811.php</code></p>
<p class="muted">Ścieżkę interpretera ustal w panelu hostingu. Nie uruchamiaj obok starego zadania bez argumentu, ponieważ nadal tworzyło kopie plików w każdą niedzielę.</p>
<p><b>Ostatni przebieg:</b> <?=p1811_h($cron['last_run']??'CRON V18.11 jeszcze nie uruchomiony')?> · <?=p1811_h($cron['last_result']??'—')?></p>
<?php foreach(($cron['errors']??[]) as $msg):?><p class="warning"><?=p1811_h($msg)?></p><?php endforeach;?>
<p><b>Kwartał:</b> <?=p1811_h($jobQuarter['quarter']??p1811_current_quarter())?> · status: <b><?=p1811_h($jobQuarter['status']??'oczekuje na pierwszy CRON')?></b></p>
<?php if(!empty($jobQuarter['last_error'])):?><p class="warning"><?=p1811_h($jobQuarter['last_error'])?></p><?php endif;?>
</section>
<section><h2>4. Kopie lokalne i stan Google Drive</h2>
<div class="scroll"><table><thead><tr><th>Kopia</th><th>Rozmiar</th><th>Drive</th><th>Sprawdzenie</th><th>Archiwum</th></tr></thead><tbody>
<?php foreach(array_slice($recent,0,24) as $r): $s=$r['status'];?><tr>
<td><?=p1811_h($r['name'])?><div class="muted"><?=p1811_h($r['kind'])?></div></td>
<td><?=p1811_h(round($r['size']/1048576,2))?> MB</td>
<td><?=!empty($s['drive'])?'wysłano':'brak potwierdzenia'?></td>
<td><?=!empty($s['drive_verified_at'])?'Zweryfikowano '.p1811_h($s['drive_verified_at']):'nie sprawdzono'?>
<?php if(!empty($s['drive_file_id'])):?><form method="post"><?=csrf_field()?><input type="hidden" name="action" value="verify"><input type="hidden" name="kind" value="<?=p1811_h($r['kind'])?>"><input type="hidden" name="filename" value="<?=p1811_h($r['name'])?>"><button type="submit" class="alt">Sprawdź na Drive</button></form><?php endif;?></td>
<td><form method="post"><?=csrf_field()?><input type="hidden" name="action" value="download"><input type="hidden" name="kind" value="<?=p1811_h($r['kind'])?>"><input type="hidden" name="filename" value="<?=p1811_h($r['name'])?>"><button class="alt" type="submit">Pobierz</button></form></td>
</tr><?php endforeach;?>
<?php if(!$recent):?><tr><td colspan="5">Brak archiwów.</td></tr><?php endif;?></tbody></table></div>
<p class="muted">Kopia strony z katalogu weekly i odpowiadający jej SQL z fullsql mają taki sam znacznik daty i czasu w nazwie. Klucz .key jest przechowywany osobno i nie jest dołączany do backupów.</p>
</section>
<p><a href="/admin/polana-backup-automat.php" class="link alt">Wróć do ustawień kopii</a></p>
</main>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit