Ajouter un onglet « Parrainage » et des champs de commission aux produits WooCommerce

Notre base SQL est créée : découvrons maintenant comment afficher et enregistrer des champs propres aux commissions dans le back-office des produits WooCommerce.

Si vous avez manqué le début de cette série de tutoriels, rendez-vous dans la première partie d’introduction pour en savoir plus 😉 Sachez aussi que ce plugin est téléchargeable gratuitement et  que vous pouvez découvrir son code sur GitHub.

Si j’apprécie l’extension e-commerce WooCommerce, c’est bien pour sa flexibilité : ce plugin est truffé de hooks (actions/filtres) qui nous permettent, grâce à du code PHP, de venir :

  1. modifier les valeurs de variables utilisées par WooCommerce (via des filtres)
  2. exécuter du code additionnel durant l’exécution du code natif de WooCommerce (via des actions)

C’est le cœur du sujet de cette seconde partie de tutoriel : nous allons d’abord utiliser un filtre pour ajouter un onglet dans la metabox « Données produits » du back-office des produits WooCommerce. Puis nous utiliserons une action pour générer le contenu de ce nouvel onglet.

Comment ajouter un onglet et des champs dans la metabox des produits Woocommerce ?

Notre objectif va être de personnaliser la metabox « Données produits » de WooCommerce pour avoir quelque chose comme cela :

Un nouvel onglet et de nouveaux champs pour les produits WooCommerce
Un nouvel onglet et de nouveaux champs pour les produits WooCommerce

Ces données seront pré-remplies dynamiquement dans la base après la soumission du formulaire de proposition d’un produit par un utilisateur (partie 3 de ce tutoriel). Mais le taux de commission ou la période de validité d’attribution d’une récompense sont des champs que seul l’administrateur de la boutique e-commerce pourra modifier.

Ajouter un onglet « Parrainage »

Ici, c’est le filtre woocommerce_product_data_tabs qui nous permet de modifier le tableau (array) $tabs.

<?php

/**
 * On ajoute un onglet "Parrainage" dans le back-office d'un produit WooCommerce
 */
function msk_add_commission_product_tab($tabs) {
	$tabs = array_insert_after('general', $tabs, 'commission', array(
		'label' => __('Parrainage', 'mosaika'),
		'target' => 'commission_product_data',
		'class' => array()
	));

	return $tabs;
}
add_filter('woocommerce_product_data_tabs', 'msk_add_commission_product_tab');

Ce tableau contient les détails de chaque onglet : son nom (label), l’ID de la div à afficher quand on clique sur l’onglet (target) et des classes CSS à ajouter à l’onglet (class).

Afficher des nouveaux champs dans la metabox produit

Maintenant, c’est l’action woocommerce_product_data_panels que nous utilisons : elle est déclenchée lors de la génération de la metabox « Données produits ». On en profite pour ajouter une div contenant les champs relatifs à nos données de commissions.

<?php

/**
 * On ajoute les champs spécifiques aux commissions/prescripteur
 */
function msk_add_commission_product_fields() { 
	global $post;
	$commission_user_id = get_post_meta($post->ID, 'commission_user_id', true); ?>

	<div id="commission_product_data" class="panel woocommerce_options_panel">
		<h4 style="padding-left:12px;"><?php _e('Parrainage et commission', 'mosaika'); ?></h4>

		<?php woocommerce_wp_text_input(
			array(
				'id' => 'commission_user_id',
				'label' => __('Identifiant utilisateur', 'mosaika'),
				'placeholder' => __('Sélectionnez l\'ID du parrain', 'mosaika'),
			)
		);

		// On affiche sous le champ le login et l'e-mail de l'utilisateur relié à l'ID défini dans le champ ci-dessus
		if (isset($commission_user_id) && $commission_user_id != '') {
			$commission_user_data = get_userdata((int)$commission_user_id);
			printf(
				'<p style="padding-left:12px;font-style:italic;margin-top: -14px;">' . __('Cet identifiant correspond à l\'utilisateur %1$s ayant l\'e-mail %2$s.', 'mosaika') . '</p>',
				'<strong>' . $commission_user_data->user_login . '</strong>',
				'<strong>' . $commission_user_data->user_email . '</strong>'
			);
		}

		woocommerce_wp_text_input(
			array(
				'id' => 'commission_rate',
				'label' => __('Commission (en %)', 'mosaika'),
				'placeholder' => __('5', 'mosaika'),
				'description' => __('Informez le pourcentage de commission qui sera calculé à partir du montant HT d\'une commande et reversé au parrain.', 'mosaika'),
				'desc_tip' => true,
				'class' => 'wc_input_price'
			)
		);

		woocommerce_wp_text_input(
			array(
				'id' => 'commission_date_start',
				'label' => __('Début de récompense', 'mosaika'),
				'placeholder' => __('01/01/2016', 'mosaika'),
				'description' => __('Indiquez ici la date de DÉBUT de période à partir de laquelle une commission sera reversée à l\'utilisateur parrain.', 'mosaika'),
				'desc_tip' => true,
				'class' => 'short input-date'
			)
		);

		woocommerce_wp_text_input(
			array(
				'id' => 'commission_date_end',
				'label' => __('Fin de récompense', 'mosaika'),
				'placeholder' => __('31/12/2016', 'mosaika'),
				'description' => __('Indiquez ici la date de FIN de période à partir de laquelle le parrainage ne sera plus effectif.', 'mosaika'),
				'desc_tip' => true,
				'class' => 'short input-date'
			)
		); ?>
	</div>

	<style>#woocommerce-product-data ul.wc-tabs li.commission_options a::before, .woocommerce ul.wc-tabs li.commission_options a::before { content: '\f155'; }</style>
	
	<?php
}
add_action('woocommerce_product_data_panels', 'msk_add_commission_product_fields');

Nous avions déjà abordé en détails, dans un tutoriel précédent, l’ajout de champs meta aux produits WooCommerce. Pour approfondir cette notion, n’hésitez pas à découvrir cet autre article contenant toutes les fonctions WooCommerce à disposition pour ajouter toute sorte de champs.

Vous verrez en fin de fonction une ligne de <style> CSS : elle nous permet de remplacer l’icône de l’onglet « Parrainage » définie précédemment, par une icône Dashicons adaptée (ici, une étoile).

Sauvegarder les données meta de ces nouveaux champs

Nos champs sont affichés : il suffit désormais de sauvegarder leur valeur dans la base de données lorsque le produit est enregistré.

<?php

/**
 * On enregistre les valeurs des champs lorsque le produit est enregistré
 */
function msk_save_commission_product_fields_data($product_id, $post, $update) {
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

	if ($post->post_type == 'product') {
		$product = wc_get_product($product_id);

		if (isset($_POST['commission_user_id'])) {
			$commission_user_id = wc_clean($_POST['commission_user_id']);
			$product->update_meta_data('commission_user_id', $commission_user_id);
		}

		if (isset($_POST['commission_rate'])) {
			$commission_rate = floatval($_POST['commission_rate']);
			$product->update_meta_data('commission_rate', $commission_rate);
		}

		if (isset($_POST['commission_date_start'])) {
			$commission_date_start = wc_clean($_POST['commission_date_start']);
			$product->update_meta_data('commission_date_start', $commission_date_start);
		}

		if (isset($_POST['commission_date_end'])) {
			$commission_date_end = wc_clean($_POST['commission_date_end']);
			$product->update_meta_data('commission_date_end', $commission_date_end);
		}

		$product->save();
	}
}
add_action('save_post', 'msk_save_commission_product_fields_data', 10, 3);

Pour chaque champ qui nous concerne, on vérifie si sa valeur est définie dans la variable $_POST. Si elle existe, on l’assigne au produit enregistré avec la méthode ->update_meta_data() qui enregistrera cette valeur comme métadonnée du produit.

Un petit mot sur l’accès et la modification des données WooCommerce depuis la version 3.0

Depuis sa version 3.0 (celle juste après la 2.6), WooCommerce conseille d’utiliser la méthode CRUD pour lire ou modifier les propriétés des objets WooCommerce (produits, commandes, panier, etc.). Il est donc déconseillé d’utiliser nos habituels update_post_meta($product_id, 'clef_meta', 'valeur_de_la_meta')pour modifier des propriétés d’un produit par exemple.

Désormais, la logique est abstraitisée :

  1. on va chercher l’objet que l’on souhaite, par exemple :
    1. $order = wc_get_order(12); pour récupérer la commande d’ID 12
    2. $product = wc_get_product(43); pour récupérer le produit d’ID 43
    3. $cart = WC()->cart; pour récupérer le panier du client
  2. on récupère (->get_…) ou modifie (->set_…) des propriétés, par exemple :
    1. $order->get_billing_first_name() pour récupérer le prénom défini dans l’adresse de facturation de la commande
    2. $product->set_description(...) pour définir la description du produit
    3. $cart->get_taxes_total() pour récupérer le montant total des taxes du panier
  3. on enregistre avec la méthode ->save(), par exemple :
    1. $order->save(); pour enregistrer des modifications faites sur une commande
    2. $product->save(); pour enregistrer des modifications faites sur un produit

Ainsi, plus besoin de savoir « les coulisses » de WooCommerce (quel est le nom du type de contenu d’un produit ? où est enregistré le prix du produit dans la base de données ?) : notre code exprime plus clairement nos intentions, et c’est WooCommerce qui s’occupe d’enregistrer les données où bon lui semble.

Cela permettra probablement, dans un futur proche, de sortir de la structure de base de données WordPress (les entités dans wp_posts et les metadonnées dans wp_postmeta) afin d’avoir des tables SQL spécifiques à WooCommerce et améliorer la performance générale et l’organisation des données de cette extension.


Maintenant que nous avons une base SQL sur-mesure et un back-office des produits WooCommerce prêt à accueillir les données relatives à nos futures commissions, créons un shortcode pour permettre aux utilisateurs de proposer un produit à la vente dans notre boutique e-commerce WordPress.

2 commentaires

Bonjour,

Sauf erreur de ma part
la fonction « array_insert_after », n’existe pas dans votre tuto, j’ai pu la retrouver dans le fichier utils.php, dans votre plugin que j’ai téléchargé, mais je suis étonné de ne voir aucun autre commentaire mentionnant cette absence.
Enfin c’est pas grave et ça m’a fait réfléchir 😉
merci pour ce super tuto, que je vais essayer de convertir pour faire un plugin de petites annonces.
ERic

Bonjour Eric,

Ha oui en effet, erreur de ma part de ne pas avoir indiquer cela. Merci du partage !
En effet, le tutoriel considère que tout le plugin est téléchargé/installé et donc que utils.php est chargé pour profiter de quelques fonctions 🙂

Bon courage et encore merci !

Laisser un commentaire