<?php
// TMS Rewritten - Early 2010
// By Joseph Robert Gillotti
defined('in_tms') or exit;
/*
* Custom exceptions used by following classes
*/
class cacheResampleException extends Exception {}
class cacheSaveException extends Exception {}
class cacheException extends Exception {}
class cacheOutputException extends Exception {}
/*
* Some standards used by these classes
*/
interface Thumbs {
// Settings
const
// Default sizes
DEFAULT_WIDTH = 100,
DEFAULT_HEIGHT = 70,
DEFAULT_TINY_WIDTH = 30,
DEFAULT_TINY_HEIGHT = 23,
MAX_WIDTH = 1000,
MAX_HEIGHT = 1000,
// Allow custom sizes?
// In theory this could cause problems. If so, make it false
AllowCustomSizes = true,
// Format for cached thumbs. (one of jpg, png, or gif)
IMG_FORMAT = 'jpg',
// And lastly, max cache custom sized thumbs
MAX_CUST_SIZES = 5;
public function isCached();
public function cachePath();
public function remove($all = false);
public function numCaches();
public function cache($overwrite = true, $save = true);
public function output_unsaved($type = self::IMG_FORMAT);
public function get_orig_path();
}
/*
* Functions and properties in common between these two classes
*/
abstract class Thumbs_base implements Thumbs {
// Hold these
protected $mid, $path, $size;
// When we're working on the new pic, keep resource here
protected
$new_image_resource;
/*
* Is this particular overview and size cached as a thumb?
*/
public function isCached() {
return file_exists($this->path) && is_readable($this->path);
}
/*
* Where is it?
*/
public function cachePath() {
return $this->path;
}
/*
* Remove it?
*/
public function remove($all = false) {
// Remove all cached thumbs for this overview
if ($all === true) {
$paths = (array) glob($sp['thumbs'] . $this->mid. '_*x*.'.self::IMG_FORMAT);
foreach ($paths as $p) {
@unlink($p);
@`rm -f $p`;
}
}
// Just remove the one at hand
else {
@unlink($this->path);
@`rm -f $this->path`;
}
}
/*
* Find out just how many custom sized thumbs we have saved for this image..
*/
public function numCaches() {
return count((array) glob($sp['thumbs'] . $this->mid. '_*x*.'.self::IMG_FORMAT));
}
/*
* Cache it, overwriting as necessary
*/
public function cache($overwrite = true, $save = true) {
global $sql, $allowed_picture_exts;
// If it exists and we're set not to overwrite and to save
if ($this->isCached() && $overwrite == false && $save == true)
throw new cacheException('Thumbnail exists and set not to overwrite.');
// If we've got too many and wanting to save this one, remove others
if ($save == true && $this->numCaches >= self::MAX_CUST_SIZES)
$this->remove(true);
/*
* Get original overview pic ready
*/
// Get path to it
$orig_path = $this->get_orig_path();
// Get it pretty
$orig_basename = basename($orig_path);
$orig_ext = get_file_extension($orig_basename);
// Make sure it has the usual image file extension
if (!in_array($orig_ext, $allowed_picture_exts))
throw new cacheException('Invalid original image file extension - '.$orig_path);
// Make sure it's an image and get the original dimensions
if (!($orig_info = @getimagesize($orig_path)))
throw new cacheException('Error getting original image info. Not a real image?');
// Get original height
list($orig_width, $orig_height, $orig_type) = $orig_info;
// Let's not make a piece of crap. (resize upwards)
if ($orig_width < $this->size[0] || $orig_height < $this->size[1])
$this->size = array($orig_width, $orig_height);
// Attempt loading it based on ext
if ($orig_type == IMAGETYPE_JPEG && !($orig_resource = @imagecreatefromjpeg($orig_path)))
throw new cacheResampleException('Could not load image from JPG');
elseif ($orig_type == IMAGETYPE_GIF && !($orig_resource = @imagecreatefromgif($orig_path)))
throw new cacheResampleException('Could not load image from GIF');
elseif ($orig_type == IMAGETYPE_PNG && !($orig_resource = imagecreatefrompng($orig_path)))
throw new cacheResampleException('Could not load image from PNG');
// We have it?
if (!is_resource($orig_resource))
throw new cacheResampleException("Could not load image resource - $orig_ext - $orig_type");
/*
* Get new image ready
*/
if (!($this->new_image_resource = @imagecreatetruecolor($this->size[0], $this->size[1])))
throw new cacheResampleException('Could not create new image');
/*
* Resize original onto new
*/
if (!@imagecopyresampled($this->new_image_resource, $orig_resource, 0, 0, 0, 0, $this->size[0], $this->size[1], $orig_width, $orig_height))
throw new cacheResampleException('Could not resample image.');
/*
* Clean up
*/
@imagedestroy($orig_resource);
/*
* Now what?
*/
// If we're set to save it, do it depending on what we want
if ($save == true) {
// Save it as whateva
switch (self::IMG_FORMAT) {
case 'png':
if (!@imagepng($this->new_image_resource, $this->cachePath(), 9))
throw new cacheSaveException('Error saving as png');
break;
case 'jpg':
if (!@imagejpeg($this->new_image_resource, $this->cachePath(), 85))
throw new cacheSaveException('Error saving as jpg');
break;
case 'gif':
if (!@imagegif($this->new_image_resource, $this->cachePath()))
throw new cacheSaveException('Error saving as gif');
break;
default:
throw new cacheSaveException('Not sure what to save it as');
break;
}
// I assume we're done with it?
imagedestroy($this->new_image_resource);
}
else {
// Otherwise, we're done. Some other method will deal with
// the $this->new_image_resource resource
}
}
/*
* Output a previously cached()'d (but not saved) image to browser directly.
*/
public function output_unsaved($type = 'png') {
// Gotta exist..
if (!is_resource($this->new_image_resource))
throw new cacheException('Cannot output nonexistant image.');
// Deal with giving it
switch ($type) {
case 'png':
if (!@imagepng($this->new_image_resource, null, 9))
throw new cacheOutputException('Error outputting as png');
break;
case 'jpg':
if (!@imagejpeg($this->new_image_resource))
throw new cacheOutputException('Error outputting as png');
break;
case 'gif':
if (!@imagegif($this->new_image_resource))
throw new cacheOutputException('Error outputting as png');
break;
default:
throw new cacheOutputException('Not sure what to output it as');
break;
}
}
}
/*
* Deal with caching and generating overview thumbnails
*/
class OV_Thumbs extends Thumbs_base implements Thumbs {
/*
* Get map ID and size localized
*/
function __construct($mid, $size = 'normal') {
global $sp, $sql;
/*
* Localize map id
*/
$this->mid = $sql->prot($mid);
/*
* Determine size
*/
// Small. Used in map lists
if ($size == 'tiny')
$this->size = array(self::DEFAULT_TINY_WIDTH, self::DEFAULT_TINY_HEIGHT);
// Custom. Nothing insanely huge since these are thumbs
elseif (is_array($size) && count($size) == 2 && (int) $size[0] < self::MAX_WIDTH && (int) $size[1] < self::MAX_HEIGHT && self::AllowCustomSizes === true)
$this->size = $size;
// Usual
else
$this->size = array(self::DEFAULT_WIDTH, self::DEFAULT_HEIGHT);
// Determine path
$this->path = $sp['thumbs'] . $this->mid . '_' . $this->size[0] . 'x' . $this->size[1] . '.'.self::IMG_FORMAT;
}
/*
* Get path to original overview image
*/
public function get_orig_path() {
global $sql, $sp;
// Load current overview image
$get_orig = $sql->query("select `img` from `maps` where `id` = '{$this->mid}' limit 1");
// Map doesn't exist??
if ($sql->num($get_orig) == 0)
throw new cacheException('Image ID does not exist');
// Get path to overview
list($orig_path) = $sql->fetch_row($get_orig);
$sql->free($get_orig);
// Remove terrible things
$orig_path = str_replace(array('/home/jrgporg/public_html/tms/','maps/'), '', $orig_path);
// Base path off of where we are
$orig_path = $sp['maps'] . $orig_path;
// Make sure it exists..
if (!file_exists($orig_path))
throw new cacheException('Original image not found');
// Return it..
return realpath($orig_path);
}
}
/*
* Deal with caching and generating screenshot thumbnails
* In some areas it differs significantly from the above
*/
class SCN_Thumbs extends Thumbs_base implements Thumbs {
// Screenshot number
protected $scrn;
/*
* Get map ID and size localized
*/
function __construct($mid, $size = 'normal', $screenshot = 1) {
global $sp, $sql;
/*
* Localize map id and screenshot number
*/
$this->mid = $sql->prot($mid);
$this->scrn = $sql->prot($screenshot);
/*
* Validate screenshot number. Can only be 1-3
*/
if (!in_array($screenshot, range(1, 3)))
throw new cacheException('Invalid screenshot number');
/*
* Determine size
*/
// Small. Used in map lists
if ($size == 'tiny')
$this->size = array(self::DEFAULT_TINY_WIDTH, self::DEFAULT_TINY_HEIGHT);
// Custom. Nothing insanely huge since these are thumbs
elseif (is_array($size) && count($size) == 2 && (int) $size[0] < self::MAX_WIDTH && (int) $size[1] < self::MAX_HEIGHT && self::AllowCustomSizes === true)
$this->size = $size;
// Usual
else
$this->size = array(self::DEFAULT_WIDTH, self::DEFAULT_HEIGHT);
// Determine path
$this->path = $sp['thumbs'] . $this->mid . '_sc'.$screenshot.'_' . $this->size[0] . 'x' . $this->size[1] . '.'.self::IMG_FORMAT;
}
/*
* Get path to original screenshot image
*/
public function get_orig_path() {
global $sql, $sp;
// Load current overview image
$get_orig = $sql->query("select `sc{$this->scrn}` from `maps` where `id` = '{$this->mid}' limit 1");
// Map doesn't exist??
if ($sql->num($get_orig) == 0)
throw new cacheException('Image ID does not exist');
// Get path to screenshot
list($orig_path) = $sql->fetch_row($get_orig);
$sql->free($get_orig);
// None?
$orig_path = trim($orig_path);
if ($orig_path == '')
throw new cacheException('Map does not have screenshot #'.$this->scrn);
// Remove terrible things
$orig_path = str_replace(array('/home/jrgporg/public_html/tms/','maps/'), '', $orig_path);
// Base path off of where we are
$orig_path = $sp['maps'] . $orig_path;
// Make sure it exists..
if (!file_exists($orig_path) || !is_file($orig_path))
throw new cacheException('Original screenshot not found');
// Return it..
return realpath($orig_path);
}
}