WebOrbiton
v1.0.0.9

Publisium

88 lines · 3.3 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. require_once __DIR__ . '/includes/config.php';
  6. require_once __DIR__ . '/includes/database.php';
  7. require_once __DIR__ . '/includes/user-auth.php';
  8. require_once __DIR__ . '/includes/language.php';
  9. require_once __DIR__ . '/includes/site-front.php';
  10. require_once __DIR__ . '/includes/pagination.php';
  11. require_once __DIR__ . '/includes/article-card.php';
  12. require_once __DIR__ . '/includes/tags.php';
  13. ​
  14. UserAuth::boot();
  15. ​
  16. $db = Database::site();
  17. $settings = SiteFront::settings();
  18. ​
  19. $slug = trim((string) ($_GET['slug'] ?? ''));
  20. $tag = ArticleTags::isEnabled() ? ArticleTags::findBySlug($slug) : null;
  21. ​
  22. if ($tag === null) {
  23. http_response_code(404);
  24. $pageTitle = Language::get('not_found_title', 'Not found') . ' - ' . $settings['site_name'];
  25. $showBanner = false;
  26. require __DIR__ . '/includes/front-header.php';
  27. echo '<p>' . htmlspecialchars(Language::get('tag_not_found', 'Tag not found.')) . '</p>';
  28. require __DIR__ . '/includes/front-footer.php';
  29. exit;
  30. }
  31. ​
  32. $tagId = (int) $tag['id'];
  33. ​
  34. $totalStatement = $db->prepare(
  35. "SELECT COUNT(*) FROM articles a JOIN article_tags l ON l.article_id = a.id WHERE l.tag_id = :tag AND a.status = 'published'" . Languages::articleFilterSql('a')
  36. );
  37. $totalStatement->execute(['tag' => $tagId]);
  38. $totalArticles = (int) $totalStatement->fetchColumn();
  39. ​
  40. $isStaticArticleLoading = ($settings['article_loading_mode'] ?? 'scroll') === 'static';
  41. $perPage = $isStaticArticleLoading
  42. ? max(1, $totalArticles)
  43. : max(1, (int) $settings['articles_per_page_category']);
  44. $totalPages = Pagination::totalPages($totalArticles, $perPage);
  45. $currentPage = $isStaticArticleLoading ? 1 : min(Pagination::currentPage(), $totalPages);
  46. $offset = Pagination::offset($currentPage, $perPage);
  47. ​
  48. $articlesStatement = $db->prepare(
  49. "SELECT a.*, c.name AS category_name, c.slug AS category_slug
  50. FROM articles a
  51. JOIN article_tags l ON l.article_id = a.id
  52. LEFT JOIN categories c ON c.id = a.category_id
  53. WHERE l.tag_id = :tag AND a.status = 'published'" . Languages::articleFilterSql('a') . "
  54. ORDER BY a.published_at DESC
  55. LIMIT :limit OFFSET :offset"
  56. );
  57. $articlesStatement->bindValue('tag', $tagId, PDO::PARAM_INT);
  58. $articlesStatement->bindValue('limit', $perPage, PDO::PARAM_INT);
  59. $articlesStatement->bindValue('offset', $offset, PDO::PARAM_INT);
  60. $articlesStatement->execute();
  61. $articles = Languages::articles($articlesStatement->fetchAll());
  62. ​
  63. $heading = str_replace('{name}', (string) $tag['name'], Language::get('tag_page_title', 'Tagged: {name}'));
  64. $pageTitle = $heading . ' - ' . $settings['site_name'];
  65. $pageDescription = '';
  66. $showBanner = false;
  67. $pageType = 'category';
  68. ​
  69. require __DIR__ . '/includes/front-header.php';
  70. ​
  71. ?>
  72. <h1 class="category-title"><?= htmlspecialchars($heading) ?></h1>
  73. ​
  74. <div class="article-grid" id="article-list">
  75. <?php foreach ($articles as $article): ?>
  76. <?= renderArticleCard($article) ?>
  77. <?php endforeach; ?>
  78. <?php if (empty($articles)): ?>
  79. <p><?= htmlspecialchars(Language::get('tag_no_articles', 'No published articles with this tag yet.')) ?></p>
  80. <?php endif; ?>
  81. </div>
  82. ​
  83. <div id="pagination-container">
  84. <?= $isStaticArticleLoading ? '' : Pagination::render('numbered', 'tag.php', $currentPage, $totalPages, ['slug' => $slug], 'article-list') ?>
  85. </div>
  86. ​
  87. <?php require __DIR__ . '/includes/front-footer.php'; ?>
  88. ​