Files
wp-multi/includes/statistik-manager.php
T
2026-10-01 05:59:49 +00:00

583 lines
26 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* WP Multi – Modul: Statistik & Banner
*
* Automatisch aus wp-multi.php ausgelagert. Wird über den Loader in
* wp-multi.php eingebunden (nur wenn das WP Multi Toolkit aktiv ist).
*/
if (!defined('ABSPATH')) { exit; }
/*
* Statistik & Banner
*/
// Funktion zum Einbinden von CSS direkt im Plugin-Code
function statistik_manager_inline_styles() {
?>
<style>
/* CSS für das Statistik Manager Plugin */
.statistik-manager-bookmarks {
font-family: Arial, sans-serif;
margin-top: 20px;
}
.statistik-manager-bookmarks ul {
list-style-type: none;
padding: 0;
}
.statistik-manager-bookmarks li {
margin-bottom: 10px;
}
.statistik-manager-bookmarks a {
text-decoration: none;
color: #0073aa;
font-size: 1.6em; /* Größerer Text für den Titel */
}
.statistik-manager-bookmarks a:hover {
color: #005177;
}
.delete-bookmark-btn {
background-color: #f44336;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
margin-right: 10px; /* Abstand zwischen Button und Titel */
margin-bottom: 10px; /* Mehr Abstand nach unten */
}
.delete-bookmark-btn:hover {
background-color: #d32f2f;
}
.form-field {
margin-bottom: 15px;
}
.form-field label {
display: block;
margin-bottom: 5px;
}
.form-field input {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.form-field button {
background-color: #0073aa;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
}
.form-field button:hover {
background-color: #005177;
}
</style>
<?php
}
add_action('wp_head', 'statistik_manager_inline_styles');
// Font Awesome einbinden
function statistik_manager_enqueue_fontawesome() {
wp_enqueue_style('fontawesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css', [], null);
}
add_action('wp_enqueue_scripts', 'statistik_manager_enqueue_fontawesome');
// Sprachdateien laden
function statistik_manager_load_textdomain() {
load_plugin_textdomain('statistik-manager', false, dirname(plugin_basename(WP_MULTI_FILE)) . '/languages');
}
add_action('plugins_loaded', 'statistik_manager_load_textdomain');
// Funktion zum Abrufen der Statistiken
function statistik_manager_get_statistics() {
global $wpdb;
// Beiträge
$posts_count = wp_count_posts()->publish;
// Kommentare
$comments_count = wp_count_comments()->total_comments;
// Kategorien
$selected_categories = get_option('statistik_manager_selected_categories', []);
$categories_count = 0;
if (!empty($selected_categories)) {
$categories_count = count($selected_categories);
} else {
// Alle Kategorien zählen, wenn keine ausgewählt wurden
$categories_count = wp_count_terms('category');
}
// Serien (angenommen, Serien sind benutzerdefinierte Taxonomie)
$series_count = 0;
if (taxonomy_exists('series')) {
$count = wp_count_terms('series');
$series_count = is_wp_error($count) ? 0 : (int) $count;
}
// Eröffnungsdatum
$opening_date = get_option('statistik_manager_opening_date', '');
return [
'posts_count' => $posts_count,
'comments_count' => $comments_count,
'categories_count' => $categories_count,
'series_count' => $series_count,
'opening_date' => $opening_date
];
}
// Banner-Funktion
function statistik_manager_display_banner($position) {
static $rendered = false;
if ($rendered) {
return; // verhindert doppelte Ausgabe (wp_body_open + Footer-Fallback)
}
if (!get_option('statistik_manager_banner_enabled', 1)) {
return;
}
$banner_text = get_option('statistik_manager_banner_text', 'Willkommen auf unserer Webseite!');
$banner_color = get_option('statistik_manager_banner_color', '#0073aa');
$banner_position = get_option('statistik_manager_banner_position', 'top');
$font_size = get_option('statistik_manager_banner_font_size', 'medium');
$banner_icon = get_option('statistik_manager_banner_icon', 'fas fa-info-circle'); // Standard-Icon
$show_icon = get_option('statistik_manager_show_icon', 1); // Option zur Aktivierung des Icons
// Schriftgröße je nach Auswahl setzen
switch ($font_size) {
case 'small':
$font_size_css = '14px';
break;
case 'medium':
$font_size_css = '18px';
break;
case 'large':
$font_size_css = '24px';
break;
default:
$font_size_css = '18px';
}
if ($banner_position !== $position) {
return;
}
$rendered = true;
// Standard-Styles für das Banner (auto-Höhe, zentriert, umbruchfähig).
// !important, damit aktive Themes (z. B. Sueva) Farbe/Breite/Position
// nicht per eigener !important-Regel überschreiben können.
// top/bottom bewusst ohne !important: wird per Script unter fixe Leisten gesetzt.
$vertical_imp = ($position === 'bottom') ? 'bottom: 0;' : 'top: 0;';
$style = "background-color: " . esc_attr($banner_color) . " !important;
color: #fff !important;
text-align: center !important;
padding: 12px 16px !important;
margin: 0 !important;
width: 100% !important;
box-sizing: border-box !important;
z-index: 99990 !important;
position: fixed !important;
left: 0 !important;
$vertical_imp
display: flex !important;
align-items: center !important;
justify-content: center !important;
gap: 8px !important;";
$text_style = "font-size: " . esc_attr($font_size_css) . " !important; color: #fff !important; margin: 0 !important; line-height: 1.4 !important;";
$icon_style = "font-size: 24px !important; margin-right: 8px !important; color: #fff !important;"; // Feste Größe für Icon
echo '<div class="statistik-manager-banner" id="statistik-manager-banner" style="' . esc_attr($style) . '">';
// Icon nur anzeigen, wenn gewünscht
if ($show_icon && !empty($banner_icon)) {
echo '<i class="' . esc_attr($banner_icon) . '" style="' . esc_attr($icon_style) . '"></i>';
}
echo '<span style="' . esc_attr($text_style) . '">' . esc_html($banner_text) . '</span>';
echo '</div>';
}
// Banner an der richtigen Stelle einhängen – abhängig von der konfigurierten
// Position. Nur wenn das Banner auch wirklich aktiviert ist.
function statistik_manager_register_banner() {
if (!get_option('statistik_manager_banner_enabled', 1)) {
return;
}
$pos = get_option('statistik_manager_banner_position', 'top');
if ($pos === 'bottom') {
// Unten: im Footer ausgeben
add_action('wp_footer', function() {
statistik_manager_display_banner('bottom');
}, 10);
} else {
// Oben: bevorzugt direkt nach <body>, plus Footer-Fallback für Themes
// ohne wp_body_open (die statische Sperre verhindert Doppelausgabe).
add_action('wp_body_open', function() {
statistik_manager_display_banner('top');
});
add_action('wp_footer', function() {
statistik_manager_display_banner('top');
}, 5);
}
// Abstand für den Seiteninhalt, damit das fixe Banner nichts verdeckt
add_action('wp_head', 'statistik_manager_banner_offset');
// Am Seitenende sofort nachrechnen – dann sind Banner und fixe Leisten
// (z. B. ShiftNav) garantiert im DOM, auch wenn DOMContentLoaded spät kommt.
add_action('wp_footer', function() {
echo '<script>window.statistikManagerBannerAdjust&&window.statistikManagerBannerAdjust();</script>';
}, 999);
}
add_action('wp', 'statistik_manager_register_banner');
// Fügt NUR bei aktivem Banner den passenden Abstand hinzu – auf der richtigen
// Seite (oben/unten) und mit Rücksicht auf die WordPress-Admin-Leiste.
function statistik_manager_banner_offset() {
if (!get_option('statistik_manager_banner_enabled', 1)) {
return;
}
$pos = get_option('statistik_manager_banner_position', 'top');
$h = 56; // ungefähre Bannerhöhe – nur für den No-JS-Fallback
// Fallback ohne JavaScript (WordPress verschiebt die Seite für die
// Admin-Leiste bereits selbst per html-margin, daher hier nicht addieren).
echo '<noscript><style>';
if ($pos === 'bottom') {
echo 'body { padding-bottom: ' . $h . 'px !important; }';
} else {
echo 'body { padding-top: ' . $h . 'px !important; }';
if (is_admin_bar_showing()) {
echo '#statistik-manager-banner { top: 32px !important; }';
echo '@media screen and (max-width: 782px) { #statistik-manager-banner { top: 46px !important; } }';
}
}
echo '</style></noscript>';
// Mit JavaScript: Banner exakt unter fixe Leisten oben setzen (WP-Admin-Leiste,
// ShiftNav-Menüleiste), sonst verdecken diese es. Der Inhalt wird nur um die
// tatsächliche Bannerhöhe verschoben – zusätzlich zum vorhandenen Abstand
// des Themes, damit das Layout ansonsten unverändert bleibt.
$is_bottom = ($pos === 'bottom') ? 'true' : 'false';
echo '<script>(function(){'
. 'var isBottom=' . $is_bottom . ';'
. 'var bars=["wpadminbar","shiftnav-toggle-main"];'
. 'function adjust(){'
. 'var b=document.getElementById("statistik-manager-banner");'
. 'if(!b){return;}'
. 'var s=document.body.style,prop=isBottom?"padding-bottom":"padding-top";'
. 's.removeProperty(prop);'
. 'var base=parseFloat(getComputedStyle(document.body)[isBottom?"paddingBottom":"paddingTop"])||0;'
. 'var extra=0;'
. 'if(!isBottom){'
. 'var off=0;'
. 'bars.forEach(function(id){'
. 'var e=document.getElementById(id);if(!e){return;}'
. 'var c=getComputedStyle(e);'
. 'if(c.position!=="fixed"||c.display==="none"||c.visibility==="hidden"){return;}'
. 'var r=e.getBoundingClientRect();'
. 'if(r.height>0&&r.bottom>off){off=r.bottom;}'
. '});'
. 'b.style.setProperty("top",off+"px","important");'
// Inhalt komplett unter Leisten + Banner beginnen lassen; die Admin-Leiste
// hat WordPress per html-margin bereits berücksichtigt.
. 'var hm=parseFloat(getComputedStyle(document.documentElement).marginTop)||0;'
. 'extra=Math.max(0,off-hm);'
. '}'
. 's.setProperty(prop,(base+extra+b.offsetHeight)+"px","important");'
. '}'
. 'window.statistikManagerBannerAdjust=adjust;'
. 'function watch(){'
. 'adjust();'
// Nachzügler abfangen (verzögert geladene CSS/JS anderer Plugins)
. '[300,1000,2500,5000].forEach(function(t){setTimeout(adjust,t);});'
. 'if(window.ResizeObserver){'
. 'var ro=new ResizeObserver(function(){adjust();});'
. '["statistik-manager-banner"].concat(bars).forEach(function(id){var e=document.getElementById(id);if(e){ro.observe(e);}});'
. '}'
. '}'
. 'if(document.readyState!=="loading"){watch();}else{document.addEventListener("DOMContentLoaded",watch);}'
. 'window.addEventListener("load",adjust);'
. 'window.addEventListener("resize",adjust);'
. '})();</script>';
}
// Shortcode für die Anzeige der Statistiken
function statistik_manager_shortcode() {
$statistics = statistik_manager_get_statistics();
$webseitenname = get_bloginfo('name');
$output = '<div class="statistik-manager">';
$output .= '<h3>Statistikübersicht</h3>';
$output .= '<div class="statistik-items">';
if (get_option('statistik_manager_show_posts')) {
$output .= '<div class="stat-item"><i class="fas fa-file-alt"></i>';
$output .= '<p><strong>Beiträge:</strong></br> ' . esc_html($statistics['posts_count']) . '</p></div>';
}
if (get_option('statistik_manager_show_comments')) {
$output .= '<div class="stat-item"><i class="fas fa-comments"></i>';
$output .= '<p><strong>Kommentare:</strong></br> ' . esc_html($statistics['comments_count']) . '</p></div>';
}
if (get_option('statistik_manager_show_categories')) {
$output .= '<div class="stat-item"><i class="fas fa-th-list"></i>';
$output .= '<p><strong>Kategorien:</strong></br> ' . esc_html($statistics['categories_count']) . '</p></div>';
}
if (get_option('statistik_manager_show_series')) {
$output .= '<div class="stat-item"><i class="fas fa-tv"></i>';
$output .= '<p><strong>Serien:</strong></br> ' . esc_html($statistics['series_count']) . '</p></div>';
}
$output .= '</div>';
// Eröffnungsdatum anzeigen, wenn gesetzt
if (!empty($statistics['opening_date'])) {
$formatted_date = date('d.m.Y', strtotime($statistics['opening_date']));
$output .= '<div class="stat-opening-date">';
$output .= '<i class="fas fa-calendar-alt"></i>';
$output .= '<p><strong>' . sprintf(__('%s wurde am %s eröffnet.', 'statistik-manager'), esc_html($webseitenname), esc_html($formatted_date)) . '</strong></p>';
$output .= '</div>';
}
$output .= '</div>';
return $output;
}
add_shortcode('statistik_manager', 'statistik_manager_shortcode');
// Admin-Panel CSS einbinden, nur auf der Plugin-Seite
// Das frühere seitenspezifische admin-style.css wurde durch das gemeinsame
// Design-System (wp-multi-toolkit/assets/admin.css) ersetzt.
// Frontend CSS nur einbinden, wenn der Shortcode verwendet wird
function statistik_manager_enqueue_frontend_styles() {
if (has_shortcode(get_post()->post_content, 'statistik_manager')) {
wp_enqueue_style('statistik-manager-frontend-style', plugins_url('css/style.css', WP_MULTI_FILE));
}
}
add_action('wp_enqueue_scripts', 'statistik_manager_enqueue_frontend_styles');
// Der Menüpunkt "Statistik & Notice" wird zentral in wp_multi_register_admin_menus() registriert.
// Funktion für die Plugin-Optionen-Seite
function statistik_manager_options_page() {
wpmt_admin_page_open(
__('Statistik & Notice', 'statistik-manager'),
__('Statistik-Shortcode, Lesezeichen und Frontend-Banner konfigurieren', 'statistik-manager')
);
wpmt_admin_card_open(__('Einstellungen', 'statistik-manager'));
?>
<form method="post" action="options.php">
<?php
settings_fields('statistik_manager_settings_group');
do_settings_sections('statistik_manager');
?>
<h2><?php _e('Statistiken anzeigen', 'statistik-manager'); ?></h2>
<table class="form-table">
<tr valign="top">
<th scope="row"><?php _e('Anzeigen', 'statistik-manager'); ?></th>
<td>
<input type="checkbox" name="statistik_manager_show_posts" value="1" <?php checked(get_option('statistik_manager_show_posts'), 1); ?> />
<label for="statistik_manager_show_posts"><?php _e('Beiträge anzeigen', 'statistik-manager'); ?></label><br>
<input type="checkbox" name="statistik_manager_show_comments" value="1" <?php checked(get_option('statistik_manager_show_comments'), 1); ?> />
<label for="statistik_manager_show_comments"><?php _e('Kommentare anzeigen', 'statistik-manager'); ?></label><br>
<input type="checkbox" name="statistik_manager_show_categories" value="1" <?php checked(get_option('statistik_manager_show_categories'), 1); ?> />
<label for="statistik_manager_show_categories"><?php _e('Kategorien anzeigen', 'statistik-manager'); ?></label><br>
<input type="checkbox" name="statistik_manager_show_series" value="1" <?php checked(get_option('statistik_manager_show_series'), 1); ?> />
<label for="statistik_manager_show_series"><?php _e('Serien anzeigen', 'statistik-manager'); ?></label>
</td>
</tr>
</table>
<h2><?php _e('Kategorien auswählen', 'statistik-manager'); ?></h2>
<table class="form-table">
<tr valign="top">
<th scope="row"><?php _e('Angezeigte Kategorien', 'statistik-manager'); ?></th>
<td>
<?php
$categories = get_terms(array(
'taxonomy' => 'category',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
));
if (!empty($categories) && !is_wp_error($categories)) :
$selected_categories = get_option('statistik_manager_selected_categories', []);
?>
<select name="statistik_manager_selected_categories[]" multiple="multiple" style="width: 300px; height: 150px;">
<?php foreach ($categories as $category) : ?>
<option value="<?php echo esc_attr($category->term_id); ?>"
<?php echo in_array($category->term_id, $selected_categories) ? 'selected' : ''; ?>>
<?php echo esc_html($category->name); ?>
</option>
<?php endforeach; ?>
</select>
<?php endif; ?>
</td>
</tr>
</table>
<h2><?php _e('Eröffnungsdatum der Webseite', 'statistik-manager'); ?></h2>
<table class="form-table">
<tr valign="top">
<th scope="row"><?php _e('Eröffnungsdatum', 'statistik-manager'); ?></th>
<td>
<input type="date" name="statistik_manager_opening_date" value="<?php echo esc_attr(get_option('statistik_manager_opening_date')); ?>" />
</td>
</tr>
</table>
<h2>Banner-Einstellungen</h2>
<table class="form-table">
<tr>
<th>Banner anzeigen</th>
<td>
<input type="checkbox" name="statistik_manager_banner_enabled" value="1" <?php checked(get_option('statistik_manager_banner_enabled', 1)); ?> />
<label for="statistik_manager_banner_enabled">Banner aktivieren</label>
</td>
</tr>
<tr>
<th>Banner Text</th>
<td><input type="text" name="statistik_manager_banner_text" value="<?php echo esc_attr(get_option('statistik_manager_banner_text', 'Willkommen auf unserer Webseite!')); ?>" /></td>
</tr>
<tr>
<th>Banner Farbe</th>
<td><input type="color" name="statistik_manager_banner_color" value="<?php echo esc_attr(get_option('statistik_manager_banner_color', '#0073aa')); ?>" /></td>
</tr>
<tr>
<th>Banner Position</th>
<td>
<select name="statistik_manager_banner_position">
<option value="top" <?php selected(get_option('statistik_manager_banner_position'), 'top'); ?>>Oben</option>
<option value="bottom" <?php selected(get_option('statistik_manager_banner_position'), 'bottom'); ?>>Unten</option>
</select>
</td>
</tr>
<tr>
<th>Icon auswählen</th>
<td>
<select name="statistik_manager_banner_icon">
<option value="fas fa-info-circle" <?php selected(get_option('statistik_manager_banner_icon'), 'fas fa-info-circle'); ?>>ℹ️ Info</option>
<option value="fas fa-exclamation-triangle" <?php selected(get_option('statistik_manager_banner_icon'), 'fas fa-exclamation-triangle'); ?>>⚠️ Warnung</option>
<option value="fas fa-bell" <?php selected(get_option('statistik_manager_banner_icon'), 'fas fa-bell'); ?>>🔔 Benachrichtigung</option>
<option value="fas fa-thumbs-up" <?php selected(get_option('statistik_manager_banner_icon'), 'fas fa-thumbs-up'); ?>>👍 Daumen hoch</option>
<option value="">Kein Icon</option>
</select>
</td>
</tr>
<tr>
<th>Icon anzeigen</th>
<td>
<input type="checkbox" name="statistik_manager_show_icon" value="1" <?php checked(get_option('statistik_manager_show_icon', 1)); ?> />
<label for="statistik_manager_show_icon">Icon anzeigen</label>
</td>
</tr>
<tr>
<th>Schriftgröße</th>
<td>
<select name="statistik_manager_banner_font_size">
<option value="small" <?php selected(get_option('statistik_manager_banner_font_size'), 'small'); ?>>Klein</option>
<option value="medium" <?php selected(get_option('statistik_manager_banner_font_size'), 'medium'); ?>>Mittel</option>
<option value="large" <?php selected(get_option('statistik_manager_banner_font_size'), 'large'); ?>>Groß</option>
</select>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
<?php
wpmt_admin_card_close();
echo '<div class="wpm-grid wpm-grid--2">';
wpmt_admin_card_open(__('Kurzanleitung: Statistik-Box', 'statistik-manager'));
?>
<ol>
<li><strong>Shortcode einfügen:</strong> Füge <code>[statistik_manager]</code> an der gewünschten Stelle in einem Beitrag oder einer Seite ein.</li>
<li><strong>Statistiken wählen:</strong> Beiträge, Kommentare, Kategorien und Serien lassen sich einzeln ein- und ausblenden.</li>
<li><strong>Kategorien:</strong> Wähle aus, welche Kategorien in die Zählung einbezogen werden.</li>
<li><strong>Eröffnungsdatum:</strong> Wird automatisch in der Statistik-Box angezeigt.</li>
<li><strong>Banner:</strong> Ein konfigurierbares Hinweis-Banner kann im Header oder Footer der Website eingeblendet werden.</li>
</ol>
<?php
wpmt_admin_card_close();
wpmt_admin_card_open(__('Kurzanleitung: Lesezeichen', 'statistik-manager'));
?>
<ol>
<li><strong>Anzeigen:</strong> Der Shortcode <code>[display_bookmarks]</code> listet die gespeicherten Lesezeichen der Besucher auf.</li>
<li><strong>Hinzufügen:</strong> Über <code>[add_bookmark]</code> erhalten Besucher ein Formular zum Speichern eines Lesezeichens.</li>
<li><strong>Löschen:</strong> Nur der Besitzer eines Lesezeichens kann es über den Löschen-Button entfernen.</li>
</ol>
<p><?php printf(__('Weitere Plugins der WP-Multi-Familie findest du auf %s.', 'statistik-manager'), '<a href="https://git.viper.ipv64.net/M_Viper" target="_blank">git.viper.ipv64.net</a>'); ?></p>
<?php
wpmt_admin_card_close();
echo '</div>';
wpmt_admin_page_close();
}
// Optionen registrieren
function statistik_manager_register_settings() {
register_setting('statistik_manager_settings_group', 'statistik_manager_show_posts');
register_setting('statistik_manager_settings_group', 'statistik_manager_show_comments');
register_setting('statistik_manager_settings_group', 'statistik_manager_show_categories');
register_setting('statistik_manager_settings_group', 'statistik_manager_show_series');
register_setting('statistik_manager_settings_group', 'statistik_manager_selected_categories');
register_setting('statistik_manager_settings_group', 'statistik_manager_opening_date');
register_setting('statistik_manager_settings_group', 'statistik_manager_banner_text');
register_setting('statistik_manager_settings_group', 'statistik_manager_banner_color', [
'sanitize_callback' => 'sanitize_hex_color',
]);
register_setting('statistik_manager_settings_group', 'statistik_manager_banner_position');
register_setting('statistik_manager_settings_group', 'statistik_manager_banner_enabled');
register_setting('statistik_manager_settings_group', 'statistik_manager_banner_icon', [
'sanitize_callback' => function($value) {
// Icon-Wert besteht aus mehreren space-getrennten CSS-Klassen (z. B. "fas fa-bell")
$classes = array_map('sanitize_html_class', explode(' ', (string) $value));
return implode(' ', array_filter($classes));
},
]);
register_setting('statistik_manager_settings_group', 'statistik_manager_show_icon');
register_setting('statistik_manager_settings_group', 'statistik_manager_banner_font_size');
}
add_action('admin_init', 'statistik_manager_register_settings');
// Standardwerte setzen
function statistik_manager_set_default_options() {
if (get_option('statistik_manager_show_posts') === false) {
update_option('statistik_manager_show_posts', 1);
}
if (get_option('statistik_manager_show_comments') === false) {
update_option('statistik_manager_show_comments', 1);
}
if (get_option('statistik_manager_show_categories') === false) {
update_option('statistik_manager_show_categories', 1);
}
if (get_option('statistik_manager_show_series') === false) {
update_option('statistik_manager_show_series', 1);
}
if (get_option('statistik_manager_selected_categories') === false) {
update_option('statistik_manager_selected_categories', []);
}
if (get_option('statistik_manager_banner_enabled') === false) {
update_option('statistik_manager_banner_enabled', 1);
}
if (get_option('statistik_manager_banner_font_size') === false) {
update_option('statistik_manager_banner_font_size', 'medium');
}
}
add_action('admin_init', 'statistik_manager_set_default_options');