Location: PHPKode > scripts > ImgBrowz0r > imgbrowz0r/imgbrowz0r.class.php
<?php

/* ---------------------------------------------------------------------------

	ImgBrowz0r, a simple PHP5 Gallery class
	Version 0.2.2, September 26th, 2008
	http://61924.wepwnyou.net/projects/imgbrowz0r.html

	Copyright (c) 2008	Frank Smit
	License: http://www.gzip.org/zlib/zlib_license.html

	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	1. The origin of this software must not be misrepresented; you must not
	   claim that you wrote the original software. If you use this software
	   in a product, an acknowledgment in the product documentation would be
	   appreciated but is not required.

	2. Altered source versions must be plainly marked as such, and must not be
	   misrepresented as being the original software.

	3. This notice may not be removed or altered from any source
	   distribution.

   --------------------------------------------------------------------------- */

define('IMGBROWZ0R_VERSION', '0.2.2');

class imgbrowz0r
{
	public $cur_category, $cur_category_name;
	private $cur_category_encoded, $config, $display=false;
	static public $supported_image_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
	// The constructor
	public function __construct($config)
	{
		// First check if GD is enabled
		if (!extension_loaded('gd') && !function_exists('gd_info'))
			exit('<a href="http://www.php.net/manual/en/book.image.php">GD</a> is not enabled!');

		// Set configuration
		$this->config = array(
			// Gallery settings - Note that 'basefile' and 'gallery_dir' are required
			'basefile'				=> isset($config['basefile']) ? $config['basefile'] : exit('You have to set a basefile!'),
			'gallery_dir'			=> isset($config['gallery_dir']) ? $config['gallery_dir'] : exit('You have to set a path to your gallery folder!'),
			'thumbs_per_page'		=> isset($config['thumbs_per_page']) ? $config['thumbs_per_page'] : 12,
			'max_thumb_row' 		=> isset($config['max_thumb_row']) ? $config['max_thumb_row'] : 4,

			// Thumbnail settings
			'max_thumb_width'		=> isset($config['max_thumb_width']) ? $config['max_thumb_width'] : 200,
			'max_thumb_height'		=> isset($config['max_thumb_height']) ? $config['max_thumb_height'] : 200,
			'no_thumb_image'		=> isset($config['no_thumb_image']) ? $config['no_thumb_image'] : 'no-thumbnail.png',

			// Template settings
			'category_template' 	=> isset($config['category_template']) ? $config['category_template'] : '<a class="thumb" href="%URL%" title="%NAME%"><img src="%THUMB%" alt="%NAME%" /></a><div class="title">%NAME%</div><div class="date">%CREATION_TIME%</div>',
			'thumb_template'		=> isset($config['thumb_template']) ? $config['thumb_template'] : '<a class="thumb" href="%URL%" title="%NAME%"><img src="%THUMB%" alt="%NAME%" /></a><div class="date">%UPLOAD_TIME%</div>',

			// Time settings
			'time_format'			=> isset($config['time_format']) ? $config['time_format'] : 'd-m-Y H:i:s',
			'time_zone' 			=> isset($config['time_zone']) ? $config['time_zone'] : 0
		);

		// Set vars
		$this->cur_category = isset($_GET['c']) ? ereg_replace('[^A-Za-z0-9,_ -()]','', self::base64_url_decode($_GET['c'])) : false;
		$this->cur_category_encoded = $this->cur_category !== false ? ereg_replace('[^A-Za-z0-9,_ -()]','', $_GET['c']) : false;
		$this->cur_category_name = $this->cur_category !== false ? $this->get_cat_name($this->cur_category) : false;
	}

	public function display()
	{
		if ($this->display === false)
		{
			$output = '';

			if ($this->cur_category !== false)
				$output .= $this->view_images();
			else
				$output .= $this->view_categories();

			echo '<div id="imgbrowz0r">'."\n\n".$output."\n\n".'</div>';

			$this->display = true;
		}
	}

	// Fetch categories
	private function view_categories()
	{
		$output = '';
		$total_count = 0;
		$page_links = '';
		$categories = array();
		$temp_categories = glob($this->config['gallery_dir'].'*', GLOB_ONLYDIR);

		// Check if there are categories
		if (count($temp_categories) < 1)
			return '<p class="info">There are currently no categories in this gallery.</p>';

		// Gather info
		foreach ($temp_categories as $category)
		{
			$total_count += $category_images = count(array_merge(glob($category.'/*.jpg'), glob($category.'/*.png'), glob($category.'/*.gif')));

			if ($category_images > 0)
			{
				$category_thumbs = array_merge(glob($category.'/thumbs/*.jpg'), glob($category.'/thumbs/*.png'), glob($category.'/thumbs/*.gif'));
				$category_thumbs_count = count($category_thumbs);

				$this_category_name = $this->get_cat_name($category);

				$categories[] = array(
					'thumb' 		=> !empty($category_thumbs_count) ? $category_thumbs[mt_rand(0, $category_thumbs_count-1)] : $this->config['no_thumb_image'],
					'name'			=> $this_category_name,
					'url'			=> $this->config['basefile'].'?c='.self::base64_url_encode(basename($category)),
					'creation_time' => filectime($category)
					);
			}
		}

		// Check if there are images
		if ($total_count === 0)
			return '<p class="info">There are currently no categories in this gallery.</p>';

		// Sorting
		if (($category_count = count($categories)) > 0)
		{
			foreach($categories as $res) $sortAux[] = $res['creation_time'];
			array_multisort($sortAux, SORT_DESC, $categories);
		}

		// Gallery info
		$output .= "\n\t".'<p class="info">'.($category_count == 1 ? 'There is '.$category_count.' category' : 'There are '.$category_count.' categories').' in this gallery and a total of '.$total_count.' images.</p>'."\n";

		// Pagination
		$page_count = ceil($category_count / $this->config['thumbs_per_page']);

		$start_img = isset($_GET['p']) && intval($_GET['p']) <= $page_count ? (intval($_GET['p'])-1) * $this->config['thumbs_per_page'] : 0;
		$end_img = ($start_img+$this->config['thumbs_per_page']) <=  $category_count ? $start_img+$this->config['thumbs_per_page'] : $category_count;

		for($p=1;$p <= $page_count;$p++)
		{
			if (isset($_GET['p']) && $p == intval($_GET['p']) || ($start_img == '0' && $p == 1))
				$page_links .= '<a href="'.$this->config['basefile'].'?p='.$p.'"><strong>'.$p.'</strong></a>'.($p != $page_count ? ' &middot; ' : '');
			else
				$page_links .= '<a href="'.$this->config['basefile'].'?p='.$p.'">'.$p.'</a>'.($p != $page_count ? ' &middot; ' : '');
		}

		if ($page_count > 1)
			$output .= "\n\t".'<p class="pagination">Pages: '.$page_links.'</p>'."\n";

		$output .= "\n\t".'<table>'."\n\t\t".'<tr>';

		$row_count = 1;
		for($x=$start_img;$x < $end_img;$x++)
		{
			$output .= "\n\t\t\t".'<td>'."\n\t\t\t\t".'<div id="cat-'.$x.'">'.strtr($this->config['category_template'], array('%THUMB%' => $categories[$x]['thumb'], '%NAME%' => $categories[$x]['name'], '%URL%' => $categories[$x]['url'], '%CREATION_TIME%' => $this->format_time($categories[$x]['creation_time']))).'</div>'."\n\t\t\t".'</td>';

			if ($row_count == $this->config['max_thumb_row'] && ($x+1) < $end_img)
			{
				$output .= "\n\t\t".'</tr>'."\n\t\t".'<tr>';
				$row_count = 0;
			}

			$row_count++;
		}

		$output .= "\n\t\t".'</tr>'."\n\t".'</table>'."\n";

		// Pagination
		if ($page_count > 1)
			$output .= "\n\t".'<p class="pagination">Pages: '.$page_links.'</p>'."\n";

		return '<div id="categories">'.$output.'</div>';
	}

	// Fetch images
	private function view_images()
	{
		$output = NULL;
		$page_links = NULL;
		$cur_category_path = $this->config['gallery_dir'].$this->cur_category;

		// Check if category exists
		if (!is_dir($cur_category_path))
			return '<p class="info">Category does not exist. Click <a href="'.$this->config['basefile'].'">here</a> to go back to the category overview.</p>';

		$opendir  = opendir($cur_category_path);
		while (false !== ($image = readdir($opendir)))
		{
			// get file extension
			$file_extension = self::get_ext($cur_category_path.'/'.$image);

			// Check if file is an supported image type
			if (!in_array($file_extension, self::$supported_image_types))
				continue;

			$images[] = array(
				'thumb' 		=> $cur_category_path.'/thumbs/thumb_'.$image,
				'name'			=> $image,
				'url'			=> $cur_category_path.'/'.$image,
				'upload_time'	=> filectime($cur_category_path.'/'.$image)
				);
		}

		// Check if there are images in the current category
		if (($image_count = count($images)) < 1)
			return '<p class="info">There are currently no images in this category. Click <a href="'.$this->config['basefile'].'">here</a> to go back to the category overview.</p>';

		// Sorting
		foreach($images as $res) $sortAux[] = $res['upload_time'];
		array_multisort($sortAux, SORT_DESC, $images);

		// Category info
		$output .= "\n\t".'<p class="info">You are viewing <strong>'.$this->cur_category_name.'</strong>, <a href="'.$this->config['basefile'].'">click here</a> to go back. There are '.$image_count.' images in this category.</p>'."\n";

		// Pagination
		$page_count = ceil($image_count / $this->config['thumbs_per_page']);

		$start_img = isset($_GET['p']) && intval($_GET['p']) <= $page_count ? (intval($_GET['p'])-1) * $this->config['thumbs_per_page'] : 0;
		$end_img = ($start_img+$this->config['thumbs_per_page']) <=  $image_count ? $start_img+$this->config['thumbs_per_page'] : $image_count;

		for($p=1;$p <= $page_count;$p++)
		{
			if (isset($_GET['p']) && $p == intval($_GET['p']) || ($start_img == '0' && $p == 1))
				$page_links .= '<a href="'.$this->config['basefile'].'?c='.$this->cur_category_encoded.'&amp;p='.$p.'"><strong>'.$p.'</strong></a>'.($p != $page_count ? ' &middot; ' : '');
			else
				$page_links .= '<a href="'.$this->config['basefile'].'?c='.$this->cur_category_encoded.'&amp;p='.$p.'">'.$p.'</a>'.($p != $page_count ? ' &middot; ' : '');
		}

		if ($page_count > 1)
			$output .= "\n\t".'<p class="pagination">Pages: '.$page_links.'</p>'."\n";

		$output .= "\n\t".'<table>'."\n\t\t".'<tr>';

		// Build image table
		$row_count = 1;
		for($x=$start_img;$x < $end_img;$x++)
		{
			// Make thumbnail if there isn't one
			if (!file_exists($images[$x]['thumb']))
				$this->make_thumb($cur_category_path, $images[$x]['name']);

			$output .= "\n\t\t\t".'<td>'."\n\t\t\t\t".'<div id="img-'.$x.'">'.str_replace(array('%THUMB%', '%NAME%', '%URL%', '%UPLOAD_TIME%'), array($images[$x]['thumb'], $images[$x]['name'], $images[$x]['url'], $this->format_time($images[$x]['upload_time'])), $this->config['thumb_template']).'</div>'."\n\t\t\t".'</td>';

			if ($row_count == $this->config['max_thumb_row'] && ($x+1) < $end_img)
			{
				$output .= "\n\t\t".'</tr>'."\n\t\t".'<tr>';
				$row_count = 0;
			}

			$row_count++;
		}

		$output .= "\n\t\t".'</tr>'."\n\t".'</table>'."\n";

		// Pagination
		if ($page_count > 1)
			$output .= "\n\t".'<p class="pagination">Pages: '.$page_links.'</p>'."\n";

		return '<div id="images">'.$output.'</div>';
	}

	// Get name of category, patch provided by Serge Timakov
	private function get_cat_name($category)
	{
		$category = basename($category);
		$category_name_file = $this->config['gallery_dir'].$category.'/.name';

		if (file_exists($category_name_file))
			return htmlspecialchars(file_get_contents($category_name_file), ENT_QUOTES, 'UTF-8');
		else
			return $category;
	}

	// Checks and prepares the source image and makes a thumbnail of it
	private function make_thumb($image_folder, $image_name)
	{
		$no_resize = false;

		//Check if thumb dir exists
		if (!is_dir($image_folder.'/thumbs'))
			mkdir($image_folder.'/thumbs', 0777);

		// Get image information
		$image_info = self::get_image_info($image_folder.'/'.$image_name);

		// Check if file is an supported image type
		if (!in_array($image_info['extension'], self::$supported_image_types))
			return false;

		// Open the image so we can make a thumbnail
		if ($image_info['type'] == 3)
			$image = imagecreatefrompng($image_folder.'/'.$image_name);
		else if ($image_info['type'] == 2)
			$image = imagecreatefromjpeg($image_folder.'/'.$image_name);
		else if ($image_info['type'] == 1)
			$image = imagecreatefromgif($image_folder.'/'.$image_name);
		else
			return false;

		// Calculate new width and height
		if ($image_info['height'] > $image_info['width'])
		{
			$thumb_width = floor($image_info['width'] * ($this->config['max_thumb_height'] / $image_info['height']));
			$thumb_height = $this->config['max_thumb_height'];
		}
		else if ($image_info['width'] > $image_info['height'])
		{
			$thumb_width = $this->config['max_thumb_width'];
			$thumb_height = floor($image_info['height'] * ($this->config['max_thumb_width'] / $image_info['width']));
		}
		else if ($image_info['width'] == $image_info['height'] && $image_info['width'] > $this->config['max_thumb_width'])
		{
			$thumb_width = $this->config['max_thumb_width'];
			$thumb_height = $this->config['max_thumb_height'];
		}
		else
		{
			$thumb_width = $image_info['width'];
			$thumb_height = $image_info['height'];
			$no_resize = true;
		}

		// Copy image into new one
		if ($no_resize === false)
		{
			$thumbnail = imagecreatetruecolor($thumb_width, $thumb_height);

			// Preserve transparency in PNG and GIF images
			if ($image_info['type'] === 3)
			{
				imagealphablending($thumbnail, false);
				imagesavealpha($thumbnail, true);
			}
			else if ($image_info['type'] === 1 && ($transparent_index = imagecolortransparent($image)) >= 0)
			{
				imagepalettecopy($image, $thumbnail);
				imagefill($thumbnail, 0, 0, $transparent_index);
				imagecolortransparent($thumbnail, $transparent_index);
				imagetruecolortopalette($thumbnail, true, 256);
			}

			imagecopyresampled($thumbnail, $image, 0, 0, 0, 0, $thumb_width, $thumb_height, $image_info['width'], $image_info['height']);
		}
		else
			$thumbnail = $image;

		// Save the thumbnail, but first check what kind of file it is
		if ($image_info['type'] == 3)
			imagepng($thumbnail, $image_folder.'/thumbs/thumb_'.$image_name);
		else if ($image_info['type'] == 2)
			imagejpeg($thumbnail, $image_folder.'/thumbs/thumb_'.$image_name, 85);
		else if ($image_info['type'] == 1)
			imagegif($thumbnail, $image_folder.'/thumbs/thumb_'.$image_name);

		// Destroy
		imagedestroy($thumbnail);
	}

	// Format unixtimestamp to a human readable date
	private function format_time($timestamp)
	{
		return gmdate($this->config['time_format'], ($timestamp + $this->config['time_zone'] * 3600));
	}

	// A url safe base64 en/de- code
	static private function base64_url_encode($input)
	{
		return strtr(base64_encode($input), '+/=', '-_,');
	}

	static private function base64_url_decode($input)
	{
		return base64_decode(strtr($input, '-_,', '+/='));
	}

	// Get info from image
	static private function get_image_info($filepath)
	{
		$getimagesize = getimagesize($filepath);

		return array('width' => $getimagesize[0], 'height' => $getimagesize[1], 'type' => $getimagesize[2], 'extension' => self::get_ext($filepath));
	}

	// Get extension from image
	static private function get_ext($filepath)
	{
		$explode = explode('.', $filepath);

		return $explode[count($explode)-1];
	}
}

?>
Return current item: ImgBrowz0r