Перейти к содержанию
Официальный форум поддержки Simpla

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


Рекомендуемые сообщения

Ребят, помогите найти ошибку. На сайте изображения ресайзятся через 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;
	}

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

Ссылка на сообщение
Поделиться на другие сайты
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

Ссылка на сообщение
Поделиться на другие сайты

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');        
}

Изменено пользователем phukortsin
Ссылка на сообщение
Поделиться на другие сайты
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);
}

 

Ссылка на сообщение
Поделиться на другие сайты
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

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

Ссылка на сообщение
Поделиться на другие сайты
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');        
}

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

Изменено пользователем Dmitry86
Ссылка на сообщение
Поделиться на другие сайты
1 час назад, Dmitry86 сказал:

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

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

Ссылка на сообщение
Поделиться на другие сайты
В 14.04.2023 в 14:07, Dmitry86 сказал:

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

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

Ссылка на сообщение
Поделиться на другие сайты
1 час назад, phukortsin сказал:

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

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

Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...