Suite ecommerce SPIP : surcharger #FORMULAIRE_INSCRIPTION via le pipeline _formulaire_traiter

Bonjour,

Suite à mon précédent sujet « Suite ecommerce SPIP : auteurs & visiteurs dans un bateau », je m’attaque à la problématique de la surcharge du #FORMULAIRE_INSCRIPTION afin de pouvoir collecter des informations d’entreprise liées à l’auteur et les enregistrer en base sur la table spip_auteurs.

Note : je sais qu’il existe un bon nombre d’excellents plugins (Profils, Contacts & Organisations…) qui pourraient couvrir ce besoin, mais je cherche avant tout à comprendre et expérimenter.

J’ai créé un petit plugin « marketplace » qui :

1) déclare de nouveaux champs sur spip_auteurs via le fichier base/marketplace.php :

function marketplace_declarer_tables_principales($tables_principales) {
	
	# Déclarer les nouveaux champs sur les auteurs
	$tables_principales['spip_auteurs']['field']['entreprise_nom'] = "VARCHAR(150)";
	$tables_principales['spip_auteurs']['field']['entreprise_siren'] = "VARCHAR(14)";
	$tables_principales['spip_auteurs']['field']['entreprise_adresse'] = "VARCHAR(200)";
	$tables_principales['spip_auteurs']['field']['entreprise_code_postal'] = "VARCHAR(5)";
	$tables_principales['spip_auteurs']['field']['entreprise_ville'] = "VARCHAR(150)";
	$tables_principales['spip_auteurs']['field']['entreprise_tva'] = "VARCHAR(13)";
		
	return $tables_principales;
	
}

2) les charge au démarrage du formulaire et ajoute les saisies idoines via marketplace_pipelines.php :

# Charge les champs entreprise au démarrage du formulaire d'inscription
function marketplace_formulaire_charger($flux) {

	if ($flux['args']['form'] == 'inscription' and $flux['data'] !== false) {
		$flux['data']['entreprise_nom'] = '';
		$flux['data']['entreprise_siren'] = '';
		$flux['data']['entreprise_adresse'] = '';
		$flux['data']['entreprise_code_postal'] = '';
		$flux['data']['entreprise_ville'] = '';
		$flux['data']['entreprise_tva'] = '';
	}

	return $flux;
}
# Ajoute le HTML des champs entreprise durant l'inscription
function marketplace_formulaire_fond($flux) {
	
	if ($flux['args']['form'] == 'inscription') {
		
		$champs_entreprise = recuperer_fond('formulaires/inc/inscription_entreprise', $flux['args']['contexte']);

		$chercher = '%<(li|div)[^>]*(saisie|editer)_mail_inscription[^>]*>.*?</\1>%is';

		$flux['data'] = preg_replace(
			$chercher,
			"$0$champs_entreprise",
			$flux['data']
		);
	}

	return $flux;
}

Tout cela fonctionne correctement : mes nouveaux champs sont déclarés en base sur spip_auteurs et apparaissent bien là où je le souhaite dans le #FORMULAIRE_INSCRIPTION.

3) Maintenant je souhaite insérer en base ces données dans la table spip_auteurs :

Là où plus rien ne va c’est dans le traitement de ces données… J’essaye de m’insérer via le pipeline _formulaire_traiter (toujours via marketplace_pipelines.php) mais sans succès.

# Ajouter en base les champs supplémentaire entreprise à l'inscription d'un auteur
function marketplace_formulaire_traiter($flux){
	
	if (
		$flux['args']['form'] == 'inscription'
		and $id_auteur = intval($flux['data']['id_auteur'])
		and $auteur = sql_fetsel('*', 'spip_auteurs', 'id_auteur = '.$id_auteur)
	){
	
		$valeurs = array(
			'entreprise_nom' => _request('entreprise_nom'),
			'entreprise_ville' => "test",
			'entreprise_siren' => $flux['data']['entreprise_siren'],
		);
		
		sql_updateq('spip_auteurs', $valeurs, 'id_auteur=' . intval($id_auteur));		
		
	}
	
	return $flux;
}

J’essaye plein de choses : récupérer les valeurs soumises via _request() ou encore $flux[‹ data ›] mais aussi en ajoutant une valeur fixe « test ».

Mais sql_updateq ne donne rien, pas d’enregistrement en base. Et rien dans mes logs qui pourrait m’aider à avancer :frowning:

J’utilise dans mon petit ecosystème les plugins inscriptionmotdepasse & inscriptionconnexion dont je me suis largement inspiré car ils utilisent les mêmes pipelines pour surcharger le fonctionnement de #FORMULAIRE_INSCRIPTION.

J’en viens à me demander si il y a un ordre d’exécution particulier des pipelines _formulaire_traiter qui pourrait parasiter mon traitement ou bien je m’y prend comme un manche :wink:

Dans la logique des choses, il me semble qu’il faudrait que inscriptionmotdepasse & inscriptionconnexion appliquent leurs traitements (création et autologin de l’auteur) puis que je puisse venir m’insérer : je récupère l’id_auteur et j’ajoute les champs.

La logique est-elle bonne ? Comment la mettre en oeuvre ? Voyez-vous d’où pourrait venir mon problème ?

Merci aux courageux qui ont pris le temps de lire tout cela !

Perso je fais ce genre de chose en utilisant le pipeline pre_edition ce qui permet de prendre en charge l’inscription et la mise à jour lors de l’édition de l’objet.

Merci @b_b pour cette très intéressante piste.

Je suis en train de tester un truc du genre :

function marketplace_pre_edition($flux){
		
	if (
		is_array($flux)
		and $flux['args']['form'] == 'inscription'
		and $id_auteur = intval($flux['data']['id_auteur'])
		and $auteur = sql_fetsel('*', 'spip_auteurs', 'id_auteur = '.$id_auteur)
	){
			
		$valeurs = array(
			'entreprise_nom' => $flux['data']['entreprise_nom'],
			'entreprise_ville' => "test",
			'entreprise_siren' => $flux['data']['entreprise_siren'],
		);
		
		sql_updateq('spip_auteurs', $valeurs, 'id_auteur=' . intval($id_auteur));		
		
	}
	
	return $flux;
}

Je vais vite voir si il se passe quelque chose, mais comme je comprend les choses, il faudrait que je puisse faire tous les traitement en même temps dans pre_edition (ceux de inscriptionmotdepasse, mes enregistrement en base) puis enchaîner avec inscriptionconnexion.

Allez, je teste, on va bien voir :wink:

Ce code ne fonctionnera pas, il n’y a pas de args/form dans l’env de ce pipeline cf pre_edition - Programmer avec SPIP 4

Le 18/10/2023 à 10:36, Pierre-Jean via Discuter de SPIP a écrit :

Note : je sais qu’il existe un bon nombre d’excellents plugins (Profils, Contacts & Organisations…) qui pourraient couvrir ce besoin, mais je cherche avant tout à comprendre et expérimenter.

Vu que tu sais qu’il existe ces plugins, je t’invite à t’inspirer du plugin Profils, puisque c’est lui qui s’occupe d’ajouter et traiter à la fois les cas de l’inscription, et de l’édition après coup.

Par ailleurs, Mot de passe à l’inscription ET Connexion à l’inscription, déclare « utiliser » Profils (puisque c’est un plugin générique commun), ce qui permet de s’assurer qu’ils passent toujours après dans les pipelines et paths :

Avec un plugin perso, tu auras un peu plus de mal à obtenir ce comportement par contre…


RastaPopoulos

hummmm, ça y est je crois comprendre :

  1. comme c’est de la pre_edition, le contexte disponible dans ce pipeline ne concernera principalement que l’objet/id_objet que l’on s’apprête à éditer.

  2. par contre j’imagine que mes champs supplémentaires sont toujours disponibles via _request()

Je vais tenter, mais ça me semble pas très propre dans le sens où si ma compréhension est bonne, à chaque modification d’un auteur, je vais déclencher ce pipeline et checker si j’ai des champs qui m’intéressent dans le _request. Donc des appels inutiles à tout bout de champ, même lorsque j’associe un auteur à un article, qu’un auteur modifie sa bio…

J’imagine que je peux enrober ça d’un if qui checkerait le contexte (par exemple cibler uniquement une pre_edition sur les auteurs réalisées depuis ma page inscription ou bien un cas de CREATE SQL…), mais je ne vois pas comment/où printer $flux pour voir à quoi j’ai accès ou pas étant donné que je dois afficher ces informations avant d’être redirigé.

Je voudrais utiliser ça, sans savoir où le mettre…
$flux['data'] .= print("<pre>".print_r($flux['args'],true)."</pre>");

Magnifique @rastapopoulos, en une phrase tu as résolu mon problème avec l’idée de @b_b pour le _pre_edition

J’ai compris l’usage de la balise utilise dans le paquet.xml (j’utilisais bêtement nécessite…)

Le pipeline _pre_edition s’est mis à fonctionner ! Il me reste maintenant à comprendre comment le limiter aux créations d’auteurs pour ne pas l’activer à tout bout de champ sur les update d’auteurs…

Merci beaucoup !

En fait, c’est encore plus intéressant que ça, je viens de me rendre compte que à la fois le pipeline _formulaire_traiter & le pipeline _pre_edition ont fonctionné de concert.

Je poste ici pour les curieux qui pourraient avoir ce besoin :

# Ajouter en base les champs supplémentaire entreprise à l'inscription d'un auteur
function marketplace_formulaire_traiter($flux){
	
	if (
		$flux['args']['form'] == 'inscription'
		and $id_auteur = intval($flux['data']['id_auteur'])
		and $auteur = sql_fetsel('*', 'spip_auteurs', 'id_auteur = '.$id_auteur)
	){
		
		spip_log("passage dans le if", "market");
	
		$valeurs = array(
			'entreprise_nom' => "nom",
			'entreprise_ville' => "ville",
			'entreprise_siren' => "123456",
		);
		
		sql_updateq('spip_auteurs', $valeurs, 'id_auteur=' . intval($id_auteur));		
		
	}
	
	return $flux;
}


// # Ajouter en base les champs supplémentaire entreprise à l'inscription d'un auteur
function marketplace_pre_edition($flux){
	
	$table = $flux['args']['table'];
	$id_objet = (int) ($flux['args']['id_objet']);
		
	if ($table == "spip_auteurs" and $id_objet){
			
		$valeurs = array(
			'entreprise_ville' => "test",
			// cela surcharge le champ définit dans _formulaire_traiter car post_edition passe après 
		);
		
		sql_updateq('spip_auteurs', $valeurs, 'id_auteur=' . intval($id_objet));		
		
	}
	
	return $flux;
}