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-v11-harmonogram.php
<?php
declare(strict_types=1);
require_once dirname(__DIR__).'/includes/functions.php';
$user=require_blog_manager();
ensure_blog_schema();
const P11_CAMPAIGN='polana_blog40_20261017';
function p11_campaign_rows(): array {
  return db()->query("SELECT c.ordinal,c.post_id,c.reviewed_at,p.title,p.status,p.publish_at,p.slug
   FROM polana_blog_campaign_items c JOIN blog_posts p ON p.id=c.post_id
   WHERE c.campaign_key='".P11_CAMPAIGN."' ORDER BY c.ordinal")->fetchAll(PDO::FETCH_ASSOC);
}
$error='';$notice='';
try {$rows=p11_campaign_rows();}
catch(Throwable $e){$rows=[];$error='Nie znaleziono kampanii V10. Najpierw wgraj importer V10 i utwórz wpisy.';}
if($_SERVER['REQUEST_METHOD']==='POST'){
 verify_csrf();
 try {
   if(($_POST['action']??'')!=='random_schedule')throw new RuntimeException('Nieznana operacja');
   if(($_POST['editorial_confirm']??'')!=='yes')throw new RuntimeException('Potwierdź, że wpisy przejrzał redaktor.');
   $startDate=(string)($_POST['start_date']??'');
   $tz=new DateTimeZone('Europe/Warsaw');
   $start=DateTimeImmutable::createFromFormat('!Y-m-d',$startDate,$tz);
   if(!$start||$start->format('Y-m-d')!==$startDate)throw new RuntimeException('Nieprawidłowa data.');
   if($start < new DateTimeImmutable('today',$tz))throw new RuntimeException('Start nie może być w przeszłości.');
   $min=max(1,min(14,(int)($_POST['min_days']??2)));
   $max=max($min,min(21,(int)($_POST['max_days']??5)));
   $includeScheduled=(($_POST['include_scheduled']??'')==='1');
   $db=db();$db->beginTransaction();
   try {
     $q=$db->prepare("SELECT c.post_id,c.ordinal,c.reviewed_at,p.status,p.publish_at
       FROM polana_blog_campaign_items c JOIN blog_posts p ON p.id=c.post_id
       WHERE c.campaign_key=? ORDER BY c.ordinal FOR UPDATE");
     $q->execute([P11_CAMPAIGN]);$campaign=$q->fetchAll(PDO::FETCH_ASSOC);
     if(!$campaign)throw new RuntimeException('Brak wpisów kampanii V10.');
     $future=[];$omitted=0;
     foreach($campaign as $item){
       if($item['status']==='published'){$omitted++;continue;}
       if($item['status']==='scheduled'&&!$includeScheduled){$omitted++;continue;}
       if(!in_array($item['status'],['draft','scheduled'],true)){$omitted++;continue;}
       $future[]=$item;
     }
     if(!$future)throw new RuntimeException('Brak szkiców do zaplanowania. Opublikowanych wpisów nie ruszamy.');
     // Editorial approval is explicit, stored only for this campaign, never for arbitrary blog posts.
     $review=$db->prepare('UPDATE polana_blog_campaign_items SET reviewed_at=COALESCE(reviewed_at,NOW()) WHERE campaign_key=? AND post_id=?');
     $update=$db->prepare("UPDATE blog_posts SET status='scheduled',publish_at=?,updated_by_user_id=?,updated_at=NOW() WHERE id=? AND status IN ('draft','scheduled')");
     $now=new DateTimeImmutable('now',$tz);
     $cursor=$start;
     $first=true;$count=0;
     foreach($future as $item){
       if(!$first)$cursor=$cursor->modify('+'.random_int($min,$max).' days');
       $first=false;
       $hour=random_int(9,18);$minute=random_int(0,59);
       $when=$cursor->setTime($hour,$minute,0);
       if($when <= $now) $when=$now->modify('+'.random_int(2,10).' hours');
       $update->execute([$when->format('Y-m-d H:i:s'),(int)$user['id'],(int)$item['post_id']]);
       $count += $update->rowCount();
       $review->execute([P11_CAMPAIGN,(int)$item['post_id']]);
     }
     $db->commit();
     admin_log('v11_blog_random','Losowy harmonogram: '.$count.' wpisów, odstęp '.$min.'–'.$max.' dni');
     $_SESSION['v11_schedule_notice']='Zaplanowano '.$count.' wpisów. Pominięto '.$omitted.' opublikowanych lub zachowanych terminów.';
     header('Location: polana-v11-harmonogram.php',true,303);exit;
   }catch(Throwable $e){$db->rollBack();throw $e;}
 }catch(Throwable $e){$error=$e->getMessage();}
}
$rows=$rows ?: [];
if(isset($_SESSION['v11_schedule_notice'])){$notice=(string)$_SESSION['v11_schedule_notice'];unset($_SESSION['v11_schedule_notice']);}
$counts=['draft'=>0,'scheduled'=>0,'published'=>0];foreach($rows as $row)if(isset($counts[$row['status']]))$counts[$row['status']]++;
render_admin_header('Blog — losowy harmonogram V11');
?>
<style>.v11-shell{max-width:1180px;margin:22px auto;padding:16px}.v11-card{background:#fff;border:1px solid #ddd;padding:20px;border-radius:14px;margin:16px 0}.v11-form{display:flex;gap:16px;align-items:end;flex-wrap:wrap}.v11-form label{display:flex;flex-direction:column;gap:7px}.v11-form input{padding:10px}.v11-table{border-collapse:collapse;width:100%;font-size:14px}.v11-table td,.v11-table th{padding:9px;border-bottom:1px solid #ddd;text-align:left}.v11-scroll{overflow-x:auto}</style>
<main class="v11-shell">
<h1>Blog SEO — losowe publikacje</h1>
<p><b><?= (int)$counts['published'] ?></b> opublikowanych · <b><?= (int)$counts['scheduled'] ?></b> zaplanowanych · <b><?= (int)$counts['draft'] ?></b> szkiców. Harmonogram działa w obecnym PHP/MariaDB, bez crona.</p>
<?php if($error): ?><div class="v11-card" style="border-color:#b93;color:#972"><?= e($error) ?></div><?php endif; ?>
<?php if($notice): ?><div class="v11-card" style="border-color:#528d44"><?= e($notice) ?></div><?php endif; ?>
<section class="v11-card">
<h2>Rozłóż wpisy losowo</h2>
<p>Domyślnie nie zmieniamy już zaplanowanych ani opublikowanych. Jeśli wcześniej ustawiłeś sztywne dni w V10, zaznacz „Przeplanuj przyszłe”. Terminy ustawiamy losowo w godz. 9:00–18:59 czasu Krakowa.</p>
<form method="post" class="v11-form">
<?= csrf_field() ?><input type="hidden" name="action" value="random_schedule">
<label>Data startu<input type="date" name="start_date" value="<?= e((new DateTimeImmutable('tomorrow',new DateTimeZone('Europe/Warsaw')))->format('Y-m-d')) ?>" required></label>
<label>Odstęp min. (dni)<input type="number" name="min_days" min="1" max="14" value="2"></label>
<label>Odstęp maks. (dni)<input type="number" name="max_days" min="1" max="21" value="5"></label>
<label style="flex-direction:row;align-items:center"><input type="checkbox" name="include_scheduled" value="1"> Przeplanuj także przyszłe wpisy z V10</label>
<label style="flex-direction:row;align-items:center;width:100%"><input type="checkbox" name="editorial_confirm" value="yes" required> Potwierdzam, że przejrzałem treści i akceptuję harmonogram publikacji.</label>
<button class="btn btn-primary" type="submit" onclick="return confirm('Zapisać losowe daty publikacji dla pozostałych wpisów kampanii?')">Zapisz losowy harmonogram</button>
</form>
</section>
<section class="v11-card"><h2>Wpisy kampanii</h2><div class="v11-scroll"><table class="v11-table"><thead><tr><th>Nr</th><th>Tytuł</th><th>Status</th><th>Data publikacji</th></tr></thead><tbody>
<?php foreach($rows as $r): ?><tr><td><?= (int)$r['ordinal'] ?></td><td><a href="/admin/blog-edit.php?id=<?= (int)$r['post_id'] ?>"><?= e((string)$r['title']) ?></a></td><td><?= e((string)$r['status']) ?></td><td><?= e((string)($r['publish_at']??'—')) ?></td></tr><?php endforeach; ?></tbody></table></div></section>
<p><a href="/admin/polana-blog-40.php">← Kampania V10</a> · <a href="/admin/v9-review.php">Tłumaczenia EN/DE/ES</a></p>
</main>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit