require_once('DB.php');
require_once('HTML/IT.php');
/*
* Check for gallery table existance. If it doesn't exist, create it.
*/
function check_table($db) {
if (in_array("gallery",$db->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();
?>