v1.0.0.8
Publisium
- <?php
-
- declare(strict_types=1);
-
- require_once __DIR__ . '/includes/config.php';
- require_once __DIR__ . '/includes/database.php';
- require_once __DIR__ . '/includes/user-auth.php';
- require_once __DIR__ . '/includes/language.php';
- require_once __DIR__ . '/includes/site-front.php';
- require_once __DIR__ . '/includes/pagination.php';
- require_once __DIR__ . '/includes/article-card.php';
- require_once __DIR__ . '/includes/author-profile.php';
- require_once __DIR__ . '/includes/avatar.php';
-
- UserAuth::boot();
-
- $db = Database::site();
- $settings = SiteFront::settings();
-
- $slug = trim((string) ($_GET['slug'] ?? ''));
- $profile = AuthorProfile::isEnabled() ? AuthorProfile::findPublicBySlug($slug) : null;
-
- if ($profile === null) {
- http_response_code(404);
- $pageTitle = Language::get('not_found_title', 'Not found') . ' - ' . $settings['site_name'];
- $showBanner = false;
- require __DIR__ . '/includes/front-header.php';
- echo '<p>' . htmlspecialchars(Language::get('artist_not_found', 'Author not found.')) . '</p>';
- require __DIR__ . '/includes/front-footer.php';
- exit;
- }
-
- if (!defined('PUBLISIUM_SHORT_LINK') && CleanUrls::slugFor('author', (string) $profile['slug']) !== null) {
- CleanUrls::redirect(SiteFront::authorUrl((string) $profile['slug']));
- }
-
- $authorId = (int) $profile['account_id'];
-
- $totalStatement = $db->prepare("SELECT COUNT(*) FROM articles a WHERE a.status = 'published' AND a.author_id = :author" . Languages::articleFilterSql('a'));
- $totalStatement->execute(['author' => $authorId]);
- $totalArticles = (int) $totalStatement->fetchColumn();
-
- $isStaticArticleLoading = ($settings['article_loading_mode'] ?? 'scroll') === 'static';
- $perPage = $isStaticArticleLoading
- ? max(1, $totalArticles)
- : max(1, (int) $settings['articles_per_page_category']);
- $currentPage = $isStaticArticleLoading ? 1 : Pagination::currentPage();
- $totalPages = Pagination::totalPages($totalArticles, $perPage);
- $currentPage = min($currentPage, $totalPages);
- $offset = Pagination::offset($currentPage, $perPage);
-
- $articlesStatement = $db->prepare(
- "SELECT a.*, c.name AS category_name, c.slug AS category_slug
- FROM articles a
- LEFT JOIN categories c ON c.id = a.category_id
- WHERE a.status = 'published' AND a.author_id = :author" . Languages::articleFilterSql('a') . "
- ORDER BY a.published_at DESC
- LIMIT :limit OFFSET :offset"
- );
- $articlesStatement->bindValue('author', $authorId, PDO::PARAM_INT);
- $articlesStatement->bindValue('limit', $perPage, PDO::PARAM_INT);
- $articlesStatement->bindValue('offset', $offset, PDO::PARAM_INT);
- $articlesStatement->execute();
- $articles = Languages::articles($articlesStatement->fetchAll());
-
- $authorName = (string) $profile['display_name'];
- $websiteUrl = AuthorProfile::safeUrl((string) $profile['website_url']);
- $bioText = trim((string) $profile['bio']);
-
- $pageTitle = $authorName . ' - ' . $settings['site_name'];
- $pageDescription = $profile['headline'] !== '' ? (string) $profile['headline'] : mb_substr((string) preg_replace('/\s+/u', ' ', $bioText), 0, 160);
- $showBanner = false;
- $pageType = 'author';
- $ogType = 'profile';
- $ogImagePath = Avatar::isValidPath((string) $profile['avatar_path']) ? (string) $profile['avatar_path'] : null;
-
- require __DIR__ . '/includes/front-header.php';
-
- ?>
- <section class="artist-header">
- <?= Avatar::html($profile, 'artist-avatar') ?>
- <div class="artist-header-info">
- <h1 class="artist-name"><?= htmlspecialchars($authorName) ?></h1>
- <?php if ($profile['headline'] !== ''): ?>
- <p class="artist-headline"><?= htmlspecialchars((string) $profile['headline']) ?></p>
- <?php endif; ?>
- <p class="artist-meta">
- <?= htmlspecialchars(str_replace('{count}', (string) $totalArticles, Language::get('author_articles_count', 'Articles: {count}'))) ?>
- <?php if ($websiteUrl !== null && $websiteUrl !== ''): ?>
- · <a href="<?= htmlspecialchars($websiteUrl, ENT_QUOTES) ?>" target="_blank" rel="nofollow ugc noopener noreferrer"><?= htmlspecialchars(Language::get('artist_website', 'Website')) ?></a>
- <?php endif; ?>
- </p>
- </div>
- </section>
-
- <?php if ($bioText !== ''): ?>
- <div class="artist-bio"><?= nl2br(htmlspecialchars($bioText)) ?></div>
- <?php endif; ?>
-
- <div class="section-heading-row">
- <h2 class="section-heading"><?= htmlspecialchars(str_replace('{name}', $authorName, Language::get('artist_articles_title', 'Articles by {name}'))) ?></h2>
- </div>
-
- <div class="article-grid" id="article-list">
- <?php foreach ($articles as $article): ?>
- <?= renderArticleCard($article) ?>
- <?php endforeach; ?>
- <?php if (empty($articles)): ?>
- <p><?= htmlspecialchars(Language::get('artist_no_articles', 'No published articles yet.')) ?></p>
- <?php endif; ?>
- </div>
-
- <div id="pagination-container">
- <?php $authorShortUrl = CleanUrls::slugFor('author', $slug) !== null ? SiteFront::authorUrl($slug) : null; ?>
- <?= $isStaticArticleLoading ? '' : Pagination::render('numbered', $authorShortUrl ?? 'artist.php', $currentPage, $totalPages, $authorShortUrl !== null ? [] : ['slug' => $slug], 'article-list') ?>
- </div>
-
- <?php require __DIR__ . '/includes/front-footer.php'; ?>
-