As multiple file upload is not possible in IMCE, I would like to add the possibilty to unzip a zip file in IMCE.
So I'm creating a module to do this.
I want to add a new button, like the delete button, and when user click on it, a confirm box appears before unzip the selected file.
The problem is that my button doesn't appears in IMCE interface.

Here is the code in my module to add the unzip button :

 function imce_unzip_form(&$form_state, $ref) {
  $imce =& $ref['imce'];
  $formUnzip['unzip'] = array(
    '#type' => 'submit',
    '#value' => t('Unzip'),
    '#submit' => $imce['perm']['unzip'] ? array('imce_unzip_submit') : NULL,//permission for submission
  );
  if (imce_perm_exists($imce, 'unzip')) {
   		$form['fset_unzip'] = array(
    	'#type' => 'fieldset',
    	'#title' => t('Unzip'),
  		) + $formUnzip;
 }
  $form['#action'] = $imce['url'];
  return $form;
}

and in my js file (my js script file is well loaded in firebug ) :

imce.hooks.load.push (function () {	
	imce.opAdd({name: 'unzip', title: Drupal.t('Unzip'), func: imce.unzipOpSubmit});
});

Is it the good way to add a new button in IMCE interface ?

CommentFileSizeAuthor
#10 imce_unzip.zip13.74 KBelopez69
#9 imce_unzip.zip13.17 KBlucuhb
#6 imce_unzip.zip12.91 KBlucuhb
#5 imce_unzip.zip12.58 KBlucuhb
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ufku’s picture

See IMCE Crop as an example for adding a new file operation.

lucuhb’s picture

Thanks for your response.

Like in imce_crop, I had the hook_imce_form_alter, like this :

/**
 * Implementation of hook_form_formID_alter().
 */
function imce_unzip_form_imce_fileop_form_alter(&$form, &$form_state) {
  $imce =& $form['#parameters'][2]['imce'];
  if (imce_perm_exists($imce, 'unzip')) {
    $form['fset_unzip'] = array(
      '#type' => 'fieldset',
      '#title' => t('Unzip'),
    ) + imce_unzip_form($imce);

    $path = drupal_get_path('module', 'imce_unzip');
   drupal_add_js($path .'/imce_unzip.js');
   // drupal_add_css($path .'/imce_crop.css');
  }
}
/**
 * Unzip form.
 */
function imce_unzip_form(&$imce) {
  
  
  $form['unzip'] = array(
    '#type' => 'submit',
    '#value' => t('Unzip'),
    '#submit' => $imce['perm']['unzip'] ? array('imce_unzip_submit') : NULL,//permission for submission
    '#prefix' => '<div class="container-inline">'.t('Unzip the file ? '),
    '#suffix' => '</div>',
  );
  $form['#validate'] = 'imce_unzip_form_validate';

  return $form;
   	
   }

The Unzip button appears now. In the implementation here, a new container-inline section is added with a submit button.When I click on this button, nothing appends and nothing in my log. Yet I added this part in my module :

/**
 * Validate file operations form.
 */
function imce_unzip_form_validate($form, &$form_state) {
  error_log("validation of the form");
  
  $imce =& $form['#parameters'][2]['imce'];

  //check if the filenames is empty
  if ($form_state['values']['filenames'] == '') {
    return form_error($form['filenames'], t('Please select a file.'));
  }

  //filenames come seperated by colon
  $filenames = explode(':', $form_state['values']['filenames']);
  $cnt = count($filenames);
  //check the number of files.
  if ($imce['filenum'] && $cnt > $imce['filenum']) {
    return form_error($form['filenames'], t('You are not allowed to operate on more than %num files.', array('%num' => $imce['filenum'])));
  }

  //check if there is any illegal choice
  for ($i = 0; $i < $cnt; $i++) {
    $filenames[$i] = $filename = rawurldecode($filenames[$i]);
    if (!isset($imce['files'][$filename])) {
      watchdog('imce', 'Illegal choice %choice in !name element.', array('%choice' => $filename, '!name' => t('directory (%dir)', array('%dir' => file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir'])))), WATCHDOG_ERROR);
      return form_error($form['filenames'], t('An illegal choice has been detected. Please contact the site administrator.'));
    }
  }

  $form_state['values']['filenames'] = $filenames;
}

/**
 * Submit unzip form.
 */
function imce_unzip_submit($form, &$form_state) {
 	
 	error_log("in fonction imce_unzip_submit");
 
  $form_state['redirect'] = FALSE;
  $imce =& $form['#parameters'][2]['imce'];

  $unzip = imce_process_files($form_state['values']['filenames'], $imce, 'imce_unzip_file');

  if (!empty($unzip)) {
    drupal_set_message(t('File unzip successful: %files.', array('%files' => utf8_encode(implode(', ', $unzip)))));
  }

}
/**
 * unzip a file in the file list.
 */
function imce_unzip_file($filename, &$imce) {
  $filepath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']) .'/'. $filename;
  if (!_imce_unzip_file_unzip($filepath, $imce)) {
    return FALSE;
  }
  return TRUE;
}


/**
 * Unzip the files and check extensions.
 */
function _imce_unzip_file_unzip($file, $imce) {

  if ($file->filemime == 'application/zip') {

	$allowed_extensions = $imce['extensions'];
  

   $zip = zip_open(realpath($file->filepath));
    
	$zip_dir = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']);
    if (!is_resource($zip)) {
      drupal_set_message(t("Error for $file->filepath = " . imce_unzip_err($zip)), 'error');
      return;
    }

    if ($zip) {
      while ($zip_entry = zip_read($zip)) {

        $filename = basename(zip_entry_name($zip_entry));
        $ext = drupal_strtolower(array_pop(explode('.', $filename)));

        // check file extension
        
        if (!in_array($ext, $allowed_extensions) && $allowed_extensions != '*') {
          drupal_set_message("Skipping $filename because extension isn't allowed", 'error');
          $valid = false;
        }
        else {
          drupal_set_message(t("Extracting $filename"), 'succes');
          $fp = fopen($zip_dir.basename($filename), "w+");
          if (zip_entry_open($zip, $zip_entry, "r")) {
              $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
              zip_entry_close($zip_entry);
          }
          fwrite($fp, $buf);
          fclose($fp);
          //delete zip file after unzip
          imce_delete_file($filename, $imce);
        }
      }
    zip_close($zip);
    }

  }
  else {
    drupal_set_message(t("no zip file"), 'error');
  }
  unlink(realpath($file->filepath));
  return;
}

I have tried to had this in my imce_unzip.file, but this doesn't work :

imce.unzipOpValidate: function(fop) {
	  if (!imce.validateSelCount(1, imce.conf.filenum)) return false;
	  switch (fop) {
	    case 'unzip':
	    	if (!imce.validateSelCount(1, 1)) {
	   		 return imce.setMessage(Drupal.t('You could unzip only one file at once'), 'error');
	    	}
	    	for (var fname in imce.selected) {
	    	      if (fname.lastIndexOf(".zip") == -1) {
	    	    	return imce.setMessage(Drupal.t('The file should be a zip file'), 'error');  
	    	      }
	    	}
	    	return confirm(Drupal.t('Unzip selected files?'));
	    
	  }
	
  return true;
}

So somebody have an idea why nothing appends ?
In addition I would like a confirm window appears rather than the div container-inline. How to do this ?

ufku’s picture

You call _imce_unzip_file_unzip() with filepath but it seems to expect an object.
imce_unzip_form_validate is unnecessary.
You should implement imce_js_unzip for ajax callbacks

lucuhb’s picture

ok, you are right, the _imce_unzip_file_unzip want an objet (I didn't care about this because there is nothing at all when I click on the 'Unzip' button), so I changed this.
I suppressed the imce_unzip_form_validate function (and its reference in imce_unzip_form) and added the imce_js_unzip function like this :

 function imce_js_unzip(&$imce) {
  if ($imce['perm']['unzip']) {
    $_POST['op'] = t('Unzip');
    return imce_process_fileop($imce);
  }
}

Unfortunatly nothing works more when I click ti the second button 'Unzip'.
In firebug, I don't see the imce_unzip.js in the script tab : it seems not to be load in imce. Is there something else to load the js file in imce ?

lucuhb’s picture

Category: support » feature
Status: Active » Needs review
FileSize
12.58 KB

The module I wanted to develop is now functional: it allows to add unzip functionality to IMCE.

You can get the module in attached file and try it. If someone sees some problems, don't hesitate to give me some returns.

thanks!

lucuhb’s picture

FileSize
12.91 KB

There was a problem of permission when the user navigates on directory. The version in the attached file corrects this problem.

Hadrien KOHL’s picture

Works nice with me !!!

You should release it as a module.

Thanks.

nateB’s picture

Nice stuff. Subscribing!

lucuhb’s picture

FileSize
13.17 KB

When the zip archive was created with a mac computer, a directory __MACOSX was created in the zip. Here is a new version of the module that do not extract this directory and files in it.

elopez69’s picture

FileSize
13.74 KB

Thanks for this code!!!

I found some problems. Only one level of subdirectories was working for me. The 2nd level, 3th, and.. so on were no created and the files inside the subdirectories goes to the directory where the zip file is located. I made some changes to fix it and I'm posting the new code. I hope the author agree with them

juanjo_vlc’s picture

I'll test it when i go back to work on monday.
I think it must be integrated into IMCE module because it is a very important feature.

I propose it to be included on IMCE module ¿anyone supports me?

ufku’s picture

Status: Needs review » Closed (won't fix)

Closing 6.x-1.x issues as this branch is no more supported.
OTH, this zip functionality can be contributed as a separate module like imce_crop.

steve.colson’s picture

I have created a project for this over here: http://drupal.org/sandbox/stephen.colson/1322504

I have fixed some bugs and brought it up to the Drupal Coding standards so far as coder is concerned. Hopefully in the next few days it gets approved as an actual module!