advdfv
Contenu complet
/*
Plugin Name: BPMB Concours
Description: Affichage des concours avec tri par likes et popup de lecture
*/
class BPMB_Concours {
private static $instance;
public static function get_instance() {
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
add_action(‘wp_enqueue_scripts’, array($this, ‘enqueue_scripts’));
add_shortcode(‘concours’, array($this, ‘shortcode_callback’));
add_action(‘wp_ajax_concours_load_post’, array($this, ‘load_post_content’));
add_action(‘wp_ajax_nopriv_concours_load_post’, array($this, ‘load_post_content’));
}
public function enqueue_scripts() {
if (has_shortcode(get_post()->post_content, ‘concours’)) {
wp_enqueue_script(‘concours-script’, plugin_dir_url(__FILE__) . ‘js/concours.js’, array(‘jquery’), ‘1.0’, true);
wp_localize_script(‘concours-script’, ‘concours_ajax’, array(
‘ajax_url’ => admin_url(‘admin-ajax.php’),
‘nonce’ => wp_create_nonce(‘concours_nonce’),
‘user_logged_in’ => is_user_logged_in() ? ‘1’ : ‘0’,
‘user_id’ => get_current_user_id()
));
// Inclure Swiper pour les carrousels dans les popups
wp_enqueue_style(‘swiper-css’, ‘https://unpkg.com/swiper/swiper-bundle.min.css’);
wp_enqueue_script(‘swiper-js’, ‘https://unpkg.com/swiper/swiper-bundle.min.js’, array(), null, true);
}
}
// Fonction pour analyser les catĂ©gories/tags de l’URL et du contexte
private function get_url_categories_tags() {
$current_categories = array();
$current_tags = array();
// RĂ©cupĂ©rer les paramĂštres d’URL pour catĂ©gories et tags
if (isset($_GET[‘category’]) && !empty($_GET[‘category’])) {
$current_categories = array_map(‘sanitize_text_field’, explode(‘,’, $_GET[‘category’]));
}
if (isset($_GET[‘tag’]) && !empty($_GET[‘tag’])) {
$current_tags = array_map(‘sanitize_text_field’, explode(‘,’, $_GET[‘tag’]));
}
// Si on est sur une page d’archive WordPress
if (is_category()) {
$current_category = get_queried_object();
if ($current_category) {
$current_categories[] = $current_category->slug;
}
}
if (is_tag()) {
$current_tag = get_queried_object();
if ($current_tag) {
$current_tags[] = $current_tag->slug;
}
}
// Si on est sur un article ou produit single, utiliser ses catégories/tags
if (is_single() || is_singular(‘product’)) {
$post_id = get_the_ID();
// RĂ©cupĂ©rer les catĂ©gories de l’article/produit actuel
if (is_singular(‘product’)) {
$post_categories = wp_get_post_terms($post_id, ‘product_cat’, array(‘fields’ => ‘slugs’));
} else {
$post_categories = wp_get_post_categories($post_id, array(‘fields’ => ‘slugs’));
}
if (!empty($post_categories)) {
$current_categories = array_merge($current_categories, $post_categories);
}
// RĂ©cupĂ©rer les tags de l’article/produit actuel
$post_tags = wp_get_post_tags($post_id, array(‘fields’ => ‘slugs’));
if (!empty($post_tags)) {
$current_tags = array_merge($current_tags, $post_tags);
}
}
// Ăviter les doublons
$current_categories = array_unique($current_categories);
$current_tags = array_unique($current_tags);
return array(
‘categories’ => $current_categories,
‘tags’ => $current_tags
);
}
// Fonction pour calculer la pertinence d’un post
private function calculate_relevance($post_id, $target_categories, $target_tags) {
$relevance_score = 0;
// Vérifier les catégories
if (get_post_type($post_id) === ‘product’) {
$post_categories = wp_get_post_terms($post_id, ‘product_cat’, array(‘fields’ => ‘slugs’));
} else {
$post_categories = wp_get_post_categories($post_id, array(‘fields’ => ‘slugs’));
}
$common_categories = array_intersect($post_categories, $target_categories);
$relevance_score += count($common_categories) * 3;
// Vérifier les tags
$post_tags = wp_get_post_tags($post_id, array(‘fields’ => ‘slugs’));
$common_tags = array_intersect($post_tags, $target_tags);
$relevance_score += count($common_tags) * 2;
return $relevance_score;
}
// Fonction pour récupérer les membres premium
private function get_premium_users() {
$premium_users = get_users(array(
‘role’ => ‘pms_subscription_plan_5424’,
‘number’ => -1
));
$author_ids = array();
foreach ($premium_users as $premium_user) {
$author_ids[] = $premium_user->ID;
}
return $author_ids;
}
// Fonction pour rĂ©cupĂ©rer le nombre de likes d’un post
private function get_like_count($post_id) {
$like_count = get_post_meta($post_id, ‘pld_like_count’, true);
return $like_count ? (int)$like_count : 0;
}
// Rendu d’un article complet (comme dans le feed)
private function render_post_card_complete($post_id) {
$post = get_post($post_id);
if (!$post) return ”;
$author_id = $post->post_author;
$current_user_id = get_current_user_id();
$comments_count = get_comments_number($post_id);
// Récupération des médias
$media_items = [];
$featured_image_added = false;
if ($thumbnail_id = get_post_thumbnail_id($post_id)) {
$media_items[] = [
‘type’ => ‘image’,
‘url’ => wp_get_attachment_url($thumbnail_id),
‘id’ => $thumbnail_id,
‘featured’ => true
];
$featured_image_added = true;
}
if (function_exists(‘wc_get_product’) && ‘product’ === get_post_type($post_id)) {
$product = wc_get_product($post_id);
if ($product) {
$gallery_ids = $product->get_gallery_image_ids();
foreach ($gallery_ids as $img_id) {
if (!$featured_image_added || $img_id != $thumbnail_id) {
$media_items[] = [
‘type’ => ‘image’,
‘url’ => wp_get_attachment_url($img_id),
‘id’ => $img_id,
‘featured’ => false
];
}
}
}
}
$attached_media = get_attached_media(”, $post_id);
foreach ($attached_media as $media) {
$mime = $media->post_mime_type;
$is_featured_media = ($featured_image_added && $media->ID == $thumbnail_id);
if (!$is_featured_media) {
if (strpos($mime, ‘image’) !== false) {
$media_items[] = [
‘type’ => ‘image’,
‘url’ => wp_get_attachment_url($media->ID),
‘id’ => $media->ID,
‘featured’ => false
];
} elseif (strpos($mime, ‘video’) !== false) {
$media_items[] = [
‘type’ => ‘video’,
‘url’ => wp_get_attachment_url($media->ID),
‘id’ => $media->ID,
‘mime’ => $mime
];
} elseif (strpos($mime, ‘audio’) !== false) {
$media_items[] = [
‘type’ => ‘audio’,
‘url’ => wp_get_attachment_url($media->ID),
‘id’ => $media->ID,
‘mime’ => $mime
];
}
}
}
$videos = array_filter($media_items, function($media) {
return $media[‘type’] === ‘video’;
});
$images = array_filter($media_items, function($media) {
return $media[‘type’] === ‘image’;
});
$audios = array_filter($media_items, function($media) {
return $media[‘type’] === ‘audio’;
});
usort($images, function($a, $b) {
if ($a[‘featured’] && !$b[‘featured’]) return -1;
if (!$a[‘featured’] && $b[‘featured’]) return 1;
return 0;
});
$media_items = array_merge($videos, $images);
$has_multiple_media = count($media_items) > 1;
// Statut d’amitiĂ©
$friendship_status = ‘not_friends’;
if (is_user_logged_in() && $current_user_id != $author_id && function_exists(‘bp_is_active’) && bp_is_active(‘friends’)) {
if (friends_check_friendship($current_user_id, $author_id)) {
$friendship_status = ‘friends’;
} elseif (friends_check_friendship_status($current_user_id, $author_id) == ‘pending’) {
$friendship_status = ‘pending’;
}
}
ob_start();
?>
<article id=”concours-post-<?php echo $post_id; ?>” class=”concours-post-popup”>
<div class=”concours-article-content-col”>
<div class=”concours-content”>
<!– SECTION MĂDIAS –>
<?php if (!empty($media_items)): ?>
<?php if ($has_multiple_media): ?>
<div class=”concours-media-carousel swiper”>
<div class=”swiper-wrapper”>
<?php foreach ($media_items as $media): ?>
<div class=”swiper-slide”>
<?php if ($media[‘type’] === ‘video’): ?>
<div class=”concours-media-wrapper concours-video-wrapper”>
<video
controls
playsinline
class=”concours-video-player”
data-video-id=”<?php echo esc_attr($media[‘id’]); ?>”
preload=”metadata”>
<source src=”<?php echo esc_url($media[‘url’]); ?>” type=”<?php echo esc_attr($media[‘mime’]); ?>”>
Votre navigateur ne supporte pas la lecture de vidéos.
</video>
<div class=”concours-media-label”>VidĂ©o</div>
</div>
<?php else: ?>
<div class=”concours-image-wrapper”>
<div class=”concours-image-container”>
<img
src=”<?php echo esc_url($media[‘url’]); ?>”
alt=””
loading=”lazy”
class=”concours-blur-up”>
<div class=”concours-image-background-blur”></div>
</div>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<div class=”swiper-pagination”></div>
<div class=”swiper-button-next”></div>
<div class=”swiper-button-prev”></div>
</div>
<?php else: ?>
<div class=”concours-media-wrapper”>
<?php $media = $media_items[0]; ?>
<?php if ($media[‘type’] === ‘video’): ?>
<div class=”concours-video-wrapper”>
<video
controls
playsinline
class=”concours-video-player”
data-video-id=”<?php echo esc_attr($media[‘id’]); ?>”
preload=”metadata”>
<source src=”<?php echo esc_url($media[‘url’]); ?>” type=”<?php echo esc_attr(get_post_mime_type($media[‘id’])); ?>”>
Votre navigateur ne supporte pas la lecture de vidéos.
</video>
<div class=”concours-media-label”>VidĂ©o</div>
</div>
<?php else: ?>
<div class=”concours-image-wrapper”>
<div class=”concours-image-container”>
<img
src=”<?php echo esc_url($media[‘url’]); ?>”
alt=””
loading=”lazy”
class=”concours-blur-up”>
<div class=”concours-image-background-blur”></div>
</div>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>
<!– TITRE –>
<div class=”concours-title-section”>
<h2 class=”concours-title”>
<?php echo get_the_title($post_id); ?>
</h2>
</div>
<!– AUTEUR ET BOUTON AMI –>
<div class=”concours-author-section” data-post-id=”<?php echo $post_id; ?>”>
<?php
$author_avatar = get_avatar_url($author_id, [‘size’ => 50]);
$author_name = get_the_author_meta(‘display_name’, $author_id);
$author_link = get_author_posts_url($author_id);
?>
<a href=”<?php echo esc_url($author_link); ?>” class=”concours-author-link”>
<img src=”<?php echo esc_url($author_avatar); ?>”
alt=”<?php echo esc_attr($author_name); ?>”
class=”concours-author-avatar”>
<span class=”concours-author-name”><?php echo esc_html($author_name); ?></span>
</a>
<div id=”concours-friendship-<?php echo $post_id; ?>”>
<?php if (is_user_logged_in() && $current_user_id != $author_id && function_exists(‘bp_is_active’)): ?>
<?php if ($friendship_status === ‘friends’): ?>
<button class=”concours-friendship-btn concours-remove”
data-action=”remove_friend”
data-author-id=”<?php echo $author_id; ?>”>
Retirer
</button>
<?php elseif ($friendship_status === ‘pending’): ?>
<span class=”concours-friendship-pending”>Demande envoyĂ©e</span>
<?php else: ?>
<button class=”concours-friendship-btn concours-add”
data-action=”add_friend”
data-author-id=”<?php echo $author_id; ?>”>
Demander en ami
</button>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<!– META INFOS –>
<div class=”concours-meta-infos”>
<?php if ($tags = get_the_terms($post_id, ‘post_tag’)): ?>
<div class=”concours-tags-section”>
#Hashtag(s) :
<?php foreach ($tags as $index => $tag): ?>
<a href=”<?php echo esc_url(get_term_link($tag)); ?>”><?php echo esc_html($tag->name); ?></a>
<?php echo ($index < count($tags) – 1) ? ‘, ‘ : ”; ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (function_exists(‘wc_get_product’) && ‘product’ === get_post_type($post_id)): ?>
<div style=”color: red; font-weight: bold; margin-top: 10px;”>
Produit Ă vendre
</div>
<?php endif; ?>
</div>
<!– AUDIO –>
<?php if (!empty($audios)): ?>
<div class=”concours-audio-player-section”>
<?php foreach ($audios as $audio): ?>
<div style=”background: white; padding: 1rem; border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);”>
<audio controls style=”width:100%; margin:10px 0;”>
<source src=”<?php echo esc_url($audio[‘url’]); ?>” type=”<?php echo esc_attr($audio[‘mime’]); ?>”>
Votre navigateur ne supporte pas la lecture audio.
</audio>
<div style=”text-align: center; color: #666; font-size: 0.9em;”>Audio</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!– ACTIONS TOP –>
<div class=”concours-actions-top”>
<button class=”concours-voir-plus-btn” onclick=”concoursToggleMoreContent(<?php echo $post_id; ?>, event)”>
<span class=”concours-voir-plus-text”>Voir plus</span>
<span class=”concours-voir-moins-text” style=”display:none;”>Voir moins</span>
<span class=”concours-arrow”>âŒ</span>
</button>
<a href=”<?php echo get_permalink($post_id); ?>” class=”concours-view-article-icon” title=”Voir l’article” target=”_bl
Auteurs : pourquoi crĂ©er une newsletter ? âïžâš
Contenu complet
Aujourdâhui, tu es peut-ĂȘtre dĂ©jĂ prĂ©sent·e sur Instagram, Facebook, ou TikTok. Et câest super. Mais si tu veux vraiment construire une relation durable avec tes lecteurs, la newsletter est un outil puissant, personnel et stratĂ©gique.
Voici pourquoi đ
đ Tu crĂ©es un lien direct, sans filtre
Les rĂ©seaux sociaux fonctionnent avec des algorithmes. MĂȘme si tu as 1000 abonnĂ©s, seul un petit pourcentage verra tes publications. Avec une newsletter, tu parles directement Ă tes lecteurs, dans leur boĂźte mail. Pas de filtre, pas de distraction. Juste toi et eux.
đ Tu invites tes lecteurs dans les coulisses de ton univers
Ta newsletter peut devenir un espace intime et authentique oĂč tu partages des morceaux de ton quotidien dâauteur : des extraits de ton prochain livre, des rĂ©flexions sur lâĂ©criture, des anecdotes amusantes ou mĂȘme des Ă©checs. Tu montres lâenvers du dĂ©cor, et ça, tes lecteurs adorent.
đ Tu prĂ©pares tes lancements de livres avec une audience dĂ©jĂ engagĂ©e
Quand vient le moment de sortir un nouveau roman, il est essentiel dâavoir une base de lecteurs prĂȘts Ă te soutenir. Une newsletter bien construite te permet de mobiliser ta communautĂ©, dâannoncer tes sorties, de proposer des prĂ©commandes et de recueillir des premiers avis.
đ Tu peux promouvoir tes livres sans te sentir en train de forcer
Personne nâaime les messages de vente trop insistants. Mais une newsletter te permet de vendre en douceur, en racontant, en partageant, en crĂ©ant du lien. Tu offres de la valeur Ă travers ton contenu, ce qui rend la promotion de tes livres naturelle et bien accueillie.
đĄ En rĂ©sumĂ© : une newsletter, ce nâest pas juste un outil marketing. Câest une conversation privilĂ©giĂ©e entre toi et ceux qui aiment te lire.
â
Alors, dis-moi : est-ce que tu as dĂ©jĂ une newsletter ? Ou est-ce que câest quelque chose que tu aimerais mettre en place prochainement ? Je serais ravie de tâaider Ă te lancer grĂące Ă ma nouvelle prestation ! đ
Sommaire
ToggleVotre newsletter avec Brevo !
Création de site internet pour auteur de livre : WenDev est spécialisée dans la conception de sites web littéraires pour promouvoir vos livres et votre univers.
đEcriture, Mes avancĂ©es – Saga L’Ultime Gardienne T1đ
Contenu complet

L’Ultime Gardienne T1. De l’attirance Ă l’espĂ©rance
“Lorsque le destin d’ĂȘtres exceptionnels se trouve mĂȘler, les graines d’un nouvel espoir pourraient ĂȘtre parsemĂ©es”
Le premier tome de ma Saga est enfin dans une version aboutie. Il nĂ©cessitera une derniĂšre réécriture, mais elle se fera lorsque j’aurai suffisamment avancĂ© dans les tomes suivants. Pour l’instant, 6 volumes sont prĂ©vus.
Trois annĂ©es, c’est le temps que ce premier bĂ©bĂ© m’aura demandĂ©. Oui, c’est mon tout premier abouti đ€. Je me suis lancĂ©e pour la premiĂšre fois dans l’Ă©criture durant l’Ă©tĂ© 2021 avec cette histoire qui me trottait dans la tĂȘte depuis tant d’annĂ©es. J’ai osĂ© franchir le pas et poser les mots pour dĂ©marrer cette superbe aventure qu’est l’Ă©criture đ.
Un Teaser pour dĂ©couvrir le 1er tome qui, je l’espĂšre, saura donnĂ© envie. DĂ©sormais, il est temps de se mettre dans l’Ă©criture du second tome đ.
J’en dĂ©voilerai plus sur l’univers de ma Saga â HĂ©laeryon â dans d’autres publications. Cet univers est trĂšs vaste et peuplĂ© de nombreuses crĂ©ature. Il sera probablement amenĂ© soit Ă Ă©voluer, soit Ă voir peut-ĂȘtre naĂźtre d’autres histoires en plus de cette saga (rien n’est encore dĂ©cidĂ© đ).
A trĂšs vite đ„°
Chargement des vidĂ©os…