GitGram — topic.php — GitGram
IndexGram / main / indexgram_v5.00 / topic.php9,423 B↓ Raw
<?php
require_once __DIR__ . '/config.php';
if (!IS_INSTALLED) { header('Location: setup.php'); exit; }
require_once ROOT_PATH . '/includes/db.php';
require_once ROOT_PATH . '/includes/functions.php';
require_once ROOT_PATH . '/includes/auth.php';
require_once ROOT_PATH . '/includes/markdown.php';

$slug  = trim($_GET['slug'] ?? '');
$topic = $slug ? get_topic($slug) : null;
if (!$topic) { http_response_code(404); die('Topic not found.'); }

// Sub-topics and ancestor breadcrumb
$subTopics = get_subtopics($topic['id']);
$ancestors = get_topic_ancestors($topic['id']);

// Filters
$allTags   = audience_tags_enabled() ? get_tags() : [];
$tagFilter = audience_tags_enabled() ? (int)($_GET['tag'] ?? 0) : 0;
$searchQ   = trim($_GET['q']   ?? '');

$where  = ["d.topic_id = ?", "d.status = 'published'"];
$params = [$topic['id']];
if ($tagFilter) { $where[] = 'd.id IN (SELECT document_id FROM document_tags WHERE tag_id = ?)'; $params[] = $tagFilter; }
if ($searchQ) {
    if (fts5_available()) {
        $where[]  = "d.id IN (SELECT document_id FROM search_index WHERE search_index MATCH ? AND status = 'published')";
        $params[] = fts5_query($searchQ);
    } else {
        $where[]  = "(d.title LIKE ? OR d.meta_description LIKE ?)";
        $params[] = "%$searchQ%";
        $params[] = "%$searchQ%";
    }
}

$stmt = db()->prepare(
    "SELECT d.*, u.username AS author_name FROM documents d
     LEFT JOIN users u ON d.author_id = u.id
     WHERE " . implode(' AND ', $where) . " ORDER BY d.updated_at DESC"
);
$stmt->execute($params);
$docs = $stmt->fetchAll();

$meta = build_meta([
    'title'    => $topic['title'] . ' — ' . get_setting('site_title', SITE_NAME),
    'og_title' => $topic['title'],
    'og_desc'  => $topic['description'] ?: get_setting('og_description'),
    'og_image' => $topic['og_image'],
    'og_type'  => 'website',
]);
include ROOT_PATH . '/includes/header.php';
?>

<!-- Breadcrumb with ancestor chain -->
<div class="breadcrumb">
  <a href="<?= h(base_url()) ?>">Home</a>
  <?php foreach ($ancestors as $anc): ?>
    &rsaquo; <a href="<?= h(topic_url($anc['slug'])) ?>"><?= h($anc['title']) ?></a>
  <?php endforeach; ?>
  &rsaquo; <?= h($topic['title']) ?>
</div>

<div class="window topic-window">
  <div class="win-titlebar">
    &#128194; <?= h($topic['title']) ?>
    <a href="<?= h(rss_url($topic['slug'])) ?>" class="rss-badge" title="RSS Feed for this topic">RSS</a>
  </div>
  <div class="win-body">
    <!-- Search at top -->
    <div class="tag-filter" style="flex-wrap:wrap;gap:6px;align-items:center;margin-bottom:8px">
      <form method="get" action="<?= h(topic_url($topic['slug'])) ?>" style="display:flex;gap:4px;align-items:center;flex-wrap:wrap">
        <?php if ($tagFilter): ?><input type="hidden" name="tag" value="<?= $tagFilter ?>"><?php endif; ?>
        <input type="search" name="q" placeholder="Search this topic…" value="<?= h($searchQ) ?>"
               style="font-size:12px;padding:2px 6px;border:1px solid #808080;background:#FFF;font-family:inherit;width:180px">
        <button type="submit" style="font-size:11px;padding:2px 8px;border:2px solid;border-color:#FFF #404040 #404040 #FFF;background:#C0C0C0;cursor:pointer;font-family:inherit">Search</button>
        <?php if ($searchQ || $tagFilter): ?>
          <a href="<?= h(topic_url($topic['slug'])) ?>" style="font-size:11px">&#10005; Clear</a>
        <?php endif; ?>
      </form>
      <?php if (!empty($allTags)): ?>
      <div style="display:flex;flex-wrap:wrap;gap:4px;align-items:center">
        <strong style="font-size:11px">Audience:</strong>
        <a href="<?= h(topic_url($topic['slug'])) ?><?= $searchQ ? '?q='.rawurlencode($searchQ) : '' ?>" class="tag-badge <?= !$tagFilter ? 'active' : '' ?>" style="background:#444;color:#FFF">All</a>
        <?php foreach ($allTags as $tg): ?>
          <?php $tagUrl = topic_url($topic['slug']) . '?tag=' . $tg['id'] . ($searchQ ? '&q='.rawurlencode($searchQ) : ''); ?>
          <a href="<?= h($tagUrl) ?>"
             class="tag-badge <?= $tagFilter === (int)$tg['id'] ? 'active' : '' ?>"
             style="background:<?= h($tg['color']) ?>; color:#FFF;"><?= h($tg['name']) ?></a>
        <?php endforeach; ?>
      </div>
      <?php endif; ?>
    </div>

    <?php if ($topic['og_image']): ?>
      <img src="<?= h(base_url('uploads/og/' . $topic['og_image'])) ?>" alt="<?= h($topic['title']) ?>" class="topic-feature-image">
    <?php endif; ?>
    <?php if ($topic['description']): ?>
      <p class="topic-description"><?= h($topic['description']) ?></p>
    <?php endif; ?>
    <p class="topic-meta">Created: <?= h(fmt_date($topic['created_at'])) ?> &bull; Updated: <?= h(fmt_date($topic['updated_at'])) ?></p>

    <!-- Topic landing page (Markdown) -->
    <?php if (!empty($topic['landing_content']) && ($topic['landing_enabled'] || has_role('editor'))): ?>
    <div class="window" style="margin-bottom:12px">
      <div class="win-titlebar">&#128196; <?= h($topic['title']) ?>
        <?php if (has_role('editor')): ?>
          <div class="win-actions" style="float:right">
            <a href="<?= h(base_url('admin/topics.php?action=edit&id=' . $topic['id'])) ?>" class="button btn-sm" style="font-size:11px">&#9998; Edit Landing</a>
          </div>
        <?php endif; ?>
        <?php if (!$topic['landing_enabled']): ?>
          <span style="font-size:11px;opacity:0.75">(disabled — editors only)</span>
        <?php endif; ?>
      </div>
      <div class="win-body"><div class="markdown-body"><?= md($topic['landing_content']) ?></div></div>
    </div>
    <?php elseif (has_role('editor') && empty($topic['landing_content'])): ?>
    <p style="font-size:11px;color:#666;margin:0 0 8px">
      <a href="<?= h(base_url('admin/topics.php?action=edit&id=' . $topic['id'])) ?>">&#43; Add topic landing page</a>
    </p>
    <?php endif; ?>

    <!-- Sub-topics (up to level 3) -->
    <?php if (!empty($subTopics)): ?>
    <div class="section-titlebar" style="margin:8px 0 6px"><h2 style="margin:0;font-size:13px">&#128193; Sub-Topics</h2></div>
    <div class="topics-grid" style="margin-bottom:14px">
      <?php foreach ($subTopics as $st): ?>
        <?php $stCount = count(get_documents($st['id'])); ?>
        <a href="<?= h(topic_url($st['slug'])) ?>" class="topic-card">
          <div class="topic-card-body">
            <?php if ($st['og_image']): ?>
              <img src="<?= h(base_url('uploads/og/' . $st['og_image'])) ?>" alt="" class="topic-thumb">
            <?php else: ?>
              <span class="topic-icon">&#128193;</span>
            <?php endif; ?>
            <strong class="topic-card-name"><?= h($st['title']) ?></strong>
            <p class="topic-desc"><?= h($st['description']) ?></p>
            <span class="topic-count"><?= $stCount ?> doc<?= $stCount !== 1 ? 's' : '' ?></span>
          </div>
        </a>
      <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <!-- Document cards -->
    <?php if (empty($docs)): ?>
      <?php if (!empty($subTopics) && !$tagFilter): ?>
        <p class="empty-state" style="margin-top:4px">Browse the sub-topics above, or select an audience tag to filter.</p>
      <?php else: ?>
        <p class="empty-state">No documents in this topic<?= $tagFilter ? ' for this audience' : '' ?>.</p>
      <?php endif; ?>
    <?php else: ?>
    <?php if (!empty($subTopics)): ?><div class="section-titlebar" style="margin:8px 0 6px"><h2 style="margin:0;font-size:13px">&#128196; Documents in this topic</h2></div><?php endif; ?>
    <div class="doc-cards">
      <?php foreach ($docs as $d): ?>
        <?php
          $dtags  = audience_tags_enabled() ? get_document_tags($d['id']) : [];
          $dgtags = get_document_generic_tags($d['id']);
        ?>
        <div class="doc-card">
          <div class="doc-card-body">
            <?php if ($d['og_image']): ?>
              <img src="<?= h(base_url('uploads/og/' . $d['og_image'])) ?>" alt="" class="doc-card-thumb">
            <?php endif; ?>
            <strong class="doc-card-name"><a href="<?= h(doc_url($topic['slug'], $d['slug'])) ?>"><?= h($d['title']) ?></a></strong>
            <?php if ($d['meta_description']): ?>
              <p class="doc-card-desc"><?= h($d['meta_description']) ?></p>
            <?php endif; ?>
            <div class="doc-card-meta">
              <?php if (!empty($dtags)): ?>
              <div class="doc-card-tags">
                <?php foreach ($dtags as $tg): ?>
                  <a href="<?= h(topic_url($topic['slug'])) ?>?tag=<?= $tg['id'] ?>"
                     class="tag-badge"
                     style="background:<?= h($tg['color']) ?>;color:#FFF"><?= h($tg['name']) ?></a>
                <?php endforeach; ?>
              </div>
              <?php endif; ?>
              <?php if (!empty($dgtags)): ?>
              <div class="doc-card-tags">
                <?php foreach ($dgtags as $gt): ?>
                  <span class="tag-badge" style="background:#555;color:#FFF"><?= h($gt['name']) ?></span>
                <?php endforeach; ?>
              </div>
              <?php endif; ?>
              <div class="doc-card-topic">
                &#128337; Updated <?= h(fmt_date($d['updated_at'])) ?>
              </div>
            </div>
          </div>
        </div>
      <?php endforeach; ?>
    </div>
    <?php endif; ?>
  </div>
</div>

<?php include ROOT_PATH . '/includes/footer.php'; ?>
Ready
GitGram