formulaire_.php entre SPIP 4.0.0 et SPIP 4.0.1

Hello

Depuis le passage à la version 4.0.1 de SPIP les formulaires de mon plugin ne marche plus (ils ont un fichier editer_xxx dans le dossier action).
J’ai vu qu’une partie du code de la fonction balise_FORMULAIRE__contexte dans /ecrire/balise/formulaire_.php a été commenté car deprecated (si je décommente ça marche).
Comment je dois modifier mes fichiers editer_xxx dans action pour corriger?
SPIP 4.0.1 sous PHP 7.4.26

Merci

Il y a peut-être une piste par ici https://git.spip.net/spip/mots/commit/1de659209271b26b38be185bb8957ecab5a74eed

Merci b_b

Si j’ai bien compris on remplace le fichier editer_xxx dans action par la fonction générique formulaires_editer_objet_traiter, c’est ça?
Mon erreur ressemble à menu_edit : Accès interdit. - #3 par Gaston, sauf que toutes les modifications apportées à action/editer_menus_entree.php dans https://git.spip.net/spip-contrib-extensions/menus/commit/8e0420d43697a3ebd6637271a5f15a23db1cfce0
sont bien dans mon code à moi:

<?php
/**
 *  Ce fichier gere la creation et la modification dans la base des points de situation twitter
 *
 *  @author George Kandalaft
 *  @author Claude Hillion
 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 *  fonction chargee en cas de demande de creation d'un point de situation twitter via l'interface utilisateur.
 *  Elle appelle la fonction pst_inserer.
 */
function action_editer_pst_dist($arg = null) {
	if (is_null($arg)) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$arg = $securiser_action();
	}

	// Si pas de id_pst ? on cree un nouveau point de situation, mais seulement si 'oui' en argument.
	if (!$id_pst = intval($arg)) {
		if ($arg != 'oui') {
			include_spip('inc/headers');
			redirige_url_ecrire();
		}
		$id_pst = pst_inserer();
	}

	return array($id_pst, $err);
}

/**
 *  permet de creer dans la table spip_psts un nouveau pst
 */
function pst_inserer($set = null) {
	$champs = is_array($set) ? $set : array();

	// Envoyer aux plugins
	$champs = pipeline('pre_insertion', array(
		'args' => array(
			'table' => 'spip_psts',
		),
		'data' => $champs
	));

	$id_pst = sql_insertq('spip_psts', $champs);

	pipeline(
		'post_insertion',
		array(
			'args' => array(
				'table' => 'spip_psts',
				'id_objet' => $id_pst
			),
			'data' => $champs
		)
	);

	return $id_pst;
}

Bien vu pour la piste que tu cites. As-tu activé les logs verbeux, si jamais ça vient de la nouvelle protection des formulaires par un jeton, tu auras des infos dans formulaires.log.

En effet, j’ai ceci dans le log:
Pri:ERREUR: signature ajax form incorrecte : editer_pst (formulaire non signe mais on a une session)

Je déplace le fil dans la catégorie dev, ça me semble plus approprié :wink:

Quand tu dis « les formulaires de mon plugin ne marche plus » quel est le message d’erreur exact que tu as ?
Si c’est le bug de l’action pas signée on est redirigé vers minipres avec « action interdite ».
Si c’est un défaut de signature on a un message du genre « impossible de prendre en compte votre saisie, ressayez ».

C’est ça ecrire/public/aiguiller.php:202:
spip_log("signature ajax form incorrecte : $form (formulaire non signe mais on a une session)", 'formulaires' . _LOG_ERREUR);

Hello Cedric

Le message est « Oups. Une erreur inattendue a empêché de soumettre le formulaire. Vous pouvez essayer à nouveau. » quand je clique sur enregistrer.
Evidemment quand je décommente le block à la ligne 273 de formulaire_.php, ça marche.

« oups une erreur innatendue » ça c’est quand le formulaire est posté en ajax et que la réponse a un status qui n’est pas 200. Du coup il faut « essayer à nouveau » comme te propose le message : le formulaire sera posté sans ajax et tu verras si tu arrive sur la minipres ou si c’est une autre erreur (ça pourrait aussi être une fatale…)

Quand j’essaye à nouveau j’ai un accès interdit sans rien dans les logs.

donc en effet il y a un truc que tu fais pas bien dans le traiter() de ton formulaire et tu arrives dans action_editer_pst() avec un arg null, du coup ça bloque ici (Je peux pas en dire plus sans voir le code)

Je peux insérer le script /formulaires/editer_pst ici?

Oui, tu peux le coller dans un bloc de code :slight_smile:

voilà:

<?php
/**
 *  Gestion du formulaire de creation des points de situation twitter
 *
 *  Ce fichier definit les fonctions permettant de gerer le traitement du formulaire d'edition d'un point de situation twitter .
 *  Cela inclut la verification des donnees, la gestion des erreurs, l'envoie des notifications au colonel de permanence...
 *
 *  @author George Kandalaft
 *  @author Taoufik Messaoud
 *
 */
if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

include_spip('inc/actions');
include_spip('inc/editer');



define(_REG_CHARS, 'a-z0-9\pN\pL\pM\'‘’°\&\+–\_•·⋅');
define(_REG_HASH, '(\#[' . _REG_CHARS . '\@\.\/-]*[' . _REG_CHARS . '])');
/**
 *  Modifie un point de situation Twitter par formulaire
 *
 *  @param int|string $id_pst
 *  @param int $id_evenement
 *  @param string $retour
 *  @return array
 *      contenu du formulaire de modification
 *
 */
function formulaires_editer_pst_charger_dist($id_pst = 'new', $id_evenement = 0, $retour = '') {
	$valeurs = formulaires_editer_objet_charger('pst', $id_pst, 'id_evenement', 0, $retour, '');
	if (!$valeurs['id_evenement']) {
		$valeurs['id_evenement'] = $id_evenement;
	}
	return $valeurs;
}

/**
 *  Vérifie les valeurs du formulaire de modification d'un point de situation evenement
 *
 *  @param int|string $id_pst
 *  @param int $id_evenement
 *  @param string $retour
 *  @return array
 *      erreurs contenues dans le formulaire
 *
 */
function formulaires_editer_pst_verifier_dist($id_pst = 'new', $id_evenement = 0, $retour = '') {
	$erreurs = formulaires_editer_objet_verifier('pst', $id_pst, array('texte'));
	if (count($erreurs) && $erreurs['texte']) {
		$erreurs['message_erreur'] = _T('incident:clavier_casse');
	}
	return $erreurs;
}

/**
 *  Traitement du point de situation twitter
 *
 *  Recupération des erreurs,
 *  envoies notifications par mail...
 *
 *  @param int|string $id_pst
 *  @param int $id_evenement
 *  @param string $retour
 *  @return array
 *      l'ensemble des message post traitement: erreurs, redirection, comportement correct
 *
 */
function formulaires_editer_pst_traiter_dist($id_pst = 'new', $id_evenement = 0, $retour = '') {
	$res = array();
	$action_editer = charger_fonction('editer_pst', 'action');
	list($id, $err) = $action_editer();

	$texte =  _request('texte');

	$mediaToUpload = array();

	$tab = explode('<img', $texte);
	if ($tab[1] != '') {
		$tab2 = explode('|', $tab[1]);
		$tab3 = explode('>', $tab[1]);
		//on enleve l'image du texte
		$texte = $tab[0].$tab3[1];

		$idImage = $tab2[0];
		$champs = array('fichier');
		$where = array(
			"id_document = $idImage"
		);

		$req = sql_select($champs, 'spip_documents', $where);
		while ($r = sql_fetch($req)) {
			$image = $r['fichier'];
		}

		$mediaToUpload[] = '/home/www/html/IMG/'.$image;
	}

	$str = _request('titre'). PHP_EOL;
	$str .= $texte. PHP_EOL;

	/* make request to Twitter API */
	$payLoad = postTweetUpdate($str, $mediaToUpload);


	if ($err || isset($payLoad->errors)) {
		if ($err) {
			$res['message_erreur'] = $err;
		} else {
			$res['message_erreur'] = $payLoad -> errors -> message;
		}
	} else {
		$res['message_ok'] = _L('ok');
		//Envoi de notifications
		$envoyer_mail = charger_fonction('envoyer_mail', 'inc');
		$email_from = $GLOBALS['meta']['email_envoi'];
		$cta = 'cpdrens@sdis91.fr';
		//$emails[] =$cta;
		//envoyer notification au colons de permanence
		$mailcol = sql_allfetsel('email', 'spip_auteurs', 'profil = ' . sql_quote('p2') . 'and bio = ""');
		$mailto = array();
		foreach ($mailcol as $mail) {
			if ($mail['email']) {
				$mailto[] = $mail['email'];
			}
		}
		$mailto[] = 'gkandalaft@sdis91.fr';
		$mailto = implode(',', $mailto);
		spip_log("Alerte Twitter mailcol $mailto", 'alerte_colonel');
		// si des OSC sont choisis, les mettre en cc sinon cc seulement le cta-codis
		if (_request('copie')) {
			$emails = _request('copie');
			foreach ($emails as $email) {
			spip_log("Alerte Twitter emails copie $email", 'alerte_colonel');
			}
		}
		$dateo = date('d-m-Y H:i:s');
		$sujet = _T('pst:alerte_osc');
		$texte = $dateo . ' : ';
		$texte .= _request('texte');
		$corps = array(
			'html' => $texte,
			'cc' => ($emails ? $emails : ''),
			'nom_envoyeur' => $email_from
		);
		$envoyer_mail($mailto, $sujet, $corps);
		spip_log("Alerte Twitter envoyée a $mailto", 'alerte_colonel');
		if ($retour) {
			$res['redirect'] = $retour;
			spip_log("Alerte Twitter retour $retour", 'alerte_colonel');
		}
	}
	return $res;
}

Ah ben oui c’est la ligne

list($id, $err) = $action_editer();

qui marche pas.
Il faut mettre

list($id, $err) = $action_editer($id_pst);

pour retrouver un fonctionnement à l’identique d’avant

Bon sang mais c’est bien sur :slightly_smiling_face:
Merci ça marche!