269 lines
14 KiB
PHP
269 lines
14 KiB
PHP
<?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 );
|