This was originally posted in a reply to
http://forum.coppermine-gallery.net/index.php?topic=43527.0Since that thread contains multiple hack versions it is very cluttered and hard to follow. Since my original post there I have made some small changes to to the commenting in the zip.php file located in the attached securezip.zip file. I also cleaned up some typos, etc. in the installation instructions. And I included a readme.html with the full installation instructions.
Download a Zipped Album With Basic SecurityI have wanted to have the functionality of users being able to download a zip of an entire album/folder for a long, long time. But I never manged to get it working on my own. That's one reason that I decided to try out CPG. So I tried out the various hacks in the forum and managed to get the zip.php version to work. The zipalbum.php version does not work at all as posted. There are errors in the scripting.
I was happy to get zip downloads working, but there was one major problem. Lack of any kind of security. All a user had to do was replace the number in the aid portion of the url and he could download any album, including private ones. Well there can be many many reasons why that is completely unacceptable. You may have family pictures stored in your CPG that you don't want the world at large to see, etc. My main reason for needing better security is that I want to be able to make updates at anytime, and then make them active on a set day by changing the permissions from admin-only to everyone.
So I decided to use the built in user levels to secure the zip script. An album with "everyone" permissions has "0" set in the visibility colum of the cpgxxx_albums table. An "admin" gallery has a "1", etc. I figured the easiest thing to implement would be a check to see what the content of the visibility column was, and then disallow any downloads if the result was not "0". I only use admin and everyone in my CPG, so that works perfectly for me. You might want to change things around a bit to suit your own setup. To find out what the visibilty value is for any particular setting just change the setting in the album's properties and then check the contents of the table with phpmyadmin or MySQL Administrator.
This is tested and working on my linux, apache, mysql, php4 server. Your mileage may vary.
This script contains work by h3nn3s, Beme, MoolFreet, easyjava and Nibbler. Thanks guys!
This mod does not require any modification of any core CPG files so it should be installable on most versions of CPG or future versions. Rather than a CPG mod it is actually a template modification. It should not cause a problem for you to update to a different version of CPG unless the way themes work is changed.
With that said I have only tested it with 1.4.13, 1.4.14 and 1.4.16. I have tried it with the following themes: Rainy Day, Classic and Water Drop. Also with a heavily customized Rainy Day variant that I am using in my CPG. It works with no problems with Stramm's ModPack installed. I have tested it with CPG 1.5 and it is working. However I am not using the latest build of 1.5.
Detailed installation instructions:# 1 ) Download the securezip.zip attached to this message.
# 2 ) Unzip it and upload zip.php to the root folder of your CPG installation. (Same folder as the index.php)
# 3 ) Open the file in your editor of choice and look for:
/* Write here the name of the folder where the zip will be created */
$sFolderZip = "zipfiles/";
It starts on line 5. Either change the name (make sure it has the "/" on the end!) of the folder or else make a folder in the root of your CPG installation called "zipfiles". Whichever one you choose, you will probably have to chmod to 777 to get the script to work.
# 4 ) Navigate to the folder of the template you are using. Something like: /yourwwwfolder/CPG/templates/name_of_template.
# 5 ) Open themes/yourtheme/theme.php in your editor of choice. Copy the following code into your theme.php file just
above the
?>
at the end of the file.
function theme_display_thumbnails(&$thumb_list, $nbThumb, $album_name, $aid, $cat, $page, $total_pages, $sort_options, $display_tabs, $mode = 'thumb')
{
global $CONFIG;
global $template_thumb_view_title_row,$template_fav_thumb_view_title_row, $lang_thumb_view, $template_tab_display, $template_thumbnail_view, $lang_album_list;
static $header = '';
static $thumb_cell = '';
static $empty_cell = '';
static $row_separator = '';
static $footer = '';
static $tabs = '';
static $spacer = '';
if ($header == '') {
$thumb_cell = template_extract_block($template_thumbnail_view, 'thumb_cell');
$tabs = template_extract_block($template_thumbnail_view, 'tabs');
$header = template_extract_block($template_thumbnail_view, 'header');
$empty_cell = template_extract_block($template_thumbnail_view, 'empty_cell');
$row_separator = template_extract_block($template_thumbnail_view, 'row_separator');
$footer = template_extract_block($template_thumbnail_view, 'footer');
$spacer = template_extract_block($template_thumbnail_view, 'spacer');
}
$cat_link = is_numeric($aid) ? '' : '&cat=' . $cat;
$uid_link = (isset($_GET['uid']) && is_numeric($_GET['uid'])) ? '&uid=' . $_GET['uid'] : '';
$theme_thumb_tab_tmpl = $template_tab_display;
if ($mode == 'thumb') {
$theme_thumb_tab_tmpl['left_text'] = strtr($theme_thumb_tab_tmpl['left_text'], array('{LEFT_TEXT}' => $aid == 'lastalb' ? $lang_album_list['album_on_page'] : $lang_thumb_view['pic_on_page']));
$theme_thumb_tab_tmpl['inactive_tab'] = strtr($theme_thumb_tab_tmpl['inactive_tab'], array('{LINK}' => 'thumbnails.php?album=' . $aid . $cat_link . $uid_link . '&page=%d'));
$theme_thumb_tab_tmpl['inactive_next_tab'] = strtr($theme_thumb_tab_tmpl['inactive_next_tab'], array('{LINK}' => 'thumbnails.php?album=' . $aid . $cat_link . $uid_link . '&page=%d'));
$theme_thumb_tab_tmpl['inactive_prev_tab'] = strtr($theme_thumb_tab_tmpl['inactive_prev_tab'], array('{LINK}' => 'thumbnails.php?album=' . $aid . $cat_link . $uid_link . '&page=%d'));
} else {
$theme_thumb_tab_tmpl['left_text'] = strtr($theme_thumb_tab_tmpl['left_text'], array('{LEFT_TEXT}' => $lang_thumb_view['user_on_page']));
$theme_thumb_tab_tmpl['inactive_tab'] = strtr($theme_thumb_tab_tmpl['inactive_tab'], array('{LINK}' => 'index.php?cat=' . $cat . '&page=%d'));
$theme_thumb_tab_tmpl['inactive_next_tab'] = strtr($theme_thumb_tab_tmpl['inactive_next_tab'], array('{LINK}' => 'index.php?cat=' . $cat . '&page=%d'));
$theme_thumb_tab_tmpl['inactive_prev_tab'] = strtr($theme_thumb_tab_tmpl['inactive_prev_tab'], array('{LINK}' => 'index.php?cat=' . $cat . '&page=%d'));
}
$thumbcols = $CONFIG['thumbcols'];
$cell_width = ceil(100 / $CONFIG['thumbcols']) . '%';
$tabs_html = $display_tabs ? create_tabs($nbThumb, $page, $total_pages, $theme_thumb_tab_tmpl) : '';
// The sort order options are not available for meta albums
if ($sort_options) {
$param = array('{ALBUM_NAME}' => $album_name,
'{AID}' => $aid,
'{PAGE}' => $page,
'{NAME}' => $lang_thumb_view['name'],
'{TITLE}' => $lang_thumb_view['title'],
'{DATE}' => $lang_thumb_view['date'],
'{SORT_TA}' => $lang_thumb_view['sort_ta'],
'{SORT_TD}' => $lang_thumb_view['sort_td'],
'{SORT_NA}' => $lang_thumb_view['sort_na'],
'{SORT_ND}' => $lang_thumb_view['sort_nd'],
'{SORT_DA}' => $lang_thumb_view['sort_da'],
'{SORT_DD}' => $lang_thumb_view['sort_dd'],
'{POSITION}' => $lang_thumb_view['position'],
'{SORT_PA}' => $lang_thumb_view['sort_pa'],
'{SORT_PD}' => $lang_thumb_view['sort_pd'],
);
// MOD - begin
$param['{ALBUM_NAME}'] .= ' <a href="zip.php?aid=' . $aid . '" title="Download album as *zip archive">[ Download Album ]</a>';
// MOD - end
$title = template_eval($template_thumb_view_title_row, $param);
} else if ($aid == 'favpics' && $CONFIG['enable_zipdownload'] == 1) { //Lots of stuff can be added here later
$param = array('{ALBUM_NAME}' => $album_name,
'{DOWNLOAD_ZIP}'=>$lang_thumb_view['download_zip']
);
$title = template_eval($template_fav_thumb_view_title_row, $param);
}else{
$title = $album_name;
}
if ($mode == 'thumb') {
starttable('100%', $title, $thumbcols);
} else {
starttable('100%');
}
echo $header;
$i = 0;
foreach($thumb_list as $thumb) {
$i++;
if ($mode == 'thumb') {
if ($aid == 'lastalb') {
$params = array('{CELL_WIDTH}' => $cell_width,
'{LINK_TGT}' => "thumbnails.php?album={$thumb['aid']}",
'{THUMB}' => $thumb['image'],
'{CAPTION}' => $thumb['caption'],
'{ADMIN_MENU}' => $thumb['admin_menu']
);
} else {
$params = array('{CELL_WIDTH}' => $cell_width,
'{LINK_TGT}' => "displayimage.php?album=$aid$cat_link&pos={$thumb['pos']}$uid_link",
'{THUMB}' => $thumb['image'],
'{CAPTION}' => $thumb['caption'],
'{ADMIN_MENU}' => $thumb['admin_menu']
);
}
} else {
$params = array('{CELL_WIDTH}' => $cell_width,
'{LINK_TGT}' => "index.php?cat={$thumb['cat']}",
'{THUMB}' => $thumb['image'],
'{CAPTION}' => $thumb['caption'],
'{ADMIN_MENU}' => ''
);
}
echo template_eval($thumb_cell, $params);
if ((($i % $thumbcols) == 0) && ($i < count($thumb_list))) {
echo $row_separator;
}
}
for (;($i % $thumbcols); $i++) {
echo $empty_cell;
}
echo $footer;
if ($display_tabs) {
$params = array('{THUMB_COLS}' => $thumbcols,
'{TABS}' => $tabs_html
);
echo template_eval($tabs, $params);
}
endtable();
echo $spacer;
}
This is assuming that you are using CPG 1.4.13 - 1.4.16 with the Classic, RainyDay or Waterdops themes. I haven't tested it in other themes. Your theme may have some or all of this code in it already. If that's the case then search the code in your theme.php for:
$param = array('{ALBUM_NAME}' => $album_name,
'{AID}' => $aid,
'{PAGE}' => $page,
'{NAME}' => $lang_thumb_view['name'],
'{TITLE}' => $lang_thumb_view['title'],
'{DATE}' => $lang_thumb_view['date'],
'{SORT_TA}' => $lang_thumb_view['sort_ta'],
'{SORT_TD}' => $lang_thumb_view['sort_td'],
'{SORT_NA}' => $lang_thumb_view['sort_na'],
'{SORT_ND}' => $lang_thumb_view['sort_nd'],
'{SORT_DA}' => $lang_thumb_view['sort_da'],
'{SORT_DD}' => $lang_thumb_view['sort_dd'],
'{POSITION}' => $lang_thumb_view['position'],
'{SORT_PA}' => $lang_thumb_view['sort_pa'],
'{SORT_PD}' => $lang_thumb_view['sort_pd'],
);
and immediately after that, insert this:
// MOD - begin
$param['{ALBUM_NAME}'] .= ' <a href="zip.php?aid=' . $aid . '" title="Download album as *zip archive">[ Download Album ]</a>';
// MOD - end
As MoolFreet pointed out you can change the formatting of the URL in that snippet to use an icon image instead of text if you like.
# 6 ) Download the pclzip library from
http://www.phpconcept.net/pclzip/index.php#download. Unzip it and and upload pclzip.lib.php to your CPG root.
# 7 )
You're done! If you want to test it just go to an album and click the download link on the top of the thumbnail view. If you want to test the security just set an album to anything except "everyone" in the album's properties, and then try to d/l it by changing the aid=123 portion of the zip url to the aid (album ID) number of the restricted gallery. You should see a white page with a red error message.
Known Limitations:
* If you are logged in as admin you will still see the "Download Album" link, but if you click it permission will be denied. Personally I don't have any need to download a zip because I am the only one allowed to upload to my site.
* As written ONLY albums with permission set to "Everyone" can be downloaded.
* The coding of the error message is inelegant, but it works.
* If you change themes you will need to do the same modifications to the theme.php of your new theme.
I am NOT a real coder. I struggled like hell to get this tiny bit of code to work. If you can improve it then feel free to do so. Hopefully something like this might make it into the next release of CPG. If you are using the "download favorites" function included in CPG you may be interested to know that it also allows the downloading of favorites without checking if the pic is in an album that is private or not. However that script only downloads the files that are already present in favorites. That makes it less of a risk because if he can't see an album a user can't add an image to his favorites. I have not checked to see if it is possible to add to favorites by changing the url around.
Possible Modifications:
If you know some PHP you can change the security settings to suit your own setup. For instance you could change
!= '0'
Into something like
==1
That would allow albums of all levels except 1 to be downloaded. That has a serious drawback if you allow private albums for anyone except admins because you will have changed the code from protecting all albums except "everyone" viewable albums, to only protecting "admin" albums.
See the 3rd post in this topic for how to modify it to use the "registered users" group instead of "everyone"
You can also mess around with elseif statements to try and make it fit better with your setup. As a general rule it is easier and safer to disallow permissions than it is to grant them when dealing with multiple user groups.
The best way to handle security would be to check if the user was logged in and then check to see if he or his user group was allowed access to the album. However that is a lot more complex and not really something suitable for a quick hack/mod.
Enjoy!
- New version 1.01 - Modified the zip.php so that the created archive removes the path. Files were being located inside albums/folder1/folder2/folder3, etc.
- New version 1.1 - Modified to delete files in the defined zip folder that are older than 60 minutes. That should make it more useable by those with diskspace restrictions. Thanks to easyjava and Nibbler. Added readme.txt and updated the readme.html.
- New version 1.2 - Modified to make the script compatible with servers where register_globals is turned off, as it should be. Thanks to VladiczeK for reporting the issue and Nibbler for providing the fix. Updated readme.txt and readme.html.