Jump to content

Ошибка 500 при обращении к несуществующему изображению


Recommended Posts

Ребят, помогите найти ошибку. На сайте изображения ресайзятся через ImageMagick. Ссылки на изображения без токенов.

Если удалить изображение из товара, и обратиться к нему по той ссылке, по которой оно раньше было доступно, то сервер сваливается с ошибкой 500, а по идее должен либо 404 либо 403 отдавать (?)

Строка 338 это:

if(!$thumb->readImage($src_file))

в функции:

private function image_constrain_imagick($src_file, $dst_file, $max_w, $max_h, $watermark=null, $watermark_offet_x=0, $watermark_offet_y=0, $watermark_opacity=1, $sharpen=0.2, $strict=null)
	{
		$thumb = new Imagick();
		
		// Читаем изображение
		if(!$thumb->readImage($src_file))
			return false;
		
		// Размеры исходного изображения
		$src_w = $thumb->getImageWidth();
		$src_h = $thumb->getImageHeight();
		
		// Нужно ли обрезать?
		if (!$watermark && !$strict && ($src_w <= $max_w) && ($src_h <= $max_h))
	    { 
			// Нет - просто скопируем файл
			if (!copy($src_file, $dst_file))
				return false;
			return true;
	    }	
			
		if ($strict) {
			$thumb->thumbnailImage($max_w, $max_h, true, true);
		} else {
			// Размеры превью при пропорциональном уменьшении
			list($dst_w, $dst_h) = $this->calc_contrain_size($src_w, $src_h, $max_w, $max_h);
		
			// Уменьшаем
			$thumb->thumbnailImage($dst_w, $dst_h);
		}
		
		// Устанавливаем водяной знак
		if($watermark && is_readable($watermark))
		{
			$overlay = new Imagick($watermark);
			
			$overlay->evaluateImage(Imagick::EVALUATE_MULTIPLY, $watermark_opacity, Imagick::CHANNEL_ALPHA);
			
			// Get the size of overlay 
			$owidth = $overlay->getImageWidth(); 
			$oheight = $overlay->getImageHeight();
			
			if ($strict) {
				$watermark_x = min(($max_w-$owidth)*$watermark_offet_x/100, $max_w); 
				$watermark_y = min(($max_h-$oheight)*$watermark_offet_y/100, $max_h); 
			} else {
				$watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/100, $dst_w); 
				$watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/100, $dst_h); 
			}
			
		}
		
		// Убираем комменты и т.п. из картинки
		$thumb->stripImage();

		// Записываем картинку
		if(!$thumb->writeImages($dst_file, true))
			return false;
		
		// Уборка
		$thumb->destroy();
		if(isset($overlay) && is_object($overlay))
			$overlay->destroy();
		
		return true;
	}

Куда копать? Спасибо.

Link to post
Share on other sites
3 часа назад, Dmitry86 сказал:

Ребят, помогите найти ошибку. На сайте изображения ресайзятся через ImageMagick. Ссылки на изображения без токенов.

Если удалить изображение из товара, и обратиться к нему по той ссылке, по которой оно раньше было доступно, то сервер сваливается с ошибкой 500, а по идее должен либо 404 либо 403 отдавать (?)

В логах у меня следующее:


[cgi:error] [pid 16335] [client 188.225.72.35:34894] AH01215:   thrown in /home/username/web/sitename.ru/public_html/api/Image.php on line 338: /home/username/web/sitename.ru/cgi-bin/php, referer: https://webmaster.yandex.ru/...

 

Строка 338 это:


if(!$thumb->readImage($src_file))

в функции:


private function image_constrain_imagick($src_file, $dst_file, $max_w, $max_h, $watermark=null, $watermark_offet_x=0, $watermark_offet_y=0, $watermark_opacity=1, $sharpen=0.2, $strict=null)
	{
		$thumb = new Imagick();
		
		// Читаем изображение
		if(!$thumb->readImage($src_file))
			return false;
		
		// Размеры исходного изображения
		$src_w = $thumb->getImageWidth();
		$src_h = $thumb->getImageHeight();
		
		// Нужно ли обрезать?
		if (!$watermark && !$strict && ($src_w <= $max_w) && ($src_h <= $max_h))
	    { 
			// Нет - просто скопируем файл
			if (!copy($src_file, $dst_file))
				return false;
			return true;
	    }	
			
		if ($strict) {
			$thumb->thumbnailImage($max_w, $max_h, true, true);
		} else {
			// Размеры превью при пропорциональном уменьшении
			list($dst_w, $dst_h) = $this->calc_contrain_size($src_w, $src_h, $max_w, $max_h);
		
			// Уменьшаем
			$thumb->thumbnailImage($dst_w, $dst_h);
		}
		
		// Устанавливаем водяной знак
		if($watermark && is_readable($watermark))
		{
			$overlay = new Imagick($watermark);
			
			$overlay->evaluateImage(Imagick::EVALUATE_MULTIPLY, $watermark_opacity, Imagick::CHANNEL_ALPHA);
			
			// Get the size of overlay 
			$owidth = $overlay->getImageWidth(); 
			$oheight = $overlay->getImageHeight();
			
			if ($strict) {
				$watermark_x = min(($max_w-$owidth)*$watermark_offet_x/100, $max_w); 
				$watermark_y = min(($max_h-$oheight)*$watermark_offet_y/100, $max_h); 
			} else {
				$watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/100, $dst_w); 
				$watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/100, $dst_h); 
			}
			
		}
		
		// Убираем комменты и т.п. из картинки
		$thumb->stripImage();

		// Записываем картинку
		if(!$thumb->writeImages($dst_file, true))
			return false;
		
		// Уборка
		$thumb->destroy();
		if(isset($overlay) && is_object($overlay))
			$overlay->destroy();
		
		return true;
	}

Куда копать? Спасибо.

Киньте сюда ваши фалы api/Image.php, api/Design.php и resize/resize.php

Link to post
Share on other sites

Simpla стандартно в такой ситуации отправляет ответ 200. Так сделано автором.

Если надо иначе, пробуйте менять в resize/resize.php 

if(!$simpla->config->check_token($filename, $token))
    exit('bad token');        
на

if(!$simpla->config->check_token($filename, $token)){
    header("http/1.0 404 not found");
    exit('bad token');        
}

Edited by phukortsin
Link to post
Share on other sites
9 часов назад, alexivchenko сказал:

Киньте сюда ваши фалы api/Image.php, api/Design.php и resize/resize.php

api/Image.php

<?php

/**
 * Simpla CMS
 *
 * @copyright	2011 Denis Pikusov
 * @link		http://simplacms.ru
 * @author		Denis Pikusov
 *
 */

require_once('Simpla.php');

class Image extends Simpla
{
	private	$allowed_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');

	public function __construct()
	{		
		parent::__construct();
	}
	
	
	/**
	 * Создание превью изображения
	 * @param $filename файл с изображением (без пути к файлу)
	 * @param max_w максимальная ширина
	 * @param max_h максимальная высота
	 * @return $string имя файла превью
	 */
	function resize($filename,$brands ='')
	{
		list($source_file, $width , $height, $set_watermark, $strict) = $this->get_resize_params($filename);
        
        $size = ($width?$width:0).'x'.($height?$height:0).($set_watermark?"w":'');
        $image_sizes = array();
        if($this->settings->image_sizes)
            $image_sizes = explode('|',$this->settings->image_sizes);
        if(!in_array($size, $image_sizes)){
            header("http/1.0 404 not found");
            exit();
        }

		// Если вайл удаленный (http://), зальем его себе
		if(substr($source_file, 0, 7) == 'http://' || substr($source_file, 0, 8) == 'https://')
		{	
			// Имя оригинального файла
			if(!$original_file = $this->download_image($source_file))
				return false;
			
			$resized_file = $this->add_resize_params($original_file, $width, $height, $set_watermark, $strict);			
		}	
		else
		{
			$original_file = $source_file;
		}
		
		$resized_file = $this->add_resize_params($original_file, $width, $height, $set_watermark, $strict);			
		
	
		
		// Пути к папкам с картинками
        if($brands){
            $originals_dir = $this->config->root_dir.$this->config->brands_images_dir;
            $preview_dir = $this->config->root_dir.$this->config->brands_m_images_dir;
        }else{
    		$originals_dir = $this->config->root_dir.$this->config->original_images_dir;
    		$preview_dir = $this->config->root_dir.$this->config->resized_images_dir;
		}

		
		$watermark_offet_x = $this->settings->watermark_offset_x;
		$watermark_offet_y = $this->settings->watermark_offset_y;
		
		$sharpen = min(100, $this->settings->images_sharpen)/100;
		$watermark_transparency =  1-min(100, $this->settings->watermark_transparency)/100;
	
	
		if($set_watermark && is_file($this->config->watermark_file))
			$watermark = $this->config->root_dir.$this->config->watermark_file;
		else
			$watermark = null;

		if(class_exists('Imagick') && $this->config->use_imagick)
			$this->image_constrain_imagick($originals_dir.$original_file, $preview_dir.$resized_file, $width, $height, $watermark, $watermark_offet_x, $watermark_offet_y, $watermark_transparency, $sharpen, $strict);
		else
			$this->image_constrain_gd($originals_dir.$original_file, $preview_dir.$resized_file, $width, $height, $watermark, $watermark_offet_x, $watermark_offet_y, $watermark_transparency, $strict);
		
		return $preview_dir.$resized_file;
	}

	public function add_resize_params($filename, $width=0, $height=0, $set_watermark=false, $strict=false)
	{
		if('.' != ($dirname = pathinfo($filename,  PATHINFO_DIRNAME)))
			$file = $dirname.'/'.pathinfo($filename, PATHINFO_FILENAME);
		else
			$file = pathinfo($filename, PATHINFO_FILENAME);
		$ext = pathinfo($filename, PATHINFO_EXTENSION);
	
		if($width>0 || $height>0)
			$resized_filename = $file.'.'.($width>0?$width:'').'x'.($height>0?$height:'').($set_watermark?'w':'').($strict?'s':'').'.'.$ext;
		else
			$resized_filename = $file.'.'.($set_watermark?'w':'').($strict?'s':'').'.'.$ext;
			
		return $resized_filename;
	}

	public function get_resize_params($filename)
	{
		// Определаяем параметры ресайза
		if(!preg_match('/(.+)\.([0-9]*)x([0-9]*)(w|s|ws)?\.([^\.]+)$/', $filename, $matches))
			return false;
			
		$file = $matches[1];					// имя запрашиваемого файла
		$width = $matches[2];					// ширина будущего изображения
		$height = $matches[3];					// высота будущего изображения
		if ($matches[4] == 'w') {
			$set_watermark = true;
		} elseif ($matches[4] == 's') {
			$strict = true;
		} elseif ($matches[4] =='ws') {
			$set_watermark = true;
			$strict = true;
		}
		$ext = $matches[5];						// расширение файла
			
		return array($file.'.'.$ext, $width, $height, $set_watermark, $strict);
	}
	
	
	public function download_image($filename)
	{
		// Заливаем только есть такой файл есть в базе
		$this->db->query('SELECT 1 FROM __images WHERE filename=? LIMIT 1', $filename);
		if(!$this->db->result())
			return false;
		
		
		// Имя оригинального файла
		$uploaded_file = array_shift(explode('?', pathinfo($filename, PATHINFO_BASENAME)));
		$uploaded_file = array_shift(explode('&', pathinfo($filename, PATHINFO_BASENAME)));
		$base = urldecode(pathinfo($uploaded_file, PATHINFO_FILENAME));
		$ext = pathinfo($uploaded_file, PATHINFO_EXTENSION);
		
		// Если такой файл существует, нужно придумать другое название
		//$new_name = urldecode($uploaded_file);
        $new_name = strtolower(uniqid()).'.'.pathinfo($uploaded_file, PATHINFO_EXTENSION);
			
		while(file_exists($this->config->root_dir.$this->config->original_images_dir.$new_name))
		{
			$new_base = pathinfo($new_name, PATHINFO_FILENAME);
			if(preg_match('/_([0-9]+)$/', $new_base, $parts))
				$new_name = $base.'_'.($parts[1]+1).'.'.$ext;
			else
				$new_name = $base.'_1.'.$ext;
		}
		$this->db->query('UPDATE __images SET filename=? WHERE filename=?', $new_name, $filename);
		
		// Перед долгим копированием займем это имя
		fclose(fopen($this->config->root_dir.$this->config->original_images_dir.$new_name, 'w'));
		copy($filename, $this->config->root_dir.$this->config->original_images_dir.$new_name);
		return $new_name;
	}

	public function upload_image($filename, $name)
	{
		// Имя оригинального файла
		$uploaded_file = $new_name = pathinfo($name, PATHINFO_BASENAME);
		$base = pathinfo($uploaded_file, PATHINFO_FILENAME);
		$ext = pathinfo($uploaded_file, PATHINFO_EXTENSION);
		
		if(in_array(strtolower($ext), $this->allowed_extentions))
		{			
			while(file_exists($this->config->root_dir.$this->config->original_images_dir.$new_name))
			{	
				$new_base = pathinfo($new_name, PATHINFO_FILENAME);
				if(preg_match('/_([0-9]+)$/', $new_base, $parts))
					$new_name = $base.'_'.($parts[1]+1).'.'.$ext;
				else
					$new_name = $base.'_1.'.$ext;
			}
			if(move_uploaded_file($filename, $this->config->root_dir.$this->config->original_images_dir.$new_name))			
				return $new_name;
		}

		return false;
	}

	
	/**
	 * Создание превью средствами gd
	 * @param $src_file исходный файл
	 * @param $dst_file файл с результатом
	 * @param max_w максимальная ширина
	 * @param max_h максимальная высота
	 * @return bool
	 */
	private function image_constrain_gd($src_file, $dst_file, $max_w, $max_h, $watermark=null, $watermark_offet_x=0, $watermark_offet_y=0, $watermark_opacity=1, $strict=null)
	{
		$quality = 100;
	
		// Параметры исходного изображения
		@list($src_w, $src_h, $src_type) = array_values(getimagesize($src_file));
		$src_type = image_type_to_mime_type($src_type);	
		
		if(empty($src_w) || empty($src_h) || empty($src_type))
			return false;
	
		// Нужно ли обрезать?
		if (!$watermark && ($src_w <= $max_w) && ($src_h <= $max_h))
	    {
			// Нет - просто скопируем файл
			if (!copy($src_file, $dst_file))
				return false;
			return true;
	    }
				
		// Размеры превью при пропорциональном уменьшении
		@list($dst_w, $dst_h) = $this->calc_contrain_size($src_w, $src_h, $max_w, $max_h);
	
		// Читаем изображение
		switch ($src_type)
		{
		case 'image/jpeg':	
			$src_img = imageCreateFromJpeg($src_file);		
			break;
		case 'image/gif':
			$src_img = imageCreateFromGif($src_file);		
			break;
		case 'image/png':
			$src_img = imageCreateFromPng($src_file);					
			imagealphablending($src_img, true);
			break;
		default:
			return false;
		}
		
		if(empty($src_img))
			return false;
			
		$src_colors = imagecolorstotal($src_img);
		
		// create destination image (indexed, if possible)
		if ($src_colors > 0 && $src_colors <= 256)
			$dst_img = imagecreate($dst_w, $dst_h);
		else
			$dst_img = imagecreatetruecolor($dst_w, $dst_h);
		
		if (empty($dst_img))
			return false;
	
		$transparent_index = imagecolortransparent($src_img);
		if ($transparent_index >= 0 && $transparent_index <= 128)
		{
			$t_c = imagecolorsforindex($src_img, $transparent_index);
			$transparent_index = imagecolorallocate($dst_img, $t_c['red'], $t_c['green'], $t_c['blue']);
			if ($transparent_index === false)
				return false;
			if (!imagefill($dst_img, 0, 0, $transparent_index))
				return false;
			imagecolortransparent($dst_img, $transparent_index);
	    }
	    // or preserve alpha transparency for png
		elseif ($src_type === 'image/png')
	    {
			if (!imagealphablending($dst_img, false))
				return false;
			$transparency = imagecolorallocatealpha($dst_img, 0, 0, 0, 127);
			if (false === $transparency)
				return false;
			if (!imagefill($dst_img, 0, 0, $transparency))
				return false;
			if (!imagesavealpha($dst_img, true))
				return false;
	    }		
			
	    // resample the image with new sizes
		if (!imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $dst_w, $dst_h, $src_w, $src_h))
			return false;	
			
		// Watermark
		if(!empty($watermark) && is_readable($watermark))
		{	
			$overlay = imagecreatefrompng($watermark);
            
			// Get the size of overlay 
			$owidth = imagesx($overlay); 
			$oheight = imagesy($overlay);
			
			$watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/100, $dst_w); 
			$watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/100, $dst_h); 
	
			//imagecopy($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);		
			imagecopymerge($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight, $watermark_opacity*100); 
			
		}	
				
			
		// recalculate quality value for png image
		if ('image/png' === $src_type)
		{
			$quality = round(($quality / 100) * 10);
			if ($quality < 1)
				$quality = 1;
			elseif ($quality > 10)
				$quality = 10;
			$quality = 10 - $quality;
		}
	
		// Сохраняем изображение
		switch ($src_type)
		{
		case 'image/jpeg':	
			return imageJpeg($dst_img, $dst_file, $quality);
		case 'image/gif':
			return imageGif($dst_img, $dst_file, $quality);
		case 'image/png':
			imagesavealpha($dst_img, true);
			return imagePng($dst_img, $dst_file, $quality);
		default:
			return false;
		}
	}
	
	/**
	 * Создание превью средствами imagick
	 * @param $src_file исходный файл
	 * @param $dst_file файл с результатом
	 * @param max_w максимальная ширина
	 * @param max_h максимальная высота
	 * @return bool
	 */
	private function image_constrain_imagick($src_file, $dst_file, $max_w, $max_h, $watermark=null, $watermark_offet_x=0, $watermark_offet_y=0, $watermark_opacity=1, $sharpen=0.2, $strict=null)
	{
		$thumb = new Imagick();
		
		// Читаем изображение
		if(!$thumb->readImage($src_file))
			return false;
		
		// Размеры исходного изображения
		$src_w = $thumb->getImageWidth();
		$src_h = $thumb->getImageHeight();
		
		// Нужно ли обрезать?
		if (!$watermark && !$strict && ($src_w <= $max_w) && ($src_h <= $max_h))
	    { 
			// Нет - просто скопируем файл
			if (!copy($src_file, $dst_file))
				return false;
			return true;
	    }	
			
		if ($strict) {
			$thumb->thumbnailImage($max_w, $max_h, true, true);
		} else {
			// Размеры превью при пропорциональном уменьшении
			list($dst_w, $dst_h) = $this->calc_contrain_size($src_w, $src_h, $max_w, $max_h);
		
			// Уменьшаем
			$thumb->thumbnailImage($dst_w, $dst_h);
		}
		
		// Устанавливаем водяной знак
		if($watermark && is_readable($watermark))
		{
			$overlay = new Imagick($watermark);
			
			$overlay->evaluateImage(Imagick::EVALUATE_MULTIPLY, $watermark_opacity, Imagick::CHANNEL_ALPHA);
			
			// Get the size of overlay 
			$owidth = $overlay->getImageWidth(); 
			$oheight = $overlay->getImageHeight();
			
			if ($strict) {
				$watermark_x = min(($max_w-$owidth)*$watermark_offet_x/100, $max_w); 
				$watermark_y = min(($max_h-$oheight)*$watermark_offet_y/100, $max_h); 
			} else {
				$watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/100, $dst_w); 
				$watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/100, $dst_h); 
			}
			
		}
		
		// Убираем комменты и т.п. из картинки
		$thumb->stripImage();

		// Записываем картинку
		if(!$thumb->writeImages($dst_file, true))
			return false;
		
		// Уборка
		$thumb->destroy();
		if(isset($overlay) && is_object($overlay))
			$overlay->destroy();
		
		return true;
	}
	
	
	/**
	 * Вычисляет размеры изображения, до которых нужно его пропорционально уменьшить, чтобы вписать в квадрат $max_w x $max_h
	 * @param src_w ширина исходного изображения
	 * @param src_h высота исходного изображения
	 * @param max_w максимальная ширина
	 * @param max_h максимальная высота
	 * @return array(w, h)
	 */
	function calc_contrain_size($src_w, $src_h, $max_w = 0, $max_h = 0)
	{
		if($src_w == 0 || $src_h == 0)
			return false;
			
		$dst_w = $src_w;
		$dst_h = $src_h;
	
		if($src_w > $max_w && $max_w>0)
		{
			$dst_h = $src_h * ($max_w/$src_w);
			$dst_w = $max_w;
		}
		if($dst_h > $max_h && $max_h>0)
		{
			$dst_w = $dst_w * ($max_h/$dst_h);
			$dst_h = $max_h;
		}
		return array($dst_w, $dst_h);
	}	
	
	
	private function files_identical($fn1, $fn2)
	{
		$buffer_len = 1024;
	    if(!$fp1 = fopen($fn1, 'rb'))
	        return FALSE;
	
	    if(!$fp2 = fopen($fn2, 'rb')) {
	        fclose($fp1);
	        return FALSE;
	    }
	
	    $same = TRUE;
	    while (!feof($fp1) and !feof($fp2))
	        if(fread($fp1, $buffer_len) !== fread($fp2, $buffer_len)) {
	            $same = FALSE;
	            break;
	        }
	
	    if(feof($fp1) !== feof($fp2))
	        $same = FALSE;
	
	    fclose($fp1);
	    fclose($fp2);
	
	    return $same;
	}
	
	
}

api/Design.php

<?php

/**
 * Simpla CMS
 *
 * @copyright	2011 Denis Pikusov
 * @link		http://simplacms.ru
 * @author		Denis Pikusov
 *
 */
 
require_once('Simpla.php');
require_once('Smarty/libs/Smarty.class.php');

class Design extends Simpla
{
	public $smarty;
    /* mobile */
	public function set_theme($theme) {
    if(is_dir($this->config->root_dir.'/design/'.$theme.'/html')) {
        setcookie('theme', $theme, time()+60*60*24*30, "/");
        return $theme;
    }
    else
        return false;
	}
	 
	public function get_theme() {
	  if(!isset($_COOKIE['theme']) || !is_dir($this->config->root_dir.'/design/'.$_COOKIE['theme'].'/html')) {
		  //$theme = $this->set_theme($this->settings->theme_full);
          if($this->is_mobile_browser())
			  $theme = $this->set_theme($this->settings->theme_mobile);
		  else
			  $theme = $this->set_theme($this->settings->theme_full);
	  }
	  else
		  if(!isset($_SESSION['admin']) && $_COOKIE['theme'] != $this->settings->theme_mobile && $_COOKIE['theme'] != $this->settings->theme_full){
		     // $theme = $this->set_theme($this->settings->theme_full);
              if($this->is_mobile_browser())
    			  $theme = $this->set_theme($this->settings->theme_mobile);
    		  else
    			  $theme = $this->set_theme($this->settings->theme_full);
		  }else
          $theme = $_COOKIE['theme'];
		  /*if($_SERVER['HTTP_X_REAL_IP'] == '188.163.90.254') {
              $theme = $_COOKIE['theme'] = '2021v3';
          }*/
	 
	  return $theme;
	}
	 
	public function get_themes()
	{
		if($handle = opendir('design/')) {
			while(false !== ($file = readdir($handle)))
			{ 
				if(is_dir('design/'.$file) && $file[0] != '.')
				{
					unset($theme);
					$theme->name = $file;
					$themes[] = $theme; 
				} 
			}
			closedir($handle); 
			sort($themes);
		}
		return $themes;
	} 
    /* mobile /*/
	
	public function __construct()
	{
		parent::__construct();

		// Создаем и настраиваем Смарти
		$this->smarty = new Smarty();
		$this->smarty->compile_check = $this->config->smarty_compile_check;
		$this->smarty->caching = $this->config->smarty_caching;
		$this->smarty->cache_lifetime = $this->config->smarty_cache_lifetime;
		$this->smarty->debugging = $this->config->smarty_debugging;
		$this->smarty->error_reporting = E_ALL & ~E_NOTICE;

		// Берем тему из настроек
        /* mobile */
		//$theme = $this->settings->theme;
		$theme = $this->get_theme();
        /* mobile /*/
		

		$this->smarty->compile_dir = $this->config->root_dir.'/compiled/'.$theme;
		$this->smarty->template_dir = $this->config->root_dir.'/design/'.$theme.'/html';		

		// Создаем папку для скомпилированных шаблонов текущей темы
		if(!is_dir($this->smarty->compile_dir))
			mkdir($this->smarty->compile_dir, 0777);
						
		$this->smarty->cache_dir = 'cache';
				
		$this->smarty->registerPlugin('modifier', 'resize', array($this, 'resize_modifier'));		
		$this->smarty->registerPlugin('modifier', 'token', array($this, 'token_modifier'));
		$this->smarty->registerPlugin('modifier', 'plural', array($this, 'plural_modifier'));		
		$this->smarty->registerPlugin('function', 'url', array($this, 'url_modifier'));		
		$this->smarty->registerPlugin('modifier', 'first', array($this, 'first_modifier'));		
		$this->smarty->registerPlugin('modifier', 'cut', array($this, 'cut_modifier'));		
		$this->smarty->registerPlugin('modifier', 'date', array($this, 'date_modifier'));		
		$this->smarty->registerPlugin('modifier', 'time', array($this, 'time_modifier'));		
		
		if($this->config->smarty_html_minify)
			$this->smarty->loadFilter('output', 'trimwhitespace');
	}
	
	public function assign($var, $value)
	{
		return $this->smarty->assign($var, $value);
	}

	public function fetch($template)
	{
		// Передаем в дизайн то, что может понадобиться в нем
		$this->design->assign('config',		$this->config);
		/* mobile */
        //$this->design->assign('settings',	$this->settings);
		$settings = $this->settings;
		$settings->theme = $this->get_theme();
		$this->design->assign('settings', $settings);
		/* mobile /*/
		return $this->smarty->fetch($template);
	}
	
	public function set_templates_dir($dir)
	{
		$this->smarty->template_dir = $dir;			
	}

	public function set_compiled_dir($dir)
	{
		$this->smarty->compile_dir = $dir;
	}
	
	public function get_var($name)
	{
		return $this->smarty->getTemplateVars($name);
	}
	
	private function is_mobile_browser()
	{

		$user_agent = $_SERVER['HTTP_USER_AGENT']; 
		$http_accept = isset($_SERVER['HTTP_ACCEPT'])?$_SERVER['HTTP_ACCEPT']:'';

		if(preg_match('/iPad/i', $user_agent))
			return false;
		
		if(stristr($user_agent, 'windows') && !stristr($user_agent, 'windows ce'))
			return false;
		
		if(preg_match('/windows ce|iemobile|mobile|symbian|mini|wap|pda|psp|up\.browser|up\.link|mmp|midp|phone|pocket/i', $user_agent))
			return true;
	
		if(stristr($http_accept, 'text/vnd.wap.wml') || stristr($http_accept, 'application/vnd.wap.xhtml+xml'))
			return true;
			
		if(!empty($_SERVER['HTTP_X_WAP_PROFILE']) || !empty($_SERVER['HTTP_PROFILE']) || !empty($_SERVER['X-OperaMini-Features']) || !empty($_SERVER['UA-pixels']))
			return true;
	
		$agents = array(
		'acs-'=>'acs-',
		'alav'=>'alav',
		'alca'=>'alca',
		'amoi'=>'amoi',
		'audi'=>'audi',
		'aste'=>'aste',
		'avan'=>'avan',
		'benq'=>'benq',
		'bird'=>'bird',
		'blac'=>'blac',
		'blaz'=>'blaz',
		'brew'=>'brew',
		'cell'=>'cell',
		'cldc'=>'cldc',
		'cmd-'=>'cmd-',
		'dang'=>'dang',
		'doco'=>'doco',
		'eric'=>'eric',
		'hipt'=>'hipt',
		'inno'=>'inno',
		'ipaq'=>'ipaq',
		'java'=>'java',
		'jigs'=>'jigs',
		'kddi'=>'kddi',
		'keji'=>'keji',
		'leno'=>'leno',
		'lg-c'=>'lg-c',
		'lg-d'=>'lg-d',
		'lg-g'=>'lg-g',
		'lge-'=>'lge-',
		'maui'=>'maui',
		'maxo'=>'maxo',
		'midp'=>'midp',
		'mits'=>'mits',
		'mmef'=>'mmef',
		'mobi'=>'mobi',
		'mot-'=>'mot-',
		'moto'=>'moto',
		'mwbp'=>'mwbp',
		'nec-'=>'nec-',
		'newt'=>'newt',
		'noki'=>'noki',
		'opwv'=>'opwv',
		'palm'=>'palm',
		'pana'=>'pana',
		'pant'=>'pant',
		'pdxg'=>'pdxg',
		'phil'=>'phil',
		'play'=>'play',
		'pluc'=>'pluc',
		'port'=>'port',
		'prox'=>'prox',
		'qtek'=>'qtek',
		'qwap'=>'qwap',
		'sage'=>'sage',
		'sams'=>'sams',
		'sany'=>'sany',
		'sch-'=>'sch-',
		'sec-'=>'sec-',
		'send'=>'send',
		'seri'=>'seri',
		'sgh-'=>'sgh-',
		'shar'=>'shar',
		'sie-'=>'sie-',
		'siem'=>'siem',
		'smal'=>'smal',
		'smar'=>'smar',
		'sony'=>'sony',
		'sph-'=>'sph-',
		'symb'=>'symb',
		't-mo'=>'t-mo',
		'teli'=>'teli',
		'tim-'=>'tim-',
		'tosh'=>'tosh',
		'treo'=>'treo',
		'tsm-'=>'tsm-',
		'upg1'=>'upg1',
		'upsi'=>'upsi',
		'vk-v'=>'vk-v',
		'voda'=>'voda',
		'wap-'=>'wap-',
		'wapa'=>'wapa',
		'wapi'=>'wapi',
		'wapp'=>'wapp',
		'wapr'=>'wapr',
		'webc'=>'webc',
		'winw'=>'winw',
		'winw'=>'winw',
		'xda-'=>'xda-'
		);
		
		if(!empty($agents[substr($_SERVER['HTTP_USER_AGENT'], 0, 4)]))
	    	return true;
	}	


	public function resize_modifier($filename, $width=0, $height=0, $first=false, $second=false, $brands=false)
	{
		if ($first == 'w' || $second == 'w')
			$set_watermark = true;
		if ($first == 's' || $second == 's')
			$strict = true;
        
        $size = ($width?$width:0).'x'.($height?$height:0).($set_watermark?"w":'');
        $image_sizes = array();
        if($this->settings->image_sizes)
            $image_sizes = explode('|',$this->settings->image_sizes);
        if(!in_array($size, $image_sizes)){
            $image_sizes[] = $size;
            $this->settings->image_sizes = implode('|',$image_sizes);
        }
		
		$resized_filename = $this->image->add_resize_params($filename, $width, $height, $set_watermark, $strict);
		$resized_filename_encoded = $resized_filename;
		
		if(substr($resized_filename_encoded, 0, 7) == 'http://' || substr($resized_filename_encoded, 0, 8) == 'https://')
			$resized_filename_encoded = rawurlencode($resized_filename_encoded);
		if($brands)
            return $this->config->root_url.'/'.$this->config->brands_m_images_dir.$resized_filename_encoded.'?'.$this->config->token($resized_filename);

		$resized_filename_encoded = rawurlencode($resized_filename_encoded);

		return $this->config->root_url.'/'.$this->config->resized_images_dir.$resized_filename_encoded;//.'?'.$this->config->token($resized_filename);
	}

	public function token_modifier($text)
	{
		return $this->config->token($text);
	}

	public function url_modifier($params)
	{
		if(is_array(reset($params)))
			return $this->request->url(reset($params));
		else
			return $this->request->url($params);
	}

	public function plural_modifier($number, $singular, $plural1, $plural2=null)
	{
		$number = abs($number); 
		if(!empty($plural2))
		{
		$p1 = $number%10;
		$p2 = $number%100;
		if($number == 0)
			return $plural1;
		if($p1==1 && !($p2>=11 && $p2<=19))
			return $singular;
		elseif($p1>=2 && $p1<=4 && !($p2>=11 && $p2<=19))
			return $plural2;
		else
			return $plural1;
		}else
		{
			if($number == 1)
				return $singular;
			else
				return $plural1;
		}
	
	}

	public function first_modifier($params = array())
	{
		if(!is_array($params))
			return false;
		return reset($params);
	}

	public function cut_modifier($array, $num=1)
	{
		if($num>=0)
	    	return array_slice($array, $num, count($array)-$num, true);
	    else
	    	return array_slice($array, 0, count($array)+$num, true);
	}
	
	public function date_modifier($date, $format = null)
	{
		if(empty($date))
			$date = date("Y-m-d");
	    return date(empty($format)?$this->settings->date_format:$format, strtotime($date));
	}
	
	public function time_modifier($date, $format = null)
	{
	    return date(empty($format)?'H:i':$format, strtotime($date));
	}
	
}

resize/resize.php

<?php


chdir('..');
require_once('api/Simpla.php');

$filename = $_GET['file'];
$token = $_GET['token'];
$brands = $_GET['brands'];

$filename = str_replace('%2F', '/', $filename);

//if(substr($filename, 0, 6) == 'http:/')
//	$filename = 'http://'.substr($filename, 6);


$simpla = new Simpla();

/*if(!$simpla->config->check_token($filename, $token))
	exit('bad token');*/		

if($brands)
    $resized_filename =  $simpla->image->resize($filename, $brands);
else
    $resized_filename =  $simpla->image->resize($filename);

	
//$resized_filename =  $simpla->image->resize($filename);
//if(is_readable($resized_filename))
//	header('Location: '.$_SERVER['REQUEST_URI']);

if(is_readable($resized_filename))
{
	header('Content-type: image');
	print file_get_contents($resized_filename);
}

 

Link to post
Share on other sites
2 часа назад, phukortsin сказал:

Simpla стандартно в такой ситуации отправляет ответ 200. Так сделано автором.

Если надо иначе, пробуйте менять в resize/resize.php 

if(!$simpla->config->check_token($filename, $token))
    exit('bad token');        
на

if(!$simpla->config->check_token($filename, $token)){
    header("http/1.0 404 not found");
    exit('bad token');        
}

Странно, но в изначальном решении https://forum.simplacms.ru/topic/8424-убираем-токен-из-адреса-изображения/ этот код закомментирован.... Если его раскомментировать, то несуществующие изображения снова начинают отдавать ответ 200 и "bad token".

 

У меня есть ещё самописный файлик, ресайзер, который на кроне автоматом должен ресайзить изображения для карточек товаров, по которым ещё не прошелся пользователь, выглядит следующим образом:

<?php
//ini_set('display_errors', 1);
chdir(dirname(__FILE__).'/');
require_once('api/Simpla.php');
$simpla = new Simpla();

#############################################
$limit = 20;
//Перед тем как ставить новое значение ресайза - нужно заглянуть в БД в таблицу s_settings и посмотреть переменную image_sizes
//Если в ней нет нового ресайза - нужно его добавить ч-з вертикальную черту, например [current_value]|120x90 иначе ресайз не пройдет
//Эта переменная отображает все используемые размеры в шаблоне клиентской и админки, и соответственно добавленные вручную значения
$size = '1024x768';
$origin_dir = dirname(__FILE__) . '/' . $simpla->config->original_images_dir;
$resize_dir = dirname(__FILE__) . '/' . $simpla->config->resized_images_dir;
#############################################

$query = $simpla->db->placehold(
                                    "SELECT i.id, i.filename 
                                        FROM __images i 
                                        INNER JOIN __products p ON i.product_id=p.id 
                                        WHERE i.id>? AND p.visible=1
                                        ORDER BY i.id 
                                        LIMIT ?", 
                                    intval($simpla->settings->current_resized_id), 
                                    $limit
                                );
$simpla->db->query($query);
$images = $simpla->db->results();
if(empty($images)) {
    $simpla->settings->current_resized_id = 0;
}
foreach($images as $k=>$image) {
    $filename = pathinfo($image->filename, PATHINFO_FILENAME);
    $fileext  = pathinfo($image->filename, PATHINFO_EXTENSION);
    $resized_filename = "$filename.$size.$fileext";
    if(file_exists($origin_dir.$image->filename) && !file_exists($resize_dir.$resized_filename)) {
        $resized_image = $simpla->image->resize($resized_filename);
    }
    $simpla->settings->current_resized_id = $image->id;
    // Тут можно замутить типа интервал между выполнением ресайзов в секундах, чтоб давать серверу отдохнуть и можно попробовать увеличить количество картинок до 15
    /*if($k && $k % 5 == 0) {
        sleep(2);
    }*/
}
exit;

И при попытке его запустить он также сваливается в 500:

[cgi:error] [pid 4180] [client 188.225.72.35:44274] AH01215:   thrown in /home/username/web/sitename.ru/public_html/api/Image.php on line 338: /home/username/web/sitename.ru/cgi-bin/php

Что-то где-то всё равно сломано..

Link to post
Share on other sites
4 часа назад, phukortsin сказал:

Simpla стандартно в такой ситуации отправляет ответ 200. Так сделано автором.

Если надо иначе, пробуйте менять в resize/resize.php 

if(!$simpla->config->check_token($filename, $token))
    exit('bad token');        
на

if(!$simpla->config->check_token($filename, $token)){
    header("http/1.0 404 not found");
    exit('bad token');        
}

Короче, если раскомментировать это, то в админке пропадают все изображения товаров, просто белый фон. И не загружаются новые изображения..

Edited by Dmitry86
Link to post
Share on other sites
1 час назад, Dmitry86 сказал:

Короче, если раскомментировать это, то в админке пропадают все изображения товаров, просто белый фон. И не загружаются новые изображения..

Ошибся. Изображения в админке пропадают из-за настроек в clodflare (потом появляются), а вот новые изображения не ресайзятся..

Link to post
Share on other sites
В 14.04.2023 в 14:07, Dmitry86 сказал:

новые изображения не ресайзятся..

Надо детально анализировать весь процесс именно на Вашем сайте, где к тому же сделано немало изменений по ресайзу. Простой код в пару строк Вам вряд ли подскажут...

Link to post
Share on other sites
1 час назад, phukortsin сказал:

Надо детально анализировать весь процесс именно на Вашем сайте, где к тому же сделано немало изменений по ресайзу. Простой код в пару строк Вам вряд ли подскажут...

Благодарю за ответы, буду разбираться.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...