xProfile tracker : tracer les modifications des profils dans #BuddyPress

Publié le

par

Crédits Photo Foot print de rla579, sur Flickr

Dernièrement on m’a demandé :

Quand on change son avatar dans BuddyPress, une activité est générée pour en informer les autres membres… Sais-tu comment faire pour réaliser la même chose en cas d’une mise à jour d’un champ xprofile ?

Je me suis dit : « ça doit pas être bien compliqué.. on intercepte le bon hook et hop bp_activity_add( $args ) fera le reste 😉

Sauf que lorsque j’ai regardé cette affaire de plus prêt, je me suis aperçu que c’était légèrement plus compliqué. Comment sait-on qu’un champ a été mis à jour ? La réponse est assez évidente : quand la valeur précédente n’est pas égale à la nouvelle valeur. Le truc c’est que lorsque BuddyPress mets à jour les champs xprofile, il ne s’embarasse pas de savoir quelle était la valeur précédente d’un champ ! Il met à jour et tous les champs, même ceux qui n’ont pas changé et puis voilà.

J’ai donc mis au point une petite astuce basée sur l’utilisation de deux variables globales pour pouvoir répondre à ce besoin. Un premier tableau récupère la liste des valeurs avant mise à jour et un deuxième la compare avec les valeurs mises à jour d’un deuxième tableau.

Détail de l’astuce :

Voici comment je récupère ces 2 tableaux. Vous remarquerez que pour $before_profile_update, je ne le rempli pas de $object->value. En fait les données contenues par cet objet sont les champs postés donc les valeurs qui mettront à jour les xprofiles !! A la place et parce que la requête d’update n’est pas encore entrée en action à ce moment de la partie, je me sers de la fonction xprofile_get_field_data pour remplir mon tableau des valeurs avant mise à jour.

function imath_profile_tracker_before_save( $object ) {
	/* adding a global to store before update values */
	global $bp, $before_profile_update;

	/**
	 * As BP_XProfile_ProfileData gets posted value, we need to use
	 * xprofile_get_field_data instead of $object->value
	 */
	
	$before_profile_update[] = array(
		'field_id' => $object->field_id,
		'field_value' => xprofile_get_field_data( $object->field_id, $object->user_id )
	);
}
add_action( 'xprofile_data_before_save', 'imath_profile_tracker_before_save', 9, 1 );

function imath_profile_tracker_after_save( $object ) {
	/* adding a global to store after update values */

	global $bp, $after_profile_update;

	// as BP_XProfile_ProfileData updated values, we can use $object->value
	$after_profile_update[] = array(
		'field_id' => $object->field_id,
		'field_value' => $object->value
	);
}
add_action( 'xprofile_data_after_save', 'imath_profile_tracker_after_save', 10, 1 );

Ensuite, j’intercepte un dernier hook – xprofile_updated_profile – de BuddyPress afin de comparer les valeurs une à une en bouclant sur le premier tableau. Si les valeurs diffèrent : il y a eu mise à jour et donc je stocke les noms de champ dans un dernier tableau. Avant de faire appel à bp_activity_add( $args ), je vérifie la longueur de ce tableau des champs mis à jour pour enregistrer que tel champ à été mis à jour ou que plusieurs champs ont été mis à jour. Dans ce dernier cas, l’activité consistera à dire « le profil a été mis à jour ». On aurait pu s’amuser à faire un implode du tableau mais dans le cas de nombreux champs « updatés », l’activité n’aurait plus ressemblé à rien…

Je ne détaille pas la fonction qui se charge de faire cette comparaison, vous la retrouverez dans le plugin de démo que j’ai conçu pour l’occase 😉

Le plugin en images !

A gauche le form d’edit et à droite les activités générées

NB : Dans l’illustration ci-dessus, j’ai d’abord mis à jour le champ « Sports », puis le champ « Do you like BuddyPress » (< la réponse est forcément positive 😉 ). Si j’avais mis à jour les 2 champs simultanément, j’aurais eu une seule activité d’actualisation de profil.

Sauf qu’en l’état, je me suis dit « et si le membre ne souhaite pas que ses changements de profil ne génèrent des activités.. il doit pouvoir disposer d’une option pour les neutraliser.

Un checkbox pour neutraliser le xprofile tracker !

Et là dang! Un des hooks dont je me suis servi sous BP 1.5 n’existe pas dans les précédentes versions !! Ce qui explique qu’à droite, j’ai très simplement pu ajouter une case à cocher juste en dessous du changement de mot de passe et qu’à gauche j’ai dû improviser un nouvel espace dépendant des settings utilisateurs.

PS : je ne dépose pas ce plugin dans le WP repository dans la mesure où je ne suis pas certain de son intérêt (et que j’ai légèrement été refroidi par le bide de mon précédent post ! 🙁 )…

4 réponses à “xProfile tracker : tracer les modifications des profils dans #BuddyPress”

  1. Avatar de Pierre-Alex
    Pierre-Alex

    Au top! tout fonctionne parfaitement 😉
    Merci

    1. Avatar de imath

      Merci pour ton commentaire 😉

  2. Avatar de Roger
    Roger

    Hi imath. Very nice tutorial, I learned a lot. I wanted to experiment a little with adding actions after a field is filled in. How would I go about writing a conditional for this? For example:

    if ( this_field_was_updated ) {
    do_this;
    }

    I tried:

    if ( $after_profile_update[0][‘field_id’] = ‘2’ ) {
    do_this;
    }
    if ( $after_profile_update[0][‘field_id’] = ‘3’ ) {
    do_that;
    }

    This does work, but it doesn’t honor the if conditional and does both, regardless. When changing to an if/else statement, it works but if both fields are updated at the same time, it only listens to the first part of the conditional. It’s probably something simple, but I’m a little confused. If you know how to accomplish this, any help would be appreciated. Thanks!

  3. Avatar de imath

    Hi Roger,

    I think your if statement will be always true.. You should try

    if( $a==1 )