Hi everyone,
Thanks so much to everyone for working on this zip download feature! Last night I spent a fair amount of time toying with it for use with my personal website, and having this new feature makes me much happier with my photo server :-). Also, I made a few more modifications / bug fixes I thought I'd share with the group.
Disclaimer: I'm not a coder by trade and this is my first experience with php, so any and all feedback is welcome :-)
#1 - Commas in directories and filenames make the code crash
Commas do not work well with zip.php and pclzip by default. If you're like me and have several directory names that have commas, the Download Album feature simply won't work. This is because, by default, the create() function of pclzip uses the comma as a filename separator in the filelist. Whoops.
This is easily solved by making a modification to both zip.php and pclzip.lib.php by changing the separator from "," to something that's extremely unlikely to occur in a directory or filename. Note that there is no reason this has to be a single character... in fact, having a multiple-character separator likely makes things more robust. I chose "#,#,#,#".
In zip.php, find:
$bilder .= "albums/" . $row['filepath'].$row['filename'].",";
And change to:
$bilder .= "albums/" . $row['filepath'].$row['filename']."#,#,#,#";
Then, in pclzip.lib.php, find:
//define( 'PCLZIP_SEPARATOR', ' ' );
// Recommanded values for smart separation of filenames.
if (!defined('PCLZIP_SEPARATOR')) {
define( 'PCLZIP_SEPARATOR', ',' );
}
And change to:
//define( 'PCLZIP_SEPARATOR', ' ' );
define( 'PCLZIP_SEPARATOR', '#,#,#,#' );
// Recommanded values for smart separation of filenames.
if (!defined('PCLZIP_SEPARATOR')) {
define( 'PCLZIP_SEPARATOR', ',' );
}
Voila - now, unless you tend to use #,#,#,# in your directory names, the Download Album button won't cause the system to crash :-)
#2 - Zip-compressing images that are already compressed is a waste of time
I have a lot of high-resolution jpeg images on my website, so sometimes it can take quite awhile to generate the zip file for download. Much of this time is spent by the zip program trying to compress jpegs... which is pretty useless. So, I modified zip.php to tell pclzip to do compression-less zipping. This saves a lot of server processing time while causing zip file sizes to grow by maybe 1-2% - a nice tradeoff in my opinion.
In zip.php, find:
$v_list = $archive->create($bilder,PCLZIP_OPT_REMOVE_ALL_PATH);
And change to:
$v_list = $archive->create($bilder,PCLZIP_OPT_REMOVE_ALL_PATH,PCLZIP_OPT_NO_COMPRESSION);
This probably isn't a good idea if you have a bunch of uncompressed files (bmp, raw, etc.), but otherwise it can be quite handy.
#3 - Filenames for zip files might be unintelligible
By default, zip.php uses urlencode() to make the filename for the zip file from the album name. This is a very robust, straightforward, and fool-proof method. However, for my purposes, I felt that it resulted in a bunch of really ugly, unintelligible filenames. For example, a descriptive name of "2009/11/23 - John Smith's birthday" becomes "2009%2F11%2F23+-+John+Smith%27s+birthday" which wasn't exactly my cup of tea :-).
So, I use str_replace() instead. For functionality, some characters must be changed. I made spaces into underscores (" " to "_"), turned apostrophes back into apostrophes ("'" to "'"), and got rid of slashes ("/" to ""). Now, "2009/11/23 - John Smith's birthday" becomes "20091123_-_John_Smith's_birthday" which looks prettier to me :-).
In zip.php, find:
$sDesiredZipName = urlencode($o_AlbumName->title);
And change to:
//$sDesiredZipName = urlencode($o_AlbumName->title);
$sDesiredZipName = str_replace(" ", "_", $o_AlbumName->title);
$sDesiredZipName = str_replace("'", "'", $sDesiredZipName);
$sDesiredZipName = str_replace("/", "", $sDesiredZipName);
This works well with my style of album titles, but likely needs tweaking for other people (particularly with the slashes... some might prefer them to be spaces or hyphens or something). Also, to be fair, this method is not as robust as the default, urlencode() method. I haven't thought through an exhaustive list of name cases... it's possible that your album naming scheme may generate something that causes the code to crash. But, it works well with mine so I thought I'd share.
#4 - Adding a "Download Album" button to the album list view
Having the Download Album button on the thumbnail view is great, but I also wanted the option of seeing the button on the album list view. That way, you don't have to open the album to be able to download it. It seemed like a nice piece of functionality to add - having the button in two different places makes it seem more user-friendly.
Adding this functionality is very similar to the default implementation of zip.php - it involves theme.php. Whereas adding the button to the thumbnail view involved the theme_display_thumbnails function, adding the button to the album list view involves (unsurprisingly) the theme_display_album_list function. Like before, odds are that this function is not, by default, defined in theme.php but rather in theme.inc.php. So, it has to be added to theme.php and then modified for our purposes.
In theme.inc.php, find:
function theme_display_album_list
...
...
...
}
and copy it in entirety to theme.php either directly above or below the theme_display_thumbnails function that was added to make zip.php work.
Then, within this function, find:
$params = array('{COL_WIDTH}' => $column_width,
'{ALBUM_TITLE}' => $album['album_title'],
'{THUMB_CELL_WIDTH}' => $thumb_cell_width,
'{ALB_LINK_TGT}' => "thumbnails.php?album={$album['aid']}",
'{ALB_LINK_PIC}' => $album['thumb_pic'],
'{ADMIN_MENU}' => $album['album_adm_menu'],
'{ALB_DESC}' => $album['album_desc'],
'{ALB_INFOS}' => $album['album_info'],
);
And change to:
$params = array('{COL_WIDTH}' => $column_width,
'{ALBUM_TITLE}' => $album['album_title'],
'{THUMB_CELL_WIDTH}' => $thumb_cell_width,
'{ALB_LINK_TGT}' => "thumbnails.php?album={$album['aid']}",
'{ALB_LINK_PIC}' => $album['thumb_pic'],
'{ADMIN_MENU}' => $album['album_adm_menu'],
'{ALB_DESC}' => $album['album_desc'],
'{ALB_INFOS}' => $album['album_info'],
);
//mod zipped album download start
$params['{ALB_INFOS}'] .= ' <a href="zip.php?aid=' . $album['aid'] . '" title="Download album as *zip archive">[ DOWNLOAD ALBUM ]</a>';
//mod zipped album download end
This implementation appends the button to the end of the info field, which looks nice for my site layout. One could also use the description field (change ALB_INFOS to ALB_DESC) or the album title itself (change ALB_INFOS to ALBUM_TITLE). I also used capital letters for the button... I thought it looked better for the album view. Change as you like :-).
Thanks again for your work on making the securezip modification, and I hope my suggestions help out someone else!
Take care,
Shad