Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
778563d991 | |||
d332fac418 |
@ -31,6 +31,9 @@
|
||||
- Statistik-Widget mit Shortcode `[statistik_manager]`
|
||||
- Anpassbares Banner mit Position, Farbe und Icon
|
||||
|
||||
- **Gast Autoren:**
|
||||
- Alphabetisches Index für Gast Autoren mit Shortcode `[guest_authors]`
|
||||
|
||||
- **Admin-Tools:**
|
||||
- Dashboard-Widget für Plugin-Updates (mit Pre-Release-Unterstützung)
|
||||
- Pinnwand für Administratoren
|
||||
|
395
wp-multi.php
395
wp-multi.php
@ -3,11 +3,12 @@
|
||||
* Plugin Name: WP Multi
|
||||
* Plugin URI: https://git.viper.ipv64.net/M_Viper/wp-multi
|
||||
* Description: Erweiterter Anti-Spam-Schutz mit Honeypot, Keyword-Filter, Link-Limit und mehr. Jetzt mit Statistik im Dashboard und HappyForms-Integration.
|
||||
* Version: 3.0
|
||||
* Version: 3.2
|
||||
* Author: M_Viper
|
||||
* Author URI: https://m-viper.de
|
||||
* Requires at least: 6.7.2
|
||||
* Tested up to: 6.7.2
|
||||
* PHP Version: 7.2
|
||||
* License: GPL2
|
||||
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
* Text Domain: wp-multi
|
||||
@ -312,6 +313,8 @@ function check_disposable_email($commentdata) {
|
||||
add_filter('preprocess_comment', 'check_disposable_email');
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Text Copy Schutz und Schutz vor Entwicklertools
|
||||
*/
|
||||
@ -3476,7 +3479,6 @@ function wp_multi_display_dashboard_widget() {
|
||||
* Gast Autoren
|
||||
*/
|
||||
|
||||
|
||||
// Gast-Autor Eingabefeld in der Sidebar im Admin-Bereich hinzufügen
|
||||
function wp_multi_add_guest_author_field() {
|
||||
add_meta_box(
|
||||
@ -3492,7 +3494,6 @@ add_action('add_meta_boxes', 'wp_multi_add_guest_author_field');
|
||||
|
||||
// Callback-Funktion, die das Eingabefeld anzeigt
|
||||
function wp_multi_guest_author_field($post) {
|
||||
// Die Metadaten des Beitrags laden (ob ein Gast-Autor gesetzt ist)
|
||||
$guest_author = get_post_meta($post->ID, '_guest_author', true);
|
||||
?>
|
||||
<label for="guest_author"><?php _e('Gast-Autor Name:', 'wp-multi'); ?></label>
|
||||
@ -3502,13 +3503,8 @@ function wp_multi_guest_author_field($post) {
|
||||
|
||||
// Speichern der Gast-Autor Daten
|
||||
function wp_multi_save_guest_author_meta($post_id) {
|
||||
// Sicherheit: Verhindere, dass die Metadaten beim Autosave überschrieben werden
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
||||
|
||||
// Überprüfen, ob der Benutzer Berechtigungen hat
|
||||
if (!current_user_can('edit_post', $post_id)) return;
|
||||
|
||||
// Überprüfen, ob der Gast-Autor Name gesetzt wurde
|
||||
if (isset($_POST['guest_author'])) {
|
||||
$guest_author = sanitize_text_field($_POST['guest_author']);
|
||||
update_post_meta($post_id, '_guest_author', $guest_author);
|
||||
@ -3523,10 +3519,8 @@ function wp_multi_display_guest_author($author_name) {
|
||||
if ((is_single() || is_archive() || is_home()) && !is_admin()) {
|
||||
$post = get_post();
|
||||
if ($post) {
|
||||
// Wenn der Beitrag einen Gast-Autor hat, diesen verwenden
|
||||
$guest_author = get_post_meta($post->ID, '_guest_author', true);
|
||||
if (!empty($guest_author)) {
|
||||
// Ersetze den Standard-Autor mit dem Gast-Autor
|
||||
$author_name = $guest_author;
|
||||
}
|
||||
}
|
||||
@ -3544,15 +3538,10 @@ function wp_multi_add_guest_author_column($columns) {
|
||||
}
|
||||
add_filter('manage_posts_columns', 'wp_multi_add_guest_author_column');
|
||||
|
||||
// Inhalt der Gast-Autor-Spalte
|
||||
function wp_multi_display_guest_author_column($column_name, $post_id) {
|
||||
if ($column_name == 'guest_author') {
|
||||
$guest_author = get_post_meta($post_id, '_guest_author', true);
|
||||
if (!empty($guest_author)) {
|
||||
echo esc_html($guest_author);
|
||||
} else {
|
||||
echo __('Kein Gast-Autor', 'wp-multi');
|
||||
}
|
||||
echo !empty($guest_author) ? esc_html($guest_author) : __('Kein Gast-Autor', 'wp-multi');
|
||||
}
|
||||
}
|
||||
add_action('manage_posts_custom_column', 'wp_multi_display_guest_author_column', 10, 2);
|
||||
@ -3570,43 +3559,67 @@ function wp_multi_add_guest_author_page() {
|
||||
}
|
||||
add_action('admin_menu', 'wp_multi_add_guest_author_page');
|
||||
|
||||
|
||||
// Callback-Funktion für die Gast-Autor-Übersicht
|
||||
function wp_multi_guest_author_overview_page() {
|
||||
// Sortierparameter aus URL lesen
|
||||
$orderby = isset($_GET['orderby']) ? sanitize_key($_GET['orderby']) : 'guest_author';
|
||||
$order = isset($_GET['order']) && in_array(strtoupper($_GET['order']), ['ASC', 'DESC']) ? strtoupper($_GET['order']) : 'ASC';
|
||||
|
||||
// Gültige Sortierfelder
|
||||
$valid_orderby = ['guest_author' => 'pm.meta_value', 'posts' => 'post_count'];
|
||||
$sql_orderby = isset($valid_orderby[$orderby]) ? $valid_orderby[$orderby] : 'pm.meta_value';
|
||||
$sql_order = $order;
|
||||
|
||||
// Basis-URL für Sortier-Links
|
||||
$base_url = add_query_arg(['page' => 'guest_author_overview'], admin_url('users.php'));
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php _e('Gast-Autor Übersicht', 'wp-multi'); ?></h1>
|
||||
<table class="wp-list-table widefat fixed striped posts">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Gast-Autor', 'wp-multi'); ?></th>
|
||||
<th><?php _e('Anzahl der Beiträge', 'wp-multi'); ?></th>
|
||||
<th class="column-guest_author">
|
||||
<a href="<?php echo esc_url(add_query_arg(['orderby' => 'guest_author', 'order' => ($orderby === 'guest_author' && $order === 'ASC') ? 'DESC' : 'ASC'], $base_url)); ?>" class="<?php echo ($orderby === 'guest_author') ? 'sorted ' . strtolower($order) : 'sortable'; ?>">
|
||||
<?php _e('Gast-Autor', 'wp-multi'); ?>
|
||||
<?php if ($orderby === 'guest_author') : ?>
|
||||
<span class="sorting-indicator"><?php echo ($order === 'ASC') ? '↑' : '↓'; ?></span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</th>
|
||||
<th class="column-posts">
|
||||
<a href="<?php echo esc_url(add_query_arg(['orderby' => 'posts', 'order' => ($orderby === 'posts' && $order === 'ASC') ? 'DESC' : 'ASC'], $base_url)); ?>" class="<?php echo ($orderby === 'posts') ? 'sorted ' . strtolower($order) : 'sortable'; ?>">
|
||||
<?php _e('Anzahl der Beiträge', 'wp-multi'); ?>
|
||||
<?php if ($orderby === 'posts') : ?>
|
||||
<span class="sorting-indicator"><?php echo ($order === 'ASC') ? '↑' : '↓'; ?></span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
// Alle Autoren und die Anzahl der Beiträge abfragen
|
||||
global $wpdb;
|
||||
$guest_authors = $wpdb->get_results("SELECT DISTINCT pm.meta_value AS guest_author
|
||||
FROM {$wpdb->posts} p
|
||||
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
|
||||
WHERE pm.meta_key = '_guest_author' AND p.post_status = 'publish'
|
||||
ORDER BY guest_author ASC");
|
||||
$query = "
|
||||
SELECT pm.meta_value AS guest_author, COUNT(*) AS post_count
|
||||
FROM {$wpdb->posts} p
|
||||
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
|
||||
WHERE pm.meta_key = '_guest_author'
|
||||
AND pm.meta_value != ''
|
||||
AND p.post_status = 'publish'
|
||||
GROUP BY pm.meta_value
|
||||
ORDER BY {$sql_orderby} {$sql_order}
|
||||
";
|
||||
$guest_authors = $wpdb->get_results($query);
|
||||
|
||||
|
||||
|
||||
// Alle Gast-Autoren anzeigen
|
||||
if ($guest_authors) {
|
||||
foreach ($guest_authors as $author) {
|
||||
// Anzahl der Beiträge für den Gast-Autor zählen
|
||||
$author_posts = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*)
|
||||
FROM {$wpdb->posts} p
|
||||
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
|
||||
WHERE pm.meta_key = '_guest_author'
|
||||
AND pm.meta_value = %s
|
||||
AND p.post_status = 'publish'", $author->guest_author));
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($author->guest_author); ?></td>
|
||||
<td><?php echo $author_posts; ?></td>
|
||||
<td><?php echo esc_html($author->post_count); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
@ -3622,46 +3635,306 @@ function wp_multi_guest_author_overview_page() {
|
||||
|
||||
// Schönes CSS nur für die Gast-Autor-Übersicht
|
||||
function wp_multi_guest_author_overview_css() {
|
||||
// CSS nur auf der Seite der Gast-Autor-Übersicht anwenden
|
||||
if (isset($_GET['page']) && $_GET['page'] == 'guest_author_overview') {
|
||||
?>
|
||||
<style>
|
||||
.wp-list-table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
.wrap {
|
||||
background-color: #ffffff;
|
||||
padding: 24px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
margin: 20px 20px 20px 0;
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
.wp-list-table th, .wp-list-table td {
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.wrap h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 24px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.wp-list-table th {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.wp-list-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.wp-list-table tr:nth-child(even) {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.wp-list-table th, .wp-list-table td {
|
||||
padding: 16px;
|
||||
font-size: 14px;
|
||||
color: #374151;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
text-align: left; /* Standard Textausrichtung */
|
||||
}
|
||||
|
||||
/* Kopfzeilen und Datenzellen der Spalte 'posts' zentrieren */
|
||||
.wp-list-table th.column-posts, .wp-list-table td.column-posts {
|
||||
text-align: center !important; /* !important stellt sicher, dass diese Regel Vorrang hat */
|
||||
vertical-align: middle !important; /* Vertikal mittig ausrichten mit !important */
|
||||
width: 200px !important; /* Kann je nach Bedarf angepasst werden */
|
||||
}
|
||||
|
||||
/* Optional: Wenn du sicherstellen möchtest, dass auch die Kopfzeile mit einer festen Breite arbeitet */
|
||||
.wp-list-table th.column-posts {
|
||||
width: 200px !important; /* Breite der Kopfzeile mit !important */
|
||||
}
|
||||
|
||||
.wp-list-table th.column-guest_author {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.wp-list-table th {
|
||||
background-color: #f8fafc;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.wp-list-table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.wp-list-table tr:nth-child(even) {
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
|
||||
.wp-list-table th a {
|
||||
text-decoration: none;
|
||||
color: #2563eb;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
transition: color 0.2s ease;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wp-list-table th a:hover {
|
||||
color: #1d4ed8;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.wp-list-table th a:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.3);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.wp-list-table th.sorted a {
|
||||
color: #111827;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wp-list-table th .sorting-indicator {
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.wp-list-table th.sorted .sorting-indicator {
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.wp-list-table th.sortable a:hover .sorting-indicator {
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.wp-list-table td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.wp-list-table th, .wp-list-table td {
|
||||
padding: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.wp-list-table th.column-posts {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.wrap h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
.wrap h1 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
add_action('admin_head', 'wp_multi_guest_author_overview_css');
|
||||
|
||||
// Funktion zum Erstellen der Gastautoren-Beitragsseite
|
||||
function wp_multi_create_guest_author_page() {
|
||||
$page_title = __('Gastautor Beiträge', 'wp-multi');
|
||||
$page_slug = 'gastautor-beitraege';
|
||||
$page = get_page_by_path($page_slug);
|
||||
|
||||
if (!$page) {
|
||||
$page_id = wp_insert_post(array(
|
||||
'post_title' => $page_title,
|
||||
'post_name' => $page_slug,
|
||||
'post_content' => '[guest_author_posts]',
|
||||
'post_status' => 'publish',
|
||||
'post_type' => 'page',
|
||||
));
|
||||
|
||||
if ($page_id && !is_wp_error($page_id)) {
|
||||
update_option('wp_multi_guest_author_page_id', $page_id);
|
||||
}
|
||||
} else {
|
||||
update_option('wp_multi_guest_author_page_id', $page->ID);
|
||||
}
|
||||
}
|
||||
add_action('init', 'wp_multi_create_guest_author_page');
|
||||
|
||||
// Shortcode für Gastautoren-Liste
|
||||
function wp_multi_guest_author_shortcode() {
|
||||
ob_start();
|
||||
global $wpdb;
|
||||
|
||||
// Alle Gastautoren mit Beitragsanzahl abrufen
|
||||
$query = "
|
||||
SELECT pm.meta_value AS guest_author, COUNT(*) AS post_count
|
||||
FROM {$wpdb->posts} p
|
||||
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
|
||||
WHERE pm.meta_key = '_guest_author'
|
||||
AND pm.meta_value != ''
|
||||
AND p.post_status = 'publish'
|
||||
GROUP BY pm.meta_value
|
||||
ORDER BY pm.meta_value ASC
|
||||
";
|
||||
$guest_authors = $wpdb->get_results($query);
|
||||
|
||||
// URL der Gastautoren-Beitragsseite
|
||||
$guest_author_page_id = get_option('wp_multi_guest_author_page_id');
|
||||
$guest_author_page_url = $guest_author_page_id ? get_permalink($guest_author_page_id) : '#';
|
||||
|
||||
?>
|
||||
<div id="guest-author-section" class="container mx-auto px-4 py-8">
|
||||
<!-- Gastautoren-Liste -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
|
||||
<?php if ($guest_authors) : ?>
|
||||
<?php foreach ($guest_authors as $author) : ?>
|
||||
<a href="<?php echo esc_url(add_query_arg('guest_author', urlencode($author->guest_author), $guest_author_page_url)); ?>" class="guest-author-card bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition">
|
||||
<h3 class="text-xl font-semibold text-gray-800"><?php echo esc_html($author->guest_author); ?></h3>
|
||||
<p class="text-gray-600"><?php echo esc_html($author->post_count); ?> <?php _e('Beiträge', 'wp-multi'); ?></p>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
<p class="col-span-2 text-center text-gray-600"><?php _e('Keine Gastautoren gefunden.', 'wp-multi'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tailwind CSS CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
add_shortcode('guest_authors', 'wp_multi_guest_author_shortcode');
|
||||
|
||||
// Shortcode für Gastautoren-Beiträge
|
||||
function wp_multi_guest_author_posts_shortcode() {
|
||||
ob_start();
|
||||
|
||||
$guest_author = isset($_GET['guest_author']) ? sanitize_text_field(urldecode($_GET['guest_author'])) : '';
|
||||
|
||||
?>
|
||||
<div id="guest-author-posts" class="container mx-auto px-4 py-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 mb-4">
|
||||
<?php
|
||||
if ($guest_author) {
|
||||
printf(__('Beiträge von %s', 'wp-multi'), esc_html($guest_author));
|
||||
} else {
|
||||
_e('Beiträge auswählen', 'wp-multi');
|
||||
}
|
||||
?>
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<?php
|
||||
if ($guest_author) {
|
||||
// Überprüfen, ob die Kategorie "series" existiert
|
||||
$series_category = term_exists('series', 'category');
|
||||
$debug_message = '';
|
||||
|
||||
if (!$series_category) {
|
||||
$debug_message = '<p class="col-span-2 text-red-600">Debug: Kategorie mit Slug "series" wurde nicht gefunden. Bitte überprüfe den Kategorie-Slug.</p>';
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_type' => ['post', 'page', 'dein_custom_post_type'],
|
||||
'post_status' => 'publish',
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_guest_author',
|
||||
'value' => $guest_author,
|
||||
'compare' => '='
|
||||
)
|
||||
),
|
||||
'tax_query' => array(
|
||||
array(
|
||||
'taxonomy' => 'category',
|
||||
'field' => 'slug',
|
||||
'terms' => 'series',
|
||||
'operator' => 'NOT IN'
|
||||
)
|
||||
),
|
||||
'posts_per_page' => -1
|
||||
);
|
||||
|
||||
$query = new WP_Query($args);
|
||||
|
||||
|
||||
|
||||
if ($query->have_posts()) {
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
// Beitragsinhalt abrufen und kürzen
|
||||
$content = get_the_content();
|
||||
$content = wp_strip_all_tags($content); // HTML-Tags entfernen
|
||||
$trimmed_content = wp_trim_words($content, 30, '...');
|
||||
?>
|
||||
<div class="post-card bg-white p-6 rounded-lg shadow-md">
|
||||
<h3 class="text-lg font-medium text-gray-800">
|
||||
<a href="<?php the_permalink(); ?>" class="hover:text-blue-600"><?php the_title(); ?></a>
|
||||
</h3>
|
||||
<p class="text-gray-600 line-clamp-3"><?php echo esc_html($trimmed_content); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
wp_reset_postdata();
|
||||
} else {
|
||||
?>
|
||||
<p class="col-span-2 text-gray-600"><?php _e('Keine Beiträge gefunden.', 'wp-multi'); ?></p>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<p class="col-span-2 text-gray-600"><?php _e('Wählen Sie einen Gastautor aus, um die Beiträge anzuzeigen.', 'wp-multi'); ?></p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tailwind CSS CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
add_shortcode('guest_author_posts', 'wp_multi_guest_author_posts_shortcode');
|
||||
|
||||
|
||||
/*
|
||||
* Custom Text Box
|
||||
|
Loading…
x
Reference in New Issue
Block a user