Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5ff8f1933 | ||
|
|
764f760b61 | ||
|
|
cf42b89332 | ||
|
|
d283e6fcce | ||
| b3583a6231 |
@@ -957,7 +957,7 @@ function wbf_admin_roles() {
|
||||
|
||||
echo '<div class="wrap"><h1>Rollen-Verwaltung <a href="?page=wbf-roles#new-role" class="page-title-action">+ Neue Rolle</a></h1>';
|
||||
echo '<table class="widefat striped" style="margin-bottom:2rem">
|
||||
<thead><tr><th style="width:180px">Rolle</th><th>Level</th><th>Permissions</th><th>Beschreibung</th><th>Aktionen</th></tr></thead><tbody>';
|
||||
<thead><tr><th style="width:180px">Rolle</th><th>Schlüssel</th><th>Level</th><th>Permissions</th><th>Beschreibung</th><th>Aktionen</th></tr></thead><tbody>';
|
||||
|
||||
foreach ( $roles as $key => $role ) {
|
||||
$color = esc_attr( $role['color'] ); $bg = esc_attr( $role['bg_color'] );
|
||||
@@ -978,7 +978,8 @@ function wbf_admin_roles() {
|
||||
}
|
||||
|
||||
echo "<tr>
|
||||
<td>$badge " . ( ( $role['locked'] ?? false ) ? '<span style="color:#999;font-size:.8em">(🔒)</span>' : '' ) . "</td>
|
||||
<td>$badge " . ( ( $role['locked'] ?? false ) ? '<span style=\"color:#999;font-size:.8em\">(🔒)</span>' : '' ) . "</td>
|
||||
<td><code>" . esc_html( $key ) . "</code></td>
|
||||
<td><strong>" . esc_html( $role['level'] ) . "</strong></td>
|
||||
<td style='font-size:.82em;color:#555'>$perms</td>
|
||||
<td style='font-size:.82em;color:#666'>" . esc_html( $role['description'] ?? '' ) . "</td>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -634,11 +634,11 @@
|
||||
// Sofort-Vorschau
|
||||
var objectUrl = URL.createObjectURL(file);
|
||||
var $wrap = $('#wbfProfileBannerWrap');
|
||||
var $existing = $wrap.find('.wbf-profile-banner__img');
|
||||
var $existing = $wrap.find('.wbf-pv-banner__img');
|
||||
|
||||
// Falls noch kein Banner-Bild existiert, eins einfügen
|
||||
if ($existing.length === 0) {
|
||||
$wrap.prepend('<img src="' + objectUrl + '" alt="" id="wbfProfileBanner" class="wbf-profile-banner__img" style="opacity:.4">');
|
||||
$wrap.prepend('<img src="' + objectUrl + '" alt="" id="wbfProfileBanner" class="wbf-pv-banner__img" style="opacity:.4">');
|
||||
} else {
|
||||
$existing.attr('src', objectUrl).css('opacity', '.4');
|
||||
}
|
||||
@@ -655,7 +655,7 @@
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function (res) {
|
||||
var $img = $wrap.find('.wbf-profile-banner__img');
|
||||
var $img = $wrap.find('.wbf-pv-banner__img');
|
||||
if (res.success) {
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
$img.attr('src', res.data.banner_url + '?v=' + Date.now());
|
||||
@@ -663,7 +663,7 @@
|
||||
$img.css('opacity', '');
|
||||
},
|
||||
error: function () {
|
||||
$wrap.find('.wbf-profile-banner__img').css('opacity', '');
|
||||
$wrap.find('.wbf-pv-banner__img').css('opacity', '');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1218,6 +1218,17 @@
|
||||
url = base + sep + 'forum_thread=' + n.thread_id;
|
||||
text = actor + ' hat deinen Beitrag geliket';
|
||||
sub = n.thread_title || '';
|
||||
} else if (n.type === 'plugin_update') {
|
||||
url = n.plugin_url || base;
|
||||
var versionStr = n.plugin_version ? ' auf <strong>v' + $('<span>').text(n.plugin_version).html() + '</strong>' : '';
|
||||
var pluginName = $('<span>').text(n.plugin_title || 'Plugin').html();
|
||||
text = '<i class="fas fa-puzzle-piece" style="color:#00d4ff;margin-right:5px"></i><strong>' + pluginName + '</strong> wurde aktualisiert' + versionStr;
|
||||
sub = 'Plugin-Update · Beobachtungsliste';
|
||||
if (n.plugin_thumb) {
|
||||
avatar = '<img src="' + n.plugin_thumb + '" alt="" class="wbf-dm-inbox-item__avatar" style="border-radius:6px;object-fit:cover;width:36px;height:36px;">';
|
||||
} else {
|
||||
avatar = '<div style="width:36px;height:36px;border-radius:6px;background:rgba(0,212,255,.1);border:1px solid rgba(0,212,255,.2);display:flex;align-items:center;justify-content:center;color:#00d4ff;font-size:16px;flex-shrink:0"><i class=\'fas fa-puzzle-piece\'></i></div>';
|
||||
}
|
||||
} else {
|
||||
// reply (default)
|
||||
url = base + sep + 'forum_thread=' + n.thread_id;
|
||||
@@ -2265,7 +2276,7 @@
|
||||
$btn.prop('disabled', false).html('<i class="fab fa-discord"></i> Code senden');
|
||||
if (res.success) {
|
||||
wbfDcMsg('<i class="fas fa-check" style="color:#16a34a"></i> ' + (res.data.message || 'Code gesendet!'), '#16a34a');
|
||||
$('#wbf-dc-step1').slideUp(200, function () { $('#wbf-dc-step2').slideDown(200); });
|
||||
$('#wbf-dc-step1-inline').slideUp(150); $('#wbf-dc-step2').slideDown(200);
|
||||
$('#wbf-discord-code-input').val('').focus();
|
||||
wbfDcStep = 2;
|
||||
} else {
|
||||
@@ -2323,7 +2334,7 @@
|
||||
|
||||
// „Zurück" in Schritt 2
|
||||
$(document).on('click', '#wbf-discord-code-back', function () {
|
||||
$('#wbf-dc-step2').slideUp(200, function () { $('#wbf-dc-step1').slideDown(200); });
|
||||
$('#wbf-dc-step2').slideUp(200); $('#wbf-dc-step1-inline').slideDown(150);
|
||||
wbfDcMsg('');
|
||||
wbfDcStep = 1;
|
||||
});
|
||||
|
||||
@@ -720,6 +720,15 @@ class WBF_Ajax {
|
||||
if ( ! $user ) wp_send_json_error(['message' => 'Nicht eingeloggt.']);
|
||||
$notifs = WBF_DB::get_notifications( $user->id, 20 );
|
||||
$unread = WBF_DB::count_unread_notifications( $user->id );
|
||||
|
||||
// Plugin-Update Notifications: Permalink + Thumbnail ergänzen
|
||||
foreach ( $notifs as $n ) {
|
||||
if ( $n->type === 'plugin_update' && ! empty( $n->object_id ) ) {
|
||||
$n->plugin_url = get_permalink( (int) $n->object_id ) ?: '';
|
||||
$n->plugin_thumb = get_the_post_thumbnail_url( (int) $n->object_id, 'thumbnail' ) ?: '';
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success(['notifications' => $notifs, 'unread' => $unread]);
|
||||
}
|
||||
|
||||
|
||||
@@ -880,10 +880,17 @@ class WBF_DB {
|
||||
return $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT n.*,
|
||||
u.display_name AS actor_name, u.avatar_url AS actor_avatar,
|
||||
t.title AS thread_title, t.id AS thread_id
|
||||
t.title AS thread_title, t.id AS thread_id,
|
||||
p.post_title AS plugin_title, p.post_name AS plugin_slug,
|
||||
pm.meta_value AS plugin_version
|
||||
FROM {$wpdb->prefix}forum_notifications n
|
||||
JOIN {$wpdb->prefix}forum_users u ON u.id = n.actor_id
|
||||
LEFT JOIN {$wpdb->prefix}forum_threads t ON t.id = n.object_id
|
||||
LEFT JOIN {$wpdb->prefix}forum_users u ON u.id = n.actor_id
|
||||
LEFT JOIN {$wpdb->prefix}forum_threads t
|
||||
ON t.id = n.object_id AND n.type != 'plugin_update'
|
||||
LEFT JOIN {$wpdb->posts} p
|
||||
ON p.ID = n.object_id AND n.type = 'plugin_update' AND p.post_type = 'mc_plugin'
|
||||
LEFT JOIN {$wpdb->postmeta} pm
|
||||
ON pm.post_id = p.ID AND pm.meta_key = '_vmcp_version'
|
||||
WHERE n.user_id = %d
|
||||
ORDER BY n.created_at DESC
|
||||
LIMIT %d",
|
||||
|
||||
@@ -932,11 +932,12 @@ class WBF_Shortcodes {
|
||||
$shop_tab_id = 'shop';
|
||||
$allowed_tabs = [1,2,3,4];
|
||||
if ($is_own && $shop_active) $allowed_tabs[] = $shop_tab_id;
|
||||
if ($is_own) $allowed_tabs[] = 'plugins';
|
||||
$active_tab = ctype_digit( (string) $ptab_raw ) ? (int) $ptab_raw : sanitize_key( $ptab_raw );
|
||||
if (is_int($active_tab) && !in_array($active_tab, [1,2,3,4])) {
|
||||
$active_tab = $is_own ? 1 : 2;
|
||||
}
|
||||
if (!is_int($active_tab) && $active_tab !== $shop_tab_id && $active_tab !== 'mc') {
|
||||
if (!is_int($active_tab) && $active_tab !== $shop_tab_id && $active_tab !== 'mc' && $active_tab !== 'plugins') {
|
||||
$active_tab = $is_own ? 1 : 2;
|
||||
}
|
||||
// Tab 1, 3, 4, "shop" und String-Tabs nur für eigenes Profil (außer Tab 2 = Aktivität)
|
||||
@@ -951,81 +952,128 @@ class WBF_Shortcodes {
|
||||
<span>/</span><span>Profil</span>
|
||||
</nav>
|
||||
|
||||
<div class="wbf-profile-layout">
|
||||
<!-- ══ NEW PROFILE LAYOUT v4 ══ -->
|
||||
<div class="wbf-pv">
|
||||
|
||||
<!-- ── SIDEBAR ─────────────────────────────────────────── -->
|
||||
<aside class="wbf-profile-sidebar">
|
||||
<!-- ── HERO CARD ────────────────────────────────────────────── -->
|
||||
<div class="wbf-pv-hero">
|
||||
<!-- Banner -->
|
||||
<div class="wbf-profile-banner" id="wbfProfileBannerWrap">
|
||||
<div class="wbf-pv-banner" id="wbfProfileBannerWrap">
|
||||
<?php if (!empty($profile->banner_url)): ?>
|
||||
<img src="<?php echo esc_url($profile->banner_url); ?>"
|
||||
alt="" id="wbfProfileBanner" class="wbf-profile-banner__img">
|
||||
<img src="<?php echo esc_url($profile->banner_url); ?>" alt="" id="wbfProfileBanner" class="wbf-pv-banner__img">
|
||||
<?php else: ?>
|
||||
<div class="wbf-profile-banner__placeholder"></div>
|
||||
<div class="wbf-pv-banner__placeholder"></div>
|
||||
<?php endif; ?>
|
||||
<div class="wbf-pv-banner__overlay"></div>
|
||||
<?php if ($is_own): ?>
|
||||
<label class="wbf-banner-upload-btn" title="Banner ändern">
|
||||
<i class="fas fa-image"></i>
|
||||
<input type="file" id="wbfBannerFile" accept="image/*" style="display:none">
|
||||
<label class="wbf-pv-banner__upload" title="Banner ändern">
|
||||
<i class="fas fa-image"></i> Banner ändern
|
||||
<input type="file" id="wbfBannerFile" name="banner" accept="image/*" style="display:none">
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="wbf-profile-sidebar__avatar-wrap">
|
||||
<!-- Identity row -->
|
||||
<div class="wbf-pv-identity-row">
|
||||
<!-- Avatar -->
|
||||
<div class="wbf-pv-avatar-wrap">
|
||||
<?php $profile_online = WBF_DB::is_online($profile->id, 15); ?>
|
||||
<div class="wbf-pv-avatar-ring">
|
||||
<img src="<?php echo esc_url($profile->avatar_url); ?>"
|
||||
alt="<?php echo esc_attr($profile->display_name); ?>"
|
||||
id="wbfProfileAvatar"
|
||||
class="wbf-profile-sidebar__avatar">
|
||||
id="wbfProfileAvatar" class="wbf-pv-avatar">
|
||||
</div>
|
||||
<?php if ($profile_online): ?>
|
||||
<span class="wbf-pv-online-dot" title="Online"></span>
|
||||
<?php endif; ?>
|
||||
<?php if ($is_own): ?>
|
||||
<label class="wbf-avatar-upload-btn" title="Avatar ändern">
|
||||
<label class="wbf-pv-avatar-cam" title="Avatar ändern">
|
||||
<i class="fas fa-camera"></i>
|
||||
<input type="file" id="wbfAvatarFile" accept="image/*" style="display:none">
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="wbf-profile-sidebar__identity">
|
||||
<h2><?php echo esc_html($profile->display_name); ?></h2>
|
||||
<!-- Name + role + username + status -->
|
||||
<div class="wbf-pv-identity">
|
||||
<h1 class="wbf-pv-name"><?php echo esc_html($profile->display_name); ?></h1>
|
||||
<div class="wbf-pv-meta">
|
||||
<?php echo self::role_badge($profile->role); ?>
|
||||
<span class="wbf-profile-sidebar__username">@<?php echo esc_html($profile->username); ?></span>
|
||||
<?php
|
||||
$profile_online = WBF_DB::is_online($profile->id, 15);
|
||||
if ($profile_online): ?>
|
||||
<span class="wbf-profile-online-badge">
|
||||
<span class="wbf-profile-online-dot"></span> Online
|
||||
</span>
|
||||
<span class="wbf-pv-username">@<?php echo esc_html($profile->username); ?></span>
|
||||
<?php if ($profile_online): ?>
|
||||
<span class="wbf-pv-online-badge"><span class="wbf-pv-online-pulse"></span> Online</span>
|
||||
<?php else:
|
||||
$last = $profile->last_active ?? null;
|
||||
if ($last && $last !== '0000-00-00 00:00:00'): ?>
|
||||
<span class="wbf-profile-lastseen">
|
||||
<i class="fas fa-clock"></i> Zuletzt aktiv: <?php echo self::time_ago($last); ?>
|
||||
</span>
|
||||
<span class="wbf-pv-lastseen"><i class="fas fa-clock"></i> <?php echo self::time_ago($last); ?></span>
|
||||
<?php endif; endif; ?>
|
||||
</div>
|
||||
<div class="wbf-profile-sidebar__stats">
|
||||
<div class="wbf-profile-sidebar__stat">
|
||||
<span><?php echo (int)$profile->post_count; ?></span>
|
||||
<em>Beiträge</em>
|
||||
</div>
|
||||
<div class="wbf-profile-sidebar__stat">
|
||||
<span><?php echo date_i18n('m/Y', strtotime($profile->registered)); ?></span>
|
||||
<em>Dabei seit</em>
|
||||
<div class="wbf-pv-stats-row">
|
||||
<div class="wbf-pv-stat"><span><?php echo number_format((int)$profile->post_count); ?></span><em>Beiträge</em></div>
|
||||
<div class="wbf-pv-stat-sep"></div>
|
||||
<div class="wbf-pv-stat"><span><?php echo date_i18n('m/Y', strtotime($profile->registered)); ?></span><em>Dabei seit</em></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($current && !$is_own && WBF_Roles::level($profile->role) >= 0): ?>
|
||||
<div class="wbf-pv-actions">
|
||||
<a href="?forum_dm=inbox&with=<?php echo (int)$profile->id; ?>" class="wbf-btn wbf-btn--primary wbf-btn--sm">
|
||||
<i class="fas fa-envelope"></i> Nachricht
|
||||
</a>
|
||||
<?php if (wbf_can_be_ignored($profile)):
|
||||
$viewer_ignores = WBF_DB::is_ignored($current->id, $profile->id); ?>
|
||||
<button class="wbf-ignore-btn wbf-btn wbf-btn--sm<?php echo $viewer_ignores?' wbf-btn--primary':''; ?>"
|
||||
data-id="<?php echo (int)$profile->id; ?>"
|
||||
data-name="<?php echo esc_attr($profile->display_name); ?>"
|
||||
data-ignored="<?php echo $viewer_ignores?'1':'0'; ?>">
|
||||
<i class="fas fa-<?php echo $viewer_ignores?'eye':'eye-slash'; ?>"></i>
|
||||
<?php echo $viewer_ignores?'Ignorierung aufheben':'Ignorieren'; ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div><!-- /.wbf-pv-identity-row -->
|
||||
</div><!-- /.wbf-pv-hero -->
|
||||
|
||||
<!-- ── TABS ──────────────────────────────────────────────────── -->
|
||||
<div class="wbf-pv-tabs-bar">
|
||||
<?php if ($is_own): ?>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=1" class="wbf-pv-tab<?php echo $active_tab===1?' active':''; ?>"><i class="fas fa-sliders"></i> Profil</a>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=2" class="wbf-pv-tab<?php echo $active_tab===2?' active':''; ?>"><i class="fas fa-comments"></i> Aktivität</a>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=3" class="wbf-pv-tab<?php echo $active_tab===3?' active':''; ?>"><i class="fas fa-shield-halved"></i> Privatsphäre</a>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=4" class="wbf-pv-tab<?php echo $active_tab===4?' active':''; ?>"><i class="fas fa-lock"></i> Sicherheit</a>
|
||||
<?php if ($shop_active): ?>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=shop" class="wbf-pv-tab<?php echo $active_tab==='shop'?' active':''; ?>"><i class="fas fa-shopping-cart"></i> Käufe</a>
|
||||
<?php endif; ?>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=mc" class="wbf-pv-tab<?php echo $active_tab==='mc'?' active':''; ?>"><i class="fas fa-plug"></i> Verbindungen</a>
|
||||
<?php if ( function_exists('vmcp_bridge_is_available') && vmcp_bridge_is_available() ) : ?>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=plugins" class="wbf-pv-tab<?php echo $active_tab==='plugins'?' active':''; ?>"><i class="fas fa-puzzle-piece"></i> Plugins</a>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=2" class="wbf-pv-tab active"><i class="fas fa-comments"></i> Aktivität</a>
|
||||
<?php endif; ?>
|
||||
</div><!-- /.wbf-pv-tabs-bar -->
|
||||
|
||||
<!-- ── BODY ──────────────────────────────────────────────────── -->
|
||||
<div class="wbf-pv-body">
|
||||
|
||||
<!-- Sidebar: Level + Bio + Sig + Custom Fields -->
|
||||
<aside class="wbf-pv-sidebar">
|
||||
<?php $level_bar = WBF_Levels::progress_bar((int)$profile->post_count); if ($level_bar): ?>
|
||||
<div class="wbf-profile-sidebar__section"><?php echo $level_bar; ?></div>
|
||||
<div class="wbf-pv-sb-section">
|
||||
<span class="wbf-pv-sb-label"><i class="fas fa-trophy"></i> Level</span>
|
||||
<?php echo $level_bar; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($profile->bio)): ?>
|
||||
<div class="wbf-profile-sidebar__section">
|
||||
<span class="wbf-profile-sidebar__section-label"><i class="fas fa-align-left"></i> Bio</span>
|
||||
<div class="wbf-profile-sidebar__bio-text"><?php echo WBF_BBCode::render($profile->bio); ?></div>
|
||||
<div class="wbf-pv-sb-section">
|
||||
<span class="wbf-pv-sb-label"><i class="fas fa-align-left"></i> Bio</span>
|
||||
<div class="wbf-pv-sb-text"><?php echo WBF_BBCode::render($profile->bio); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($profile->signature)): ?>
|
||||
<div class="wbf-profile-sidebar__section">
|
||||
<span class="wbf-profile-sidebar__section-label"><i class="fas fa-pen-nib"></i> Signatur</span>
|
||||
<div class="wbf-profile-sidebar__sig"><?php echo WBF_BBCode::render($profile->signature); ?></div>
|
||||
<div class="wbf-pv-sb-section wbf-pv-sb-section--sig">
|
||||
<span class="wbf-pv-sb-label"><i class="fas fa-pen-nib"></i> Signatur</span>
|
||||
<div class="wbf-pv-sb-sig"><?php echo WBF_BBCode::render($profile->signature); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!-- Öffentliche Custom Fields — nach Kategorie gruppiert -->
|
||||
<?php
|
||||
$cf_by_cat_sb = [];
|
||||
foreach ($cf_defs as $def_sb) {
|
||||
@@ -1037,121 +1085,44 @@ class WBF_Shortcodes {
|
||||
$cf_by_cat_sb[$cid_sb][] = ['def'=>$def_sb,'val'=>$val_sb];
|
||||
}
|
||||
$sb_sections = $cf_cats;
|
||||
if (isset($cf_by_cat_sb['__none__'])) {
|
||||
$sb_sections[] = ['id'=>'__none__','name'=>'Weitere Infos','icon'=>''];
|
||||
}
|
||||
if (isset($cf_by_cat_sb['__none__'])) $sb_sections[] = ['id'=>'__none__','name'=>'Weitere Infos','icon'=>''];
|
||||
foreach ($sb_sections as $scat_sb):
|
||||
$scid_sb = $scat_sb['id'];
|
||||
if (empty($cf_by_cat_sb[$scid_sb])) continue;
|
||||
?>
|
||||
<div class="wbf-profile-sidebar__section">
|
||||
<span class="wbf-profile-sidebar__section-label" style="display:flex;align-items:center;gap:5px;margin-bottom:4px">
|
||||
<?php if(!empty($scat_sb['icon'])): ?>
|
||||
<span style="font-size:.9rem"><?php echo esc_html($scat_sb['icon']); ?></span>
|
||||
<?php endif; ?>
|
||||
<div class="wbf-pv-sb-section">
|
||||
<span class="wbf-pv-sb-label">
|
||||
<?php if(!empty($scat_sb['icon'])): ?><span><?php echo esc_html($scat_sb['icon']); ?></span><?php endif; ?>
|
||||
<?php echo esc_html($scat_sb['name']); ?>
|
||||
</span>
|
||||
<?php foreach ($cf_by_cat_sb[$scid_sb] as $cf_entry_sb):
|
||||
$def_sb = $cf_entry_sb['def'];
|
||||
$val_sb = $cf_entry_sb['val'];
|
||||
// Auto-Link für Telegram und Discord anhand des Feld-Keys erkennen
|
||||
$key_sb = strtolower($def_sb['key']);
|
||||
$is_telegram = strpos($key_sb, 'telegram') !== false;
|
||||
$is_discord = strpos($key_sb, 'discord') !== false;
|
||||
?>
|
||||
<div style="display:flex;justify-content:space-between;align-items:flex-start;gap:6px;margin-bottom:4px;font-size:.85rem">
|
||||
<span style="color:var(--c-muted,#94a3b8);flex-shrink:0"><?php echo esc_html($def_sb['label']); ?></span>
|
||||
<?php foreach ($cf_by_cat_sb[$scid_sb] as $cf_e):
|
||||
$def_sb=$cf_e['def']; $val_sb=$cf_e['val'];
|
||||
$k_sb=strtolower($def_sb['key']);
|
||||
$is_tg=strpos($k_sb,'telegram')!==false;
|
||||
$is_dc=strpos($k_sb,'discord')!==false; ?>
|
||||
<div class="wbf-pv-cf-row">
|
||||
<span class="wbf-pv-cf-lbl"><?php echo esc_html($def_sb['label']); ?></span>
|
||||
<?php if ($def_sb['type']==='url'): ?>
|
||||
<a href="<?php echo esc_url($val_sb); ?>" target="_blank" rel="noopener noreferrer"
|
||||
style="color:var(--c-primary);word-break:break-all;text-align:right">
|
||||
<?php echo esc_html(mb_strtolower(preg_replace('#^https?://#i','',$val_sb))); ?>
|
||||
</a>
|
||||
<?php elseif ($is_telegram):
|
||||
// Username bereinigen: @ und Leerzeichen entfernen
|
||||
$tg_user = ltrim(trim($val_sb), '@');
|
||||
$tg_url = 'https://t.me/' . rawurlencode($tg_user);
|
||||
?>
|
||||
<a href="<?php echo esc_url($tg_url); ?>" target="_blank" rel="noopener noreferrer"
|
||||
style="color:#29b6f6;text-align:right;font-size:inherit">
|
||||
@<?php echo esc_html($tg_user); ?>
|
||||
</a>
|
||||
<?php elseif ($is_discord): ?>
|
||||
<span style="color:#7289da;text-align:right;font-size:inherit">
|
||||
<?php echo esc_html($val_sb); ?>
|
||||
</span>
|
||||
<a href="<?php echo esc_url($val_sb); ?>" target="_blank" rel="noopener noreferrer" class="wbf-pv-cf-val wbf-pv-cf-val--link"><?php echo esc_html(mb_strtolower(preg_replace('#^https?://#i','',$val_sb))); ?></a>
|
||||
<?php elseif($is_tg): $tu=ltrim(trim($val_sb),'@'); ?>
|
||||
<a href="https://t.me/<?php echo rawurlencode($tu); ?>" target="_blank" rel="noopener noreferrer" style="color:#29b6f6">@<?php echo esc_html($tu); ?></a>
|
||||
<?php elseif($is_dc): ?>
|
||||
<span style="color:#7289da"><?php echo esc_html($val_sb); ?></span>
|
||||
<?php elseif($def_sb['type']==='textarea'): ?>
|
||||
<span style="text-align:right"><?php echo nl2br(esc_html($val_sb)); ?></span>
|
||||
<?php elseif ($def_sb['type'] === 'date'):
|
||||
$age_sb = self::calc_age($val_sb); ?>
|
||||
<span><?php echo $age_sb !== null ? esc_html((string)$age_sb) . ' Jahre' : '—'; ?></span>
|
||||
<span><?php echo nl2br(esc_html($val_sb)); ?></span>
|
||||
<?php elseif($def_sb['type']==='date'): $as=self::calc_age($val_sb); ?>
|
||||
<span><?php echo $as!==null?esc_html((string)$as).' Jahre':'—'; ?></span>
|
||||
<?php else: ?>
|
||||
<span style="text-align:right"><?php echo esc_html($val_sb); ?></span>
|
||||
<span class="wbf-pv-cf-val"><?php echo esc_html($val_sb); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</aside>
|
||||
</aside><!-- /.wbf-pv-sidebar -->
|
||||
|
||||
<!-- ── MAIN ────────────────────────────────────────────── -->
|
||||
<div class="wbf-profile-main">
|
||||
|
||||
<!-- DM-Button + Ignorieren-Button (nur auf fremden Profilen) -->
|
||||
<?php if ($current && !$is_own && WBF_Roles::level($profile->role) >= 0): ?>
|
||||
<div style="display:flex;justify-content:flex-end;gap:.5rem;margin-bottom:.75rem;flex-wrap:wrap">
|
||||
<a href="?forum_dm=inbox&with=<?php echo (int)$profile->id; ?>"
|
||||
class="wbf-btn wbf-btn--sm wbf-btn--primary">
|
||||
<i class="fas fa-envelope"></i> Nachricht senden
|
||||
</a>
|
||||
<?php if ( wbf_can_be_ignored($profile) ):
|
||||
$viewer_ignores = WBF_DB::is_ignored($current->id, $profile->id); ?>
|
||||
<button class="wbf-ignore-btn wbf-btn wbf-btn--sm<?php echo $viewer_ignores?' wbf-btn--primary':''; ?>"
|
||||
data-id="<?php echo (int)$profile->id; ?>"
|
||||
data-name="<?php echo esc_attr($profile->display_name); ?>"
|
||||
data-ignored="<?php echo $viewer_ignores?'1':'0'; ?>">
|
||||
<i class="fas fa-<?php echo $viewer_ignores?'eye':'eye-slash'; ?>"></i>
|
||||
<?php echo $viewer_ignores?'Ignorierung aufheben':'Nutzer ignorieren'; ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- ── TAB-NAVIGATION ─────────────────────────────── -->
|
||||
<?php if ($is_own): ?>
|
||||
<div class="wbf-profile-tabs">
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=1"
|
||||
class="wbf-profile-tab<?php echo $active_tab===1?' active':''; ?>">
|
||||
<i class="fas fa-sliders"></i> Profil
|
||||
</a>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=2"
|
||||
class="wbf-profile-tab<?php echo $active_tab===2?' active':''; ?>">
|
||||
<i class="fas fa-comments"></i> Aktivität
|
||||
</a>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=3"
|
||||
class="wbf-profile-tab<?php echo $active_tab===3?' active':''; ?>">
|
||||
<i class="fas fa-shield-halved"></i> Privatsphäre
|
||||
</a>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=4"
|
||||
class="wbf-profile-tab<?php echo $active_tab===4?' active':''; ?>">
|
||||
<i class="fas fa-lock"></i> Sicherheit
|
||||
</a>
|
||||
<?php if ($shop_active): ?>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=shop"
|
||||
class="wbf-profile-tab<?php echo $active_tab==='shop'?' active':''; ?>">
|
||||
<i class="fas fa-shopping-cart"></i> Käufe
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
// „Verbindungen" Tab — immer sichtbar (Discord eingebaut, MC optional)
|
||||
$wbf_has_connections = true;
|
||||
if ( $wbf_has_connections ) : ?>
|
||||
<a href="?forum_profile=<?php echo (int)$profile->id; ?>&ptab=mc"
|
||||
class="wbf-profile-tab<?php echo $active_tab==='mc'?' active':''; ?>">
|
||||
<i class="fas fa-plug"></i> Verbindungen
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!-- Content: tab output -->
|
||||
<div class="wbf-pv-content">
|
||||
<!-- ══════════════════════════════════════════════════
|
||||
TAB SHOP — Käufe (Shop-Plugin)
|
||||
══════════════════════════════════════════════════ -->
|
||||
@@ -1799,124 +1770,113 @@ class WBF_Shortcodes {
|
||||
Neue Integrationen: einfach weiteres .wbf-connection-card-Block
|
||||
via apply_filters('wbf_profile_connections', ...) hinzufügen.
|
||||
══════════════════════════════════════════════════ -->
|
||||
<?php
|
||||
/* ── PLUGINS TAB ── direkt in wbf-pv-content, gleiche Ebene wie Shop/Tab1/2/3 */
|
||||
if ( $is_own && $active_tab === 'plugins' && function_exists('wbf_render_plugin_watch_tab') ) :
|
||||
wbf_render_plugin_watch_tab( $profile, $current );
|
||||
endif;
|
||||
?>
|
||||
|
||||
<?php if ( $is_own && $active_tab === 'mc' ) : ?>
|
||||
<?php
|
||||
// ── Gallerie Bridge ──
|
||||
$has_gallery = class_exists('MC_Gallery_Forum_Bridge');
|
||||
$mc_gallery_content = $has_gallery ? apply_filters('wbf_profile_tab_content', '', 'minecraft', $profile) : '';
|
||||
// ── StatusAPI Bridge ──
|
||||
$mc_enabled = class_exists('WBF_MC_Bridge') && WBF_MC_Bridge::is_enabled();
|
||||
$mc_uuid = $mc_enabled ? WBF_MC_Bridge::get_mc_uuid($profile->id) : '';
|
||||
$mc_name = $mc_enabled ? WBF_MC_Bridge::get_mc_name($profile->id) : '';
|
||||
$mc_linked = !empty($mc_uuid);
|
||||
// ── Discord ──
|
||||
$discord_meta = WBF_DB::get_user_meta($profile->id);
|
||||
$discord_current = trim($discord_meta['discord_username'] ?? '');
|
||||
$discord_connected = $discord_current !== '';
|
||||
$s_cfg = wbf_get_settings();
|
||||
$discord_bot_configured = !empty(trim($s_cfg['discord_bot_token'] ?? ''));
|
||||
?>
|
||||
|
||||
<div class="wbf-profile-card">
|
||||
<div class="wbf-profile-card__header">
|
||||
<i class="fas fa-plug"></i> Verbundene Dienste
|
||||
</div>
|
||||
<div class="wbf-profile-card__body wbf-connections-body">
|
||||
<div class="wbf-svc-list">
|
||||
|
||||
<?php if ( class_exists('MC_Gallery_Forum_Bridge') ) :
|
||||
$mc_content = apply_filters('wbf_profile_tab_content', '', 'minecraft', $profile);
|
||||
?>
|
||||
<div class="wbf-connection-card">
|
||||
<div class="wbf-connection-card__icon" style="background:rgba(101,163,13,.15);border-color:rgba(101,163,13,.3)">
|
||||
<i class="fas fa-cubes" style="color:#65a30d"></i>
|
||||
<!-- ── GALLERIE ─────────────────────────────────── -->
|
||||
<?php if ($has_gallery): ?>
|
||||
<div class="wbf-svc-card">
|
||||
<div class="wbf-svc-card__row">
|
||||
<div class="wbf-svc-icon wbf-svc-icon--mc">
|
||||
<i class="fas fa-images"></i>
|
||||
</div>
|
||||
<div class="wbf-connection-card__head">
|
||||
<span class="wbf-connection-card__title">Gallerie Verbindung</span>
|
||||
<div class="wbf-svc-info">
|
||||
<span class="wbf-svc-name">Gallerie</span>
|
||||
<span class="wbf-svc-desc">Minecraft-Account verknüpfen um Bilder ohne Token hochzuladen</span>
|
||||
</div>
|
||||
<div class="wbf-svc-actions wbf-svc-gallery-actions">
|
||||
<?php echo $mc_gallery_content; ?>
|
||||
</div>
|
||||
<div class="wbf-connection-card__content">
|
||||
<?php echo $mc_content; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
// ── StatusAPI Bridge: Account-Verknüpfung & Ingame-Benachrichtigungen ──
|
||||
$mc_enabled = class_exists( 'WBF_MC_Bridge' ) && WBF_MC_Bridge::is_enabled();
|
||||
$mc_uuid = $mc_enabled ? WBF_MC_Bridge::get_mc_uuid( $profile->id ) : '';
|
||||
$mc_name = $mc_enabled ? WBF_MC_Bridge::get_mc_name( $profile->id ) : '';
|
||||
$mc_linked = ! empty( $mc_uuid );
|
||||
?>
|
||||
<div class="wbf-connection-card">
|
||||
<div class="wbf-connection-card__icon" style="background:rgba(101,163,13,.15);border-color:rgba(101,163,13,.3)">
|
||||
<i class="fas fa-cubes" style="color:#65a30d"></i>
|
||||
<!-- ── MINECRAFT INGAME ──────────────────────────── -->
|
||||
<div class="wbf-svc-card">
|
||||
<div class="wbf-svc-card__row">
|
||||
<div class="wbf-svc-icon wbf-svc-icon--mc">
|
||||
<i class="fas fa-cubes"></i>
|
||||
</div>
|
||||
<div class="wbf-connection-card__head">
|
||||
<span class="wbf-connection-card__title">Minecraft InGame Verbindung</span>
|
||||
<div class="wbf-svc-info">
|
||||
<div class="wbf-svc-info__top">
|
||||
<span class="wbf-svc-name">Minecraft</span>
|
||||
<?php if (!$mc_enabled): ?>
|
||||
<span class="wbf-connection-badge" style="color:#9ca3af;background:rgba(156,163,175,.1);border-color:rgba(156,163,175,.3)">
|
||||
<i class="fas fa-circle-xmark"></i> Nicht konfiguriert
|
||||
</span>
|
||||
<span class="wbf-svc-badge wbf-svc-badge--off"><i class="fas fa-circle-xmark"></i> Nicht konfiguriert</span>
|
||||
<?php elseif ($mc_linked): ?>
|
||||
<span class="wbf-connection-badge wbf-connection-badge--connected">
|
||||
<i class="fas fa-check-circle"></i> Verbunden
|
||||
</span>
|
||||
<span class="wbf-svc-badge wbf-svc-badge--on"><i class="fas fa-check-circle"></i> Verbunden</span>
|
||||
<div class="wbf-svc-linked-user">
|
||||
<img src="https://mc-heads.net/avatar/<?php echo urlencode($mc_name ?: $mc_uuid); ?>/24" width="24" height="24" style="border-radius:3px;image-rendering:pixelated">
|
||||
<strong><?php echo esc_html($mc_name ?: $mc_uuid); ?></strong>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<span class="wbf-connection-badge wbf-connection-badge--disconnected">
|
||||
<i class="fas fa-circle-xmark"></i> Nicht verbunden
|
||||
</span>
|
||||
<span class="wbf-svc-badge wbf-svc-badge--off"><i class="fas fa-circle-xmark"></i> Nicht verbunden</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="wbf-connection-card__content">
|
||||
<span class="wbf-svc-desc">Ingame-Benachrichtigungen bei Antworten, Erwähnungen & PNs</span>
|
||||
</div>
|
||||
<div class="wbf-svc-actions">
|
||||
<?php if (!$mc_enabled): ?>
|
||||
<p class="wbf-connection-card__desc" style="color:var(--c-muted)">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Die Minecraft Bridge ist noch nicht eingerichtet.
|
||||
Ein Admin muss sie zuerst in den Forum-Einstellungen aktivieren.
|
||||
</p>
|
||||
<!-- nothing -->
|
||||
<?php elseif ($mc_linked): ?>
|
||||
<div class="wbf-mc-linked-info" style="display:flex;align-items:center;gap:.75rem;margin-bottom:.75rem">
|
||||
<img src="https://mc-heads.net/avatar/<?php echo urlencode( $mc_name ?: $mc_uuid ); ?>/40"
|
||||
alt="" width="40" height="40"
|
||||
style="border-radius:4px;image-rendering:pixelated">
|
||||
<div>
|
||||
<strong style="color:var(--c-text)"><?php echo esc_html( $mc_name ?: $mc_uuid ); ?></strong><br>
|
||||
<small style="color:var(--c-muted);font-size:.75rem"><?php echo esc_html( $mc_uuid ); ?></small>
|
||||
</div>
|
||||
</div>
|
||||
<p style="font-size:.82rem;color:var(--c-muted);margin:.25rem 0 .75rem">
|
||||
<i class="fas fa-bell" style="color:#65a30d"></i>
|
||||
Du erhältst Ingame-Benachrichtigungen bei Antworten, Erwähnungen und PNs.
|
||||
</p>
|
||||
<div id="wbf-mc-msg" style="font-size:.82rem;margin-bottom:.5rem"></div>
|
||||
<button type="button" class="wbf-btn wbf-btn--ghost" id="wbf-mc-unlink-btn"
|
||||
onclick="wbfMcUnlink()">
|
||||
<i class="fas fa-unlink"></i> Verknüpfung aufheben
|
||||
<div id="wbf-mc-msg" class="wbf-svc-msg"></div>
|
||||
<button type="button" id="wbf-mc-unlink-btn" onclick="wbfMcUnlink()" style="height:34px;padding:0 14px;font-size:.79rem;font-weight:600;display:inline-flex;align-items:center;gap:5px;border-radius:6px;background:var(--c-surface2);color:var(--c-text-dim);border:1.5px solid var(--c-border-d);white-space:nowrap;cursor:pointer;font-family:inherit;box-sizing:border-box;line-height:1">
|
||||
<i class="fas fa-unlink"></i> Trennen
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<p class="wbf-connection-card__desc">
|
||||
Verknüpfe deinen Minecraft-Account für Ingame-Benachrichtigungen
|
||||
bei neuen Antworten, Erwähnungen und Privatnachrichten.
|
||||
</p>
|
||||
<p style="font-size:.82rem;color:var(--c-muted);margin-bottom:.75rem">
|
||||
<i class="fas fa-terminal"></i>
|
||||
Schritt 1: Token generieren →
|
||||
Schritt 2: <code>/forumlink <token></code> ingame eingeben
|
||||
</p>
|
||||
<div id="wbf-mc-token-box" style="display:none;background:var(--c-surface);border:1px solid var(--c-border);border-radius:8px;padding:.85rem 1rem;margin-bottom:.75rem">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-bottom:.4rem">
|
||||
<span style="font-size:.75rem;color:var(--c-muted);text-transform:uppercase;letter-spacing:.05em">Dein Token</span>
|
||||
<span id="wbf-mc-token-timer" style="font-size:.75rem;color:#f97316;font-weight:600"></span>
|
||||
<div id="wbf-mc-msg" class="wbf-svc-msg"></div>
|
||||
<button type="button" id="wbf-mc-gen-btn" onclick="wbfMcGenerateToken()" style="height:34px;padding:0 14px;font-size:.79rem;font-weight:600;display:inline-flex;align-items:center;gap:5px;border-radius:6px;background:var(--c-primary);color:#fff;border:1.5px solid var(--c-primary);white-space:nowrap;cursor:pointer;font-family:inherit;box-sizing:border-box;line-height:1">
|
||||
<i class="fas fa-key"></i> Verknüpfen
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($mc_enabled && !$mc_linked): ?>
|
||||
<div class="wbf-svc-card__form" id="wbf-mc-token-box" style="display:none">
|
||||
<div class="wbf-svc-token-box">
|
||||
<div class="wbf-svc-token-box__header">
|
||||
<span><i class="fas fa-terminal"></i> Ingame eingeben: <code id="wbf-mc-cmd-value">/forumlink ...</code></span>
|
||||
<div style="display:flex;align-items:center;gap:.5rem">
|
||||
<code id="wbf-mc-token-value"
|
||||
style="font-size:1.4rem;letter-spacing:.25em;font-weight:700;color:var(--c-accent);flex:1"></code>
|
||||
<button type="button" class="wbf-btn wbf-btn--sm" id="wbf-mc-copy-btn"
|
||||
onclick="wbfMcCopyToken()" title="Befehl kopieren">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
<span id="wbf-mc-token-timer" style="font-size:.75rem;color:#f97316;font-weight:600"></span>
|
||||
<button type="button" class="wbf-btn wbf-btn--sm" id="wbf-mc-copy-btn" onclick="wbfMcCopyToken()"><i class="fas fa-copy"></i></button>
|
||||
</div>
|
||||
<div style="margin-top:.5rem;font-size:.8rem;color:var(--c-muted)">
|
||||
Ingame eingeben: <code id="wbf-mc-cmd-value">/forumlink </code>
|
||||
</div>
|
||||
<div style="margin-top:.5rem">
|
||||
<div style="height:4px;border-radius:2px;background:var(--c-border);overflow:hidden">
|
||||
<div id="wbf-mc-token-progress"
|
||||
style="height:100%;background:#65a30d;transition:width 1s linear;width:100%"></div>
|
||||
<code id="wbf-mc-token-value" class="wbf-svc-token-code"></code>
|
||||
<div style="margin-top:.6rem;height:3px;border-radius:2px;background:var(--c-border);overflow:hidden">
|
||||
<div id="wbf-mc-token-progress" style="height:100%;background:var(--c-primary);transition:width 1s linear;width:100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wbf-mc-msg" style="font-size:.82rem;margin-bottom:.5rem"></div>
|
||||
<button type="button" class="wbf-btn wbf-btn--primary" id="wbf-mc-gen-btn"
|
||||
onclick="wbfMcGenerateToken()">
|
||||
<i class="fas fa-key"></i> Token generieren
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
var _pollInterval = null;
|
||||
@@ -2018,84 +1978,79 @@ class WBF_Shortcodes {
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?php
|
||||
// ── Discord-Card (eingebaut, kein extra Plugin nötig) ──────────────
|
||||
$discord_meta = WBF_DB::get_user_meta( $profile->id );
|
||||
$discord_current = trim( $discord_meta['discord_username'] ?? '' );
|
||||
$discord_connected = $discord_current !== '';
|
||||
?>
|
||||
<?php
|
||||
$s = wbf_get_settings();
|
||||
$discord_bot_configured = ! empty( trim( $s['discord_bot_token'] ?? '' ) );
|
||||
?>
|
||||
<div class="wbf-connection-card wbf-connection-card--discord">
|
||||
<div class="wbf-connection-card__icon">
|
||||
<!-- ── DISCORD ──────────────────────────────────── -->
|
||||
<div class="wbf-svc-card wbf-svc-card--last">
|
||||
<div class="wbf-svc-card__row">
|
||||
<div class="wbf-svc-icon wbf-svc-icon--discord">
|
||||
<i class="fab fa-discord"></i>
|
||||
</div>
|
||||
<div class="wbf-connection-card__head">
|
||||
<span class="wbf-connection-card__title">Discord</span>
|
||||
<div class="wbf-svc-info">
|
||||
<div class="wbf-svc-info__top">
|
||||
<span class="wbf-svc-name">Discord</span>
|
||||
<?php if ($discord_connected): ?>
|
||||
<span class="wbf-connection-badge wbf-connection-badge--connected">
|
||||
<i class="fas fa-check-circle"></i> Verbunden
|
||||
</span>
|
||||
<span class="wbf-svc-badge wbf-svc-badge--on"><i class="fas fa-check-circle"></i> Verbunden</span>
|
||||
<div class="wbf-svc-linked-user wbf-svc-linked-user--discord">
|
||||
<i class="fab fa-discord"></i>
|
||||
<strong><?php echo esc_html($discord_current); ?></strong>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<span class="wbf-connection-badge wbf-connection-badge--disconnected">
|
||||
<i class="fas fa-circle-xmark"></i> Nicht verbunden
|
||||
</span>
|
||||
<span class="wbf-svc-badge wbf-svc-badge--off"><i class="fas fa-circle-xmark"></i> Nicht verbunden</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="wbf-connection-card__content">
|
||||
|
||||
<span class="wbf-svc-desc">Discord-Account mit deinem Profil verknüpfen</span>
|
||||
</div>
|
||||
<div class="wbf-svc-actions">
|
||||
<?php if ($discord_connected): ?>
|
||||
<!-- ── Bereits verbunden ── -->
|
||||
<div class="wbf-discord-connected-info">
|
||||
<span class="wbf-discord-linked-name">
|
||||
<i class="fab fa-discord" style="color:#5865f2"></i>
|
||||
<?php echo esc_html( $discord_current ); ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="wbf-connect-row" style="margin-top:.75rem">
|
||||
<button type="button" class="wbf-btn wbf-btn--primary" id="wbf-discord-relink">
|
||||
<i class="fas fa-rotate"></i> Neu verknüpfen
|
||||
</button>
|
||||
<button type="button" class="wbf-btn wbf-btn--ghost" id="wbf-discord-disconnect">
|
||||
<i class="fas fa-unlink"></i> Trennen
|
||||
</button>
|
||||
</div>
|
||||
<div id="wbf-discord-msg" style="margin-top:.5rem;font-size:.82rem"></div>
|
||||
|
||||
<!-- Formular (standardmäßig ausgeblendet, bei "Neu verknüpfen" sichtbar) -->
|
||||
<div id="wbf-discord-form" style="display:none;margin-top:1rem">
|
||||
<?php self::render_discord_form( $discord_bot_configured ); ?>
|
||||
</div>
|
||||
|
||||
<button type="button" id="wbf-discord-relink" style="height:34px;padding:0 14px;font-size:.79rem;font-weight:600;display:inline-flex;align-items:center;gap:5px;border-radius:6px;background:var(--c-primary);color:#fff;border:1.5px solid var(--c-primary);white-space:nowrap;cursor:pointer;font-family:inherit;box-sizing:border-box;line-height:1"><i class="fas fa-rotate"></i> Neu verknüpfen</button>
|
||||
<button type="button" id="wbf-discord-disconnect" style="height:34px;padding:0 14px;font-size:.79rem;font-weight:600;display:inline-flex;align-items:center;gap:5px;border-radius:6px;background:var(--c-surface2);color:var(--c-text-dim);border:1.5px solid var(--c-border-d);white-space:nowrap;cursor:pointer;font-family:inherit;box-sizing:border-box;line-height:1"><i class="fas fa-unlink"></i> Trennen</button>
|
||||
<?php else: ?>
|
||||
<!-- ── Noch nicht verbunden ── -->
|
||||
<p class="wbf-connection-card__desc">
|
||||
Verknüpfe deinen Discord-Account mit deinem Profil.
|
||||
<!-- Step 1 inline: input + send button -->
|
||||
<?php if ($discord_bot_configured): ?>
|
||||
Ein Bestätigungs-Code wird dir per Discord-DM zugeschickt.
|
||||
<div class="wbf-svc-discord-inline" id="wbf-dc-step1-inline">
|
||||
<input type="text" id="wbf-discord-input" placeholder="Discord-Username" maxlength="40" autocomplete="off" style="height:34px;padding:0 10px;font-size:.82rem;font-family:inherit;background:var(--c-bg2);border:1.5px solid var(--c-border-d);border-radius:6px;color:var(--c-text);width:155px;box-sizing:border-box">
|
||||
<button type="button" id="wbf-discord-send-code" style="height:34px;padding:0 14px;font-size:.79rem;font-weight:600;display:inline-flex;align-items:center;gap:5px;border-radius:6px;background:var(--c-primary);color:#fff;border:1.5px solid var(--c-primary);white-space:nowrap;cursor:pointer;font-family:inherit;box-sizing:border-box;line-height:1">
|
||||
<i class="fab fa-discord"></i> Code senden
|
||||
</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<em style="color:var(--c-muted)">(Bot noch nicht konfiguriert – wende dich an einen Admin.)</em>
|
||||
<span style="font-size:.75rem;color:var(--c-muted)"><i class="fas fa-triangle-exclamation"></i> Bot nicht konfiguriert</span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<div id="wbf-discord-msg" style="margin-top:.3rem;font-size:.82rem"></div>
|
||||
<div id="wbf-discord-form">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Step 2: code verification (expands below) -->
|
||||
<?php if (!$discord_connected && $discord_bot_configured): ?>
|
||||
<div id="wbf-dc-step2" style="display:none">
|
||||
<div class="wbf-svc-card__form">
|
||||
<div class="wbf-svc-discord-step2-row">
|
||||
<label style="font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--c-text-dim);margin-bottom:.3rem;display:block">Bestätigungs-Code (aus Discord-DM)</label>
|
||||
<div style="display:flex;align-items:center;gap:.4rem;flex-wrap:wrap">
|
||||
<input type="text" id="wbf-discord-code-input" placeholder="A1B2C3" maxlength="6" autocomplete="off"
|
||||
style="font-family:monospace;letter-spacing:.15em;text-transform:uppercase;width:120px">
|
||||
<button type="button" class="wbf-btn wbf-btn--sm wbf-btn--primary" id="wbf-discord-verify">
|
||||
<i class="fas fa-check"></i> Bestätigen
|
||||
</button>
|
||||
<button type="button" class="wbf-btn wbf-btn--sm" id="wbf-discord-code-back">
|
||||
<i class="fas fa-arrow-left"></i> Zurück
|
||||
</button>
|
||||
</div>
|
||||
<p style="font-size:.75rem;color:var(--c-muted);margin:.35rem 0 0"><i class="fas fa-clock"></i> Code ist 10 Minuten gültig.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!-- Connected: re-link form (hidden by default) -->
|
||||
<?php if ($discord_connected): ?>
|
||||
<div id="wbf-discord-form" style="display:none">
|
||||
<div class="wbf-svc-card__form">
|
||||
<?php self::render_discord_form($discord_bot_configured); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
<div id="wbf-discord-msg" class="wbf-svc-msg"></div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// Hook für weitere Verbindungen (z.B. Steam, Twitch, …)
|
||||
// Nutzung: add_filter('wbf_profile_connections', function($html, $profile) {
|
||||
// return $html . '<div class="wbf-connection-card">…</div>';
|
||||
// }, 10, 2);
|
||||
echo apply_filters('wbf_profile_connections', '', $profile);
|
||||
?>
|
||||
<?php echo apply_filters('wbf_profile_connections', '', $profile); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -2104,6 +2059,9 @@ class WBF_Shortcodes {
|
||||
|
||||
</div><!-- /.wbf-profile-main -->
|
||||
</div><!-- /.wbf-profile-layout -->
|
||||
</div><!-- /.wbf-pv-content -->
|
||||
</div><!-- /.wbf-pv-body -->
|
||||
</div><!-- /.wbf-pv -->
|
||||
</div>
|
||||
</div>
|
||||
<?php self::render_auth_modal(); ?>
|
||||
|
||||
269
includes/forum-plugin-watch.php
Normal file
269
includes/forum-plugin-watch.php
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
/**
|
||||
* WP Business Forum — Plugin-Watch Profil-Tab & Benachrichtigungen
|
||||
* Pfad: includes/forum-plugin-watch.php
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════
|
||||
Allowed Tabs erweitern
|
||||
══════════════════════════════════════════════════════════════ */
|
||||
add_filter( 'wbf_allowed_profile_tabs', function( $tabs ) {
|
||||
$tabs[] = 'plugins';
|
||||
return $tabs;
|
||||
} );
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════
|
||||
Tab-Inhalt rendern (direkt via class-forum-shortcodes.php Hook)
|
||||
══════════════════════════════════════════════════════════════ */
|
||||
function wbf_render_plugin_watch_tab( $profile, $current ) {
|
||||
$watches = function_exists('vmcp_bridge_get_watches')
|
||||
? vmcp_bridge_get_watches( $profile->id, 100 )
|
||||
: [];
|
||||
$archive_url = get_post_type_archive_link('mc_plugin') ?: home_url('/mc-plugins/');
|
||||
// Nonce für vmcp_toggle_watch (aus MC-Plugin)
|
||||
$vmcp_nonce = wp_create_nonce('vmcp_nonce');
|
||||
$ajax_url = admin_url('admin-ajax.php');
|
||||
?>
|
||||
<div class="wbf-profile-card wbf-plugin-watch-card">
|
||||
<div class="wbf-profile-card__header">
|
||||
<i class="fas fa-bell"></i> Beobachtete Plugins
|
||||
<span class="wbf-profile-card__count" id="wbf-watch-count-badge"><?php echo count($watches); ?></span>
|
||||
</div>
|
||||
|
||||
<?php if ( empty($watches) ) : ?>
|
||||
<div class="wbf-profile-empty" style="text-align:center;padding:24px 16px;">
|
||||
<i class="fas fa-bell-slash" style="font-size:2.2em;color:#2a3a4a;margin-bottom:10px;display:block;"></i>
|
||||
<p style="margin:0 0 10px;color:#4a6a8a;">Du beobachtest noch kein Plugin.</p>
|
||||
<a href="<?php echo esc_url($archive_url); ?>" style="color:#00d4ff;font-weight:600;">
|
||||
Plugins entdecken →
|
||||
</a>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<ul class="wbf-watch-list" id="wbf-watch-list">
|
||||
<?php foreach ( $watches as $w ) :
|
||||
$link = get_permalink( $w->plugin_id );
|
||||
$thumb = get_the_post_thumbnail_url( $w->plugin_id, 'thumbnail' );
|
||||
$version = get_post_meta( $w->plugin_id, '_vmcp_version', true );
|
||||
$premium = get_post_meta( $w->plugin_id, '_vmcp_premium', true ) === '1';
|
||||
$initial = mb_strtoupper( mb_substr( $w->post_title, 0, 1 ) );
|
||||
$since = human_time_diff( strtotime($w->created_at), current_time('timestamp') );
|
||||
?>
|
||||
<li class="wbf-watch-item" data-plugin="<?php echo (int)$w->plugin_id; ?>">
|
||||
<a href="<?php echo esc_url($link); ?>" class="wbf-watch-item__thumb">
|
||||
<?php if ($thumb): ?>
|
||||
<img src="<?php echo esc_url($thumb); ?>" alt="" loading="lazy">
|
||||
<?php else: ?>
|
||||
<div class="wbf-watch-item__initial"><?php echo esc_html($initial); ?></div>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<div class="wbf-watch-item__body">
|
||||
<a href="<?php echo esc_url($link); ?>" class="wbf-watch-item__name">
|
||||
<?php echo esc_html($w->post_title); ?>
|
||||
</a>
|
||||
<div class="wbf-watch-item__meta">
|
||||
<?php if ($version): ?>
|
||||
<span class="wbf-watch-item__ver">v<?php echo esc_html($version); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ($premium): ?>
|
||||
<span class="wbf-watch-item__premium">⭐ Premium</span>
|
||||
<?php endif; ?>
|
||||
<span class="wbf-watch-item__since">Seit <?php echo esc_html($since); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button"
|
||||
class="wbf-watch-unwatch-btn"
|
||||
data-plugin="<?php echo (int)$w->plugin_id; ?>"
|
||||
title="Beobachtung beenden">
|
||||
<i class="fas fa-bell-slash"></i>
|
||||
</button>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Wunschliste (client-seitig aus localStorage) -->
|
||||
<div class="wbf-profile-card wbf-plugin-watch-card" style="margin-top:20px;">
|
||||
<div class="wbf-profile-card__header">
|
||||
<i class="fas fa-heart"></i> Wunschliste
|
||||
<span class="wbf-profile-card__count wbf-wishlist-count-badge">0</span>
|
||||
</div>
|
||||
<div id="wbf-wishlist-plugin-content">
|
||||
<div class="wbf-profile-empty" style="text-align:center;padding:20px;">
|
||||
<i class="fas fa-spinner fa-spin" style="color:#2a3a4a;font-size:1.5em;display:block;margin-bottom:8px;"></i>
|
||||
Lade Wunschliste…
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
var ajaxUrl = <?php echo wp_json_encode( $ajax_url ); ?>;
|
||||
var nonce = <?php echo wp_json_encode( $vmcp_nonce ); ?>;
|
||||
var archiveUrl = <?php echo wp_json_encode( $archive_url ); ?>;
|
||||
|
||||
/* ── Unwatch direkt aus dem Profil ── */
|
||||
document.querySelectorAll('.wbf-watch-unwatch-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var pluginId = btn.dataset.plugin;
|
||||
if (!confirm('Beobachtung für dieses Plugin wirklich beenden?')) return;
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
|
||||
|
||||
var fd = new FormData();
|
||||
fd.append('action', 'vmcp_toggle_watch');
|
||||
fd.append('nonce', nonce);
|
||||
fd.append('plugin_id', pluginId);
|
||||
|
||||
fetch(ajaxUrl, { method:'POST', body:fd })
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(res){
|
||||
if (res.success && !res.data.watching) {
|
||||
var li = btn.closest('.wbf-watch-item');
|
||||
if (li) {
|
||||
li.style.opacity = '0';
|
||||
li.style.transition = 'opacity .3s';
|
||||
setTimeout(function(){ li.remove(); }, 300);
|
||||
}
|
||||
// Badge aktualisieren
|
||||
var badge = document.getElementById('wbf-watch-count-badge');
|
||||
if (badge) badge.textContent = Math.max(0, (parseInt(badge.textContent)||0)-1);
|
||||
// Leerliste zeigen wenn keine mehr da
|
||||
var list = document.getElementById('wbf-watch-list');
|
||||
if (list && list.querySelectorAll('.wbf-watch-item').length <= 1) {
|
||||
setTimeout(function(){
|
||||
list.closest('.wbf-plugin-watch-card').querySelector('.wbf-profile-card__header').insertAdjacentHTML('afterend',
|
||||
'<div class="wbf-profile-empty" style="text-align:center;padding:24px 16px;">' +
|
||||
'<i class="fas fa-bell-slash" style="font-size:2.2em;color:#2a3a4a;margin-bottom:10px;display:block;"></i>' +
|
||||
'<p style="margin:0 0 10px;color:#4a6a8a;">Du beobachtest noch kein Plugin.</p>' +
|
||||
'<a href="'+archiveUrl+'" style="color:#00d4ff;font-weight:600;">Plugins entdecken →</a></div>'
|
||||
);
|
||||
if (list) list.remove();
|
||||
}, 350);
|
||||
}
|
||||
} else {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<i class="fas fa-bell-slash"></i>';
|
||||
if (res.data && res.data.message) alert(res.data.message);
|
||||
}
|
||||
})
|
||||
.catch(function(){
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<i class="fas fa-bell-slash"></i>';
|
||||
alert('Fehler beim Verbinden. Bitte Seite neu laden.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/* ── Wunschliste aus localStorage laden ── */
|
||||
var wishlistContent = document.getElementById('wbf-wishlist-plugin-content');
|
||||
var wishlistBadge = document.querySelector('.wbf-wishlist-count-badge');
|
||||
var favs = [];
|
||||
try { favs = JSON.parse(localStorage.getItem('vmcp_favs') || '[]'); } catch(e){}
|
||||
|
||||
if (wishlistBadge) wishlistBadge.textContent = favs.length;
|
||||
|
||||
if (!favs || favs.length === 0) {
|
||||
wishlistContent.innerHTML =
|
||||
'<div class="wbf-profile-empty" style="text-align:center;padding:24px 16px;">' +
|
||||
'<i class="fas fa-heart-crack" style="font-size:2.2em;color:#2a3a4a;margin-bottom:10px;display:block;"></i>' +
|
||||
'<p style="margin:0 0 10px;color:#4a6a8a;">Deine Wunschliste ist leer.</p>' +
|
||||
'<a href="' + archiveUrl + '" style="color:#00d4ff;font-weight:600;">Plugins entdecken →</a>' +
|
||||
'</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
/* Plugins via vmcp AJAX laden */
|
||||
var fd2 = new FormData();
|
||||
fd2.append('action', 'vmcp_wishlist_load');
|
||||
fd2.append('nonce', nonce);
|
||||
fd2.append('favs', JSON.stringify(favs));
|
||||
|
||||
fetch(ajaxUrl, { method:'POST', body:fd2 })
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(res){
|
||||
if (res.success && res.data && res.data.html) {
|
||||
wishlistContent.innerHTML = res.data.html;
|
||||
} else {
|
||||
wishlistContent.innerHTML =
|
||||
'<div class="wbf-profile-empty" style="padding:20px;text-align:center;">' +
|
||||
'<p style="color:#4a6a8a;">Keine Plugins gefunden.</p></div>';
|
||||
}
|
||||
})
|
||||
.catch(function(){
|
||||
wishlistContent.innerHTML =
|
||||
'<div class="wbf-profile-empty" style="padding:20px;text-align:center;">' +
|
||||
'<p style="color:#4a6a8a;">Fehler beim Laden.</p></div>';
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wbf-watch-list { list-style:none; margin:0; padding:12px; display:flex; flex-direction:column; gap:8px; }
|
||||
.wbf-watch-item {
|
||||
display:flex; align-items:center; gap:12px; padding:10px 12px;
|
||||
background:rgba(255,255,255,.03); border:1px solid rgba(255,255,255,.06);
|
||||
border-radius:10px; transition:border-color .15s, opacity .3s;
|
||||
}
|
||||
.wbf-watch-item:hover { border-color:rgba(0,212,255,.2); }
|
||||
.wbf-watch-item__thumb img,
|
||||
.wbf-watch-item__thumb { width:42px; height:42px; border-radius:8px; object-fit:cover; display:block; flex-shrink:0; }
|
||||
.wbf-watch-item__initial {
|
||||
width:42px; height:42px; border-radius:8px; flex-shrink:0;
|
||||
background:rgba(0,212,255,.1); border:1px solid rgba(0,212,255,.2);
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
font-size:18px; font-weight:800; color:#00d4ff;
|
||||
}
|
||||
.wbf-watch-item__body { flex:1; min-width:0; }
|
||||
.wbf-watch-item__name { display:block; font-weight:700; color:#e0e6f0; text-decoration:none; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
||||
.wbf-watch-item__name:hover { color:#00d4ff; }
|
||||
.wbf-watch-item__meta { display:flex; flex-wrap:wrap; gap:6px; margin-top:3px; font-size:12px; }
|
||||
.wbf-watch-item__ver { color:#00d4ff; }
|
||||
.wbf-watch-item__premium { color:#f5c542; }
|
||||
.wbf-watch-item__since { color:#4a6a8a; }
|
||||
.wbf-watch-unwatch-btn {
|
||||
background:none; border:none; cursor:pointer; color:#3a4a5a;
|
||||
font-size:15px; padding:6px; border-radius:6px; flex-shrink:0;
|
||||
transition:color .15s, background .15s;
|
||||
}
|
||||
.wbf-watch-unwatch-btn:hover { color:#e11d48; background:rgba(225,29,72,.1); }
|
||||
.wbf-plugin-watch-card .vmcp-grid { gap:10px; }
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════
|
||||
Benachrichtigung rendern
|
||||
══════════════════════════════════════════════════════════════ */
|
||||
add_filter( 'wbf_notification_html', function( $html, $notif ) {
|
||||
if ( $notif->type !== 'plugin_update' ) return $html;
|
||||
$plugin_id = (int) $notif->object_id;
|
||||
$post = get_post( $plugin_id );
|
||||
if ( ! $post ) return $html;
|
||||
$title = esc_html( $post->post_title );
|
||||
$link = esc_url( get_permalink( $plugin_id ) );
|
||||
$version = esc_html( get_post_meta( $plugin_id, '_vmcp_version', true ) );
|
||||
$thumb = get_the_post_thumbnail_url( $plugin_id, 'thumbnail' );
|
||||
$time_ago = human_time_diff( strtotime($notif->created_at), current_time('timestamp') );
|
||||
ob_start(); ?>
|
||||
<div class="wbf-notif-item<?php echo $notif->is_read ? '' : ' wbf-notif-unread'; ?>"
|
||||
data-id="<?php echo (int)$notif->id; ?>">
|
||||
<div class="wbf-notif-icon wbf-notif-icon--plugin">
|
||||
<?php if ($thumb): ?>
|
||||
<img src="<?php echo esc_url($thumb); ?>" width="36" height="36"
|
||||
style="border-radius:6px;object-fit:cover;display:block;" alt="">
|
||||
<?php else: ?>
|
||||
<i class="fas fa-puzzle-piece"></i>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="wbf-notif-body">
|
||||
<span class="wbf-notif-text">
|
||||
<a href="<?php echo $link; ?>"><?php echo $title; ?></a>
|
||||
wurde aktualisiert<?php echo $version ? ' auf <strong>v'.$version.'</strong>' : ''; ?>.
|
||||
</span>
|
||||
<span class="wbf-notif-time">vor <?php echo esc_html($time_ago); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php return ob_get_clean();
|
||||
}, 10, 2 );
|
||||
@@ -1,20 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: WP Business Forum
|
||||
* Plugin URI: https://git.viper.ipv64.net/M_Viper/WP-Business-Forum
|
||||
* Description: Professionelles Forum mit eigenem Login, Rollen, Signaturen, Hierarchie und Moderations-Tools.
|
||||
* Version: 1.0.5
|
||||
* Author: M_Viper
|
||||
* Author URI: https://m-viper.de
|
||||
* Text Domain: wp-business-forum
|
||||
* Requires PHP: 7.0
|
||||
/*
|
||||
Plugin Name: WP Business Forum
|
||||
Plugin URI:https://git.viper.ipv64.net/M_Viper/WP-Business-Forum
|
||||
Description: Professionelles Forum mit eigenem Login, Rollen, Signaturen, Hierarchie und Moderations-Tools.
|
||||
Version: 1.0.6
|
||||
Author: M_Viper
|
||||
Author URI: https://m-viper.de
|
||||
Requires at least: 6.8
|
||||
Tested up to: 6.8
|
||||
PHP Version: 7.4
|
||||
License: GPL2
|
||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
Text Domain: wp-business-forum
|
||||
Tags: forum, community, roles, moderation, shortcode, bbcode, admin, frontend, security, export-import
|
||||
Support: [Discord Support](https://discord.com/invite/FdRs4BRd8D)
|
||||
Support: [Telegram Support](https://t.me/M_Viper04)
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
define( 'WBF_PATH', plugin_dir_path( __FILE__ ) );
|
||||
define( 'WBF_URL', plugin_dir_url( __FILE__ ) );
|
||||
define( 'WBF_VERSION', '1.0.5' );
|
||||
define( 'WBF_VERSION', '1.0.6' );
|
||||
|
||||
require_once WBF_PATH . 'includes/class-forum-db.php';
|
||||
require_once WBF_PATH . 'includes/class-forum-roles.php';
|
||||
@@ -27,6 +34,12 @@ require_once WBF_PATH . 'includes/class-forum-export.php';
|
||||
require_once WBF_PATH . 'includes/class-forum-mc-bridge.php';
|
||||
require_once WBF_PATH . 'includes/class-forum-totp.php';
|
||||
require_once WBF_PATH . 'includes/forum-statusapi.php';
|
||||
|
||||
/* ─── Plugin-Watch Bridge (optional — nur wenn MC Plugin aktiv) ── */
|
||||
$wbf_plugin_watch = WBF_PATH . 'includes/forum-plugin-watch.php';
|
||||
if ( file_exists( $wbf_plugin_watch ) ) {
|
||||
require_once $wbf_plugin_watch;
|
||||
}
|
||||
require_once WBF_PATH . 'admin/forum-admin.php';
|
||||
require_once WBF_PATH . 'admin/forum-settings.php';
|
||||
require_once WBF_PATH . 'admin/forum-setup.php';
|
||||
|
||||
Reference in New Issue
Block a user