GitGram — index.php — GitGram
IndexGram / main / indexgram_v5.00 / index.php10,389 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';

$topics    = get_topics();       // top-level only, for the topic grid
$allTopics = get_topics(null, true); // all topics, for filter dropdown

// Apply admin-configured root topic: show sub-topics of chosen topic instead of full root list
$_rootTopicId = (int)get_setting('topic_index_start_id', '0');
if ($_rootTopicId > 0) {
    $_children = get_subtopics($_rootTopicId);
    if (!empty($_children)) $topics = $_children;
}
unset($_rootTopicId, $_children);
$allTags   = audience_tags_enabled() ? get_tags() : [];

// Filters from query string
$filterTopic = (int)($_GET['topic'] ?? 0);
$filterTag   = audience_tags_enabled() ? (int)($_GET['tag'] ?? 0) : 0;
$filterQ     = trim($_GET['q']      ?? '');

// Build documents query with all active filters
$where  = ["d.status = 'published'"];
$params = [];
if ($filterTopic) { $where[] = 'd.topic_id = ?'; $params[] = $filterTopic; }
if ($filterQ) {
    if (fts5_available()) {
        $where[]  = "d.id IN (SELECT document_id FROM search_index WHERE search_index MATCH ? AND status = 'published')";
        $params[] = fts5_query($filterQ);
    } else {
        $where[]  = "(d.title LIKE ? OR d.meta_description LIKE ?)";
        $params[] = "%$filterQ%";
        $params[] = "%$filterQ%";
    }
}
if ($filterTag)   { $where[] = 'd.id IN (SELECT document_id FROM document_tags WHERE tag_id = ?)'; $params[] = $filterTag; }

$sql = "SELECT d.*, t.slug AS topic_slug, t.title AS topic_title
        FROM documents d JOIN topics t ON d.topic_id = t.id
        WHERE " . implode(' AND ', $where) . "
        ORDER BY d.updated_at DESC LIMIT 120";
$stmt = db()->prepare($sql);
$stmt->execute($params);
$recent = $stmt->fetchAll();

$meta = build_meta();
include ROOT_PATH . '/includes/header.php';
?>

<?php
$landingPage = get_page('landing');
if ($landingPage && ($landingPage['enabled'] || has_role('editor')) && trim($landingPage['content']) !== ''):
?>
<div class="window" style="margin-bottom:14px">
  <div class="win-titlebar">&#127968; <?= h($landingPage['nav_label'] ?: $landingPage['title']) ?>
    <?php if (has_role('editor')): ?>
      <div class="win-actions">
        <a href="<?= h(base_url('admin/pages.php?edit=landing')) ?>" class="button btn-sm">&#9998; Edit</a>
      </div>
    <?php endif; ?>
    <?php if (!$landingPage['enabled']): ?>
      <span style="font-size:11px;opacity:0.75">(disabled — only visible to editors)</span>
    <?php endif; ?>
  </div>
  <div class="win-body">
    <div class="markdown-body"><?= md($landingPage['content']) ?></div>
  </div>
</div>
<?php endif; ?>

<!-- Hero -->
<div class="win-titlebar page-hero">
  <div class="hero-inner">
    <?php $logo = get_setting('logo'); if ($logo): ?>
      <img src="<?= h(base_url('uploads/images/' . $logo)) ?>" alt="<?= h(get_setting('site_title')) ?>" class="hero-logo">
    <?php else: ?>
      <span class="hero-sitename"><?= h(get_setting('site_title', 'IndexGram')) ?></span>
    <?php endif; ?>
    <p class="hero-desc"><?= h(get_setting('site_description')) ?></p>
  </div>
</div>

<!-- Search & Filter -->
<section class="search-section">
  <form method="get" style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
    <input type="search" name="q" placeholder="Search documents…" value="<?= h($filterQ) ?>"
           style="font-size:13px;padding:4px 8px;border:2px solid;border-color:#808080 #FFF #FFF #808080;background:#FFF;font-family:inherit;flex:1;min-width:160px">
    <select name="topic" style="font-size:13px;padding:4px 6px;border:2px solid;border-color:#808080 #FFF #FFF #808080;background:#FFF;font-family:inherit">
      <option value="0" <?= !$filterTopic ? 'selected' : '' ?>>All Topics</option>
      <?php foreach ($allTopics as $t): ?>
        <?php $indent = $t['parent_id'] ? (get_topic_by_id((int)$t['parent_id'])['parent_id'] ? '&nbsp;&nbsp;&nbsp;&nbsp;» ' : '&nbsp;&nbsp;› ') : ''; ?>
        <option value="<?= $t['id'] ?>" <?= $filterTopic === (int)$t['id'] ? 'selected' : '' ?>><?= $indent . h($t['title']) ?></option>
      <?php endforeach; ?>
    </select>
    <?php if (!empty($allTags)): ?>
    <select name="tag" style="font-size:13px;padding:4px 6px;border:2px solid;border-color:#808080 #FFF #FFF #808080;background:#FFF;font-family:inherit">
      <option value="0" <?= !$filterTag ? 'selected' : '' ?>>All Audiences</option>
      <?php foreach ($allTags as $tg): ?>
        <option value="<?= $tg['id'] ?>" <?= $filterTag === (int)$tg['id'] ? 'selected' : '' ?>><?= h($tg['name']) ?></option>
      <?php endforeach; ?>
    </select>
    <?php endif; ?>
    <button type="submit" style="font-size:13px;padding:4px 12px;border:2px solid;border-color:#FFF #404040 #404040 #FFF;background:#C0C0C0;cursor:pointer;font-family:inherit">&#128269; Search</button>
    <?php if ($filterTopic || $filterTag || $filterQ): ?>
      <a href="<?= h(base_url()) ?>" style="font-size:12px">&#10005; Clear</a>
    <?php endif; ?>
  </form>
</section>

<!-- Topics Grid -->
<section class="topics-section">
  <div class="section-titlebar"><h2>&#128194; Topic Index</h2></div>
  <div class="topics-grid">
    <?php if (empty($topics)): ?>
      <p class="empty-state">No topics yet. <a href="<?= h(base_url('login')) ?>">Log in</a> to add one.</p>
    <?php endif; ?>
    <?php foreach ($topics as $t): ?>
      <?php $count = count(get_documents($t['id'])); ?>
      <div class="topic-card">
        <div class="topic-card-body">
          <?php if ($t['og_image']): ?>
            <img src="<?= h(base_url('uploads/og/' . $t['og_image'])) ?>" alt="" class="topic-thumb">
          <?php else: ?>
            <span class="topic-icon">&#128193;</span>
          <?php endif; ?>
          <a href="<?= h(topic_url($t['slug'])) ?>" class="topic-card-link"><?= h($t['title']) ?></a>
          <p class="topic-desc"><?= h($t['description']) ?></p>
          <span class="topic-count"><?= $count ?> document<?= $count !== 1 ? 's' : '' ?></span>
          <span class="topic-rss"><a href="<?= h(rss_url($t['slug'])) ?>">RSS</a></span>
        </div>
      </div>
    <?php endforeach; ?>
  </div>
</section>

<!-- Document Index -->
<section class="recent-section">
  <div class="section-titlebar" id="doc-index-bar"
       style="cursor:pointer;user-select:none"
       onclick="toggleDocIndex()" title="Click to expand/collapse">
    <h2 style="margin:0">&#128196; Document Index <span id="doc-index-arrow" style="font-size:11px">&#9654;</span></h2>
  </div>

  <div id="doc-index-body" style="display:none">
  <!-- Active audience filter tags shown as badges -->
  <?php if (!empty($allTags) && !empty($recent) && audience_tags_enabled()): ?>
  <div style="margin:6px 0 4px;display:flex;flex-wrap:wrap;gap:4px;align-items:center">
    <span style="font-size:11px;color:#444">Filter by audience:</span>
    <a href="<?= h(base_url() . ($filterTopic ? '?topic='.$filterTopic : '')) ?>"
       class="tag-badge <?= !$filterTag ? 'active' : '' ?>"
       style="background:#444;color:#FFF">All</a>
    <?php foreach ($allTags as $tg): ?>
      <?php $href = base_url() . '?tag=' . $tg['id'] . ($filterTopic ? '&topic='.$filterTopic : ''); ?>
      <a href="<?= h($href) ?>"
         class="tag-badge <?= $filterTag === (int)$tg['id'] ? 'active' : '' ?>"
         style="background:<?= h($tg['color']) ?>;color:#FFF"><?= h($tg['name']) ?></a>
    <?php endforeach; ?>
  </div>
  <?php endif; ?>

  <?php if (empty($recent)): ?>
    <p class="empty-state">No documents found.</p>
  <?php else: ?>
  <div class="doc-cards">
    <?php foreach ($recent 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($d['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): ?>
                <?php $tagHref = base_url() . '?tag=' . $tg['id'] . ($filterTopic ? '&topic='.$filterTopic : ''); ?>
                <a href="<?= h($tagHref) ?>"
                   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">
              &#128194; <a href="<?= h(topic_url($d['topic_slug'])) ?>"><?= h($d['topic_title']) ?></a>
            </div>
          </div>
        </div>
      </div>
    <?php endforeach; ?>
  </div>
  <?php endif; ?>
  </div><!-- /#doc-index-body -->
</section>

<script>
(function(){
  var open   = sessionStorage.getItem('docIndexOpen') === '1';
  // If there's an active filter, default to open
  <?php if ($filterTopic || $filterTag || $filterQ): ?>open = true;<?php endif; ?>
  var body   = document.getElementById('doc-index-body');
  var arrow  = document.getElementById('doc-index-arrow');
  function applyState() {
    if (body)  body.style.display  = open ? '' : 'none';
    if (arrow) arrow.textContent   = open ? '▼' : '►';
  }
  applyState();
  window.toggleDocIndex = function(){
    open = !open;
    sessionStorage.setItem('docIndexOpen', open ? '1' : '0');
    applyState();
  };
})();
</script>

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