WebOrbiton
v1.0.0.9

Publisium

101 lines · 4.5 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. ​
  13. UserAuth::boot();
  14. ​
  15. $db = Database::site();
  16. $settings = SiteFront::settings();
  17. ​
  18. $slug = trim((string) ($_GET['slug'] ?? ''));
  19. ​
  20. $categoryStatement = $db->prepare('SELECT * FROM categories WHERE slug = :slug LIMIT 1');
  21. $categoryStatement->execute(['slug' => $slug]);
  22. $category = $categoryStatement->fetch();
  23. if ($category) {
  24. $category = Languages::categories([$category])[0];
  25. }
  26. ​
  27. if (!$category) {
  28. http_response_code(404);
  29. $pageTitle = Language::get('not_found_title', 'Not found') . ' - ' . $settings['site_name'];
  30. $showBanner = false;
  31. require __DIR__ . '/includes/front-header.php';
  32. echo '<p>' . htmlspecialchars(Language::get('category_not_found', 'We couldn’t find this category.')) . '</p>';
  33. require __DIR__ . '/includes/front-footer.php';
  34. exit;
  35. }
  36. ​
  37. $currentPage = Pagination::currentPage();
  38. $totalStatement = $db->prepare("SELECT COUNT(*) AS c FROM articles a WHERE a.status = 'published' AND a.category_id = :category_id" . Languages::articleFilterSql('a'));
  39. $totalStatement->execute(['category_id' => $category['id']]);
  40. $totalArticles = (int) $totalStatement->fetch()['c'];
  41. $isStaticArticleLoading = ($settings['article_loading_mode'] ?? 'scroll') === 'static';
  42. $perPage = $isStaticArticleLoading
  43. ? max(1, $totalArticles)
  44. : max(1, (int) $settings['articles_per_page_category']);
  45. $currentPage = $isStaticArticleLoading ? 1 : $currentPage;
  46. $offset = Pagination::offset($currentPage, $perPage);
  47. $totalPages = Pagination::totalPages($totalArticles, $perPage);
  48. ​
  49. $articlesStatement = $db->prepare(
  50. "SELECT a.* FROM articles a WHERE a.status = 'published' AND a.category_id = :category_id" . Languages::articleFilterSql('a') . " ORDER BY a.published_at DESC LIMIT :limit OFFSET :offset"
  51. );
  52. $articlesStatement->bindValue('category_id', $category['id'], PDO::PARAM_INT);
  53. $articlesStatement->bindValue('limit', $perPage, PDO::PARAM_INT);
  54. $articlesStatement->bindValue('offset', $offset, PDO::PARAM_INT);
  55. $articlesStatement->execute();
  56. $articles = Languages::articles($articlesStatement->fetchAll());
  57. ​
  58. $pageTitle = $category['name'] . ' - ' . $settings['site_name'];
  59. $pageDescription = $category['description'] ?? '';
  60. $showBanner = false;
  61. $pageType = 'category';
  62. $rssFeedUrl = $settings['sitemap_rss_enabled'] === '1' && $settings['rss_category_feeds_enabled'] === '1'
  63. ? 'rss.php?category=' . rawurlencode((string) $category['slug'])
  64. : null;
  65. ​
  66. require __DIR__ . '/includes/front-header.php';
  67. ​
  68. ?>
  69. <h1 class="category-title"><?= htmlspecialchars($category['name']) ?></h1>
  70. <?php if (!empty($category['description'])): ?>
  71. <p class="category-description"><?= htmlspecialchars($category['description']) ?></p>
  72. <?php endif; ?>
  73. <?php if ($rssFeedUrl !== null): ?>
  74. <a href="<?= htmlspecialchars($rssFeedUrl, ENT_QUOTES) ?>" class="category-rss-link">
  75. <svg class="icon icon-sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg>
  76. <?= htmlspecialchars(Language::get('category_rss', 'RSS feed for this category')) ?>
  77. </a>
  78. <?php endif; ?>
  79. ​
  80. <?= SiteFront::renderAds('category-top') ?>
  81. ​
  82. <div class="article-grid" id="article-list" data-pagination-source="category" data-category-slug="<?= htmlspecialchars($slug, ENT_QUOTES) ?>">
  83. <?php $inFeedAds = SiteFront::activeAds('in-feed'); ?>
  84. <?php foreach ($articles as $inFeedIndex => $article): ?>
  85. <?= renderArticleCard($article) ?>
  86. <?php if ($inFeedIndex === 2 && !empty($inFeedAds)): ?>
  87. <?php foreach ($inFeedAds as $inFeedAd): ?>
  88. <?= SiteFront::renderAd($inFeedAd) ?>
  89. <?php endforeach; ?>
  90. <?php endif; ?>
  91. <?php endforeach; ?>
  92. <?php if (empty($articles)): ?>
  93. <p><?= htmlspecialchars(Language::get('category_no_articles', 'No articles in this category yet.')) ?></p>
  94. <?php endif; ?>
  95. </div>
  96. ​
  97. <div id="pagination-container">
  98. <?= $isStaticArticleLoading ? '' : Pagination::render($settings['pagination_style'], 'category.php', $currentPage, $totalPages, ['slug' => $slug], 'article-list') ?>
  99. </div>
  100. ​
  101. <?php require __DIR__ . '/includes/front-footer.php'; ?>