301 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			301 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
if( !defined('is_running' ) ){
 | 
						|
 | 
						|
	define('is_running',true);
 | 
						|
	define('gpdebug',false);
 | 
						|
	define('gp_cookie_cmd',false);
 | 
						|
	//define('gp_dev_combine',false); //prevents cache and 304 header when set to true
 | 
						|
 | 
						|
	require_once('common.php');
 | 
						|
	\gp\tool::EntryPoint(1,'image.php',false);
 | 
						|
	new gp_resized();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
class gp_resized{
 | 
						|
 | 
						|
	public $img;
 | 
						|
	public $height;
 | 
						|
	public $width;
 | 
						|
	public static $index = false;
 | 
						|
	private static $index_checksum = false;
 | 
						|
	private static $last_index = '9';
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Check the path of the img, return full path of image if the requested image is found
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	function __construct(){
 | 
						|
		global $dataDir;
 | 
						|
 | 
						|
		if( !isset($_GET['w']) || !isset($_GET['h']) || !isset($_GET['img']) ){
 | 
						|
			self::Send404();
 | 
						|
			//dies
 | 
						|
		}
 | 
						|
 | 
						|
		$img		= $_GET['img'];
 | 
						|
		$height		= $_GET['h'];
 | 
						|
		$width		= $_GET['w'];
 | 
						|
 | 
						|
		if( !is_numeric($height) || !is_numeric($width) ){
 | 
						|
			self::Send404();
 | 
						|
			//dies
 | 
						|
		}
 | 
						|
 | 
						|
		$width		= (int)$width;
 | 
						|
		$height		= (int)$height;
 | 
						|
		$img		= \gp\tool\Files::NoNull($img);
 | 
						|
 | 
						|
		//check file path
 | 
						|
		if( strpos($img,'./') !== false || strpos($img,'%2f') !== false || strpos($img,'%2F') !== false ){
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		//make sure the index is set
 | 
						|
		gp_resized::SetIndex();
 | 
						|
		$index		= \gp\tool::ArrayKey($_GET['i'], (array)self::$index );
 | 
						|
		if( !$index ){
 | 
						|
			self::Send404();
 | 
						|
			//dies
 | 
						|
		}
 | 
						|
 | 
						|
		//if the image has been renamed, redirect to the new name
 | 
						|
		$index_img = self::$index[$index];
 | 
						|
		if( $index_img != $img ){
 | 
						|
			$path = \gp\tool::GetDir('/include/image.php',false).'?i='.$index.'&w='.$width.'&h='.$height.'&img='.rawurlencode($index_img);
 | 
						|
			\gp\tool::Redirect($path);
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		$info			= self::ImageInfo($img,$width,$height);
 | 
						|
		$folder			= $dataDir.'/data/_resized/'.$info['index'];
 | 
						|
		$full_path		= $folder.'/'.$info['name'];
 | 
						|
 | 
						|
		//if it exists return true
 | 
						|
		if( file_exists($full_path) ){
 | 
						|
			header('Cache-Control: public, max-age=5184000');//60 days
 | 
						|
 | 
						|
			//attempt to send 304
 | 
						|
			$stats = lstat($full_path);
 | 
						|
			if( $stats ){
 | 
						|
				\gp\tool::Send304( \gp\tool::GenEtag( $stats['mtime'], $stats['size'] ) );
 | 
						|
			}
 | 
						|
 | 
						|
			header('Content-Transfer-Encoding: binary');
 | 
						|
			header('Content-Type: '.$info['ctype']);
 | 
						|
			readfile($full_path);
 | 
						|
			die();
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		//redirect to next largest image if available
 | 
						|
		$usage = self::GetUsage($info['index']);
 | 
						|
		foreach($usage as $size => $data){
 | 
						|
			if( !$data['uses'] ){
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
			list($use_width,$use_height) = explode('x',$size);
 | 
						|
			if( ($use_width >= $width && $use_height > $height)
 | 
						|
				|| ($use_width > $width && $use_height >= $height)
 | 
						|
				){
 | 
						|
 | 
						|
					$path = \gp\tool::GetDir('/include/image.php',false).'?i='.$index.'&w='.$use_width.'&h='.$use_height.'&img='.rawurlencode($img);
 | 
						|
					\gp\tool::Redirect($path);
 | 
						|
					//dies
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		//redirect to full size image
 | 
						|
		$original = \gp\tool::GetDir('/data/_uploaded'.$img,false);
 | 
						|
		\gp\tool::Redirect($original);
 | 
						|
		//dies
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Send a 404 Not Found header to the client
 | 
						|
	 */
 | 
						|
	static function Send404(){
 | 
						|
		\gp\tool::status_header(404,'404 Not Found');
 | 
						|
		die();
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Return information about a resized image
 | 
						|
	 * 	- path
 | 
						|
	 *  - extension
 | 
						|
	 *  - ctype
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function ImageInfo($img,$width,$height){
 | 
						|
		global $dataDir;
 | 
						|
		$info = array();
 | 
						|
 | 
						|
		$part_name = basename($img);
 | 
						|
		$parts = explode('.',$part_name);
 | 
						|
		if( count($parts) == 0 ){
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
		$info['extension'] = array_pop($parts);
 | 
						|
		$part_name = implode('.',$parts);
 | 
						|
 | 
						|
		switch(strtolower($info['extension'])){
 | 
						|
			case 'gif':
 | 
						|
				$info['ctype'] = 'image/gif';
 | 
						|
			break;
 | 
						|
			case 'png':
 | 
						|
				$info['ctype'] = 'image/png';
 | 
						|
			break;
 | 
						|
			case 'jpeg':
 | 
						|
			case 'jpg':
 | 
						|
				$info['ctype'] = 'image/jpg';
 | 
						|
			break;
 | 
						|
			default:
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		//check to see if the reduced image exists
 | 
						|
		$info['name'] = $width.'x'.$height.'.'.$info['extension'];
 | 
						|
		$info['index'] = array_search($img,(array)self::$index);
 | 
						|
		return $info;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get a new folder
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function NewFolder(){
 | 
						|
		global $dataDir;
 | 
						|
		$new_index = gp_resized::NewIndex();
 | 
						|
		return $dataDir.'/data/_resized/'.$new_index;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the next index
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function NewIndex(){
 | 
						|
		$next_numeric = base_convert(self::$last_index,36,10)+1;
 | 
						|
		do{
 | 
						|
			$index = array();
 | 
						|
			$this_numeric = $next_numeric;
 | 
						|
			do{
 | 
						|
				$index[] = base_convert( substr($this_numeric,-2),10,36);
 | 
						|
				$this_numeric = floor($this_numeric/100);
 | 
						|
			}while($this_numeric >= 1);
 | 
						|
 | 
						|
			$index = implode('/',array_reverse($index));
 | 
						|
			$next_numeric++;
 | 
						|
		}while( is_numeric($index) || isset(self::$index[$index]) );
 | 
						|
 | 
						|
		self::$last_index = $index;
 | 
						|
		return $index;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the image index information
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function SetIndex(){
 | 
						|
		global $dataDir;
 | 
						|
 | 
						|
		//prevent setting twice
 | 
						|
		if( self::$index !== false ){
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$index_file		= $dataDir.'/data/_site/image_index.php';
 | 
						|
		self::$index	= \gp\tool\Files::Get($index_file,'image_index');
 | 
						|
 | 
						|
		if( self::$index ){
 | 
						|
			self::$index_checksum	= self::checksum(self::$index);
 | 
						|
 | 
						|
			if( isset(\gp\tool\Files::$last_meta['last_index']) ){
 | 
						|
				self::$last_index		= \gp\tool\Files::$last_meta['last_index'];
 | 
						|
			}elseif( isset(\gp\tool\Files::$last_stats['last_index']) ){			//pre 4.3.6
 | 
						|
				self::$last_index		= \gp\tool\Files::$last_stats['last_index'];
 | 
						|
			}
 | 
						|
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Save the image index information if the checksum has changed
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function SaveIndex(){
 | 
						|
		global $dataDir;
 | 
						|
 | 
						|
		if( self::$index_checksum === self::checksum(self::$index) ){
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
 | 
						|
		$meta = array('last_index'=>self::$last_index);
 | 
						|
 | 
						|
		$index_file = $dataDir.'/data/_site/image_index.php';
 | 
						|
		return \gp\tool\Files::SaveData($index_file,'image_index',(array)self::$index,'meta_data',$meta);
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Generate a checksum for the $array
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function checksum($array){
 | 
						|
		return md5(serialize($array) );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get usage information about a image
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function GetUsage($index){
 | 
						|
		return \gp\tool\Files::Get('_resized/'.$index.'/data','usage');
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get usage information about a image
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function SaveUsage($index,$data){
 | 
						|
		global $dataDir;
 | 
						|
		$data_file = $dataDir.'/data/_resized/'.$index.'/data.php';
 | 
						|
		return \gp\tool\Files::SaveData($data_file,'usage',$data);
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Return the folder path used for resized images of $img
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function Folder($img){
 | 
						|
		global $dataDir;
 | 
						|
		$name = basename($img);
 | 
						|
		return $dataDir.'/data/_resized'.\gp\tool::DirName($img).'/'.gp_resized::EncodePath($name);
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Encode a path component
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function EncodePath($path){
 | 
						|
		$encoded = base64_encode($path);
 | 
						|
		$encoded = rtrim($encoded, '=');
 | 
						|
		return strtr($encoded, '+/=', '-_.');
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Dencode a path component
 | 
						|
	 *
 | 
						|
	 */
 | 
						|
	static function DecodePath($encoded){
 | 
						|
		$encoded = strtr($encoded, '-_.', '+/=');
 | 
						|
		return base64_decode($encoded);
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 |