From 73852c82414c231f866ed73506f75216ccc90ecb Mon Sep 17 00:00:00 2001 From: M_Viper Date: Sun, 18 Oct 2026 09:31:29 +0000 Subject: [PATCH] Upload via GUI (41 Dateien) --- includes/guest-authors.php | 206 ++++++++++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 5 deletions(-) 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 .= '
  1. '; + if ($label) { + $html .= '' . esc_html($label) . ' '; + } + $html .= '' . esc_html(get_the_title($part['id'])) . '' + . ' ' . wp_multi_guest_author_post_meta($part['id'], $part['date']) . '
  2. '; + } + + return $html . '
'; +} + +/** + * Eigenes CSS für Autorenübersicht und -profil (ersetzt das frühere Tailwind-CDN). + * Farben werden vom Theme geerbt, damit helle und dunkle Designs funktionieren. + */ +function wp_multi_guest_author_styles() { + static $printed = false; + + if ($printed) { + return; + } + $printed = true; + ?> + + - - last_part_date))); ?>

+ term_id]) ? $series_parts[(int) $row->term_id] : [], (int) $row->total_parts); // phpcs:ignore WordPress.Security.EscapeOutput ?> @@ -2022,16 +2219,15 @@ function wp_multi_guest_author_posts_shortcode() {

ID)); ?>

-

post_date)); ?>

+

ID, $row->post_date); // phpcs:ignore WordPress.Security.EscapeOutput ?>

- -