Files
conservatorio-tomadini/components/com_jem/classes/image.class.php
2024-12-17 17:34:10 +01:00

319 lines
10 KiB
PHP

<?php
/**
* @package JEM
* @copyright (C) 2013-2024 joomlaeventmanager.net
* @copyright (C) 2005-2009 Christoph Lukes
* @license https://www.gnu.org/licenses/gpl-3.0 GNU/GPL
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Language\Text;
require_once(JPATH_SITE.'/components/com_jem/classes/Zebra_Image.php');
/**
* Holds the logic for image manipulation
*
* @package JEM
*/
class JemImage
{
static public function thumb($name,$filename,$new_w,$new_h)
{
// load the image manipulation class
//require 'path/to/Zebra_Image.php';
// create a new instance of the class
$image = new Zebra_Image();
// indicate a source image (a GIF, PNG or JPEG file)
$image->source_path = $name;
// indicate a target image
// note that there's no extra property to set in order to specify the target
// image's type -simply by writing '.jpg' as extension will instruct the script
// to create a 'jpg' file
$image->target_path = $filename;
// since in this example we're going to have a jpeg file, let's set the output
// image's quality (95% has no visible effect but saves some bytes)
$image->jpeg_quality = 95;
// some additional properties that can be set
// read about them in the documentation
$image->preserve_aspect_ratio = true;
$image->enlarge_smaller_images = false;
$image->preserve_time = true;
$image->auto_handle_exif_orientation = true;
// resize the image to at best 100x100 pixels by using the "not boxed" method
// (read more in the overview section or in the documentation)
// and if there is an error, check what the error is about
if (!$image->resize($new_w, $new_h, ZEBRA_IMAGE_NOT_BOXED, -1)) {
//only admins will see these errors
if (Factory::getApplication()->getIdentity()->authorise('core.manage')) {
// if there was an error, let's see what the error is about
switch ($image->error) {
case 1:
Factory::getApplication()->enqueueMessage("Source file $name could not be found!", 'warning');
break;
case 2:
Factory::getApplication()->enqueueMessage("Source file $name is not readable!", 'warning');
break;
case 3:
Factory::getApplication()->enqueueMessage("Could not write target file $filename !", 'warning');
break;
case 4:
Factory::getApplication()->enqueueMessage('Unsupported source file format!', 'warning');
break;
case 5:
Factory::getApplication()->enqueueMessage('Unsupported target file format!', 'warning');
break;
case 6:
Factory::getApplication()->enqueueMessage('GD library version does not support target file format!', 'warning');
break;
case 7:
Factory::getApplication()->enqueueMessage('GD library is not installed!', 'warning');
break;
case 8:
Factory::getApplication()->enqueueMessage('"chmod" command is disabled via configuration', 'warning');
break;
case 9:
Factory::getApplication()->enqueueMessage('"exif_read_data" function is not available', 'warning');
break;
}
}
}
}
/**
* Determine the GD version
* Code from php.net
*
* @param int
*
* @return int
*/
static public function gdVersion($user_ver = 0)
{
if (! extension_loaded('gd')) {
return;
}
static $gd_ver = 0;
// Just accept the specified setting if it's 1.
if ($user_ver == 1) {
$gd_ver = 1;
return 1;
}
// Use the static variable if function was called previously.
if ($user_ver != 2 && $gd_ver > 0) {
return $gd_ver;
}
// Use the gd_info() function if possible.
if (function_exists('gd_info')) {
$ver_info = gd_info();
preg_match('/\d/', $ver_info['GD Version'], $match);
$gd_ver = $match[0];
return $match[0];
}
// If phpinfo() is disabled use a specified / fail-safe choice...
if (preg_match('/phpinfo/', ini_get('disable_functions'))) {
if ($user_ver == 2) {
$gd_ver = 2;
return 2;
} else {
$gd_ver = 1;
return 1;
}
}
// ...otherwise use phpinfo().
ob_start();
phpinfo(8);
$info = ob_get_contents();
ob_end_clean();
$info = stristr($info, 'gd version');
preg_match('/\d/', $info, $match);
$gd_ver = $match[0];
return $match[0];
}
/**
* Creates image information of an image
*
* @param string $image The image name
* @param array $settings
* @param string $type event or venue
*
* @return imagedata if available
*/
static public function flyercreator($image, $type)
{
$settings = JemHelper::config();
if (($settings->imagewidth < 1) || ($settings->imagehight < 1)) {
return false;
}
//define the environment based on the type
if ($type == 'event') {
$folder = 'events';
} else if ($type == 'category') {
$folder = 'categories';
} else if ($type == 'venue') {
$folder = 'venues';
} else {
return false;
}
if ($image) {
$img_orig = 'images/jem/'.$folder.'/'.$image;
$img_thumb = 'images/jem/'.$folder.'/small/'.$image;
$filepath = JPATH_SITE.'/'.$img_orig;
$save = JPATH_SITE.'/'.$img_thumb;
// At least original image must exist
if (!file_exists($filepath)) {
return false;
}
//Create thumbnail if enabled and it does not exist already
if ($settings->gddisabled == 1 && !file_exists($save)) {
JemImage::thumb($filepath, $save, $settings->imagewidth, $settings->imagehight);
}
//set paths
$dimage['original'] = $img_orig;
$dimage['thumb'] = $img_thumb;
//get imagesize of the original
$iminfo = @getimagesize($img_orig);
// and it should be an image
if (!is_array($iminfo) || count($iminfo) < 2) {
return false;
}
//if the width or height is too large this formula will resize them accordingly
if (($iminfo[0] > $settings->imagewidth) || ($iminfo[1] > $settings->imagehight)) {
$iRatioW = $settings->imagewidth / $iminfo[0];
$iRatioH = $settings->imagehight / $iminfo[1];
if ($iRatioW < $iRatioH) {
$dimage['width'] = round($iminfo[0] * $iRatioW);
$dimage['height'] = round($iminfo[1] * $iRatioW);
} else {
$dimage['width'] = round($iminfo[0] * $iRatioH);
$dimage['height'] = round($iminfo[1] * $iRatioH);
}
} else {
$dimage['width'] = $iminfo[0];
$dimage['height'] = $iminfo[1];
}
if (File::exists(JPATH_SITE.'/'.$img_thumb)) {
//get imagesize of the thumbnail
$thumbiminfo = @getimagesize($img_thumb);
$dimage['thumbwidth'] = $thumbiminfo[0];
$dimage['thumbheight'] = $thumbiminfo[1];
}
return $dimage;
}
return false;
}
static public function check($file, $jemsettings)
{
$sizelimit = $jemsettings->sizelimit*1024; //size limit in kb
$imagesize = $file['size'];
$filetypes = $jemsettings->image_filetypes ?: 'jpg,gif,png,webp';
//check if the upload is an image...getimagesize will return false if not
if (!getimagesize($file['tmp_name'])) {
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_UPLOAD_FAILED_NOT_AN_IMAGE').': '.htmlspecialchars($file['name'], ENT_COMPAT, 'UTF-8'), 'warning');
return false;
}
//check if the imagefiletype is valid
$fileext = strtolower(File::getExt($file['name']));
$allowable = explode(',', strtolower($filetypes));
array_walk($allowable, function(&$v){$v = trim($v);});
if (!in_array($fileext, $allowable)) {
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_WRONG_IMAGE_FILE_TYPE').': '.htmlspecialchars($file['name'], ENT_COMPAT, 'UTF-8'), 'warning');
return false;
}
//Check filesize
if ($imagesize > $sizelimit) {
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_IMAGE_FILE_SIZE').': '.htmlspecialchars($file['name'], ENT_COMPAT, 'UTF-8'), 'warning');
return false;
}
//XSS check
//$xss_check = File::read($file['tmp_name'], false, 256);
$xss_check = file_get_contents($file['tmp_name'], false, NULL, 0, 256);
$html_tags = array('abbr','acronym','address','applet','area','audioscope','base','basefont','bdo','bgsound','big','blackface','blink','blockquote','body','bq','br','button','caption','center','cite','code','col','colgroup','comment','custom','dd','del','dfn','dir','div','dl','dt','em','embed','fieldset','fn','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','iframe','ilayer','img','input','ins','isindex','keygen','kbd','label','layer','legend','li','limittext','link','listing','map','marquee','menu','meta','multicol','nobr','noembed','noframes','noscript','nosmartquotes','object','ol','optgroup','option','param','plaintext','pre','rt','ruby','s','samp','script','select','server','shadow','sidebar','small','spacer','span','strike','strong','style','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','ul','var','wbr','xml','xmp','!DOCTYPE', '!--');
foreach ($html_tags as $tag) {
// A tag is '<tagname ', so we need to add < and a space or '<tagname>'
if (stristr($xss_check, '<'.$tag.' ') || stristr($xss_check, '<'.$tag.'>')) {
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_WARN_IE_XSS'), 'warning');
return false;
}
}
return true;
}
/**
* Sanitize the image file name and return an unique string
*
*
* @param string $base_Dir the target directory
* @param string $filename the unsanitized imagefile name
*
* @return string $filename the sanitized and unique image file name
*/
static public function sanitize($base_Dir, $filename)
{
//check for any leading/trailing dots and remove them (trailing shouldn't be possible cause of the getEXT check)
$filename = preg_replace("/^[.]*/", '', $filename);
$filename = preg_replace("/[.]*$/", '', $filename); //shouldn't be necessary, see above
//we need to save the last dot position cause preg_replace will also replace dots
$lastdotpos = strrpos($filename, '.');
//replace invalid characters
$filename = strtolower(preg_replace("/[^0-9a-zA-Z_-]/", '_', $filename));
//get the parts before and after the dot (assuming we have an extension...check was done before)
$beforedot = substr($filename, 0, $lastdotpos);
$afterdot = substr($filename, $lastdotpos + 1);
//make a unique filename for the image and check it is not already taken
//if it is already taken keep trying till success
//$now = time();
$now = rand();
while (File::exists($base_Dir . $beforedot . '_' . $now . '.' . $afterdot)) {
$now++;
}
//create out of the seperated parts the new filename
$filename = $beforedot . '_' . $now . '.' . $afterdot;
return $filename;
}
}
?>