[Résolu] Relier un form de type checkboxes à la DB via hook_schema

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.

Salut,

Donc voila je suis en train de faire un petit module pour ajouter un type de field date aux type de contenu.

Dans le widget de mon field, il y a plusieurs form dont un form de type checkboxes (contenant les jours de la semaine).

J'ai donc déclaré une table sql avec un hook_schema dans mon fichier module.install afin que les valeur de mon field soit ecrite dans la DB.

Tout marche bien avec les champs de type textfield ou radios les valeur sont bien écrite dans la DB mais dès que je rajoute mon checkboxes j'ai droit a un message d'erreur venant de PDO.

Comment relier correctement mon form de type checkboxes a ma table sql déclaré avec hook_schema ?

Voici mon code :

field_date_plus.install

<?php

function field_date_plus_field_schema($field) {

    $schema["columns"]["type_date"] = array(
       
"type" => "varchar",
       
"length" => 255,
       
"not null" => FALSE,
    );
   
   
$schema["columns"]["date_debut"] = array(
       
"type" => "varchar",
       
"length" => 255,
       
"not null" => FALSE,
    );

    $schema["columns"]["date_fin"] = array(
       
"type" => "varchar",
       
"length" => 255,
       
"not null" => FALSE,
    );
   
   
$schema["columns"]["heur_debut"] = array(
       
"type" => "varchar",
       
"length" => 255,
       
"not null" => FALSE,
    );

    $schema["columns"]["heur_fin"] = array(
       
"type" => "varchar",
       
"length" => 255,
       
"not null" => FALSE,
    );

    $schema["columns"]["jours"] = array(
       
"type" => "varchar",
       
"length" => 255,
       
"not null" => FALSE,
    );

    $schema["indexes"] = array(
       
"type_date" => array("type_date"),
       
"date_debut" => array("date_debut"),
       
"date_fin" => array("date_fin"),
       
"heur_debut" => array("heur_debut"),
       
"heur_fin" => array("heur_fin"),
       
"jours" => array("jours"),
    );
    return
$schema;
}

?>

field_date_plus.module (une partie) :

<?php

function field_date_plus_field_info() {

    return  array(
        "date_plus"=>array(
           
"label" => t("Date plus"),
           
"description" => t("Permet une selection avancée des dates"),
           
"default_widget" => "date_plus_widget",
           
"default_formatter" => "date_plus_formater",
        ),  
    );
}

function field_date_plus_field_widget_info() {

    return array(
        // Déclaration du widget text
       
"date_plus_widget" => array(
           
"label" => t("Widget Date plus"),
           
"field types" => array("date_plus"),
        ),
    );
}

function field_date_plus_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

    $type_date_value = isset($items[$delta]["type_date"]) ? $items[$delta]["type_date"] : 0;
   
$date_debut_value = isset($items[$delta]["date_debut"]) ? $items[$delta]["date_debut"] : "";
   
$date_fin_value = isset($items[$delta]["date_fin"]) ? $items[$delta]["date_fin"] : "";
   
$heur_debut_value = isset($items[$delta]["heur_debut"]) ? $items[$delta]["heur_debut"] : "";

    $field_name = $field['field_name'];

    $field_data = array(
       
'field_name' => $field_name,
       
'langcode' => $langcode,
       
'delta' => $delta,
    );
 
   
$form_state['dad']['field_data'] = $field_data;

    $element['#prefix'] = '<div id="checkboxes-div">';
   
$element['#suffix'] = '</div>';
   
$element['#type'] = 'fieldset';

    $element["type_date"] = array(
       
'#type' => 'radios',
       
'#title' => t(''),
       
'#options' => array(
           
'0' => ('Date simple'),
           
'1' => ('Date en continue'),
           
'2' => ('Date avancée'),
        ),
       
'#default_value' => $type_date_value,
       
'#ajax' => array(
           
'callback' => 'field_date_plus_selection_date_ajax_callback',
           
'wrapper' => 'checkboxes-div',
        ),         
    );

    $teste = isset($form_state['values'][$field_name][$langcode][$delta]['type_date']) ? $form_state['values'][$field_name][$langcode][$delta]['type_date'] : $type_date_value;
    switch (
$teste) {
        case
'0':

            $element['date_debut'] = array(
               
'#type' => 'datepicker',
               
'#title' => t('Le'),
               
'#prefix' => '<div id="field-date-plus-date-debut">',
               
'#suffix' => '</div>',
            );

            $element["heur_debut"]= array(
               
"#type" => "textfield",
               
'#title' => t('de'),
               
"#default_value" => $heur_debut_value,
               
"#size" => 10,
               
"#maxlength" => 5,
               
'#prefix' => '<div id="field-date-plus-heur-debut">',
               
'#suffix' => '</div>',
            );

            $element["heur_fin"]= array(
               
"#type" => "textfield",
               
'#title' => t('à'),
               
"#default_value" => $heur_debut_value,
               
"#size" => 10,
               
"#maxlength" => 5,
               
'#prefix' => '<div id="field-date-plus-heur-fin">',
               
'#suffix' => '</div>',
            );

            break;
       
        case '1':

            $element['date_debut'] = array(
               
'#type' => 'datepicker',
               
'#title' => t('Du'),
               
'#prefix' => '<div id="field-date-plus-date-debut">',
               
'#suffix' => '</div>',
            );

            $element["heur_debut"]= array(
               
"#type" => "textfield",
               
'#title' => t('à'),
               
"#default_value" => $heur_debut_value,
               
"#size" => 10,
               
"#maxlength" => 5,
               
'#prefix' => '<div id="field-date-plus-heur-debut">',
               
'#suffix' => '</div>',
            );

            $element["date_fin"]= array(
               
'#type' => 'datepicker',
               
'#title' => t('au'),
               
'#prefix' => '<div id="field-date-plus-date-fin">',
               
'#suffix' => '</div>',
            );

            $element["heur_fin"]= array(
               
"#type" => "textfield",
               
'#title' => t('à'),
               
"#default_value" => $heur_debut_value,
               
"#size" => 10,
               
"#maxlength" => 5,
               
'#prefix' => '<div id="field-date-plus-heur-fin">',
               
'#suffix' => '</div>',
            );

            break;

        case '2':

            $element['date_debut'] = array(
               
'#type' => 'datepicker',
               
'#title' => t('Du'),
               
'#prefix' => '<div id="field-date-plus-date-debut">',
               
'#suffix' => '</div>',
            );

            $element["date_fin"]= array(
               
'#type' => 'datepicker',
               
'#title' => t('au'),
               
'#prefix' => '<div id="field-date-plus-date-fin">',
               
'#suffix' => '</div>',
            );

            $element["heur_debut"]= array(
               
"#type" => "textfield",
               
'#title' => t('de'),
               
"#default_value" => $heur_debut_value,
               
"#size" => 10,
               
"#maxlength" => 5,
               
'#prefix' => '<div id="field-date-plus-heur-debut">',
               
'#suffix' => '</div>',
            );

            $element["heur_fin"]= array(
               
"#type" => "textfield",
               
'#title' => t('à'),
               
"#default_value" => $heur_debut_value,
               
"#size" => 10,
               
"#maxlength" => 5,
               
'#prefix' => '<div id="field-date-plus-heur-fin">',
               
'#suffix' => '</div>',
            );
           
$element['jours'] = array(
               
'#type' => 'checkboxes',
               
'#options' => drupal_map_assoc(array(t('Lundi'), t('Mardi'),t('Mercredi'), t('Jeudi'),t('Vendredi'), t('Samedi'), t('Dimanche'))),
               
'#title' => t(''),
               
'#prefix' => '<div id="field-date-plus-checkbox-jours">',
               
'#suffix' => '</div>',
            );
            break;
    }
    return
$element;
}

function field_date_plus_selection_date_ajax_callback($form, $form_state, $element) {

  $lang = 'und';
  if (
$form['#form_id'] == 'field_ui_field_edit_form') {
    return
$form['instance']['default_value_widget'][$form['#field']['field_name']][$lang][0];
  }
  else {
    return
$form[$form_state['triggering_element']['#parents'][0]][$lang][0];
  }
}

?>

Et pour finir le message d'erreur :

PDOException : SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1: INSERT INTO {field_data_field_date} (entity_type, entity_id, revision_id, bundle, delta, language, field_date_type_date, field_date_date_debut, field_date_date_fin, field_date_heur_debut, field_date_heur_fin, field_date_jours) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7_date1, :db_insert_placeholder_8_date1, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11_Lundi, :db_insert_placeholder_11_Mardi, :db_insert_placeholder_11_Mercredi, :db_insert_placeholder_11_Jeudi, :db_insert_placeholder_11_Vendredi, :db_insert_placeholder_11_Samedi, :db_insert_placeholder_11_Dimanche); Array ( [:db_insert_placeholder_0] => node [:db_insert_placeholder_1] => 37 [:db_insert_placeholder_2] => 37 [:db_insert_placeholder_3] => localisation [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => 2 [:db_insert_placeholder_9] => [:db_insert_placeholder_10] => [:db_insert_placeholder_7_date1] => 09/02/2013 [:db_insert_placeholder_8_date1] => 09/02/2013 [:db_insert_placeholder_11_Lundi] => Lundi [:db_insert_placeholder_11_Mardi] => Mardi [:db_insert_placeholder_11_Mercredi] => Mercredi [:db_insert_placeholder_11_Jeudi] => Jeudi [:db_insert_placeholder_11_Vendredi] => Vendredi [:db_insert_placeholder_11_Samedi] => Samedi [:db_insert_placeholder_11_Dimanche] => Dimanche ) dans field_sql_storage_field_storage_write() (ligne 448 dans /home/web/www/model/modules/field/modules/field_sql_storage/field_sql_storage.module).

Voilà en espérent que quelqu'un pourra m'éclairer.

Merci d'avance pour votre aide

a+

Forum : 
Version de Drupal : 

Bon j'ai trouvé une solution je sais pas si c'est la bonne en tout cas ça marche.

Donc si les données des checkboxes n'été pas écrite dans la DB, c'est parce que ces dernieres sont stocké à un niveau inférieur du tableau $items et que drupal ne va apparement pas récupéré les données à ce niveau du tableau (peut etre j'ai mal fait les choses quelque part).

Bref donc la solution que j'ai trouvé c'est de reécrire les données à un niveau supérieur du tableau $items dans un hook_field_presave. ça marche également pour les fields situé dans des fieldset car j'avais le meme soucie avec ce type de situation. Cependant si quelqu'un a une solution plus conventionnel a drupal je suis preneur.

Je remet mon code avec le hook_field_widget_form, hook_ajax_callback et hook_field_presave si ça peut aider d'autre personne dans le meme cas que moi tant mieux.

<?php
function field_date_plus_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

    $type_date_value = isset($items[$delta]["type_date"]) ? $items[$delta]["type_date"] : 1;
  
$date_debut_value = isset($items[$delta]["date_debut"]) ? $items[$delta]["date_debut"] : "";
 
$date_fin_value = isset($items[$delta]["date_fin"]) ? $items[$delta]["date_fin"] : "";
  
$heur_debut_value = isset($items[$delta]["heur_debut"]) ? $items[$delta]["heur_debut"] : "";
 
$heur_fin_value = isset($items[$delta]["heur_fin"]) ? $items[$delta]["heur_fin"] : "";
  
$jours_value = isset($items[$delta]['jours']) ? explode(',',$items[$delta]['jours']) : '';

    $settings = $field["settings"];
 
$options_type_date = array();
  foreach (
$settings['checkboxes_panneaux'] as $value) {

      switch($value){

           case '1':
               
$options_type_date['1'] = 'Date simple';
           break;

            case '2':
               
$options_type_date['2'] = 'Date en continue';
          break;

            case '3':
               
$options_type_date['3'] = 'Date avancée';
          break;
     }
  }

 if($settings['saisie_heure'] == 1){
     
$z = 0;
       
$horaire = array();
        for (
$j=1; $j < 3; $j++) {

         $heure_debut_list = strstr($settings['fieldset_saisie_heure']['heure_debut_list_'.$j],'h', TRUE);
           
$heure_fin_list = strstr($settings['fieldset_saisie_heure']['heure_fin_list_'.$j],'h', TRUE);
           
$minute_debut_list = substr(strrchr($settings['fieldset_options_widget_date_plus']['fieldset_saisie_heure']['heure_debut_list_'.$j], 'h'), 1);
        
$minute_fin_list = substr(strrchr($settings['fieldset_options_widget_date_plus']['fieldset_saisie_heure']['heure_fin_list_'.$j], 'h'), 1);
        
$tranche_list = $settings['fieldset_options_widget_date_plus']['fieldset_saisie_heure']['tranche_list_'.$j];

            for ($i=$heure_debut_list; $i < $heure_fin_list; $i++){
           
              
$heure = (strlen($i) == 1) ? '0'.$i : $i;

               if($i == $heure_debut_list){

                  $diviseur_minute = 60 - $minute_debut_list;
                   
$y = $minute_debut_list/$tranche_list;

                }
             else{

                 $diviseur_minute = 60;
                
$y =0;
             }
              for (
$y=$y; $y < (60/$tranche_list); $y++) {

                   $minute = (strlen($tranche_list<em>$y) == 1) ? '0'.$tranche_list</em>$y : $tranche_list<em>$y;
                
$horaire[$j][$z] = $heure.'h'.$minute;
                  
$z++;
              }

             if($i == $heure_fin_list - 1){

                    for ($y=0; $y < ($minute_fin_list/$tranche_list); $y++) {

                      $minute = (strlen($tranche_list</em>$y) == 1) ? '0'.$tranche_list<em>$y : $tranche_list</em>$y;
                    
$horaire[$j][$z] = ($heure+1).'h'.$minute;
                      
$z++;
                  }
              }
          }
         
$horaire[$j][$z] = $settings['fieldset_options_widget_date_plus']['fieldset_saisie_heure']['heure_fin_list_'.$j];
        }

     $form_heure_debut = array(
        
'#type' => 'select',
           
'#title' => t('de'),
           
'#options' => $horaire['1'],
           
'#default_value' => '7h30'
          
'#prefix' => '<div id="field-date-plus-heur-debut">',
          
'#suffix' => '</div>',
       );

        $form_heure_fin = array(
          
'#type' => 'select',
           
'#title' => t('à'),
        
'#options' => $horaire['2'],
           
'#default_value' => '7h30',
        
'#prefix' => '<div id="field-date-plus-heur-fin">',
        
'#suffix' => '</div>',    
       );
 }
  else{

     $form_heure_debut = array(
        
"#type" => "textfield",
        
'#title' => t('de'),
           
"#default_value" => $heur_debut_value,
           
"#size" => 10,
           
"#maxlength" => 5,
           
'#prefix' => '<div id="field-date-plus-heur-debut">',
          
'#suffix' => '</div>',
            );

        $form_heure_fin= array(
           
"#type" => "textfield",
        
'#title' => t('à'),
        
"#default_value" => $heur_fin_value,
         
"#size" => 10,
           
"#maxlength" => 5,
           
'#prefix' => '<div id="field-date-plus-heur-fin">',
        
'#suffix' => '</div>',
            );

    }

     $field_name = $field['field_name'];

     $field_data = array(
      
'field_name' => $field_name,
     
'langcode' => $langcode,
     
'delta' => $delta,
    );
 

     $form_state['dad']['field_data'] = $field_data;

   $element['arg_delta'] = array('#type' => 'hidden', '#value' => $delta);
 
$element["type_date"] = array(
      
'#type' => 'radios',
       
'#title' => t(''),
     
'#options' => $options_type_date,
    
'#default_value' => $type_date_value,
    
'#ajax' => array(
            
'path' => 'field_date_plus_selection_date_ajax_callback',
          
'wrapper' => 'fieldset-field-date-plus-'.$delta,
        ),         
   );

    $element['fieldset_field_date_plus'] = array(
       
'#type' => 'fieldset',
     
'#title' => t(''),
     
'#collapsible' => FALSE,
     
'#collapsed' => FALSE,
       
'#prefix' => '<div id="fieldset-field-date-plus-'.$delta.'">',
       
'#suffix' => '</div>',
    );

    $teste = isset($form_state['values'][$field_name][$langcode][$delta]['type_date']) ? $form_state['values'][$field_name][$langcode][$delta]['type_date'] : $type_date_value;
 
 switch (
$teste){
       case
'1':

          $element['fieldset_field_date_plus']['date_debut'] = array(
               
'#type' => 'datepicker',
               
'#title' => t('Le'),
               
'#prefix' => '<div id="field-date-plus-date-debut">',
              
'#suffix' => '</div>',
               
'#tree' => TRUE,
          );

            $element['fieldset_field_date_plus']["heur_debut"] = $form_heure_debut;

           $element['fieldset_field_date_plus']["heur_fin"] = $form_heure_fin;

       break;
    
       case '2':

           $element['fieldset_field_date_plus']['date_debut'] = array(
               
'#type' => 'datepicker',
               
'#title' => t('Du'),
               
'#prefix' => '<div id="field-date-plus-date-debut">',
              
'#suffix' => '</div>',
               
'#tree' => TRUE,
          );

            $element['fieldset_field_date_plus']["heur_debut"] = $form_heure_debut;

           $element['fieldset_field_date_plus']["date_fin"] = array(
             
'#type' => 'datepicker',
               
'#title' => t('au'),
               
'#prefix' => '<div id="field-date-plus-date-fin">',
            
'#suffix' => '</div>',
            );

            $element['fieldset_field_date_plus']["heur_fin"] = $form_heure_fin;

       break;

        case '3':

           $element['fieldset_field_date_plus']['date_debut'] = array(
               
'#type' => 'datepicker',
               
'#title' => t('Du'),
               
'#prefix' => '<div id="field-date-plus-date-debut">',
              
'#suffix' => '</div>',
               
'#tree' => TRUE,
          );

            $element['fieldset_field_date_plus']["date_fin"] = array(
             
'#type' => 'datepicker',
               
'#title' => t('au'),
               
'#prefix' => '<div id="field-date-plus-date-fin">',
            
'#suffix' => '</div>',
            );

            $element['fieldset_field_date_plus']["heur_debut"] = $form_heure_debut;

           $element['fieldset_field_date_plus']["heur_fin"] = $form_heure_fin;

           $element['fieldset_field_date_plus']['jours'] = array(
            
'#type' => 'checkboxes',
               
'#options' => array(
                 
'1' => ('Lundi'),
                  
'2' => ('Mardi'),
                  
'3' => ('Mercredi'),
                   
'4' => ('Jeudi'),
                  
'5' => ('Vendredi'),
                   
'6' => ('Samedi'),
                 
'7' => ('Dimanche'),
                ),
            
'#default_value' => $jours_value,
            
'#title' => t(''),
             
'#prefix' => '<div id="field-date-plus-checkbox-jours">',
              
'#suffix' => '</div>',
            );
     break;
     }

 return $element;
}

function field_date_plus_selection_date_ajax_callback($form, $form_state) {

      $lang = 'und';
   if (
$form['#form_id'] == 'field_ui_field_edit_form') {
         return
$form['instance']['default_value_widget'][$form['#field']['field_name']][$lang][0]['fieldset_field_date_plus'];
   }
      else {

        return $form[$form_state['triggering_element']['#parents'][0]][$lang][0]['fieldset_field_date_plus'];
    }

}

function field_date_plus_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {

  foreach($items as $i => $item) {

       foreach ($item['fieldset_field_date_plus'] as $key => $value) {

          $value = ($key == 'jours') ? implode(',', $value) : $value;
           
$items[$i][$key] = $value;
     }
  }
}
?>