I allow users to upload zip files I extract, and look into them to see if they contain a .jpg file. I use that file to create a new node. The differences between the .jpg and the .zip file uploaded are that the first came as an object, while I don't know how I can take the second as an object.

I'm using the PclZip library.

This is part of the code I use when the uploaded file is a JPEG.

$file = $form_state['values']['file'];

$original_filename = $file->filename;
$original = file_unmanaged_copy($file->uri, 'public://work', FILE_EXISTS_REPLACE);
list($file, $tfile) = some_fileprep($original_filename);

This is the code I use when the file is a .zip file.

include $pclzip_lib.'pclzip.lib.php';
$zip = new PclZip($file->uri);

for ($i=0; $i<$total_files; $i++) {
    $file_name = $list[$i]['filename'];
    list($f_name,$xt) = explode('.', $file_name);

    $regex = '/\.(' . preg_replace('/ +/', '|', preg_quote('png gif jpg jpeg tif tiff html')) . ')$/i';
    if (preg_match($regex, $xt) and ($list[$i]['size'] < 10000000)) {
        $error[] = "File with conflict: ".$file_name;
        if((($xt == 'png') or ($xt == 'gif') or ($xt == 'jpg') or ($xt == 'jpeg') or ($xt == 'tif') or ($xt == 'tiff')) and ($f_name == 'preview')){
            $file->filename = $f_name.".".$xt;
            $file->uri = $f_name.".".$xt;
            echo "Yes: ".$f_name.".".$xt;
            $preview = true;

            $to_extract = $GLOBALS['_SERVER']['DOCUMENT_ROOT'] . '/' . drupal_get_path('module', 'some') . '/testing/';
            $ar = $zip->extract(PCLZIP_OPT_PATH, $to_extract);
            $file->filename = $ar->filename;
            $file->uri = $ar->filename;

  • 1
    I'm not sure if I understand the problem and/or question here? – mpdonadio Jul 2 '12 at 16:30
  • when you upload a jpg or a file, drupal take it as an object, so, I'm uploading a zip and I need to extract it, I put the files into the server and need to take one of this files like if it was uploaded by normal mode (as an object), how can I do that? (I'm from Argentina and my english isn't good, sry about the grammar) – Andres Grosso Jul 2 '12 at 17:44
  • You should show some_fileprep()'s code. – kiamlaluno Jul 2 '12 at 18:16

When you successfully unzip a file you have the code:

        $to_extract = $GLOBALS['_SERVER']['DOCUMENT_ROOT'] . '/' . drupal_get_path('module', 'some') . '/testing/';
        $ar = $zip->extract(PCLZIP_OPT_PATH, $to_extract);
        $file->filename = $ar->filename;
        $file->uri = $ar->filename;

Once you've extracted the zip you have a $file object ... just save it using the drupal API such as:

$original = file_unmanaged_copy($file->uri, 'public://work', FILE_EXISTS_REPLACE);

  • Hi tenken, thanks for the answer, but when I make a var_dump($file->filename) or var_dump($file->uri) or var_dump($ar->filename) I get nulls, but the file was extracted, how can take it as an object? – Andres Grosso Jul 2 '12 at 19:19

You can simply use file_unmanaged_save_data(), as in the following code, where $data is the content of the .jpeg file contained the .zip file.

file_unmanaged_save_data($data, 'public://work', FILE_EXISTS_REPLACE);

As side note, Drupal includes the ArchiverZip class, which should probably be used instead of the PclZip class. You don't normally deal with the class directly, but you use code similar to the following one, used by update_manager_archive_extract().

  $archiver = archiver_get_archiver($file);
  if (!$archiver) {
    throw new Exception(t('Cannot extract %file, not a valid archive.', array('%file' => $file)));

  // Remove the directory if it exists, otherwise it might contain a mixture of
  // old files mixed with the new files (e.g. in cases where files were removed
  // from a later release).
  $files = $archiver->listContents();

  // Unfortunately, we can only use the directory name to determine the project
  // name. Some archivers list the first file as the directory (i.e., MODULE/)
  // and others list an actual file (i.e., MODULE/README.TXT).
  $project = strtok($files[0], '/\\');

  $extract_location = $directory . '/' . $project;
  if (file_exists($extract_location)) {


archiver_get_archiver() uses drupal_realpath(); this means it is able to get the realpath of a file when its filename is using stream wrappers, such as public://archive.zip.

  • Hi kiamlaluno, Thanks for the answer, When I started with this, the first thing i tried to use was the ArchiverZip class, but unfortunately, I can't understand it at all, because when I read the documentation, this says something about edit the php.ini and I have no access to that file (Production server), so, the ArchiverZip was discarded immediately, but, I'll to make a new read about it, thanks. – Andres Grosso Jul 2 '12 at 19:26
  • I don't have access to the php.ini file in my web server, but update_manager_archive_extract() works fine; in fact, I am updating the modules using the update manager, and it works. As far as I know, the Zip extension is normally enabled, in PHP 5. – kiamlaluno Jul 2 '12 at 20:07
  • Hello Again kiamlaluno, I'm trying to use ArchverZip as you says, but I'm getting an exception, this is the code (for now): $zip = new ArchiverZip($file->uri); Where $file->uri is the URI of the zipped file, and this is the exception I'm getting Exception: Cannot open <em class="placeholder">temporary://ahi_va_preview.zip</em> in ArchiverZip->__construct() (line 91 of /var/www/html/modules/system/system.archiver.inc). Some ideas about what I'm doing wrong? – Andres Grosso Jul 3 '12 at 17:22
  • Check the process running PHP has the right file permissions on the directory used as directory for temporary files. – kiamlaluno Jul 4 '12 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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