v2.0.0.0
Publisium
- <?php
-
- declare(strict_types=1);
-
- require_once __DIR__ . '/includes/config.php';
- require_once __DIR__ . '/includes/database.php';
- require_once __DIR__ . '/includes/auth.php';
- require_once __DIR__ . '/includes/csrf.php';
- require_once __DIR__ . '/includes/block-editor.php';
- require_once __DIR__ . '/includes/site-front.php';
- require_once __DIR__ . '/includes/activity-log.php';
- require_once __DIR__ . '/includes/indexnow.php';
- require_once __DIR__ . '/includes/author-profile.php';
- require_once __DIR__ . '/includes/avatar.php';
- require_once __DIR__ . '/includes/article-versions.php';
- require_once __DIR__ . '/includes/tags.php';
- require_once __DIR__ . '/includes/login-throttle.php';
- require_once __DIR__ . '/includes/two-factor.php';
- require_once __DIR__ . '/includes/read-aloud.php';
-
- Auth::boot();
- Auth::requireLogin();
-
- $currentUser = Auth::user();
- $currentRole = Auth::role();
- SiteFront::settings();
- $view = $_GET['view'] ?? 'overview';
- $allowedViews = ['overview', 'articles', 'article-edit', 'categories', 'pages', 'stats', 'profile', 'profile-reviews', 'security', 'trash'];
- if (!in_array($view, $allowedViews, true)) {
- $view = 'overview';
- }
-
- $flashMessage = null;
- $flashType = 'success';
-
- if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- if (!Csrf::verify($_POST['csrf_token'] ?? null)) {
- $flashMessage = 'Your session expired. Please try again.';
- $flashType = 'error';
- } else {
- $action = $_POST['action'] ?? '';
-
- if ($action === 'save_article') {
- [$flashMessage, $flashType, $redirectId] = require __DIR__ . '/dashboard-actions/save-article.php';
- if ($redirectId !== null) {
- ActivityLog::record('article.save', 'article', (int) $redirectId, trim((string) ($_POST['title'] ?? '')) . ' [' . (string) ($_POST['publish_action'] ?? '') . ']');
- ArticleVersions::snapshot((int) $redirectId, (int) $currentUser['id'], (string) $currentUser['display_name']);
-
- if (ArticleTags::isEnabled() && isset($_POST['tags'])) {
- $taggedArticle = Database::site()->prepare('SELECT author_id FROM articles WHERE id = :id');
- $taggedArticle->execute(['id' => (int) $redirectId]);
- $taggedAuthor = $taggedArticle->fetchColumn();
-
- if ($taggedAuthor !== false && ((int) $taggedAuthor === (int) $currentUser['id'] || Auth::hasRoleAtLeast(Auth::ROLE_EDITOR_IN_CHIEF))) {
- ArticleTags::sync((int) $redirectId, ArticleTags::parse((string) $_POST['tags']));
- }
- }
-
- ReadAloud::saveArticleFields((int) $redirectId, $_POST, $currentUser);
- ReadAloud::queueGeneration((int) $redirectId);
- IndexNow::notifyArticle((int) $redirectId);
- header('Location: dashboard.php?view=article-edit&id=' . $redirectId . '&saved=1');
- exit;
- }
- }
-
- if ($action === 'restore_version') {
- [$flashMessage, $flashType, $restoredId] = require __DIR__ . '/dashboard-actions/restore-version.php';
- if ($restoredId !== null) {
- IndexNow::notifyArticle((int) $restoredId);
- header('Location: dashboard.php?view=article-edit&id=' . $restoredId . '&saved=1');
- exit;
- }
- }
-
- if (in_array($action, ['restore_article', 'purge_article', 'empty_trash'], true)) {
- $trashedId = require __DIR__ . '/dashboard-actions/trash-article.php';
- if ($action === 'restore_article' && $trashedId > 0) {
- IndexNow::notifyArticle($trashedId);
- ReadAloud::queueGeneration($trashedId);
- }
- header('Location: dashboard.php?view=' . ($action === 'restore_article' && $trashedId > 0 ? 'articles' : 'trash') . '&saved=1');
- exit;
- }
-
- if (in_array($action, ['totp_begin', 'totp_cancel', 'totp_confirm', 'totp_disable', 'totp_regenerate'], true)) {
- [$flashMessage, $flashType, $securityDone] = require __DIR__ . '/dashboard-actions/security.php';
- if ($securityDone) {
- header('Location: dashboard.php?view=security');
- exit;
- }
- }
-
- if ($action === 'delete_article') {
- $deletedArticle = Database::site()->prepare('SELECT title, slug, status FROM articles WHERE id = :id');
- $deletedArticle->execute(['id' => (int) ($_POST['article_id'] ?? 0)]);
- $deletedArticle = $deletedArticle->fetch() ?: [];
- require __DIR__ . '/dashboard-actions/delete-article.php';
- ActivityLog::record('article.trash', 'article', (int) ($_POST['article_id'] ?? 0), (string) ($deletedArticle['title'] ?? ''));
- if (($deletedArticle['status'] ?? '') === 'published') {
- IndexNow::notifyRemoved((string) $deletedArticle['slug'], (int) ($_POST['article_id'] ?? 0));
- }
- header('Location: dashboard.php?view=articles&deleted=1');
- exit;
- }
-
- if ($action === 'moderate_article') {
- require __DIR__ . '/dashboard-actions/moderate-article.php';
- ActivityLog::record('article.moderate', 'article', (int) ($_POST['article_id'] ?? 0), (string) ($_POST['decision'] ?? ''));
- ReadAloud::queueGeneration((int) ($_POST['article_id'] ?? 0));
- IndexNow::notifyArticle((int) ($_POST['article_id'] ?? 0));
- header('Location: dashboard.php?view=articles&moderated=1');
- exit;
- }
-
- if ($action === 'save_profile') {
- [$flashMessage, $flashType, $profileSaved] = require __DIR__ . '/dashboard-actions/save-profile.php';
- if ($profileSaved) {
- header('Location: dashboard.php?view=profile&saved=1');
- exit;
- }
- }
-
- if ($action === 'review_profile') {
- [$flashMessage, $flashType, $profileReviewed] = require __DIR__ . '/dashboard-actions/review-profile.php';
- if ($profileReviewed) {
- header('Location: dashboard.php?view=profile-reviews&moderated=1');
- exit;
- }
- }
-
- if ($action === 'save_category') {
- require __DIR__ . '/dashboard-actions/save-category.php';
- ActivityLog::record('category.save', 'category', (int) ($_POST['category_id'] ?? 0) ?: null, trim((string) ($_POST['name'] ?? '')));
- header('Location: dashboard.php?view=categories&saved=1');
- exit;
- }
-
- if ($action === 'delete_category') {
- require __DIR__ . '/dashboard-actions/delete-category.php';
- ActivityLog::record('category.delete', 'category', (int) ($_POST['category_id'] ?? 0));
- header('Location: dashboard.php?view=categories&deleted=1');
- exit;
- }
-
- if ($action === 'toggle_category_menu') {
- require __DIR__ . '/dashboard-actions/toggle-category-menu.php';
- header('Location: dashboard.php?view=categories');
- exit;
- }
-
- if ($action === 'save_page') {
- require __DIR__ . '/dashboard-actions/save-page.php';
- ActivityLog::record('page.save', 'page', (int) ($_POST['page_id'] ?? 0) ?: null, trim((string) ($_POST['title'] ?? '')));
- header('Location: dashboard.php?view=pages&saved=1');
- exit;
- }
-
- if ($action === 'save_homepage') {
- require __DIR__ . '/dashboard-actions/save-homepage.php';
- ActivityLog::record('page.save', 'page', null, 'Home page');
- header('Location: dashboard.php?view=pages&saved=1');
- exit;
- }
-
- if ($action === 'delete_page') {
- require __DIR__ . '/dashboard-actions/delete-page.php';
- ActivityLog::record('page.delete', 'page', (int) ($_POST['page_id'] ?? 0));
- header('Location: dashboard.php?view=pages&deleted=1');
- exit;
- }
- }
- }
-
- $dashView = $view;
- $dashPageTitle = 'Dashboard';
- $dashLoadBlockEditor = $view === 'article-edit';
-
- require __DIR__ . '/includes/dash-header.php';
-
- ?>
-
- <?php if ($flashMessage !== null): ?>
- <div class="dash-flash dash-flash-<?= htmlspecialchars($flashType) ?>"><?= Icons::icon($flashType === 'error' ? 'x' : 'check', 'icon icon-sm') ?><?= htmlspecialchars($flashMessage) ?></div>
- <?php endif; ?>
-
- <?php if (isset($_GET['saved'])): ?>
- <div class="dash-flash dash-flash-success"><?= Icons::icon('check', 'icon icon-sm') ?>Changes saved.</div>
- <?php endif; ?>
- <?php if (isset($_GET['deleted'])): ?>
- <div class="dash-flash dash-flash-success"><?= Icons::icon('check', 'icon icon-sm') ?>Deleted.</div>
- <?php endif; ?>
- <?php if (isset($_GET['moderated'])): ?>
- <div class="dash-flash dash-flash-success"><?= Icons::icon('check', 'icon icon-sm') ?>Done. The article has been updated.</div>
- <?php endif; ?>
-
- <?php
- switch ($view) {
- case 'overview':
- require __DIR__ . '/dashboard-views/overview.php';
- break;
- case 'articles':
- require __DIR__ . '/dashboard-views/articles.php';
- break;
- case 'article-edit':
- require __DIR__ . '/dashboard-views/article-edit.php';
- break;
- case 'categories':
- require __DIR__ . '/dashboard-views/categories.php';
- break;
- case 'pages':
- require __DIR__ . '/dashboard-views/pages.php';
- break;
- case 'stats':
- require __DIR__ . '/dashboard-views/stats.php';
- break;
- case 'profile':
- require __DIR__ . '/dashboard-views/profile.php';
- break;
- case 'profile-reviews':
- require __DIR__ . '/dashboard-views/profile-reviews.php';
- break;
- case 'security':
- require __DIR__ . '/dashboard-views/security.php';
- break;
- case 'trash':
- require __DIR__ . '/dashboard-views/trash.php';
- break;
- }
- ?>
-
- <?php require __DIR__ . '/includes/dash-footer.php'; ?>
-