1

I am learning hot to use Drupal for my physics PHD. I was studying how to insert a batch into my custom module. I wrote a simple module which allows to upload a CSV through a form, check the extension and save it into a directory. This is just a try because i want to use batch API for another custom module Here is the code:

/**
* Implementation of hook_menu()   
*/

function rhmtts_csvimport_menu() {
     $items['rhmtts/csvimport'] = array(
           'title' => 'Import CSV files',
           'page callback' => 'rhmtts_csvimport_page_default',
           'type' => MENU_NORMAL_ITEM,
           'access callback' => TRUE,
           );

     return $items;
}


function rhmtts_csvimport_uploadform() {
      $form['#attributes'] = array('enctype' => "multipart/form-data");
      $form['csvfile'] = array(
           '#type' => 'file',
           '#title' => t("Upload a CSV file"),
           '#size' => 40,
           );
      $form['submit'] = array(
           '#type' => 'submit',
           '#value' => t('Submit'),
           );
  return $form;
 }

           /////// Setup a batch //////////////

  function rhmtts_batch_submit(){

      $batch=array(
          'title' => t('Importing CSV ...'),
          'operations' => array(),
          'init_message' => t('Commencing'),
          'progress_message' => t('Processed @current out of @total.'),
          'error_message' => t('An error occurred during processing'),
          'finished' => 'rhmtts_csvimport_finished',
          );


      batch_set($batch);
      $batch['operations'][] = array('rhmtts_csvimport_uploadform_submit',                    array());

      }

     ////// Define finished function ////////////////////////////

   function rhmtts_csvimport_finished($success, $results, $operations) {

     if ($success) {
        $message = t('All users have had first and last names processed.');
      }
     else {
     $message = t('Finished with error.');
     }
   drupal_set_message($message);
   }

   ///// Methods definition ////

   function rhmtts_csvimport_uploadform_submit($form, &$form_state) {



   // create a csv upload directory in sites/default/files if it doesn't exist 
   // yet
   $filepath = 'public://csvuploads';
   file_prepare_directory($filepath, FILE_CREATE_DIRECTORY);

   // save the uploaded file
   $file = file_save_upload('csvfile', array('file_validate_extensions' =>             array('CSV')), $filepath, FILE_EXISTS_REPLACE);
   drupal_set_message('The file you have uploaded is: <pre>'.print_r($file,    TRUE).'</pre>');

  // now read from it
  $realpath = drupal_realpath($file->uri);
  drupal_set_message("The real path of the file is $realpath");
  $fh = fopen($realpath, 'r');

  $table_header = NULL;
  $table = array();
  while(($row = fgetcsv($fh, NULL,';')) !== FALSE){
  if($table_header == NULL) {
  foreach($row as $field) {
    $table_header[] = $field;
    };
    continue;
    };
    $table_row = array();
    for($i = 0; $i < count($table_header) ; $i++) {
    $table_row[$table_header[$i]] = $row[$i];
    };
    $table[] = $table_row;
    }
    fclose($fh);
    drupal_set_message("You have uploaded: <pre>".print_r($table, TRUE)."</pre>");
   }

When i choose a file from the form it completed the operation, but the usual page showing batch progression is not showed. Is this because the operation is to fast? Or there are other problems in the code?

Many thanks

Alberto

2 Answers 2

0
  • your menu callback function is rhmtts_csvimport_page_default. This does not exist or currently does nothing.
  • Your form function rhmtts_csvimport_uploadform has this submit handler rhmtts_csvimport_uploadform_submit and it never calls or creates your batch function called rhmtts_batch_submit.

Your code is more or less all there I would:

  • use drupal_get_form as my hook_menu callback function and give it the name of my form function.
  • I would add my batch function onto the form submit handlers for my form as outlined here https://www.drupal.org/node/180528. Then it should all work.
1
  • Dear tenken many thanks for your answer, I just try to modify my code, I still have one question. I post below new code and the question.
    – Alberto
    Commented Sep 15, 2014 at 15:12
0

I try to modify a little bit the code, which now is:

<?php


 /**
  * @file
  */


 // Implementation of hook_menu()

 function rhmtts_csvimport_menu() {
   $items['rhmtts/csvimport'] = array(
     'title' => 'Import CSV files',
     'page callback' => 'rhmtts_csvimport_uploadform',
     'type' => MENU_NORMAL_ITEM,
     'access callback' => TRUE,
     );

   return $items;
 }


 function rhmtts_csvimport_uploadform($form, &$form_state) {
 $form['#attributes'] = array('enctype' => "multipart/form-data");
   $form['csvfile'] = array(
     '#type' => 'file',
     '#title' => t("Upload a CSV file"),
     '#size' => 40,

   );
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Submit'),

   );


  $form['#submit'] = array(
    'rhmtts_csvimport_uploadform_submit',
  );

 return $form;

 }

 ////////// Form submission logic ///////////////////////


 function rhmtts_csvimport($form, &$form_state){
   // create a csv upload directory in sites/default/files if it doesn't exist 
   // yet
   $filepath = 'public://csvuploads';
   file_prepare_directory($filepath, FILE_CREATE_DIRECTORY);
   drupal_set_messagge('Upload directory has been created');


   // save the uploaded file
   $file = file_save_upload('csvfile', array('file_validate_extensions' =>      array('CSV')), $filepath, FILE_EXISTS_REPLACE);
   drupal_set_message('The file you have uploaded is: <pre>'.print_r($file,  TRUE).'</pre>');

   // now read from it
   $realpath = drupal_realpath($file->uri);
   drupal_set_message("The real path of the file is $realpath");
   $fh = fopen($realpath, 'r');

   $table_header = NULL;
   $table = array();
   while(($row = fgetcsv($fh, NULL,';')) !== FALSE){
     if($table_header == NULL) {
      foreach($row as $field) {
        $table_header[] = $field;
     };
  continue;
    };
    $table_row = array();
    for($i = 0; $i < count($table_header) ; $i++) {
       $table_row[$table_header[$i]] = $row[$i];
    };
    $table[] = $table_row;
  }
   fclose($fh);
   drupal_set_message("You have uploaded: <pre>".print_r($table, TRUE)."    </pre>");


 }



 function rhmtts_csvimport_uploadform_submit($form, &$form_state) {

 $batch=array(
   'title' => t('Importing CSV ...'),
   'operations' => array(
    array('rhmtts_csvimport',array($form, &$form_state)),
    ),
    'init_message' => t('Starting process'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('An error occurred during processing'),
     'finished' => 'rhmtts_finished',
    );

    batch_set($batch);

    }

   function rhmtts_finished($success, $results, $operations){

   if ($success) {
     // Here we do something meaningful with the results.
     $message = count($results) .' processed.';
     drupal_set_message($message);
    }
   else {
      // An error occurred.
   // $operations contains the operations that remained unprocessed.
    $error_operation = reset($operations);
    $message = t('An error occurred while processing %error_operation with   arguments: @arguments', array('%error_operation' => $error_operation[0],  '@arguments' => print_r($error_operation[1], TRUE)));
     drupal_set_message($message, 'error');
  }  
  }

When i try to use it the batch page is open correctly, the progress bar is correct, but when the batch has finished it reports than 0 operations have been processed and file directory and file is not uploaded. I cannot understand where is the mistake. Any idea? Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.