Upload via GUI (41 Dateien)
This commit is contained in:
+201
-5
@@ -64,6 +64,32 @@ function wp_multi_display_guest_author($author_name) {
|
|||||||
}
|
}
|
||||||
add_filter('the_author', 'wp_multi_display_guest_author');
|
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)
|
// Anzeige des Gast-Autors in der Beitragsübersicht (Backend)
|
||||||
function wp_multi_add_guest_author_column($columns) {
|
function wp_multi_add_guest_author_column($columns) {
|
||||||
if (isset($columns['author'])) {
|
if (isset($columns['author'])) {
|
||||||
@@ -1728,6 +1754,175 @@ function wp_multi_get_guest_author_overview_url() {
|
|||||||
return $cached ? get_permalink($cached) : '';
|
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 .= ' <span class="ga-badge" title="' . esc_attr__('Hinter einer Altersfreigabe verborgen', 'wp-multi') . '">' . esc_html($profile['title']) . '</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = '<details class="ga-parts"><summary>' . esc_html($summary) . '</summary><ol>';
|
||||||
|
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
$label = $part['part'] > 0
|
||||||
|
? sprintf(__('Teil %d', 'wp-multi'), $part['part'])
|
||||||
|
: '';
|
||||||
|
|
||||||
|
$html .= '<li>';
|
||||||
|
if ($label) {
|
||||||
|
$html .= '<span class="ga-part-no">' . esc_html($label) . '</span> ';
|
||||||
|
}
|
||||||
|
$html .= '<a href="' . esc_url(get_permalink($part['id'])) . '">' . esc_html(get_the_title($part['id'])) . '</a>'
|
||||||
|
. ' <span class="ga-part-meta">' . wp_multi_guest_author_post_meta($part['id'], $part['date']) . '</span></li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $html . '</ol></details>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
?>
|
||||||
|
<style id="wp-multi-guest-author-css">
|
||||||
|
/* Breite zwingend an die Spalte binden: das Theme gibt der Klasse "container" feste Breiten. */
|
||||||
|
#guest-author-section, #guest-author-posts { width: 100%; min-width: 0; max-width: 100%; float: none; margin: 0; padding: 2rem 0; box-sizing: border-box; overflow-wrap: anywhere; }
|
||||||
|
#guest-author-section *, #guest-author-posts * { box-sizing: border-box; }
|
||||||
|
#guest-author-section .grid, #guest-author-posts .grid { display: grid; grid-template-columns: 1fr; gap: 1.5rem; margin-bottom: 2rem; }
|
||||||
|
@media (min-width: 768px) { #guest-author-section .grid, #guest-author-posts .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||||||
|
#guest-author-section .guest-author-card, #guest-author-posts .post-card {
|
||||||
|
display: block; padding: 1.25rem 1.5rem; border-radius: .6rem; text-decoration: none; color: inherit;
|
||||||
|
background: rgba(127,127,127,.09); border: 1px solid rgba(127,127,127,.28);
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,.12); transition: box-shadow .15s, border-color .15s;
|
||||||
|
}
|
||||||
|
#guest-author-section .guest-author-card:hover, #guest-author-posts .post-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.22); border-color: rgba(127,127,127,.55); }
|
||||||
|
#guest-author-section h3, #guest-author-posts h2, #guest-author-posts h3, #guest-author-posts h4 { margin: 0 0 .4rem; color: inherit; }
|
||||||
|
#guest-author-posts h2 { font-size: 1.6rem; }
|
||||||
|
#guest-author-posts h3 { font-size: 1.25rem; margin-top: 2rem; }
|
||||||
|
#guest-author-posts h4 { font-size: 1.05rem; }
|
||||||
|
#guest-author-section p, #guest-author-posts p { margin: 0 0 .5rem; }
|
||||||
|
#guest-author-section .guest-author-sort { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-bottom: 1.5rem; }
|
||||||
|
#guest-author-section .guest-author-sort-label { font-size: 16px !important; }
|
||||||
|
#guest-author-section .guest-author-sort-link { padding: .4rem 1rem; border: 1px solid rgba(127,127,127,.45); border-radius: .4rem; text-decoration: none; font-size: 16px !important; line-height: 1.3; }
|
||||||
|
#guest-author-section .guest-author-sort-link.is-active { font-weight: 600; border-color: currentColor; }
|
||||||
|
#guest-author-section .text-sm, #guest-author-posts .text-sm { font-size: 15px !important; }
|
||||||
|
#guest-author-section .guest-author-last-post { font-size: 15px !important; }
|
||||||
|
#guest-author-section .text-gray-500, #guest-author-posts .text-gray-500,
|
||||||
|
#guest-author-section .text-gray-600, #guest-author-posts .text-gray-600 { opacity: .75; }
|
||||||
|
#guest-author-posts .guest-author-popular { padding-left: 1.25rem; list-style: disc; }
|
||||||
|
#guest-author-posts .guest-author-popular li { margin-bottom: .25rem; }
|
||||||
|
#guest-author-posts .guest-author-milestone-badge { font-size: 1.1rem; font-weight: 600; }
|
||||||
|
.ga-badge { display: inline-block; padding: 0 .45rem; border-radius: 999px; font-size: .75rem; background: rgba(120,80,200,.22); }
|
||||||
|
.ga-parts { margin-top: .6rem; }
|
||||||
|
.ga-parts summary { cursor: pointer; font-size: .9rem; }
|
||||||
|
.ga-parts ol { margin: .5rem 0 0; padding-left: 0; list-style: none; max-height: 18rem; overflow: auto; }
|
||||||
|
.ga-parts li { padding: .2rem 0; border-top: 1px solid rgba(127,127,127,.18); font-size: .9rem; }
|
||||||
|
.ga-part-no { font-weight: 600; margin-right: .25rem; }
|
||||||
|
.ga-part-meta { opacity: .7; font-size: .8rem; }
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
// Shortcode für Gastautoren-Liste
|
// Shortcode für Gastautoren-Liste
|
||||||
function wp_multi_guest_author_shortcode($atts = []) {
|
function wp_multi_guest_author_shortcode($atts = []) {
|
||||||
ob_start();
|
ob_start();
|
||||||
@@ -1847,9 +2042,8 @@ function wp_multi_guest_author_shortcode($atts = []) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tailwind CSS CDN -->
|
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
|
||||||
<?php
|
<?php
|
||||||
|
wp_multi_guest_author_styles();
|
||||||
|
|
||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
@@ -1879,6 +2073,7 @@ function wp_multi_guest_author_posts_shortcode() {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
|
wp_multi_guest_author_styles();
|
||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1889,6 +2084,7 @@ function wp_multi_guest_author_posts_shortcode() {
|
|||||||
$series_data = wp_multi_get_guest_author_series($guest_author);
|
$series_data = wp_multi_get_guest_author_series($guest_author);
|
||||||
$series = $series_data['series'];
|
$series = $series_data['series'];
|
||||||
$series_post_ids = $series_data['post_ids'];
|
$series_post_ids = $series_data['post_ids'];
|
||||||
|
$series_parts = wp_multi_get_guest_author_series_parts($guest_author, $series);
|
||||||
|
|
||||||
// Neueste Einzelgeschichten (Serienteile stehen im eigenen Abschnitt)
|
// Neueste Einzelgeschichten (Serienteile stehen im eigenen Abschnitt)
|
||||||
$exclude_sql = $series_post_ids ? 'AND p.ID NOT IN (' . implode(',', $series_post_ids) . ')' : '';
|
$exclude_sql = $series_post_ids ? 'AND p.ID NOT IN (' . implode(',', $series_post_ids) . ')' : '';
|
||||||
@@ -1998,6 +2194,7 @@ function wp_multi_guest_author_posts_shortcode() {
|
|||||||
·
|
·
|
||||||
<?php printf(esc_html__('zuletzt %s', 'wp-multi'), esc_html(mysql2date(get_option('date_format'), $row->last_part_date))); ?>
|
<?php printf(esc_html__('zuletzt %s', 'wp-multi'), esc_html(mysql2date(get_option('date_format'), $row->last_part_date))); ?>
|
||||||
</p>
|
</p>
|
||||||
|
<?php echo wp_multi_guest_author_render_parts(isset($series_parts[(int) $row->term_id]) ? $series_parts[(int) $row->term_id] : [], (int) $row->total_parts); // phpcs:ignore WordPress.Security.EscapeOutput ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
@@ -2022,16 +2219,15 @@ function wp_multi_guest_author_posts_shortcode() {
|
|||||||
<h4 class="text-lg font-medium text-gray-800">
|
<h4 class="text-lg font-medium text-gray-800">
|
||||||
<a href="<?php echo esc_url(get_permalink((int) $row->ID)); ?>" class="hover:text-blue-600"><?php echo esc_html(get_the_title((int) $row->ID)); ?></a>
|
<a href="<?php echo esc_url(get_permalink((int) $row->ID)); ?>" class="hover:text-blue-600"><?php echo esc_html(get_the_title((int) $row->ID)); ?></a>
|
||||||
</h4>
|
</h4>
|
||||||
<p class="text-gray-500 text-sm"><?php echo esc_html(mysql2date(get_option('date_format'), $row->post_date)); ?></p>
|
<p class="text-gray-500 text-sm"><?php echo wp_multi_guest_author_post_meta((int) $row->ID, $row->post_date); // phpcs:ignore WordPress.Security.EscapeOutput ?></p>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tailwind CSS CDN -->
|
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
|
||||||
<?php
|
<?php
|
||||||
|
wp_multi_guest_author_styles();
|
||||||
|
|
||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user