forked from tahmidrayat/Decrypt
-
Notifications
You must be signed in to change notification settings - Fork 0
Create PHP news site with admin dashboard and Shopee ad flow #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
huzely
wants to merge
1
commit into
master
Choose a base branch
from
codex/create-complete-news-website-li1yet
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| RewriteEngine On | ||
| RewriteCond %{REQUEST_URI} !^/(admin|api|bots|assets|includes|lib|cache|logs)/ | ||
| RewriteCond %{REQUEST_FILENAME} !-f | ||
| RewriteRule ^([A-Za-z0-9-]+)/?$ post.php?slug=$1 [L,QSA] | ||
|
|
||
| RewriteRule ^$ index.php [L] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Báo tin tức PHP thuần | ||
|
|
||
| Triển khai cho hosting share (PHP 7.4, MySQL) với ba theme, quản trị tiếng Việt và flow quảng cáo Shopee không delay, giữ link affiliate s.shopee.vn. | ||
|
|
||
| ## Cách cài đặt | ||
| 1. Upload toàn bộ thư mục `public_html` lên hosting (dataonline.vn hoặc tương tự). | ||
| 2. Import MySQL file `sql/database.sql` (đã seed admin: `admin / admin567`). | ||
| 3. Sửa file `public_html/config.php` với thông tin DB, `BASE_URL`, token Telegram, `APP_DEBUG`. | ||
| 4. Đảm bảo file `.htaccess` hoạt động để rewrite slug: `/slug` -> `post.php?slug=...`. | ||
| 5. Phân quyền ghi cho thư mục `cache/` và `logs/`. | ||
|
|
||
| ## Đăng nhập admin | ||
| - URL: `/admin/login.php` | ||
| - Tài khoản mặc định: **admin / admin567** (mật khẩu đã được hash trong DB). | ||
|
|
||
| ## Kiểm tra nhanh sau khi deploy | ||
| - **Quảng cáo Shopee**: Bật quảng cáo ở `Admin > Cài đặt`, nhập link s.shopee.vn. Truy cập bài viết: overlay xuất hiện, bấm bất kỳ nơi nào hoặc nút X sẽ mở bài ở tab mới với `?ad=0` và tab hiện tại đi Shopee (không delay). Truy cập trực tiếp `/slug` vẫn thấy overlay trừ khi URL có `?ad=0`. | ||
| - **Theme**: Vào `Admin > Cài đặt`, đổi giữa Theme 1/2/3, toàn site đổi màu ngay. | ||
| - **Chống click ảo**: Tracking dùng token phiên + rate limit IP/UA/slug (30s) trong `/api/track.php`; spam gọi API sẽ nhận `rate_limited`. | ||
| - **Log lỗi**: Khi `APP_DEBUG=false`, lỗi được ghi vào `logs/app.log` và hiển thị `error.php` thân thiện (không trắng trang). | ||
|
|
||
| ## Thư mục chính | ||
| - `index.php`: trang chủ, phân trang, menu 3D, trigger quảng cáo trên click bài. | ||
| - `post.php`: trang bài, meta SEO/OG, hiển thị media Telegram, overlay quảng cáo nếu bật. | ||
| - `assets/css`: `base.css` + `theme1/2/3.css` + `admin.css`. | ||
| - `assets/js`: `app.js` (UI + menu), `adflow.js` (overlay Shopee đúng flow), `track.js` (tracking không chậm redirect). | ||
| - `admin/`: đăng nhập, CRUD bài, copy link, cài đặt, thống kê (view/ngày/tháng/ad click, reset). | ||
| - `api/track.php`: nhận tracking page/post/ad với rate limit và token, gộp thông báo Telegram. | ||
| - `lib/`: PDO, auth, cache file, csrf, slugify, rate-limit, telegram, helpers, error handler. | ||
|
|
||
| ## Lưu ý vận hành | ||
| - Ảnh/logo/banner được lưu trong `assets/img/` (nhẹ, phù hợp share hosting). | ||
| - Cache file cho trang chủ/bài ~45s; cài đặt cache 5 phút. | ||
| - Không sử dụng framework hay CLI/composer. | ||
| - Gửi Telegram: cấu hình token/chat_id trong `config.php`; hàng đợi + gộp click trong `telegram_queue` và `telegram_notifications`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../lib/db.php'; | ||
| require_once __DIR__ . '/../lib/helpers.php'; | ||
| require_once __DIR__ . '/../lib/csrf.php'; | ||
| require_once __DIR__ . '/../lib/auth.php'; | ||
| require_once __DIR__ . '/../lib/telegram.php'; | ||
| require_auth(); | ||
|
|
||
| flushTelegramQueue(); | ||
| $totalArticles = (int)$pdo->query("SELECT COUNT(*) FROM articles")->fetchColumn(); | ||
| $publicArticles = (int)$pdo->query("SELECT COUNT(*) FROM articles WHERE status='public'")->fetchColumn(); | ||
| $views = (int)$pdo->query("SELECT COUNT(*) FROM events WHERE event_type='post_view'")->fetchColumn(); | ||
| $adClicks = (int)$pdo->query("SELECT COUNT(*) FROM events WHERE event_type='ad_click'")->fetchColumn(); | ||
| include __DIR__ . '/includes/header.php'; | ||
| ?> | ||
| <div class="topbar"> | ||
| <h1>Chào, <?php echo e($_SESSION['admin_username'] ?? 'admin'); ?></h1> | ||
| <a class="btn" href="/">Xem trang</a> | ||
| </div> | ||
| <div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap:14px;"> | ||
| <div class="card">Tổng bài viết: <strong><?php echo $totalArticles; ?></strong></div> | ||
| <div class="card">Bài public: <strong><?php echo $publicArticles; ?></strong></div> | ||
| <div class="card">Lượt xem bài: <strong><?php echo $views; ?></strong></div> | ||
| <div class="card">Click quảng cáo: <strong><?php echo $adClicks; ?></strong></div> | ||
| </div> | ||
| <?php include __DIR__ . '/includes/footer.php'; ?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../../lib/auth.php'; | ||
| require_auth(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| </main> | ||
| </div> | ||
| </body> | ||
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../includes/auth_check.php'; | ||
| ?> | ||
| <!DOCTYPE html> | ||
| <html lang="vi"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>Quản trị</title> | ||
| <link rel="stylesheet" href="/assets/css/admin.css"> | ||
| </head> | ||
| <body> | ||
| <div class="admin-shell"> | ||
| <aside class="sidebar"> | ||
| <h2>Admin</h2> | ||
| <a href="/admin/dashboard.php">Bảng tin</a> | ||
| <a href="/admin/posts.php">Bài viết</a> | ||
| <a href="/admin/post_add.php">Thêm bài</a> | ||
| <a href="/admin/settings.php">Cài đặt</a> | ||
| <a href="/admin/stats.php">Thống kê</a> | ||
| <a href="/admin/logout.php">Đăng xuất</a> | ||
| </aside> | ||
| <main class="main"> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../lib/auth.php'; | ||
| require_once __DIR__ . '/../lib/helpers.php'; | ||
| require_once __DIR__ . '/../lib/csrf.php'; | ||
|
|
||
| $message = ''; | ||
| if (is_post()) { | ||
| $token = $_POST['csrf'] ?? ''; | ||
| if (!verify_csrf($token)) { | ||
| $message = 'Token không hợp lệ'; | ||
| } else { | ||
| $username = trim($_POST['username'] ?? ''); | ||
| $password = $_POST['password'] ?? ''; | ||
| if (login($username, $password)) { | ||
| redirect('/admin/dashboard.php'); | ||
| } | ||
| $message = 'Sai tài khoản hoặc mật khẩu'; | ||
| } | ||
| } | ||
| ?> | ||
| <!DOCTYPE html> | ||
| <html lang="vi"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>Đăng nhập quản trị</title> | ||
| <link rel="stylesheet" href="/assets/css/admin.css"> | ||
| </head> | ||
| <body style="display:grid; place-items:center; min-height:100vh;"> | ||
| <div class="card" style="width:min(420px, 92%);"> | ||
| <h2>Đăng nhập</h2> | ||
| <?php if ($message): ?><div class="alert"><?php echo e($message); ?></div><?php endif; ?> | ||
| <form method="POST"> | ||
| <label>Tài khoản</label> | ||
| <input type="text" name="username" value="<?php echo e($_POST['username'] ?? ''); ?>" required> | ||
| <label>Mật khẩu</label> | ||
| <input type="password" name="password" required> | ||
| <input type="hidden" name="csrf" value="<?php echo csrf_token(); ?>"> | ||
| <button class="btn" type="submit">Đăng nhập</button> | ||
| </form> | ||
| <p style="margin-top:12px; color:#94a3b8;">Tài khoản mặc định: admin / admin567</p> | ||
| </div> | ||
| </body> | ||
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../lib/auth.php'; | ||
| logout(); | ||
| header('Location: /admin/login.php'); | ||
| exit; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../lib/db.php'; | ||
| require_once __DIR__ . '/../lib/helpers.php'; | ||
| require_once __DIR__ . '/../lib/auth.php'; | ||
| require_once __DIR__ . '/../lib/csrf.php'; | ||
| require_once __DIR__ . '/../lib/slugify.php'; | ||
| require_once __DIR__ . '/../lib/telegram.php'; | ||
| require_auth(); | ||
|
|
||
| $message = ''; | ||
| if (is_post()) { | ||
| if (!verify_csrf($_POST['csrf'] ?? '')) { | ||
| $message = 'Token không hợp lệ'; | ||
| } else { | ||
| $title = trim($_POST['title'] ?? ''); | ||
| $slug = trim($_POST['slug'] ?? '') ?: slugify($title); | ||
| $excerpt = trim($_POST['excerpt'] ?? ''); | ||
| $content = trim($_POST['content'] ?? ''); | ||
| $telegram_media = trim($_POST['telegram_media'] ?? ''); | ||
| $meta_title = trim($_POST['meta_title'] ?? ''); | ||
| $meta_description = trim($_POST['meta_description'] ?? ''); | ||
| $meta_keywords = trim($_POST['meta_keywords'] ?? ''); | ||
| $status = $_POST['status'] === 'public' ? 'public' : 'draft'; | ||
| $stmt = $pdo->prepare("INSERT INTO articles(title, slug, excerpt, content, telegram_media, meta_title, meta_description, meta_keywords, status, created_at, updated_at) VALUES(:title,:slug,:excerpt,:content,:media,:mt,:md,:mk,:status,NOW(),NOW())"); | ||
| try { | ||
| $stmt->execute([ | ||
| ':title' => $title, | ||
| ':slug' => $slug, | ||
| ':excerpt' => $excerpt, | ||
| ':content' => $content, | ||
| ':media' => $telegram_media, | ||
| ':mt' => $meta_title, | ||
| ':md' => $meta_description, | ||
| ':mk' => $meta_keywords, | ||
| ':status' => $status, | ||
| ]); | ||
| queueTelegramMessage('Bài mới: ' . $title . ' - ' . current_url($slug)); | ||
| redirect('/admin/posts.php'); | ||
| } catch (Throwable $e) { | ||
| $message = 'Không thể lưu bài: ' . $e->getMessage(); | ||
| } | ||
| } | ||
| } | ||
| include __DIR__ . '/includes/header.php'; | ||
| ?> | ||
| <div class="topbar"><h1>Thêm bài</h1></div> | ||
| <?php if ($message): ?><div class="alert"><?php echo e($message); ?></div><?php endif; ?> | ||
| <form method="POST"> | ||
| <label>Tiêu đề</label> | ||
| <input name="title" required value="<?php echo e($_POST['title'] ?? ''); ?>"> | ||
| <label>Slug</label> | ||
| <input name="slug" value="<?php echo e($_POST['slug'] ?? ''); ?>" placeholder="tieu-de-khong-dau"> | ||
| <label>Tóm tắt</label> | ||
| <textarea name="excerpt" rows="2"><?php echo e($_POST['excerpt'] ?? ''); ?></textarea> | ||
| <label>Nội dung</label> | ||
| <textarea name="content" rows="8" required><?php echo e($_POST['content'] ?? ''); ?></textarea> | ||
| <label>Telegram media (mỗi dòng 1 link)</label> | ||
| <textarea name="telegram_media" rows="3"><?php echo e($_POST['telegram_media'] ?? ''); ?></textarea> | ||
| <label>Meta title</label> | ||
| <input name="meta_title" value="<?php echo e($_POST['meta_title'] ?? ''); ?>"> | ||
| <label>Meta description</label> | ||
| <input name="meta_description" value="<?php echo e($_POST['meta_description'] ?? ''); ?>"> | ||
| <label>Meta keywords</label> | ||
| <input name="meta_keywords" value="<?php echo e($_POST['meta_keywords'] ?? ''); ?>"> | ||
| <label>Trạng thái</label> | ||
| <select name="status"> | ||
| <option value="draft">Nháp</option> | ||
| <option value="public">Public</option> | ||
| </select> | ||
| <input type="hidden" name="csrf" value="<?php echo csrf_token(); ?>"> | ||
| <button class="btn" type="submit">Lưu</button> | ||
| </form> | ||
| <?php include __DIR__ . '/includes/footer.php'; ?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../lib/db.php'; | ||
| require_once __DIR__ . '/../lib/helpers.php'; | ||
| require_once __DIR__ . '/../lib/auth.php'; | ||
| require_once __DIR__ . '/../lib/csrf.php'; | ||
| require_auth(); | ||
|
|
||
| $slug = $_GET['slug'] ?? ''; | ||
| $link = $slug ? current_url($slug) : current_url(); | ||
| ?> | ||
| <!DOCTYPE html> | ||
| <html lang="vi"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <title>Copy link</title> | ||
| <link rel="stylesheet" href="/assets/css/admin.css"> | ||
| </head> | ||
| <body style="display:grid; place-items:center; min-height:100vh;"> | ||
| <div class="card" style="width:min(420px, 92%); text-align:center;"> | ||
| <p>Link bài viết:</p> | ||
| <code style="display:block; margin-bottom:12px; word-break:break-all;"><?php echo e($link); ?></code> | ||
| <button class="btn" id="copy">Copy</button> | ||
| <p style="margin-top:12px; color:#94a3b8;">Dán link gửi cho bạn đọc.</p> | ||
| </div> | ||
| <script> | ||
| document.getElementById('copy').addEventListener('click', function(){ | ||
| navigator.clipboard.writeText('<?php echo e($link); ?>').then(() => alert('Đã copy link!')); | ||
| }); | ||
| </script> | ||
| </body> | ||
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../lib/db.php'; | ||
| require_once __DIR__ . '/../lib/helpers.php'; | ||
| require_once __DIR__ . '/../lib/auth.php'; | ||
| require_once __DIR__ . '/../lib/csrf.php'; | ||
| require_auth(); | ||
|
|
||
| $id = (int)($_GET['id'] ?? 0); | ||
| $stmt = $pdo->prepare('DELETE FROM articles WHERE id = :id'); | ||
| $stmt->execute([':id' => $id]); | ||
| redirect('/admin/posts.php'); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| <?php | ||
| require_once __DIR__ . '/../lib/error_handler.php'; | ||
| require_once __DIR__ . '/../lib/db.php'; | ||
| require_once __DIR__ . '/../lib/helpers.php'; | ||
| require_once __DIR__ . '/../lib/auth.php'; | ||
| require_once __DIR__ . '/../lib/csrf.php'; | ||
| require_once __DIR__ . '/../lib/slugify.php'; | ||
| require_once __DIR__ . '/../lib/telegram.php'; | ||
| require_auth(); | ||
|
|
||
| $id = (int)($_GET['id'] ?? 0); | ||
| $stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id'); | ||
| $stmt->execute([':id' => $id]); | ||
| $post = $stmt->fetch(); | ||
| if (!$post) { echo 'Không tìm thấy'; exit; } | ||
|
|
||
| $message = ''; | ||
| if (is_post()) { | ||
| if (!verify_csrf($_POST['csrf'] ?? '')) { | ||
| $message = 'Token không hợp lệ'; | ||
| } else { | ||
| $title = trim($_POST['title'] ?? ''); | ||
| $slug = trim($_POST['slug'] ?? '') ?: slugify($title); | ||
| $excerpt = trim($_POST['excerpt'] ?? ''); | ||
| $content = trim($_POST['content'] ?? ''); | ||
| $telegram_media = trim($_POST['telegram_media'] ?? ''); | ||
| $meta_title = trim($_POST['meta_title'] ?? ''); | ||
| $meta_description = trim($_POST['meta_description'] ?? ''); | ||
| $meta_keywords = trim($_POST['meta_keywords'] ?? ''); | ||
| $status = $_POST['status'] === 'public' ? 'public' : 'draft'; | ||
| $stmtUpdate = $pdo->prepare("UPDATE articles SET title=:title, slug=:slug, excerpt=:excerpt, content=:content, telegram_media=:media, meta_title=:mt, meta_description=:md, meta_keywords=:mk, status=:status, updated_at=NOW() WHERE id=:id"); | ||
| try { | ||
| $stmtUpdate->execute([ | ||
| ':title' => $title, | ||
| ':slug' => $slug, | ||
| ':excerpt' => $excerpt, | ||
| ':content' => $content, | ||
| ':media' => $telegram_media, | ||
| ':mt' => $meta_title, | ||
| ':md' => $meta_description, | ||
| ':mk' => $meta_keywords, | ||
| ':status' => $status, | ||
| ':id' => $id, | ||
| ]); | ||
| redirect('/admin/posts.php'); | ||
| } catch (Throwable $e) { | ||
| $message = 'Không thể cập nhật: ' . $e->getMessage(); | ||
| } | ||
| } | ||
| } | ||
| include __DIR__ . '/includes/header.php'; | ||
| ?> | ||
| <div class="topbar"><h1>Sửa bài</h1></div> | ||
| <?php if ($message): ?><div class="alert"><?php echo e($message); ?></div><?php endif; ?> | ||
| <form method="POST"> | ||
| <label>Tiêu đề</label> | ||
| <input name="title" required value="<?php echo e($_POST['title'] ?? $post['title']); ?>"> | ||
| <label>Slug</label> | ||
| <input name="slug" value="<?php echo e($_POST['slug'] ?? $post['slug']); ?>"> | ||
| <label>Tóm tắt</label> | ||
| <textarea name="excerpt" rows="2"><?php echo e($_POST['excerpt'] ?? $post['excerpt']); ?></textarea> | ||
| <label>Nội dung</label> | ||
| <textarea name="content" rows="8" required><?php echo e($_POST['content'] ?? $post['content']); ?></textarea> | ||
| <label>Telegram media</label> | ||
| <textarea name="telegram_media" rows="3"><?php echo e($_POST['telegram_media'] ?? $post['telegram_media']); ?></textarea> | ||
| <label>Meta title</label> | ||
| <input name="meta_title" value="<?php echo e($_POST['meta_title'] ?? $post['meta_title']); ?>"> | ||
| <label>Meta description</label> | ||
| <input name="meta_description" value="<?php echo e($_POST['meta_description'] ?? $post['meta_description']); ?>"> | ||
| <label>Meta keywords</label> | ||
| <input name="meta_keywords" value="<?php echo e($_POST['meta_keywords'] ?? $post['meta_keywords']); ?>"> | ||
| <label>Trạng thái</label> | ||
| <select name="status"> | ||
| <option value="draft" <?php echo (($post['status'] ?? '') === 'draft') ? 'selected' : ''; ?>>Nháp</option> | ||
| <option value="public" <?php echo (($post['status'] ?? '') === 'public') ? 'selected' : ''; ?>>Public</option> | ||
| </select> | ||
| <input type="hidden" name="csrf" value="<?php echo csrf_token(); ?>"> | ||
| <button class="btn" type="submit">Lưu thay đổi</button> | ||
| </form> | ||
| <?php include __DIR__ . '/includes/footer.php'; ?> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
post_delete.php performs the DELETE directly from a GET
idwithout verifying a CSRF token. A malicious page loaded by a logged-in admin can fire a GET to this URL (e.g., via an image tag) and delete posts without server-side verification. This endpoint should require POST and callverify_csrfbefore executing the deletion.Useful? React with 👍 / 👎.