0

I am working on a button which will download the images as a zip on specific posts. It works if I leave the files array in functions.php with a few hard-coded img links. But when I move the array to the custom post where the images I need to zip are already being looped and displayed, I can still download via button, but opening the downloaded zip I get error "Unable to expand archive. It is in an unsupported format" "Unable to expand archive. It is in an unsupported format

I have tried moving different parts of the code back and forth, like all of the code in the custom post, and all of the code in functions.php, to no avail. I must be not getting the img file urls properly but I'm not sure how.

This is all of the mentioned code, only in functions.php (except the download button), with the hard-coded image links, which works as intended:

$image1 = 'https://com.tripletigers/wp-content/uploads/homesweet_nowords-1920x1920.jpg';
$image2 = 'https://com.tripletigers/wp-content/uploads/V3-1920x2880.jpg';
$image3 = 'https://com.tripletigers/wp-content/uploads/SM_Single-Cover_Damn-Strait-1920x1920.jpg';

$files = array($image1, $image2, $image3);


$tmpFile = tempnam('/tmp', '');

$zip = new ZipArchive;
$zip->open($tmpFile, ZipArchive::CREATE);
foreach ($files as $file) {
    // download file
    $fileContent = file_get_contents($file);

    $zip->addFromString(basename($file), $fileContent);
}
$zip->close();

// Download Created Zip file from button via form submit
if(isset($_POST['download'])){

    header('Content-Type: application/zip');
    header('Content-disposition: attachment; filename=artist-photos.zip');
    header('Content-Length: ' . filesize($tmpFile));
    readfile($tmpFile);

    unlink($tmpFile);
}

This is what leads to the error, trying to get the images from the otherwise working loop in the custom post:

foreach( $list_posts as $list_item ) :
    if ( $list_item->post_type == 'crb_photo' ):
        if ( has_post_thumbnail( $list_item->ID ) ) {
            $img_url = get_the_post_thumbnail_url( $list_item->ID, 'crb_full_width' );              
             // this var i created for the zip, to add each image url to the array
            $getImage =  esc_url($img_url);
            // testing: prints image url. Why is that url not getting to the zip?
            echo '<h6>' . $img_url . '</h6>';
            
            // create array for zip - tried both = and .=   
            $files[] .= $getImage;
            // same result as above
            // $files[] = $getImage;
        } ?>
                            
            <li>
                <div>
                   <?php if ( ! empty( $img_url ) ) : ?>
                        <a href="<?php echo esc_url( $img_url ); ?>"></a>
                   <?php endif; ?>
                </div>
            </li>
    <?php endif; ?>

The functions.php used with above (same as first snippet but without hard-coded array)

$tmpFile = tempnam('/tmp', '');

$zip = new ZipArchive;
$zip->open($tmpFile, ZipArchive::CREATE);
foreach ($files as $file) {
    // download file
    $fileContent = file_get_contents($file);

    $zip->addFromString(basename($file), $fileContent);
}
$zip->close();

// Download Created Zip file
if(isset($_POST['download'])){

    header('Content-Type: application/zip');
    header('Content-disposition: attachment; filename=artist-photos.zip');
    header('Content-Length: ' . filesize($tmpFile));
    readfile($tmpFile);

    unlink($tmpFile);
}

When trying to open zip via command line:

When trying to open zip via command line

What am i missing in order to get those images into the zip properly?

8
  • If the URLs are fine, and you've confirmed they're fine then this looks like a generic PHP zip file generation problem not a WordPress problem. Also you're doing this in a very slow way. Instead of using file_get_contents to download the thumbnail URLs, why not access the file directly off the disk? Use get_post_thumbnail_id to get the attachment ID then use the standard attachment functions to grab the path/filename of the file for the image size you want
    – Tom J Nowell
    Commented Sep 23, 2022 at 15:37
  • also have you tried using addFile( $file, basename( $file ) ) instead of reading it in as a string and using addFromString?
    – Tom J Nowell
    Commented Sep 23, 2022 at 15:55
  • Thanks for the comments. I have been trying these ideas and still am stuck. Working on a better code snippet soon to show what I've been trying.
    – Ben Blue
    Commented Sep 24, 2022 at 15:17
  • note that the files you're trying to zip up themselves could be a part of the problem. It could even be that because you've downloaded the zip 50 times, it's assuming this is part 50 of a larger collection, etc
    – Tom J Nowell
    Commented Sep 25, 2022 at 8:14
  • I have been changing the name of the downloaded file along the way, filename=artist-photos.zip') to filename=artist-photos-2.zip'), and so on. Hopefully that would have prevented what you mentioned. I'm just getting back to this but will update my question code later with where I'm at with it..
    – Ben Blue
    Commented Sep 27, 2022 at 13:38

1 Answer 1

0

As the files are within the same WP installation (not a remote), you don't need to download the file using get_file_contents(), try to add the file using its absolute path of the attachment.

if(isset($_POST['download'])){
    $tmpFile = tempnam('/tmp', '');
    $zip = new ZipArchive();
    $zip->open($tmpFile, ZipArchive::CREATE);

    
    foreach( $list_posts as $list_item ) :
      if ( $list_item->post_type == 'crb_photo' ):
        if ( has_post_thumbnail( $list_item->ID ) ) {
          $zip->addFile(get_attached_file(get_post_thumbnail_id($list_item->ID )));
        }
      }
    }

    $zip->close();

    header('Content-Type: application/zip');
    header('Content-disposition: attachment; filename=artist-photos.zip');
    header('Content-Length: ' . filesize($tmpFile));
    readfile($tmpFile);

    unlink($tmpFile);
}

Note typed the code in this editor, may contain syntax error.

1
  • I have been trying this and still cannot get it to work (fixed the syntax errors). When i use hard-coded image array, i could not even get that to work with addFile - only with addFromString. Using $zip->addFile(get_attached_file(get_post_thumbnail_id( $list_item->ID ))); as you wrote gives same error. Can you share a way to use addFromString and file_get_contents maybe?
    – Ben Blue
    Commented Sep 24, 2022 at 15:16

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.