getCol("show tables"))) { return; } $db->query("create table gallery (image_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, path VARCHAR(255), mini_thumb MEDIUMBLOB, thumb MEDIUMBLOB, width INT, height INT, size INT)"); if (DB::isError($db)) { die ($db->getMessage()); } } /* * Recursive directory listing, returns files only with full path. * Will hunt to depth $sub_dirs. */ function get_dir_listing($dir, $sub_dirs) { $listing = array(); $sub_listing = array(); $dh = opendir($dir); while ($file = readdir($dh)) { $path = $dir.$file; if (is_dir($path)) { if ($file==".." || $file==".") { continue; } array_push($sub_listing, $path."/"); } else { array_push($listing, $path); } } closedir($dh); if ($sub_dirs) { foreach ($sub_listing as $d) { $m = get_dir_listing($d, $sub_dirs-1); // Buggy PHP can't handle assignment into an argument $result = array_merge($listing, get_dir_listing($d, 0)); $listing = $result; } } sort($listing); return $listing; } /* * Resizes a GD image and returns a string containing the image as a JPEG, * encoded appropriately for insertion into a MySQL database * */ function get_resampled($im, $w, $h) { $sx = imagesx($im); $sy = imagesy($im); if ($sx>$sy) { $h = (int)(($sy/$sx)*$w); } else { $w = (int)(($sx/$sy)*$h); } $new_im = ImageCreateTrueColor($w,$h); ImageCopyResampled($new_im, $im, 0,0,0,0,$w,$h,$sx, $sy); ob_start(); ImageJPEG($new_im); $output=ob_get_contents(); ob_end_clean(); return mysql_escape_string($output); } /* * Resizes a file and inserts it into the database */ function add_file($db, $file) { global $config; $details = @GetImageSize($file); // We only accept JPEG if ($details[2] != 2) { return; } $im = ImageCreateFromJPEG($file); if (!$im) { die("GD Failed to load $file"); } $thumbnail = get_resampled($im, $config['image_index']['thumbnail_width'], $config['image_index']['thumbnail_height']); $mini_thumbnail = get_resampled($im, $config['category_index']['thumbnail_width'], $config['category_index']['thumbnail_height']); $db->query("insert into gallery (path,mini_thumb, thumb, width, height, size) values ('$file','$mini_thumbnail','$thumbnail',".$details[0].",".$details[1].",".ceil(filesize($file)/1024).")"); if (DB::isError($db)) { die ($db->getMessage()); } } /* * Removes a file from the database. */ function remove_file($db, $file) { $db->query("delete from gallery where path='$file'"); if (DB::isError($db)) { die ($db->getMessage()); } } /* * Does a full listing of the image directories, adds in any files not currently * in the database, removes those that no longer exist on the filesystem. */ function update_file_list($db) { global $config; $db_list = $db->getCol("select path from gallery"); $file_list = get_dir_listing($config['gallery']['directory'],1); $new_files = array_diff($file_list, $db_list); $removed_files = array_diff($db_list, $file_list); foreach ($new_files as $f) { add_file($db,$f); } foreach ($removed_files as $f) { remove_file($db, $f); } } /* * Some configuration checks, make sure things that should be directories are, and normalise * certain variables. */ function check_config($config) { if (!is_dir($config['gallery']['directory'])) { die("Error: configuration item 'directory' in section 'gallery' is not a valid directory"); } if (!preg_match('/\/$/',$config['gallery']['directory'])) { $config['gallery']['directory'].="/"; } if (!is_dir($config['gallery']['templates'])) { die("Error: configuration item 'templates' in section 'gallery' is not a valid directory"); } } $config = parse_ini_file('gallery.ini',TRUE); check_config($config); $db = DB::connect("mysql://".$config['database']['username'].":".$config['database']['password']."@".$config['database']['host']."/".$config['database']['database']); if (DB::isError($db)) { die ($db->getMessage()); } check_table($db); // Checks the table exists, sets it up if it doesn't. update_file_list($db); // Set up template object with path to templates. $tpl = new IntegratedTemplate($config['gallery']['templates']); // Security checks on user input if ($_GET['image'] && !preg_match('/^'.$config['gallery']['filename_regex'].'$/',$_GET['image'])) { die('Potential security violation, image contains illegal characters'); } if ($_GET['category'] && !preg_match('/^'.$config['gallery']['category_regex'].'$/',$_GET['category'])) { die('Potential security violation, category contains illegal characters'); } if ($GET['mode'] && !preg_match('/^[a-zA-Z_-]*$/',$_GET['mode'])) { die('Potential security violation, mode contains illegal characters'); } // General switch for the various script modes switch ($mode) { case "mini_thumb": $path = $config['gallery']['directory'].$_GET['category']."/".$_GET['image']; header('Content-type: image/jpeg'); echo $db->getOne("select mini_thumb from gallery where path='$path'"); break; case "thumb": $path = $config['gallery']['directory'].$_GET['category']."/".$_GET['image']; header('Content-type: image/jpeg'); echo $db->getOne("select thumb from gallery where path='$path'"); break; case "image": $path = $config['gallery']['directory'].$_GET['category']."/".$_GET['image']; header('Content-type: image/jpeg'); readfile($path); break; case "view": $nice_name = preg_replace('/.jpg|.jpeg$/','',$_GET['image']); $tpl->loadTemplatefile("image.tpl.html", true, true); $tpl->setCurrentBlock("image_details"); $tpl->setVariable("image",$nice_name); $tpl->setVariable("url","index.php?mode=image&category=".$_GET['category']."&image=".$_GET['image']); $tpl->parseCurrentBlock("image_details"); $tpl->show(); break; case "category": $files = $db->getCol("select path from gallery where path like '".$config['gallery']['directory'].$_GET['category']."/%' order by path"); $tpl->loadTemplatefile("category.tpl.html", true, true); $tpl->setCurrentBlock("category_details"); $tpl->setVariable("category",$_GET['category']); $tpl->parseCurrentBlock("category_details"); foreach ($files as $f) { preg_match('/.*\/([^\/]+)\/(.+)$/',$f,$d); $category_name = $d[1]; $image_name = $d[2]; $nice_name = preg_replace('/.jpg$/','',$image_name); $image_name = urlencode($image_name); $category_name = urlencode($category_name); $query = "select width,height,size from gallery where path='$f'"; list($width,$height,$size) = $db->getRow($query); $tpl->setCurrentBlock("image"); $tpl->setVariable("width", $width); $tpl->setVariable("height", $height); $tpl->setVariable("size", $size."kb"); $tpl->setVariable("image", $nice_name); $tpl->setVariable("thumbnail", "index.php?mode=thumb&category=$category_name&image=$image_name"); $tpl->setVariable("url", "index.php?mode=view&image=$image_name&category=$category_name"); $tpl->parseCurrentBlock("image"); $count++; if ($count == $config['image_index']['thumbnail_per_line']) { $count=0; $tpl->setCurrentBlock("image_row"); $tpl->parseCurrentBlock("image_row"); } } $tpl->show(); break; default: $list = array(); $files = $db->getCol("select path from gallery"); if (sizeof($files)==0) { die('No categories are available to view'); } foreach ($files as $f) { preg_match('/.*\/([^\/]+)\/(.+)$/',$f,$d); $category_name = $d[1]; if (!$list[$category_name]) { $list[$category_name] = array($d[2]); } else if (sizeof($list[$category_name]) < $config['category_index']['thumbnail_limit']) { array_push($list[$category_name],$d[2]); } } $tpl->loadTemplatefile("index.tpl.html", true, true); foreach (array_keys($list) as $category) { sort($list[$category]); foreach ($list[$category] as $image_name) { $nice_name = preg_replace('/.jpg$/','',$image_name); $tpl->setCurrentBlock("image"); $tpl->setVariable("name", $nice_name); $tpl->setVariable("thumbnail", "index.php?mode=mini_thumb&category=$category&image=$image_name"); $tpl->setVariable("url", "index.php?mode=image&image=$category/$image_name"); $tpl->parseCurrentBlock("image"); } $tpl->setCurrentBlock("category"); $tpl->setVariable("category",$category); $tpl->parseCurrentBlock("category"); } $tpl->show(); break; } $db->disconnect(); ?>