2021-09-08 19:52:21 +02:00
|
|
|
<?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();
|
2021-10-06 21:01:02 +02:00
|
|
|
$index = \gp\tool::ArrayKey($_GET['i'], (array)self::$index );
|
2021-09-08 19:52:21 +02:00
|
|
|
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'];
|
2021-10-06 21:01:02 +02:00
|
|
|
$info['index'] = array_search($img,(array)self::$index);
|
2021-09-08 19:52:21 +02:00
|
|
|
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';
|
2021-10-06 21:01:02 +02:00
|
|
|
return \gp\tool\Files::SaveData($index_file,'image_index',(array)self::$index,'meta_data',$meta);
|
2021-09-08 19:52:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|