3 * The PHP Mini Gallery V1.2
4 * (C) 2008 Richard "Shred" K�rber -- all rights reserved
5 * http://www.shredzone.net/go/minigallery
7 * Requirements: PHP 4.1 or higher, GD (GD2 recommended) or ImageMagick
9 * This software is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * $Id: index.php,v 1.5 2003/12/07 14:14:20 shred Exp $
26 /*=== CONFIGURATION ===*/
28 $CONFIG['thumb.width'] = 100; // Thumbnail width (pixels)
29 $CONFIG['thumb.height'] = 100; // Thumbnail height (pixels)
30 $CONFIG['thumb.scale'] = 'gd2'; // Set to 'gd2', 'im' or 'gd'
31 $CONFIG['tool.imagick'] = '/usr/bin/convert'; // Path to convert
32 $CONFIG['index.cols'] = 6; // Colums per row on index print
33 $CONFIG['template'] = 'template.php'; // Template file
36 /*=== SHOW A THUMBNAIL? ===*/
37 if(isset($_GET['thumb'])) {
38 $file = trim($_GET['thumb']);
39 //--- Protect against hacker attacks ---
40 if(preg_match('#\.\.|/#', $file)) die("Illegal characters in path!");
41 $thfile = 'th_'.$file.'.jpg';
42 //--- Get the thumbnail ---
43 if(is_file($file) && is_readable($file)) {
44 //--- Check if the thumbnail is missing or out of date ---
45 if(!is_file($thfile) || (filemtime($file)>filemtime($thfile))) {
46 //--- Get information about the image ---
47 $aySize = getimagesize($file);
48 if(!isset($aySize)) die("Picture $file not recognized...");
49 //--- Compute the thumbnail size, keep aspect ratio ---
50 $srcWidth = $aySize[0]; $srcHeight = $aySize[1];
51 if($srcWidth==0 || $srcHeight==0) { // Avoid div by zero
54 }else if($srcWidth > $srcHeight) { // Landscape
55 $thWidth = $CONFIG['thumb.width'];
56 $thHeight = round(($CONFIG['thumb.width'] * $srcHeight) / $srcWidth);
58 $thWidth = round(($CONFIG['thumb.height'] * $srcWidth) / $srcHeight);
59 $thHeight = $CONFIG['thumb.height'];
61 //--- Get scale mode ---
62 $scmode = strtolower($CONFIG['thumb.scale']);
63 //--- Create source image ---
66 case 1: $imgPic = imagecreatefromgif($file); break;
67 case 2: $imgPic = imagecreatefromjpeg($file); break;
68 case 3: $imgPic = imagecreatefrompng($file); break;
69 default: die("Picture $file must be either JPEG, PNG or GIF...");
75 $imgThumb = imagecreatetruecolor($thWidth, $thHeight);
76 imagecopyresampled($imgThumb, $imgPic, 0,0, 0,0, $thWidth,$thHeight, $srcWidth,$srcHeight);
79 $imgThumb = imagecreate($thWidth,$thHeight);
80 imagecopyresized($imgThumb, $imgPic, 0,0, 0,0, $thWidth,$thHeight, $srcWidth,$srcHeight);
82 case 'im': // Image Magick
84 '%s -geometry %dx%d -interlace plane %s jpeg:%s',
85 $CONFIG['tool.imagick'],
86 $CONFIG['thumb.width'],
87 $CONFIG['thumb.height'],
93 die("Unknown scale mode ".$CONFIG['thumb.scale']);
97 imagejpeg($imgThumb, $thfile);
98 imagedestroy($imgPic);
99 imagedestroy($imgThumb);
103 //--- Check if there is an if-modified-since header ---
104 $fileModified = date('D, d M Y H:i:s \G\M\T', filemtime($thfile));
105 if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE']==$fileModified) {
106 header('HTTP/1.0 304 Not Modified');
110 //--- Send the thumbnail to the browser ---
111 session_cache_limiter('');
112 header('Content-Type: image/jpeg');
113 header("Content-Length: ".filesize($thfile));
114 header("Last-Modified: $fileModified");
118 //--- Tell there is no image like that ---
119 if(is_file($thfile)) unlink($thfile); // Delete a matching thumbnail file
120 header('HTTP/1.0 404 Not Found');
121 print('Sorry, this picture was not found');
126 /*=== CREATE CONTEXT ===*/
129 /*=== GET FILE LISTING ===*/
132 while(($file = readdir($dh)) !== false) {
133 if($file{0}=='.') continue; // No dirs and temp files
134 if(substr($file,0,3) == 'th_') continue; // No thumbnails
135 if(preg_match('#\.(jpe?g|png|gif)$#i', $file)) {
136 if(is_file($file) && is_readable($file)) {
142 $CONTEXT['count'] = count($ayFiles);
143 $CONTEXT['files'] =& $ayFiles;
145 /*=== SHOW A PICTURE? ===*/
146 if(isset($_GET['pic'])) {
147 $file = trim($_GET['pic']);
148 //--- Protect against hacker attacks ---
149 if(preg_match('#\.\.|/#', $file)) die("Illegal characters in path!");
150 //--- Check existence ---
151 if(!(is_file($file) && is_readable($file))) {
152 header('HTTP/1.0 404 Not Found');
153 print('Sorry, this picture was not found');
156 $CONTEXT['page'] = 'picture';
157 //--- Find our index ---
158 $index = array_search($file, $ayFiles);
159 if(!isset($index) || $index===false) die("Invalid picture $file");
160 $CONTEXT['current'] = $index+1;
161 //--- Get neighbour pictures ---
162 $CONTEXT['first'] = $ayFiles[0];
163 $CONTEXT['last'] = $ayFiles[count($ayFiles)-1];
165 $CONTEXT['prev'] = $ayFiles[$index-1];
166 if($index<count($ayFiles)-1)
167 $CONTEXT['next'] = $ayFiles[$index+1];
168 //--- Assemble the content ---
169 list($pWidth,$pHeight) = getimagesize($file);
171 '<img class="picimg" src="%s" width="%s" height="%s" alt="#%s" border="0" />',
172 htmlspecialchars($file),
173 htmlspecialchars($pWidth),
174 htmlspecialchars($pHeight),
175 htmlspecialchars($index+1)
177 if(isset($CONTEXT['next'])) {
178 $page = sprintf('<a href="index.php?pic=%s">%s</a>', htmlspecialchars($CONTEXT['next']), $page);
180 $CONTEXT['pictag'] = $page;
181 if(is_file($file.'.txt') && is_readable($file.'.txt')) {
182 $CONTEXT['caption'] = join('', file($file.'.txt'));
186 /*=== SHOW INDEX PRINT ===*/
188 //--- Set context ---
189 $CONTEXT['page'] = 'index';
190 $CONTEXT['first'] = $ayFiles[0];
191 $CONTEXT['last'] = $ayFiles[count($ayFiles)-1];
194 //--- Assemble the index table ---
195 $page = '<table class="tabindex">'."\n";
197 foreach($ayFiles as $key=>$file) {
198 if($cnt % $CONFIG['index.cols'] == 0) $page .= '<tr>';
200 '<td><a href="index.php?pic=%s"><img class="thumbimg" src="index.php?thumb=%s" alt="#%s" border="0" /></a></td>',
201 htmlspecialchars($file),
202 htmlspecialchars($file),
203 htmlspecialchars($key+1)
206 if($cnt % $CONFIG['index.cols'] == 0) $page .= '</tr>'."\n";
208 //--- Fill empty cells in last row ---
210 while($cnt % $CONFIG['index.cols'] != 0) {
211 $page .= '<td> </td>';
215 if($close) $page .= '</tr>'."\n";
217 //--- Set content ---
218 $CONTEXT['indextag'] = $page;
220 /*=== GET TEMPLATE CONTENT ===*/
222 require($CONFIG['template']);
223 $template = ob_get_contents();
226 /*=== REMOVE UNMATCHING SECTION ===*/
227 if($CONTEXT['page']=='index') {
228 $template = preg_replace('#<pmg:if\s+page="picture">.*?</pmg:if>#s', '', $template);
229 $template = preg_replace('#<pmg:if\s+page="index">(.*?)</pmg:if>#s', '$1', $template);
231 $template = preg_replace('#<pmg:if\s+page="index">.*?</pmg:if>#s', '', $template);
232 $template = preg_replace('#<pmg:if\s+page="picture">(.*?)</pmg:if>#s', '$1', $template);
235 /*=== REPLACE TEMPLATE TAGS ===*/
236 //--- Always present neighbour links ---
238 '<pmg:first>', '</pmg:first>',
239 '<pmg:last>', '</pmg:last>',
240 '<pmg:toc>', '</pmg:toc>'
242 $ayReplace = array();
243 $ayReplace[] = sprintf('<a href="index.php?pic=%s">', htmlspecialchars($CONTEXT['first']));
244 $ayReplace[] = '</a>';
245 $ayReplace[] = sprintf('<a href="index.php?pic=%s">', htmlspecialchars($CONTEXT['last']));
246 $ayReplace[] = '</a>';
247 $ayReplace[] = '<a href="index.php">';
248 $ayReplace[] = '</a>';
249 $template = str_replace($aySearch, $ayReplace, $template);
251 //--- Link to previous picture ---
252 if(isset($CONTEXT['prev'])) {
253 $aySearch = array('<pmg:prev>', '</pmg:prev>');
255 sprintf('<a href="index.php?pic=%s">', htmlspecialchars($CONTEXT['prev'])),
258 $template = str_replace($aySearch, $ayReplace, $template);
260 $template = preg_replace('#<pmg:prev>.*?</pmg:prev>#s', '', $template);
263 //--- Link to next picture ---
264 if(isset($CONTEXT['next'])) {
265 $aySearch = array('<pmg:next>', '</pmg:next>');
267 sprintf('<a href="index.php?pic=%s">', htmlspecialchars($CONTEXT['next'])),
270 $template = str_replace($aySearch, $ayReplace, $template);
272 $template = preg_replace('#<pmg:next>.*?</pmg:next>#s', '', $template);
275 //--- Image, Index Print, Caption ---
276 $aySearch = array('<pmg:image/>', '<pmg:index/>', '<pmg:caption/>', '<pmg:count/>', '<pmg:current/>');
278 (isset($CONTEXT['pictag']) ? $CONTEXT['pictag'] : ''),
279 (isset($CONTEXT['indextag']) ? $CONTEXT['indextag'] : ''),
280 (isset($CONTEXT['caption']) ? $CONTEXT['caption'] : ''),
282 (isset($CONTEXT['current']) ? $CONTEXT['current'] : ''),
284 $template = str_replace($aySearch, $ayReplace, $template);
286 /*=== PRINT TEMPLATE ===*/
287 ob_start('ob_gzhandler');
289 print("\n".'<!-- Created by PHP Mini Gallery, (C) Richard Shred Koerber, https://github.com/shred/phpminigallery -->'."\n");