mirror of
				https://github.com/e107inc/e107.git
				synced 2025-10-27 03:31:47 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			622 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			622 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 	/**
 | |
| 	 * e107 website system
 | |
| 	 *
 | |
| 	 * Copyright (C) 2008-2020 e107 Inc (e107.org)
 | |
| 	 * Released under the terms and conditions of the
 | |
| 	 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
 | |
| 	 *
 | |
| 	 */
 | |
| 
 | |
| 
 | |
| 
 | |
| use Intervention\Image\ImageManagerStatic as Image;
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  */
 | |
| class e_thumbnail
 | |
| {
 | |
| 	private $_debug = false;
 | |
| 
 | |
| 	private $_cache = true;
 | |
| 
 | |
| 	/**
 | |
| 	 * Page request
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	protected $_request = array();
 | |
| 
 | |
| 	/**
 | |
| 	 * @var string image source path (e107 path shortcode)
 | |
| 	 */
 | |
| 	protected $_src = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * @var string source path modified/sanitized
 | |
| 	 */
 | |
| 	protected $_src_path = null;
 | |
| 
 | |
| 
 | |
| 	/** Stores watermark prefs
 | |
| 	 */
 | |
| 	protected $_watermark = array('activate'=>null);
 | |
| 
 | |
| 	protected $_placeholder = false;
 | |
| 
 | |
| 	protected $_thumbQuality = 65;
 | |
| 
 | |
| 	protected $_upsize = true;
 | |
| 
 | |
| 	protected $_forceWebP = false;
 | |
| 
 | |
| 	/**
 | |
| 	 * Constructor - init paths
 | |
| 	 *
 | |
| 	 *
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function __construct()
 | |
| 	{
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Initialize the class with e107 core prefs.
 | |
| 	 * @param array $pref
 | |
| 	 * @return null
 | |
| 	 */
 | |
| 	public function init($pref)
 | |
| 	{
 | |
| 		$this->parseRequest();
 | |
| 
 | |
| 		if(!empty($this->_request['noinit']))
 | |
| 		{
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		$this->_watermark = array(
 | |
| 			'activate'		=> vartrue($pref['watermark_activate'], false),
 | |
| 			'text'			=> vartrue($pref['watermark_text']),
 | |
| 			'size'			=> vartrue($pref['watermark_size'], 20),
 | |
| 			'pos'			=> vartrue($pref['watermark_pos'],"BR"),
 | |
| 			'color'			=> vartrue($pref['watermark_color'],'fff'),
 | |
| 			'font'			=> vartrue($pref['watermark_font']),
 | |
| 			'margin'		=> vartrue($pref['watermark_margin'],30),
 | |
| 			'shadowcolor'	=> vartrue($pref['watermark_shadowcolor'], '000000'),
 | |
| 			'opacity'		=> vartrue($pref['watermark_opacity'], 20)
 | |
| 		);
 | |
| 
 | |
| 		$this->_thumbQuality = vartrue($pref['thumbnail_quality'],65);
 | |
| 
 | |
| 		$this->_upsize = ((isset($this->_request['w']) && $this->_request['w'] > 110) || (isset($this->_request['aw']) && ($this->_request['aw'] > 110))); // don't resizeUp the icon images.
 | |
| 
 | |
| 		$this->_forceWebP = empty($this->_request['type']) && !empty($pref['thumb_to_webp']) && (strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false) ? true : false;
 | |
| 	//	var_dump($this);
 | |
| 	//	exit;
 | |
| 		return null;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param array $array keys: activate, text, size, pos, color, font, margin, shadowcolor, opacity. @see above.
 | |
| 	 */
 | |
| 	public function setWatermark($array)
 | |
| 	{
 | |
| 		$this->_watermark = (array) $array;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Enabled/Disable debugging/testing.
 | |
| 	 * @param $val
 | |
| 	 */
 | |
| 	public function setDebug($val)
 | |
| 	{
 | |
| 		$this->_debug = (bool) $val;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Enable/disable image caching.
 | |
| 	 * @param bool $val
 | |
| 	 */
 | |
| 	public function setCache($val)
 | |
| 	{
 | |
| 		$this->_cache = (bool) $val;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return $this
 | |
| 	 */
 | |
| 	private function parseRequest()
 | |
| 	{
 | |
| 
 | |
| 		$e_QUERY = !empty($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : e_QUERY;
 | |
| 
 | |
| 		if(isset($_GET['id'])) // very-basic url-tampering prevention and path cloaking
 | |
| 		{
 | |
| 			$e_QUERY = base64_decode($_GET['id']);
 | |
| 		}
 | |
| 
 | |
| 		$e_QUERY= str_replace('e_AVATAR', 'e_AVATAR/', $e_QUERY); // FIXME  Quick and dirty fix.
 | |
| 
 | |
| 		parse_str(str_replace('&', '&', $e_QUERY), $this->_request);
 | |
| 
 | |
| 		if(isset($this->_request['w']))
 | |
| 		{
 | |
| 			$this->_request['w'] = (int) $this->_request['w'];
 | |
| 		}
 | |
| 		if(isset($this->_request['h']))
 | |
| 		{
 | |
| 			$this->_request['h'] = (int) $this->_request['h'];
 | |
| 		}
 | |
| 
 | |
| 		return $this;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Manually Set the Request parameters
 | |
| 	 * @param array $array keys: w, h, ah, aw, c(rop)
 | |
| 	 */
 | |
| 	public function setRequest($array)
 | |
| 	{
 | |
| 		$this->_request = (array) $array;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return array|string|string[]
 | |
| 	 */
 | |
| 	private function getImageInfo()
 | |
| 	{
 | |
| 		$thumbnfo = pathinfo($this->_src_path);
 | |
| 
 | |
| 		if($this->_forceWebP === true || (!empty($this->_request['type']) && $this->_request['type'] == 'webp'))
 | |
| 		{
 | |
| 			$thumbnfo['extension'] = 'webp';
 | |
| 		}
 | |
| 
 | |
| 		return $thumbnfo;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Validate and Sanitize the Request.
 | |
| 	 * @return bool true when request is okay.
 | |
| 	 */
 | |
| 	public function checkSrc()
 | |
| 	{
 | |
| 		if(!vartrue($this->_request['src'])) // display placeholder when src is missing.
 | |
| 		{
 | |
| 			$this->_placeholder = true;
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		$tp = e107::getParser();
 | |
| 
 | |
| 		// convert raw to SC path
 | |
| 		$this->_request['src'] = str_replace($tp->getUrlConstants('raw'), $tp->getUrlConstants(), $this->_request['src']);
 | |
| 
 | |
| 		// convert absolute and full url to SC URL
 | |
| 		$this->_src = $tp->createConstants($this->_request['src'], 'mix');
 | |
| 
 | |
| 		if(preg_match('#^(https?|ftps?|file)://#i', $this->_request['src']))
 | |
| 		{
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		if(!is_writable(e_CACHE_IMAGE))
 | |
| 		{
 | |
| 			echo 'Cache folder not writeable! ';
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// convert to relative server path
 | |
| 		$path = $tp->replaceConstants(str_replace('..', '', $this->_src)); //should be safe enough
 | |
| 
 | |
| 		if(is_file($path) && is_readable($path))
 | |
| 		{
 | |
| 			$this->_src_path = $path;
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		if($this->_debug === true || defined("e_DEBUG_THUMBNAIL"))
 | |
| 		{
 | |
| 			echo "File Not Found: ".$path;
 | |
| 		}
 | |
| 
 | |
| 		$this->_placeholder = true;
 | |
| 		return true;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return $this|false|string|void
 | |
| 	 */
 | |
| 	public function sendImage()
 | |
| 	{
 | |
| 		if($this->_placeholder == true)
 | |
| 		{
 | |
| 			$width = ($this->_request['aw']) ? $this->_request['aw'] : $this->_request['w'];
 | |
| 			$height = ($this->_request['ah']) ? $this->_request['ah'] : $this->_request['h'];
 | |
| 
 | |
| 			$parm = array('size' => $width."x".$height);
 | |
| 
 | |
| 			$this->placeholder($parm);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		if(!$this->_src_path) // would only happen during testing.
 | |
| 		{
 | |
| 			echo "no source";
 | |
| 			return $this;
 | |
| 		}
 | |
| 
 | |
| 		$thumbnfo = $this->getImageInfo();
 | |
| 		$options = $this->getRequestOptions();
 | |
| 
 | |
| 		$fname = e107::getParser()->thumbCacheFile($this->_src_path, $options);
 | |
| 		$cache_filename = e_CACHE_IMAGE . $fname;
 | |
| 
 | |
| 		$this->sendCachedImage($cache_filename, $thumbnfo);
 | |
| 
 | |
| 		// No Cached file found - proceed with image creation.
 | |
| 
 | |
| 		$img = Image::make($this->_src_path);
 | |
| 
 | |
| 
 | |
| 		if(!empty($options['c'])) // Cropping:  $quadrant T(op), B(ottom), C(enter), L(eft), R(right)
 | |
| 		{
 | |
| 			if(!empty($this->_request['ah']))
 | |
| 			{
 | |
| 				$this->_request['h'] = $this->_request['ah'];
 | |
| 			}
 | |
| 
 | |
| 			if(!empty($this->_request['aw']))
 | |
| 			{
 | |
| 				$this->_request['w'] = $this->_request['aw'];
 | |
| 			}
 | |
| 
 | |
| 			$key = $options['c'];
 | |
| 			$fit = array(
 | |
| 				'T' => 'top',
 | |
| 				'C' => 'center',
 | |
| 				'B' => 'bottom',
 | |
| 				'L' => 'left',
 | |
| 				'R' => 'right'
 | |
| 			);
 | |
| 
 | |
| 			$position = varset($fit[$key],'top');
 | |
| 
 | |
| 			$img->fit(vartrue($this->_request['w'], null), vartrue($this->_request['h'], null), null, $position);
 | |
| 		}
 | |
| 		elseif(!empty($this->_request['w']) || !empty($this->_request['h']))
 | |
| 		{
 | |
| 			$img->resize(vartrue($this->_request['w'], null), vartrue($this->_request['h'], null), function ($constraint)
 | |
| 			{
 | |
| 		        $constraint->aspectRatio();
 | |
| 
 | |
| 		        if(!$this->_upsize)
 | |
| 				{
 | |
| 		            $constraint->upsize();
 | |
| 				}
 | |
| 
 | |
| 			});
 | |
| 		}
 | |
| 		elseif(!empty($this->_request['ah']) || !empty($this->_request['aw']))
 | |
| 		{
 | |
| 			$img->fit(vartrue($this->_request['aw'], null), vartrue($this->_request['ah'], null), null, 'top');
 | |
| 		}
 | |
| 
 | |
| 		/*
 | |
| 			todo watermark support. @see http://image.intervention.io/api/text
 | |
| 			todo also @see: http://image.intervention.io/api/insert
 | |
| 		*/
 | |
| 
 | |
| 
 | |
| 		$img->save($cache_filename, $this->_thumbQuality, $thumbnfo['extension']);
 | |
| 
 | |
| 		$this->_request = array(); // reset the request.
 | |
| 
 | |
| 		if($this->_debug === true) // return the cache file path for testing.
 | |
| 		{
 | |
| 			return $cache_filename;
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		$imageData = $img->encode($thumbnfo['extension'], $this->_thumbQuality);
 | |
| 		$thumbnfo['fsize'] = strlen($imageData);
 | |
| 
 | |
| 		$this->sendHeaders($thumbnfo);
 | |
| 		echo $imageData;
 | |
| 
 | |
| 		exit;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
| 	protected function sendImageOld() // for reference. - can be removed at a later date.
 | |
| 	{
 | |
| 
 | |
| 		if($this->_placeholder == true)
 | |
| 		{
 | |
| 			$width = ($this->_request['aw']) ? $this->_request['aw'] : $this->_request['w'];
 | |
| 			$height = ($this->_request['ah']) ? $this->_request['ah'] : $this->_request['h'];
 | |
| 
 | |
| 			$parm = array('size' => $width."x".$height);
 | |
| 
 | |
| 			$this->placeholder($parm);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		if(!$this->_src_path)
 | |
| 		{
 | |
| 			echo "no source";
 | |
| 			return $this;
 | |
| 		}
 | |
| 
 | |
| 		$thumbnfo = pathinfo($this->_src_path);
 | |
| 		$options = $this->getRequestOptions();
 | |
| 		$fname = e107::getParser()->thumbCacheFile($this->_src_path, $options);
 | |
| 		$cache_filename = e_CACHE_IMAGE . $fname;
 | |
| 
 | |
| 		$this->sendCachedImage($cache_filename,$thumbnfo);
 | |
| 
 | |
| 		require_once(e_HANDLER.'phpthumb/ThumbLib.inc.php');
 | |
| 
 | |
| 		if(!$thumb = PhpThumbFactory::create($this->_src_path))
 | |
| 		{
 | |
| 			if(getperms('0'))
 | |
| 			{
 | |
| 				echo "Couldn't load thumb factory";
 | |
| 			}
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		$sizeUp = ((isset($this->_request['w']) && $this->_request['w'] > 110) || (isset($this->_request['aw']) && ($this->_request['aw'] > 110))); // don't resizeUp the icon images.
 | |
| 	   	$thumb->setOptions(array(
 | |
| 		   	    'correctPermissions'    => true,
 | |
| 		   	    'resizeUp'              => $sizeUp,
 | |
| 		   	    'jpegQuality'           => $this->_thumbQuality,
 | |
| 			    'interlace'             => true // improves performance
 | |
| 		    ));
 | |
| 
 | |
| 
 | |
| 		// Image Cropping by Quadrant.
 | |
| 		if(!empty($options['c'])) // $quadrant T(op), B(ottom), C(enter), L(eft), R(right)
 | |
| 		{
 | |
| 			if(!empty($this->_request['ah']))
 | |
| 			{
 | |
| 				$this->_request['h'] = $this->_request['ah'];
 | |
| 			}
 | |
| 
 | |
| 			if(!empty($this->_request['aw']))
 | |
| 			{
 | |
| 				$this->_request['w'] = $this->_request['aw'];
 | |
| 			}
 | |
| 
 | |
| 
 | |
| 
 | |
| 			$thumb->adaptiveResizeQuadrant((integer) vartrue($this->_request['w'], 0), (integer) vartrue($this->_request['h'], 0), $options['c']);
 | |
| 		}
 | |
| 		if(isset($this->_request['w']) || isset($this->_request['h']))
 | |
| 		{
 | |
| 			$thumb->resize((integer) vartrue($this->_request['w'], 0), (integer) vartrue($this->_request['h'], 0));
 | |
| 		}
 | |
| 		elseif(!empty($this->_request['ah']))
 | |
| 		{
 | |
| 			//Typically gives a better result with images of people than adaptiveResize().
 | |
| 			$thumb->adaptiveResizeQuadrant((integer) vartrue($this->_request['aw'], 0), (integer) vartrue($this->_request['ah'], 0), 'T');
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$thumb->adaptiveResize((integer) vartrue($this->_request['aw'], 0), (integer) vartrue($this->_request['ah'], 0));
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		if($this->_debug === true)
 | |
| 		{
 | |
| 			// echo "time: ".round((microtime(true) - $start),4);
 | |
| 
 | |
| 			var_dump($thumb);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// Watermark Option - See admin->MediaManager->prefs for details.
 | |
| 
 | |
| 	/	if(($this->_watermark['activate'] < $options['w']
 | |
| 		|| $this->_watermark['activate'] < $options['aw']
 | |
| 		|| $this->_watermark['activate'] < $options['h']
 | |
| 		|| $this->_watermark['activate'] < $options['ah']
 | |
| 		) && $this->_watermark['activate'] > 0 && $this->_watermark['font'] !='')
 | |
| 		{
 | |
| 			$tp = e107::getParser();
 | |
| 			$this->_watermark['font'] = $tp->createConstants($this->_watermark['font'], 'mix');
 | |
| 			$this->_watermark['font'] =  realpath($tp->replaceConstants($this->_watermark['font'],'rel'));
 | |
| 
 | |
| 		//	$thumb->WatermarkText($this->_watermark); // failing due to phpThumb::
 | |
| 		}
 | |
| 		//	echo "hello";
 | |
| 
 | |
| 
 | |
| 		// set cache
 | |
| 		$thumb->save($cache_filename);
 | |
| 
 | |
| 		$this->_request = array(); // reset the request.
 | |
| 
 | |
| 		if($this->_debug === true) // return the cache file path for testing.
 | |
| 		{
 | |
| 			return $cache_filename;
 | |
| 		}
 | |
| 
 | |
| 		// show thumb
 | |
| 		$thumb->show();
 | |
| 
 | |
| 		return $this;
 | |
| 	}
 | |
| */
 | |
| 
 | |
| 	/**
 | |
| 	 * When caching is enabled, send the cached image with headers and then exit the script.
 | |
| 	 * @param string $cache_filename
 | |
| 	 * @param array $thumbnfo
 | |
| 	 * @return null
 | |
| 	 */
 | |
| 	private function sendCachedImage($cache_filename, $thumbnfo)
 | |
| 	{
 | |
| 		if(!$this->_cache || !is_file($cache_filename) || !is_readable($cache_filename) || $this->_debug)
 | |
| 		{
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		$thumbnfo['lmodified'] = filemtime($cache_filename);
 | |
| 		$thumbnfo['md5s'] = md5_file($cache_filename);
 | |
| 		$thumbnfo['fsize'] = filesize($cache_filename);
 | |
| 
 | |
| 			// Send required headers
 | |
| 		if($this->_debug !== true)
 | |
| 		{
 | |
| 			$this->sendHeaders($thumbnfo);
 | |
| 		}
 | |
| 
 | |
| 		// check browser cache
 | |
| 		if (@$_SERVER['HTTP_IF_MODIFIED_SINCE'] && ($thumbnfo['lmodified'] <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) && (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $thumbnfo['md5s']))
 | |
| 		{
 | |
| 			header('HTTP/1.1 304 Not Modified');
 | |
| 			//$bench->end()->logResult('thumb.php', $_GET['src'].' - 304 not modified');
 | |
| 			exit;
 | |
| 		}
 | |
| 
 | |
| 		eShims::readfile($cache_filename);
 | |
| 
 | |
| 		exit;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return array
 | |
| 	 */
 | |
| 	private function getRequestOptions()
 | |
| 	{
 | |
| 		$ret = array();
 | |
| 		$ret['w'] = isset($this->_request['w']) ? intval($this->_request['w']) : false;
 | |
| 		$ret['h'] = isset($this->_request['h']) ? intval($this->_request['h']) : $ret['w'];
 | |
| 		$ret['aw'] = isset($this->_request['aw']) ? intval($this->_request['aw']) : false;
 | |
| 		$ret['ah'] = isset($this->_request['ah']) ? intval($this->_request['ah']) : $ret['aw'];
 | |
| 		$ret['c'] = isset($this->_request['c']) ? strtoupper(substr(e107::getParser()->filter($this->_request['c'], 'str'),0,1)) : false;
 | |
| 	//	$ret['wm'] = isset($this->_request['wm']) ? intval($this->_request['wm']) : $ret['wm'];
 | |
| 
 | |
| 		if($ret['c'] == 'A') // auto
 | |
| 		{
 | |
| 			$ret['c'] = 'T'; // default is 'Top';
 | |
| 		}
 | |
| 
 | |
| 		if(!empty($this->_request['type']))
 | |
| 		{
 | |
| 			$ret['type'] = $this->_request['type'];
 | |
| 		}
 | |
| 		elseif($this->_forceWebP)
 | |
| 		{
 | |
| 			$ret['type'] = 'webp'; 
 | |
| 		}
 | |
| 
 | |
| 		return $ret;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $thumbnfo
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	private function sendHeaders($thumbnfo)
 | |
| 	{
 | |
| 
 | |
| 		if(headers_sent($filename, $linenum))
 | |
| 		{
 | |
| 			echo 'Headers already sent in '.$filename.' on line '.$linenum;
 | |
| 			exit;
 | |
| 		}
 | |
| 
 | |
| 		if (function_exists('date_default_timezone_set'))
 | |
| 		{
 | |
| 		    date_default_timezone_set('UTC');
 | |
| 		}
 | |
| 
 | |
| 		header('Cache-Control: must-revalidate');
 | |
| 
 | |
| 		if(isset($thumbnfo['lmodified']))
 | |
| 		{
 | |
| 			header('Last-Modified: '.gmdate('D, d M Y H:i:s', $thumbnfo['lmodified']).' GMT');
 | |
| 		}
 | |
| 
 | |
| 		if(isset($thumbnfo['fsize'])) // extra check, if empty image will fail.
 | |
| 		{
 | |
| 			header('Content-Length: '.$thumbnfo['fsize']);
 | |
| 		}
 | |
| 
 | |
| 		header('Content-Disposition: filename='.$thumbnfo['basename']); // important for right-click save-as.
 | |
| 
 | |
| 		$ctype = $this->ctype($thumbnfo['extension']);
 | |
| 		if(null !== $ctype)
 | |
| 		{
 | |
| 			header('Content-Type: '.$ctype);
 | |
| 		}
 | |
| 
 | |
| 		// Expire header - 1 year
 | |
| 		$time = time() + 365 * 86400;
 | |
| 		header('Expires: '.gmdate("D, d M Y H:i:s", $time).' GMT');
 | |
| 
 | |
| 		if(isset($thumbnfo['md5s']))
 | |
| 		{
 | |
| 			header("Etag: ".$thumbnfo['md5s']);
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $ftype
 | |
| 	 * @return mixed|string|null
 | |
| 	 */
 | |
| 	private function ctype($ftype)
 | |
| 	{
 | |
| 		static $known_types = array(
 | |
| 			'gif'  => 'image/gif',
 | |
| 			'jpg'  => 'image/jpeg',
 | |
| 			'jpeg' => 'image/jpeg',
 | |
| 			'png'  => 'image/png',
 | |
| 			'webp'  => 'image/webp',
 | |
| 			//'bmp'  => 'image/bmp',
 | |
| 		);
 | |
| 
 | |
| 		$ftype = strtolower($ftype);
 | |
| 		if(isset($known_types[$ftype]))
 | |
| 		{
 | |
| 			return $known_types[$ftype];
 | |
| 		}
 | |
| 		return null;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	// Display a placeholder image.
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $parm
 | |
| 	 * @return void|null
 | |
| 	 */
 | |
| 	private function placeholder($parm)
 | |
| 	{
 | |
| 		if($this->_debug === true)
 | |
| 		{
 | |
| 			echo "Placeholder activated";
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		$getsize = $parm['size'] ?? '100x100';
 | |
| 
 | |
| 		header('location: https://placehold.co/'.$getsize);
 | |
| 		header('Content-Length: 0');
 | |
| 		exit();
 | |
| 	}
 | |
| 
 | |
| 
 | |
| }
 |