Message d'avertissement

The subscription service is currently unavailable. Please try again later.

hook_form_alter, #required et validation

Information importante

En raison d'un grand nombre d'inscriptions de spammers sur notre site, polluant sans relache notre forum, nous suspendons la création de compte via le formulaire de "sign up".

Il est néanmoins toujours possible de devenir adhérent•e en faisant la demande sur cette page, rubrique "Inscription" : https://www.drupal.fr/contact


De plus, le forum est désormais "interdit en écriture". Il n'est plus autorisé d'y écrire un sujet/billet/commentaire.

Pour contacter la communauté, merci de rejoindre le slack "drupalfrance".

Si vous voulez contacter le bureau de l'association, utilisez le formulaire disponible ici, ou envoyez-nous un DM sur twitter.

Bonjour,

J'écris un module permettant d'obliger certains utilisateurs à entrer un message de révision lors de l'édition de contenu. J'ai modifié le formulaire d'édition de node afin que l'utilisateur puisse savoir que ce champ est requis (le plus souvent matérialisé par une étoile rouge à côté du champ).

Le code marche mais un cas de figure n'est pas pris en compte : si un utilisateur a des permissions suffisantes (genre 'administer nodes'), il pourra décocher la case "créer une nouvelle révision", et dans ce cas on ne voudra pas l'obliger à remplir le champ message de révision.

Mais pas moyen de faire ça : dès qu'on soumet le formulaire, Drupal vérifie que les champs requis sont remplis et renvoie une erreur sinon. Cette vérification intervient avant toute autre validation via hook_nodeapi, donc je ne peux rien faire de ce côté là.

Je cherche un moyen de pouvoir exécuter une fonction avant que le formulaire soit envoyé à Drupal, soit via des paramètres de FormAPI (#after_build ?), soit via AHAH, mais autant dire que la documentation ne m'a pas beaucoup aidé à comprendre.

D'après le code ci-dessous, comment feriez-vous pour enlever l'élément $form['revision_information']['log']['#required'] si l'utilisateur décoche la case "Créer une nouvelle révision" ?

<?php
function enforce_revlog_form_alter(&$form, $form_state, $form_id) {
  global
$user;
  if (isset(
$form['#id']) && $form['#id'] == 'node-form') {
   
$form_name = $form['type']['#value'] . '_node_form';
    switch (
$form_id) {
      case
$form_name:
       
// identify if we should require a log message for this content type with this user
       
if (
         
variable_get(enforce_revlog_node_type_ . $form['type']['#value'], 1)
          && (isset(
$form['#node']) && $form['#node']->revision)
          && !
user_access('skip revision log message', 1)
          ) {
         
$form['revision_information']['log']['#required'] = TRUE;
        }
        break;
    }
  }
}
?>
Forum : 
Version de Drupal : 
Tags : 

Bonjour,
Au lieu de mettre directement le champ requis obligatoire $form['revision_information']['log']['#required'] = TRUE;, j'utiliserais une fonction de validation : à savoir dans ton form_alter :

<?php
if (
         
variable_get(enforce_revlog_node_type_ . $form['type']['#value'], 1)
          && (isset(
$form['#node']) && $form['#node']->revision)
          && !
user_access('skip revision log message', 1)
          ) {
         
$form['revision_information']['log']['#required'] = TRUE;
        }
?>

devient

<?php
if (
         
variable_get(enforce_revlog_node_type_ . $form['type']['#value'], 1)
          && (isset(
$form['#node']) && $form['#node']->revision)
          ) {        
         
$form['#validate'][] = '_enforce_revlog_revision_validate';
        }
?>

ensuite une fonction de validation :

<?php
function _enforce_revlog_revision_validate($form, &$form_state) {
if(!
user_access('skip revision log message', 0) && empty($form_state['values']['revision_information']['log'])) {
form_set_error('revision_information', t('révision obligatoire));
}
}
?>

Hello,

Merci pour ton aide :-) Malheureusement l'attribut n'est pas passé au bon élément, ce qui fausse le rendu.

J'ai pu écrire un callback AHAH pour adapter dynamiquement le paramètre #required selon si la case "créer une nouvelle révision" est cochée ou non. Ça ne fonctionne que si Javascript est activé, mais je pense que c'est acceptable vu que c'est l'interface d'administration.

Voici l'appel dans mon_module_form_alter() :

<?php
$form
['revision_information']['revision']['#ahah'] = array(
           
'event' => 'change'// not necessary, added for clarity
           
'path' => 'mon_module/js',
           
'wrapper' => 'edit-log-wrapper',
          );
?>

Voici l'appel au callback dans mon_module_menu() :

<?php
$items
['mon_module/js'] = array(
   
'page callback' => 'mon_module_js',
   
'access arguments' => array('access content'),
   
'type' => MENU_CALLBACK,
  );
?>

Et voici la fonction de callback proprement dite :

<?php
function mon_module_js() {
 
$form_state = array('submitted' =>  FALSE);
 
$form_build_id = $_POST['form_build_id'];
 
// Add the new element to the stored form. Without adding the element to the
  // form, Drupal is not aware of this new elements existence and will not
  // process it. We retreive the cached form, add the element, and resave.
 
$form = form_get_cache($form_build_id, $form_state);
  if (
$form['revision_information']['log']['#required'] === TRUE) {
   
$form['revision_information']['log']['#required'] = FALSE;
  }
  else {
   
$form['revision_information']['log']['#required'] = TRUE;
  }
 
form_set_cache($form_build_id, $form, $form_state);
 
$form += array(
   
'#post' => $_POST,
   
'#programmed' => FALSE,
  );
 
// Rebuild the form.
 
$form = form_builder($_POST['form_id'], $form, $form_state);

 
// Render the new output.
 
$new_form = $form['revision_information']['log'];

  return
drupal_json(array(
   
'status' => TRUE,
   
'data' => drupal_render($new_form),
  ));
}
?>

C'est un bout de code adapté d'un tutoriel sur le net donc il y a peut-être des parties inutiles, mais je n'ai pas trouvé d'exemple canonique pour l'interaction entre AHAH et les formulaires sous Drupal, chacun semble avoir sa manière de faire.