Files
WP-Business-Forum/includes/class-forum-levels.php
2026-03-29 13:41:26 +02:00

130 lines
5.4 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
if ( ! defined( 'ABSPATH' ) ) exit;
/**
* WBF_Levels — Post-Count-basiertes Level-System
* Levels werden in wp_options gespeichert und können im Admin verwaltet werden.
* Das System kann global aktiviert/deaktiviert werden.
*/
class WBF_Levels {
const OPTION_KEY = 'wbf_level_config';
const ENABLED_KEY = 'wbf_levels_enabled';
// ── An/Aus ────────────────────────────────────────────────────
public static function is_enabled() {
return (bool) get_option( self::ENABLED_KEY, true );
}
public static function set_enabled( $bool ) {
update_option( self::ENABLED_KEY, (bool) $bool );
}
// ── Standard-Level beim ersten Aktivieren ────────────────────
private static function default_levels() {
return [
[ 'min' => 0, 'label' => 'Neuling', 'icon' => 'fas fa-seedling', 'color' => '#94a3b8' ],
[ 'min' => 10, 'label' => 'Schreiberling', 'icon' => 'fas fa-feather', 'color' => '#60a5fa' ],
[ 'min' => 50, 'label' => 'Erfahrener', 'icon' => 'fas fa-fire', 'color' => '#f97316' ],
[ 'min' => 150, 'label' => 'Veteran', 'icon' => 'fas fa-shield-halved', 'color' => '#a78bfa' ],
[ 'min' => 500, 'label' => 'Legende', 'icon' => 'fas fa-crown', 'color' => '#fbbf24' ],
];
}
// ── Laden / Speichern ─────────────────────────────────────────
public static function get_all() {
$saved = get_option( self::OPTION_KEY, null );
if ( $saved === null ) {
$defaults = self::default_levels();
update_option( self::OPTION_KEY, $defaults );
return $defaults;
}
$levels = (array) $saved;
usort( $levels, function($a, $b) { return (int)$a['min'] <=> (int)$b['min']; } );
return $levels;
}
public static function save( $levels ) {
usort( $levels, function($a, $b) { return (int)$a['min'] <=> (int)$b['min']; } );
update_option( self::OPTION_KEY, $levels );
}
public static function reset_to_defaults() {
update_option( self::OPTION_KEY, self::default_levels() );
}
// ── Level für eine Beitragsanzahl ermitteln ───────────────────
public static function get_for_count( $post_count ) {
$levels = self::get_all();
// Von oben (höchster min) nach unten suchen
$sorted = array_reverse( $levels );
foreach ( $sorted as $level ) {
if ( (int) $post_count >= (int) $level['min'] ) {
return $level;
}
}
return $levels[0]; // Fallback: niedrigstes Level
}
// Nächstes Level (für Fortschrittsanzeige)
public static function get_next( $post_count ) {
$levels = self::get_all(); // bereits aufsteigend sortiert
foreach ( $levels as $level ) {
if ( (int) $level['min'] > (int) $post_count ) {
return $level;
}
}
return null; // Maxlevel erreicht
}
// Fortschritt in Prozent zum nächsten Level (0100)
public static function progress( $post_count ) {
$current = self::get_for_count( $post_count );
$next = self::get_next( $post_count );
if ( ! $next ) return 100;
$range = (int) $next['min'] - (int) $current['min'];
if ( $range <= 0 ) return 100;
$done = (int) $post_count - (int) $current['min'];
return min( 100, (int) round( $done / $range * 100 ) );
}
// ── Badge HTML ────────────────────────────────────────────────
public static function badge( $post_count ) {
if ( ! self::is_enabled() ) return '';
$level = self::get_for_count( $post_count );
$label = esc_html( $level['label'] );
$icon = esc_attr( $level['icon'] );
$color = esc_attr( $level['color'] );
return "<span class=\"wbf-level-badge\" style=\"--lc:{$color}\">"
. "<i class=\"{$icon}\"></i> {$label}</span>";
}
// ── Fortschrittsbalken HTML (für Profil-Sidebar) ──────────────
public static function progress_bar( $post_count ) {
if ( ! self::is_enabled() ) return '';
$current = self::get_for_count( $post_count );
$next = self::get_next( $post_count );
$pct = self::progress( $post_count );
$color = esc_attr( $current['color'] );
$cur_lbl = esc_html( $current['label'] );
$next_lbl = $next ? esc_html( $next['label'] ) : $cur_lbl;
$posts_to = $next ? ( (int)$next['min'] - (int)$post_count ) . ' Beiträge bis ' . $next_lbl : 'Maximales Level erreicht';
return "
<div class=\"wbf-level-progress\">
<div class=\"wbf-level-progress__labels\">
<span style=\"color:{$color}\">" . self::badge( $post_count ) . "</span>
<span class=\"wbf-level-progress__hint\">{$posts_to}</span>
</div>
<div class=\"wbf-level-progress__bar\">
<div class=\"wbf-level-progress__fill\" style=\"width:{$pct}%;background:{$color}\"></div>
</div>
</div>";
}
}