130 lines
5.4 KiB
PHP
130 lines
5.4 KiB
PHP
<?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, fn($a,$b) => (int)$a['min'] <=> (int)$b['min'] );
|
||
return $levels;
|
||
}
|
||
|
||
public static function save( $levels ) {
|
||
usort( $levels, fn($a,$b) => (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 (0–100)
|
||
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>";
|
||
}
|
||
} |