WebOrbiton
v2.0.0.1

Publisium

104 lines · 5.2 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. $db = Database::site();
  6. ​
  7. $isAdmin = Auth::isAdministrative();
  8. ​
  9. $statement = $isAdmin
  10. ? $db->query('SELECT a.*, COALESCE(t.display_name, a.author_name) AS display_name, a.author_id AS owner_id, c.name AS category_name FROM articles a LEFT JOIN team_accounts t ON t.id = a.author_id LEFT JOIN categories c ON c.id = a.category_id WHERE a.deleted_at IS NULL ORDER BY a.updated_at DESC')
  11. : $db->prepare('SELECT a.*, COALESCE(t.display_name, a.author_name) AS display_name, a.author_id AS owner_id, c.name AS category_name FROM articles a LEFT JOIN team_accounts t ON t.id = a.author_id LEFT JOIN categories c ON c.id = a.category_id WHERE a.author_id = :id AND a.deleted_at IS NULL ORDER BY a.updated_at DESC');
  12. ​
  13. if (!$isAdmin) {
  14. $statement->execute(['id' => $currentUser['id']]);
  15. $articles = $statement->fetchAll();
  16. } else {
  17. $articles = $statement->fetchAll();
  18. }
  19. ​
  20. $trashStatement = $isAdmin
  21. ? $db->query('SELECT COUNT(*) FROM articles WHERE deleted_at IS NOT NULL')
  22. : $db->prepare('SELECT COUNT(*) FROM articles WHERE deleted_at IS NOT NULL AND author_id = :id');
  23. if (!$isAdmin) {
  24. $trashStatement->execute(['id' => $currentUser['id']]);
  25. }
  26. $trashCount = (int) $trashStatement->fetchColumn();
  27. ​
  28. ?>
  29. <div class="dash-header-row">
  30. <h1 class="dash-title"><?= Icons::icon("articles", "icon icon-lg") ?>Articles</h1>
  31. <a href="dashboard.php?view=trash" class="dash-btn"><?= Icons::icon('trash', 'icon icon-sm') ?>Trash<?= $trashCount > 0 ? ' (' . $trashCount . ')' : '' ?></a>
  32. <a href="dashboard.php?view=article-edit" class="dash-btn dash-btn-primary"><?= Icons::icon('plus', 'icon icon-sm') ?>New article</a>
  33. </div>
  34. ​
  35. <table class="dash-table">
  36. <thead>
  37. <tr>
  38. <th><?= Icons::icon('heading', 'icon icon-sm') ?>Title</th>
  39. <th><?= Icons::icon('categories', 'icon icon-sm') ?>Category</th>
  40. <th><?= Icons::icon('user', 'icon icon-sm') ?>Author</th>
  41. <th><?= Icons::icon('lock', 'icon icon-sm') ?>Access</th>
  42. <th><?= Icons::icon('flag', 'icon icon-sm') ?>Status</th>
  43. <th><?= Icons::icon('clock', 'icon icon-sm') ?>Updated</th>
  44. <th></th>
  45. </tr>
  46. </thead>
  47. <tbody>
  48. <?php foreach ($articles as $article): ?>
  49. <tr>
  50. <td><a href="dashboard.php?view=article-edit&id=<?= (int) $article['id'] ?>"><?= htmlspecialchars($article['title']) ?></a></td>
  51. <td><?= htmlspecialchars($article['category_name'] ?? 'None') ?></td>
  52. <td><?= htmlspecialchars((string) ($article['display_name'] ?? 'System')) ?><?php if ($article['owner_id'] === null): ?> <span class="status-pill status-draft" title="The author's account was removed. The article stays on the site under their name.">system</span><?php endif; ?></td>
  53. <td><?= $article['access_type'] === 'paid' ? 'Paid' : 'Free' ?></td>
  54. <td><span class="status-pill status-<?= htmlspecialchars($article['status']) ?>"><?= htmlspecialchars(dashStatusLabel((string) $article['status'])) ?></span></td>
  55. <td><?= htmlspecialchars($article['updated_at']) ?></td>
  56. <td class="dash-table-actions">
  57. ​
  58. <?php if ($isAdmin && $article['status'] === 'pending_review'): ?>
  59. <form method="post" style="display:inline;">
  60. <?= Csrf::field() ?>
  61. <input type="hidden" name="action" value="moderate_article">
  62. <input type="hidden" name="article_id" value="<?= (int) $article['id'] ?>">
  63. <input type="hidden" name="decision" value="approve">
  64. <button type="submit" class="dash-btn-small dash-btn-success"><?= Icons::icon('check', 'icon icon-sm') ?>Approve</button>
  65. </form>
  66. <button type="button" class="dash-btn-small dash-btn-danger js-reject-btn" data-article-id="<?= (int) $article['id'] ?>"><?= Icons::icon('x', 'icon icon-sm') ?>Send back</button>
  67. <?php endif; ?>
  68. ​
  69. <form method="post" style="display:inline;" onsubmit="return confirm('Move this article to the trash?');">
  70. <?= Csrf::field() ?>
  71. <input type="hidden" name="action" value="delete_article">
  72. <input type="hidden" name="article_id" value="<?= (int) $article['id'] ?>">
  73. <button type="submit" class="dash-btn-small dash-btn-danger"><?= Icons::icon('trash', 'icon icon-sm') ?>Delete</button>
  74. </form>
  75. <?php if ($article['status'] === 'published' && !empty($article['slug'])): ?>
  76. <a href="<?= htmlspecialchars(SiteFront::articleUrl($article['slug'])) ?>" class="dash-btn-small" target="_blank" rel="noopener noreferrer"><?= Icons::icon('eye', 'icon icon-sm') ?>View</a>
  77. <?php else: ?>
  78. <a href="article.php?preview=<?= (int) $article['id'] ?>" class="dash-btn-small" target="_blank" rel="noopener noreferrer"><?= Icons::icon('eye', 'icon icon-sm') ?>Preview</a>
  79. <?php endif; ?>
  80. </td>
  81. </tr>
  82. ​
  83. <?php if ($isAdmin && $article['status'] === 'pending_review'): ?>
  84. <tr class="js-reject-row" id="reject-row-<?= (int) $article['id'] ?>" style="display:none;">
  85. <td colspan="7">
  86. <form method="post">
  87. <?= Csrf::field() ?>
  88. <input type="hidden" name="action" value="moderate_article">
  89. <input type="hidden" name="article_id" value="<?= (int) $article['id'] ?>">
  90. <input type="hidden" name="decision" value="reject">
  91. <input type="text" name="rejection_reason" placeholder="Tell the author what to change" class="dash-input-inline">
  92. <button type="submit" class="dash-btn-small dash-btn-danger"><?= Icons::icon('check', 'icon icon-sm') ?>Send back to author</button>
  93. </form>
  94. </td>
  95. </tr>
  96. <?php endif; ?>
  97. ​
  98. <?php endforeach; ?>
  99. <?php if (empty($articles)): ?>
  100. <tr><td colspan="7">No articles yet. Click New article to write your first one.</td></tr>
  101. <?php endif; ?>
  102. </tbody>
  103. </table>
  104. ​