We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I was interested in dynamically creating Zip files for users to download, but when I created a custom content type for "zip" (uses application/zip MIME type), it seems that it doesn't work... it doesn't even seem that my Snippet on the page is parsing -- viewing the page does trigger a download, but the contents are simply the page contents -- i.e. the raw Snippet call.

    Anyone have any ideas here? This seems like really odd behavior.
      • 22303 MODX Staff
      • 10,725 Posts
      My zip content works fine. Make sure it is marked as binary.
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        Thanks Jason -- I found the problem: my own stupidity. Many of the examples on the PHP site were incomplete: I was creating the zip file, but I wasn't returning it via readfile -- it's obvious in retrospect that you need to do this, but so many examples online skipped that step.

        Just for the record, here is the simplified Snippet:


        <?php
        
        $file = '/tmp/my-zip.zip';
        
        $zip = new ZipArchive();
        
        $res = $zip->open($file, ZipArchive::CREATE);
        
        if ($res === true) {
        
        	// Add a file generated from a Snippet
        	$xls_contents = $modx->runSnippet('createXLS',array('something' => 'parameter'));
        	$zip->addFromString('My-File.xls', $xls_contents);
        	
        	$zip->close();
        
        	// Barf out the file
        	readfile($file); 
        	
        	unlink($file);
        
        } else {
        	$modx->log(xPDO::LOG_LEVEL_ERROR, "downloadZip: ZipArchive failed to create a zip file");
        	return 'An error occurred while trying to create the zip file.';
        }
        


        As long as the page containing that Snippet call is generating the appropriate headers, this downloads just fine. Using this code in a CMP, you have to add some headers before barfing out the file. I added a few headers right before the readfile() bit:


        	header("Content-Type: application/zip"); 
        	header("Content-Length: " . filesize($file)); 
        	header("Content-Disposition: attachment; filename=".basename($file)); 
        


        All working now. Thanks!