function verifier_generer_aide(){
	// On a déjà la liste par saisie
	$verifications = verifier_lister_disponibles();
	
	// On construit une liste par options
	$options = array();
	foreach ($verifications as $type_verif=>$verification){
		$options_verification = saisies_lister_par_nom($verification['options'], false);
		foreach ($options_verification as $nom=>$option){
			// Si l'option n'existe pas encore
			if (!isset($options[$nom])){
				$options[$nom] = _T_ou_typo($option['options']);
			}
			// On ajoute toujours par qui c'est utilisé
			$options[$nom]['utilisee_par'][] = $type_verif;
		}
		ksort($options_verification);
		$verifications[$type_verif]['options'] = $options_verification;
	}
	ksort($options);
	
	return array(
		'verifications' => $verifications,
		'options' => $options
	);
}
示例#2
0
/**
 * Compter les saisies extras d'une table
 *
 * @param String $table Table sql
 * @return Int Nombre d'éléments.
**/
function compter_champs_extras($table)
{
    static $tables = array();
    if (!count($tables)) {
        include_spip('inc/saisies');
        $saisies_tables = iextras_champs_extras_definis();
        foreach ($saisies_tables as $t => $s) {
            if ($s = saisies_lister_par_nom($s)) {
                $tables[$t] = count($s);
            }
        }
    }
    if (isset($tables[$table])) {
        return $tables[$table];
    }
}
示例#3
0
/**
 * Retourne un champ extra d'un objet
 *
 * @param string $objet
 * @param string $champ
**/
function iextras_exporter_objet_champ($objet, $champ) {
	include_spip('inc/iextras');
	$champs = array();
	$table = table_objet_sql($objet);
	if ($liste = iextras_champs_extras_definis($table)) {
		include_spip('inc/saisies');
		$liste = saisies_lister_par_nom($liste);
		if (!empty($liste[$champ])) {
			$champs[$table] = array();
			$champs[$table][] = $liste[$champ];
		}
	}
	return $champs;
}
示例#4
0
/**
 * Ajouter les saisies SQL et de recherche
 * sur les options de config d'une saisie (de champs extras)
 *
 * @param array
 * @return array
**/
function iextras_formulaire_verifier($flux) {
	if ($flux['args']['form'] == 'construire_formulaire'
	AND strpos($flux['args']['args'][0], 'champs_extras_')===0
	AND $nom_ou_id = _request('configurer_saisie') ) {

		// On ajoute le préfixe devant l'identifiant
		$identifiant = 'constructeur_formulaire_'.$flux['args']['args'][0];
		// On récupère le formulaire à son état actuel
		$formulaire_actuel = session_get($identifiant);

		if ($nom_ou_id[0] == '@') {
			$saisies_actuelles = saisies_lister_par_identifiant($formulaire_actuel);
			$name = $saisies_actuelles[$nom_ou_id]['options']['nom'];
		} else {
			$saisies_actuelles = saisies_lister_par_nom($formulaire_actuel);
			$name = $nom_ou_id;
		}

		// saisie inexistante => on sort
		if (!isset($saisies_actuelles[$nom_ou_id])) {
			return $flux;
		}

		$nom = 'configurer_' . $name;
		$table = substr($flux['args']['args'][0], strlen('champs_extras_'));


		// on ajoute le fieldset de restrictions de champs
		// (des autorisations pre-reglées en quelque sorte)
		$saisies_restrictions = array();

		// les restrictions de X ne peuvent apparaître que
		// si l'objet possede un Y.
		// secteurs -> id_secteur
		// branches -> id_rubrique
		// groupes -> id_groupe
		$desc = lister_tables_objets_sql($table);
		$types = array(
			'secteurs' => 'id_secteur',
			'branches' => 'id_rubrique',
			'groupes'  => 'id_groupe',
		);
		foreach ($types as $type => $champ) {
			if (isset($desc['field'][$champ])) {
				$saisies_restrictions[] = array(
					'saisie' => 'input',
					'options' => array(
						'nom' => "saisie_modifiee_${name}[options][restrictions][$type]",
						'label' => _T('iextras:label_restrictions_' . $type),
						'explication' => _T('iextras:precisions_pour_restrictions_' . $type),
						'defaut' => '',
					)
				);
			}
		}

		// ajout des restrictions voir | modifier par auteur
		$actions = array('voir', 'modifier');
		foreach ($actions as $action) {
			$saisies_restrictions[] = array(
					'saisie' => 'fieldset',
					'options' => array(
						'nom' => "saisie_modifiee_${name}[options][restrictions][$action]",
						'label' => _T('iextras:legend_restrictions_' . $action),
					),
					'saisies' => array(
						array(
							'saisie' => 'radio',
							'options' => array(
								'nom' => "saisie_modifiee_${name}[options][restrictions][$action][auteur]",
								'label' => _T('iextras:label_restrictions_auteur'),
								'defaut' => '',
								'datas' => array(
									'' => _T('iextras:radio_restrictions_auteur_aucune'),
									'admin' => _T('iextras:radio_restrictions_auteur_admin'),
									'admin_complet' => _T('iextras:radio_restrictions_auteur_admin_complet'),
									'webmestre' => _T('iextras:radio_restrictions_auteur_webmestre'),
								)
							)
						)
					)
				);
		}


		$flux['data'][$nom] = saisies_inserer($flux['data'][$nom], array(
			'saisie' => 'fieldset',
			'options' => array(
				'nom' => "saisie_modifiee_${name}[options][restrictions]",
				'label' => _T('iextras:legend_restriction'),
			),
			'saisies' => $saisies_restrictions
		));



		// on récupère les informations de la saisie
		// pour savoir si c'est un champs éditable (il a une ligne SQL)
		// et dans ce cas, on ajoute les options techniques
		$type_saisie = $saisies_actuelles[$nom_ou_id]['saisie'];
		$saisies_sql = saisies_lister_disponibles_sql();

		if (isset($saisies_sql[$type_saisie])) {

			// liste 'type_de_saisie' => 'Titre de la saisie'
			$liste_saisies = array();
			foreach ($saisies_sql as $s=>$d) {
				$liste_saisies[$s] = $d['titre'];
			}

			$sql = $saisies_sql[$type_saisie]['defaut']['options']['sql'];
			$flux['data'][$nom] = saisies_inserer($flux['data'][$nom], array(

				'saisie' => 'fieldset',
				'options' => array(
					'nom' => "saisie_modifiee_${name}[options][options_techniques]",
					'label' => _T('iextras:legend_options_techniques'),
				),
				'saisies' => array(
					array(
						'saisie' => 'input',
						'options' => array(
							'nom' => "saisie_modifiee_${name}[options][sql]",
							'label' => _T('iextras:label_sql'),
							'obligatoire' => 'oui',
							'size' => 50,
							'defaut' => $sql
						)
					),
					array(
						'saisie' => 'oui_non',
						'options' => array(
							'nom' => "saisie_modifiee_${name}[options][rechercher]",
							'label' => _T('iextras:label_rechercher'),
							'explication' => _T('iextras:precisions_pour_rechercher'),
							'defaut' => ''
						)
					),
					array(
						'saisie' => 'input',
						'options' => array(
							'nom' => "saisie_modifiee_${name}[options][rechercher_ponderation]",
							'label' => _T('iextras:label_rechercher_ponderation'),
							'explication' => _T('iextras:precisions_pour_rechercher_ponderation'),
							'defaut' => 2,
							'afficher_si' => "@saisie_modifiee_${name}[options][rechercher]@ != ''",
						)
					),
					array(
						'saisie' => 'radio',
						'options' => array(
							'nom' => "saisie_modifiee_${name}[options][traitements]",
							'label' => _T('iextras:label_traitements'),
							'explication' => _T('iextras:precisions_pour_traitements'),
							'defaut' => '',
							'datas' => array(
								'' => _T('iextras:radio_traitements_aucun'),
								'_TRAITEMENT_TYPO' => _T('iextras:radio_traitements_typo'),
								'_TRAITEMENT_RACCOURCIS' => _T('iextras:radio_traitements_raccourcis'),
							)
						)
					),
					array(
						'saisie' => 'oui_non',
						'options' => array(
							'nom' => "saisie_modifiee_${name}[options][versionner]",
							'label' => _T('iextras:label_versionner'),
							'explication' => _T('iextras:precisions_pour_versionner'),
							'defaut' => ''
						)
					),
					array(
						'saisie' => 'selection',
						'options' => array(
							'nom' => "saisie_modifiee_${name}[options][nouveau_type_saisie]",
							'label' => _T('iextras:label_saisie'),
							'explication' => _T('iextras:precisions_pour_nouvelle_saisie'),
							'attention' => _T('iextras:precisions_pour_nouvelle_saisie_attention'),
							'defaut' => $type_saisie,
							'datas' => $liste_saisies
						)
					),
				)));
		}
	}
	return $flux;
}
示例#5
0
/**
 * Le tableau de saisies a-t-il une option afficher_si_remplissage ?
 *
 * @param array $saisies Un tableau de saisies
 * @return boolean
 */
function saisies_afficher_si_remplissage($saisies)
{
    $saisies = saisies_lister_par_nom($saisies, true);
    // Dès qu'il y a au moins une option afficher_si_remplissage, on l'active
    foreach ($saisies as $saisie) {
        if (isset($saisie['options']['afficher_si_remplissage'])) {
            return true;
        }
    }
    return false;
}
function formulaires_construire_formulaire_verifier($identifiant, $formulaire_initial=array(), $options=array()){
	include_spip('inc/saisies');
	$erreurs = array();
	// l'une ou l'autre sera presente
	$configurer_saisie = $enregistrer_saisie = '';

	// Pas d'erreur si l'on ne demande rien
	if (!($nom_ou_id = $configurer_saisie  = _request('configurer_saisie')
	OR    $nom_ou_id = $enregistrer_saisie = _request('enregistrer_saisie'))) {
		return $erreurs;
	}

	// On ajoute un préfixe devant l'identifiant
	$identifiant = 'constructeur_formulaire_'.$identifiant;
	// On récupère le formulaire à son état actuel
	$formulaire_actuel = session_get($identifiant);

	// On récupère les saisies actuelles, par identifiant ou par nom
	if ($nom_ou_id[0] == '@') {
		$saisies_actuelles = saisies_lister_par_identifiant($formulaire_actuel);
		$nom = $saisies_actuelles[$nom_ou_id]['options']['nom'];
	} else {
		$saisies_actuelles = saisies_lister_par_nom($formulaire_actuel);
		$nom = $nom_ou_id;
	}
	$noms_autorises = array_keys($saisies_actuelles);

	// le nom (ou identifiant) doit exister
	if (!in_array($nom_ou_id, $noms_autorises)) {
		return $erreurs;
	}
	
	// La liste des saisies
	$saisies_disponibles = saisies_lister_disponibles();
	
	$saisie = $saisies_actuelles[$nom_ou_id];
	$formulaire_config = $saisies_disponibles[$saisie['saisie']]['options'];
	array_walk_recursive($formulaire_config, 'formidable_transformer_nom', "saisie_modifiee_${nom}[options][@valeur@]");
	$formulaire_config = saisie_identifier(array('saisies'=>$formulaire_config));
	$formulaire_config = $formulaire_config['saisies'];
	
	// Si la saisie possede un identifiant, on l'ajoute
	// au formulaire de configuration pour ne pas le perdre en route
	if (isset($saisie['identifiant']) and $saisie['identifiant']) {
		$formulaire_config = saisies_inserer(
			$formulaire_config,
			array(
				'saisie' => 'hidden',
				'options' => array(
					'nom' => "saisie_modifiee_${nom}[identifiant]",
					'defaut' => $saisie['identifiant']
				),
			)
		);
	}
	
	// S'il y a l'option adéquat, on ajoute le champ pour modifier le nom
	if (isset($options['modifier_nom']) and $options['modifier_nom']
	  and $chemin_nom = saisies_chercher($formulaire_config, "saisie_modifiee_${nom}[options][description]", true))
	{
		$chemin_nom[] = 'saisies';
		$chemin_nom[] = '0';

		$formulaire_config = saisies_inserer(
			$formulaire_config,
			array(
				'saisie' => 'input',
				'options' => array(
					'nom' => "saisie_modifiee_${nom}[options][nom]",
					'label' => _T('saisies:option_nom_label'),
					'explication' => _T('saisies:option_nom_explication'),
					'obligatoire' => 'oui',
					'size' => 50
				),
				'verifier' => array(
					'type' => 'regex',
					'options' => array(
						'modele' => '/^[\w]+$/'
					)
				)
			),
			$chemin_nom
		);
	}

	// liste des options de vérification
	$verif_options = array();

	// S'il y a un groupe "validation" alors on va construire le formulaire des vérifications
	if ($chemin_validation = saisies_chercher($formulaire_config, "saisie_modifiee_${nom}[options][validation]", true)){
		include_spip('inc/verifier');
		$liste_verifications = verifier_lister_disponibles();
		$chemin_validation[] = 'saisies';
		$chemin_validation[] = 1000000; // à la fin
		
		// On construit la saisie à insérer et les fieldset des options
		$saisie_liste_verif = array(
			'saisie' => 'selection',
			'options' => array(
				'nom' => "saisie_modifiee_${nom}[verifier][type]",
				'label' => _T('saisies:construire_verifications_label'),
				'option_intro' => _T('saisies:construire_verifications_aucune'),
				'conteneur_class' => 'liste_verifications',
				'datas' => array()
			)
		);

		foreach ($liste_verifications as $type_verif => $verif){
			$saisie_liste_verif['options']['datas'][$type_verif] = $verif['titre'];
			// Si le type de vérif a des options, on ajoute un fieldset
			if (isset($verif['options']) and $verif['options'] and is_array($verif['options'])){
				$groupe = array(
					'saisie' => 'fieldset',
					'options' => array(
						'nom' => 'options',
						'label' => $verif['titre'],
						'conteneur_class' => "$type_verif options_verifier"
					),
					'saisies' => $verif['options']
				);
				array_walk_recursive($groupe, 'formidable_transformer_nom', "saisie_modifiee_${nom}[verifier][$type_verif][@valeur@]");
				$verif_options[$type_verif] = $groupe;
			}
		}
		$verif_options = array_merge(array($saisie_liste_verif), $verif_options);
	}
	
	
	if ($enregistrer_saisie){
		// La saisie modifié
		$saisie_modifiee = _request("saisie_modifiee_${nom}");
		// On cherche les erreurs de la configuration
		$vraies_erreurs = saisies_verifier($formulaire_config);
		// Si on autorise à modifier le nom ET qu'il doit être unique : on vérifie
		if (isset($options['modifier_nom']) and $options['modifier_nom']
		  and isset($options['nom_unique']) and $options['nom_unique'])
		{
			$nom_modifie = $saisie_modifiee['options']['nom'];
			if ($nom_modifie != $enregistrer_saisie and saisies_chercher($formulaire_actuel, $nom_modifie))
				$vraies_erreurs["saisie_modifiee_${nom}[options][nom]"] = _T('saisies:erreur_option_nom_unique');
		}
		// On regarde s'il a été demandé un type de vérif
		if (isset($saisie_modifiee['verifier']['type'])
		  and (($type_verif = $saisie_modifiee['verifier']['type']) != '')
		  and $verif_options[$type_verif])
		{
			// On ne vérifie que les options du type demandé
			$vraies_erreurs = array_merge($vraies_erreurs, saisies_verifier($verif_options[$type_verif]['saisies']));
		}
	}

	// On insère chaque saisie des options de verification
	if ($verif_options){
		foreach ($verif_options as $saisie_verif){
			$formulaire_config = saisies_inserer($formulaire_config, $saisie_verif, $chemin_validation);
		}
	}
	$erreurs['configurer_'.$nom] = $formulaire_config;
	$erreurs['positionner'] = '#configurer_'.$nom;

	if ($enregistrer_saisie) {
		if ($vraies_erreurs) {
			$erreurs = array_merge($erreurs, $vraies_erreurs);
		} else {
			$erreurs = array();
		}
	} else {
		$erreurs['message_erreur'] = ''; // on ne veut pas du message_erreur automatique
	}

	return $erreurs;
}
示例#7
0
/**
 * Prend la description complète du contenu d'un formulaire et retourne
 * une liste des valeurs par défaut des champs du formulaire.
 *
 * @param array $contenu Le contenu d'un formulaire
 *
 * @return array Un tableau renvoyant la valeur par défaut de chaque champs
 */
function saisies_lister_valeurs_defaut($contenu) {
	$contenu = saisies_lister_par_nom($contenu, false);
	$defauts = array();
	foreach ($contenu as $nom => $saisie) {
		// Si le nom du champ est un tableau indexé, il faut parser !
		if (preg_match('/([\w]+)((\[[\w]+\])+)/', $nom, $separe)) {
			$nom = $separe[1];
			// Dans ce cas on ne récupère que le nom, la valeur par défaut du tableau devra être renseigné autre part
			$defauts[$nom] = array();
		} else {
			$defauts[$nom] = isset($saisie['options']['defaut']) ? $saisie['options']['defaut'] : '';
		}
	}

	return $defauts;
}
示例#8
0
/**
 * Génère, à partir d'un tableau de saisie le code javascript ajouté à la fin de #GENERER_SAISIES
 * pour produire un affichage conditionnel des saisies ayant une option afficher_si ou afficher_si_remplissage.
 *
 * @param array $saisies
 *     Tableau de descriptions des saisies
 * @param string $id_form
 *     Identifiant unique pour le formulaire
 * @return text
 *     Code javascript
 */
function saisies_generer_js_afficher_si($saisies, $id_form)
{
    $i = 0;
    $saisies = saisies_lister_par_nom($saisies, true);
    $code = '';
    $code .= '(function($){';
    $code .= '$(document).ready(function(){chargement=true;';
    $code .= 'verifier_saisies_' . $id_form . " = function(form){\n";
    foreach ($saisies as $saisie) {
        // on utilise comme selecteur l'identifiant de saisie en priorite s'il est connu
        // parce que li_class = 'tableau[nom][option]' ne fonctionne evidement pas
        // lorsque le name est un tableau
        if (isset($saisie['options']['afficher_si']) or isset($saisie['options']['afficher_si_remplissage'])) {
            $i++;
            // retrouver la classe css probable
            switch ($saisie['saisie']) {
                case 'fieldset':
                    $class_li = 'fieldset_' . $saisie['options']['nom'];
                    break;
                case 'explication':
                    $class_li = 'explication_' . $saisie['options']['nom'];
                    break;
                default:
                    $class_li = 'editer_' . $saisie['options']['nom'];
            }
            $afficher_si = isset($saisie['options']['afficher_si']) ? $saisie['options']['afficher_si'] : '';
            $afficher_si_remplissage = isset($saisie['options']['afficher_si_remplissage']) ? $saisie['options']['afficher_si_remplissage'] : '';
            $condition = join("\n", array_filter(array($afficher_si, $afficher_si_remplissage)));
            // retrouver l'identifiant
            $identifiant = '';
            if (isset($saisie['identifiant']) and $saisie['identifiant']) {
                $identifiant = $saisie['identifiant'];
            }
            // On gère le cas @plugin:non_plugin@
            preg_match_all('#@plugin:(.+)@#U', $condition, $matches);
            foreach ($matches[1] as $plug) {
                if (defined('_DIR_PLUGIN_' . strtoupper($plug))) {
                    $condition = preg_replace('#@plugin:' . $plug . '@#U', 'true', $condition);
                } else {
                    $condition = preg_replace('#@plugin:' . $plug . '@#U', 'false', $condition);
                }
            }
            // On gère le cas @config:plugin:meta@ suivi d'un test
            preg_match_all('#@config:(.+):(.+)@#U', $condition, $matches);
            foreach ($matches[1] as $plugin) {
                $config = lire_config($plugin);
                $condition = preg_replace('#@config:' . $plugin . ':' . $matches[2][0] . '@#U', '"' . $config[$matches[2][0]] . '"', $condition);
            }
            // On transforme en une condition valide
            preg_match_all('#@(.+)@#U', $condition, $matches);
            foreach ($matches[1] as $nom) {
                switch ($saisies[$nom]['saisie']) {
                    case 'radio':
                    case 'oui_non':
                        $condition = preg_replace('#@' . preg_quote($nom) . '@#U', '$(form).find("[name=\'' . $nom . '\']:checked").val()', $condition);
                        break;
                    case 'case':
                        $condition = preg_replace('#@' . preg_quote($nom) . '@#U', '($(form).find(".checkbox[name=\'' . $nom . '\']").is(":checked") ? $(form).find(".checkbox[name=\'' . $nom . '\']").val() : "")', $condition);
                        break;
                    case 'checkbox':
                        preg_match_all('#@(.+)@\\s*==\\s*"(.*)"$#U', $condition, $matches2);
                        foreach ($matches2[2] as $value) {
                            $condition = preg_replace('#@' . preg_quote($nom) . '@#U', '($(form).find(".checkbox[name=\'' . $nom . '[]\'][value=' . $value . ']").is(":checked") ? $(form).find(".checkbox[name=\'' . $nom . '[]\'][value=' . $value . ']").val() : "")', $condition);
                        }
                        break;
                    default:
                        $condition = preg_replace('#@' . preg_quote($nom) . '@#U', '$(form).find("[name=\'' . $nom . '\']").val()', $condition);
                }
            }
            if ($identifiant) {
                $sel = "li[data-id='{$identifiant}']";
            } else {
                $sel = "li.{$class_li}";
            }
            $code .= "\tif (" . $condition . ') {$(form).find("' . $sel . '").show(400);} ' . "\n\t";
            $code .= 'else {if (chargement==true) {$(form).find("' . $sel . '").hide(400).css("display","none");} else {$(form).find("' . $sel . '").hide(400);};} ' . "\n";
        }
    }
    $code .= "};";
    $code .= '$("li#afficher_si_' . $id_form . '").parents("form").each(function(){verifier_saisies_' . $id_form . '(this);});';
    $code .= '$("li#afficher_si_' . $id_form . '").parents("form").change(function(){verifier_saisies_' . $id_form . '(this);});';
    $code .= 'chargement=false;})';
    $code .= '})(jQuery);';
    return $i > 0 ? $code : '';
}
/**
 * Importe une description de champs extras donnée
 *
 * @param array $description 
 *    description des champs extras (table sql => liste des champs extras)
 * @param string $message
 *    message de retour, rempli par cette fonction
 * @param bool $fusionner_doublons
 *    true si on fusionne les champs présents dans la sauvegarde et aussi présents sur le site. False pour les ignorer.
 * @return bool
 *    true si tout s'est bien passé, false sinon
**/
function iextras_importer_description($description, &$message, $fusionner_doublons = false)
{
    include_spip('inc/iextras');
    include_spip('inc/saisies');
    include_spip('inc/texte');
    include_spip('inc/cextras');
    $tables_sql_presentes = array_keys(lister_tables_objets_sql());
    $message = '';
    $nbt = count($description);
    $message .= "{{Fichier importé :}}\n";
    $message .= "- {$nbt} objets éditoriaux.\n";
    $nbc = 0;
    foreach ($description as $table => $saisies) {
        $nbc += count($saisies);
    }
    $message .= "- {$nbc} champs extras.\n";
    foreach ($description as $table => $saisies) {
        if (!in_array($table, $tables_sql_presentes)) {
            $message .= "\nTable {{ {$table} }} absente sur le site\n";
            $message .= count($saisies) . " champs extras ignorés !!\n";
            continue;
        }
        $champs_presents = $champs_futurs = iextras_champs_extras_definis($table);
        $champs_presents_par_nom = saisies_lister_par_nom($champs_presents);
        $objet = objet_type($table);
        $titre = _T(objet_info($objet, 'texte_objets'));
        $message .= "\n{{ {$titre} :}}\n";
        $message .= count($saisies) . " champs extras\n";
        foreach ($saisies as $saisie) {
            $nom = isset($saisie['options']['nom']) ? $saisie['options']['nom'] : '';
            if (!$nom) {
                $message .= "- !! Saisie sans nom ignorée\n";
                continue;
            }
            // champ déjà présent ?
            if (isset($champs_presents_par_nom[$nom])) {
                if ($fusionner_doublons) {
                    $message .= "- {{ {$nom} :}} modifié (déjà présent)\n";
                    $champs_futurs = saisies_modifier($champs_futurs, $nom, $saisie);
                } else {
                    $message .= "- {{ {$nom} :}} ignoré (déjà présent)\n";
                }
            } else {
                $message .= "- {{ {$nom} :}} ajouté\n";
                $champs_futurs = saisies_inserer($champs_futurs, $saisie);
            }
        }
        $diff = saisies_comparer_par_identifiant($champs_presents, $champs_futurs);
        // ajouter les nouveaux champs;
        if ($diff['ajoutees']) {
            $message .= count($diff['ajoutees']) . " champs ajoutés.\n";
            champs_extras_creer($table, $diff['ajoutees']);
        }
        // modifier les champs modifies;
        if ($diff['modifiees']) {
            $message .= count($diff['modifiees']) . " champs modifiés.\n";
            $anciennes = saisies_lister_par_identifiant($champs_presents);
            $anciennes = array_intersect_key($anciennes, $diff['modifiees']);
            champs_extras_modifier($table, $diff['modifiees'], $anciennes);
        }
        // enregistrer la nouvelle config
        if ($diff['ajoutees'] or $diff['modifiees']) {
            ecrire_meta("champs_extras_" . $table, serialize($champs_futurs));
        } else {
            $message .= "Aucune modification !\n";
        }
    }
    $message = propre($message);
    return true;
}