diff --git a/includes/guest-authors.php b/includes/guest-authors.php
index 6163774..3738da2 100644
--- a/includes/guest-authors.php
+++ b/includes/guest-authors.php
@@ -64,6 +64,32 @@ function wp_multi_display_guest_author($author_name) {
}
add_filter('the_author', 'wp_multi_display_guest_author');
+// Link hinter dem Autornamen: zur Gastautor-Seite statt zum (redirecteten) WordPress-Benutzer
+function wp_multi_guest_author_link($link, $author_id) {
+ if (is_admin() || !(is_single() || is_archive() || is_home() || is_search())) {
+ return $link;
+ }
+
+ $post = get_post();
+ if (!$post || (int) $post->post_author !== (int) $author_id) {
+ return $link;
+ }
+
+ $guest_author = get_post_meta($post->ID, '_guest_author', true);
+ if (empty($guest_author)) {
+ return $link;
+ }
+
+ $page_id = (int) get_option('wp_multi_guest_author_page_id');
+ $page_url = $page_id ? get_permalink($page_id) : '';
+ if (!$page_url) {
+ return $link;
+ }
+
+ return add_query_arg('guest_author', rawurlencode($guest_author), $page_url);
+}
+add_filter('author_link', 'wp_multi_guest_author_link', 10, 2);
+
// Anzeige des Gast-Autors in der Beitragsübersicht (Backend)
function wp_multi_add_guest_author_column($columns) {
if (isset($columns['author'])) {
@@ -1728,6 +1754,175 @@ function wp_multi_get_guest_author_overview_url() {
return $cached ? get_permalink($cached) : '';
}
+/**
+ * Datum · Kategorie · Altersfreigabe (Age Gate) einer Geschichte als HTML.
+ * Es wird nie Text der Geschichte ausgegeben – gesperrte Beiträge bleiben verborgen.
+ */
+function wp_multi_guest_author_post_meta($post_id, $post_date) {
+ $bits = [esc_html(mysql2date(get_option('date_format'), $post_date))];
+
+ $names = [];
+ foreach ((array) get_the_category((int) $post_id) as $category) {
+ $names[] = esc_html($category->name);
+ }
+ if ($names) {
+ $bits[] = implode(', ', $names);
+ }
+
+ $html = implode(' · ', $bits);
+
+ if (function_exists('zst_profile_for_post')) {
+ $profile = zst_profile_for_post((int) $post_id);
+ if (is_array($profile) && !empty($profile['title'])) {
+ $html .= ' ' . esc_html($profile['title']) . '';
+ }
+ }
+
+ return $html;
+}
+
+/**
+ * Alle Teile eines Autors je Serie, nach Teilnummer sortiert.
+ *
+ * @param string $guest_author Name des Gast-Autors.
+ * @param array $series Serienzeilen aus wp_multi_get_guest_author_series().
+ * @return array term_id => [ ['id','title','date','part'], … ]
+ */
+function wp_multi_get_guest_author_series_parts($guest_author, $series) {
+ $source = wp_multi_detect_series_source();
+
+ if (!$series || !$source || $guest_author === '') {
+ return [];
+ }
+
+ global $wpdb;
+
+ $term_ids = array_map('intval', wp_list_pluck($series, 'term_id'));
+ $in = implode(',', $term_ids);
+ $parent_sql = $source['parent'] ? $wpdb->prepare('AND tt.parent = %d', $source['parent']) : '';
+
+ $rows = $wpdb->get_results($wpdb->prepare("
+ SELECT DISTINCT p.ID, p.post_title, p.post_date, tt.term_id
+ FROM {$wpdb->posts} p
+ INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = '_guest_author' AND pm.meta_value = %s
+ INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id = p.ID
+ INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tt.taxonomy = %s {$parent_sql}
+ WHERE p.post_status = 'publish' AND tt.term_id IN ({$in})
+ ", $guest_author, $source['taxonomy']));
+
+ $default_key = defined('SERIES_PART_KEY') ? SERIES_PART_KEY : '_series_part';
+ $out = [];
+
+ foreach ((array) $rows as $row) {
+ $term_id = (int) $row->term_id;
+ $key = apply_filters('orgseries_part_key', $default_key, $term_id);
+ $out[$term_id][] = [
+ 'id' => (int) $row->ID,
+ 'title' => $row->post_title,
+ 'date' => $row->post_date,
+ 'part' => (int) get_post_meta((int) $row->ID, $key, true),
+ ];
+ }
+
+ foreach ($out as &$list) {
+ usort($list, function ($a, $b) {
+ if ($a['part'] !== $b['part']) {
+ return $a['part'] <=> $b['part'];
+ }
+ return strcmp($a['date'], $b['date']);
+ });
+ }
+ unset($list);
+
+ return $out;
+}
+
+/**
+ * Einklappbare Teile-Liste einer Serie.
+ *
+ * @param array $parts Teile des Autors in dieser Serie.
+ * @param int $total_parts Gesamtzahl der Teile der Serie.
+ */
+function wp_multi_guest_author_render_parts($parts, $total_parts) {
+ if (!$parts) {
+ return '';
+ }
+
+ $summary = sprintf(
+ /* translators: 1: Anzahl Teile des Autors, 2: Gesamtzahl der Teile */
+ _n('%1$d Teil von %2$d anzeigen', '%1$d Teile von %2$d anzeigen', count($parts), 'wp-multi'),
+ count($parts),
+ max((int) $total_parts, count($parts))
+ );
+
+ $html = '' . esc_html($summary) . '
';
+
+ foreach ($parts as $part) {
+ $label = $part['part'] > 0
+ ? sprintf(__('Teil %d', 'wp-multi'), $part['part'])
+ : '';
+
+ $html .= '
post_date)); ?>
+ID, $row->post_date); // phpcs:ignore WordPress.Security.EscapeOutput ?>
- -