xProfile tracker : tracer les modifications des profils dans #BuddyPress

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 commentaires sur “xProfile tracker : tracer les modifications des profils dans #BuddyPress

  1. 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!

Les commentaires sont fermés.