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

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

Друзья, помогите пожалуйста. Всё работает -> фото грузится в папку -> пишется в базу -> выводится на странице товаров.
Но есть проблема с удалением файла из админки. У меня создано дополнение, в виде ответа на комментарий. Собственно это и есть страница comment.tpl

мой api/Comments.php

 

<?php

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

require_once('Simpla.php');

class Comments extends Simpla
{

	// Возвращает комментарий по id
	public function get_comment($id)
	{
		$query = $this->db->placehold("SELECT c.id, c.object_id, c.name, c.image, c.ip, c.type, c.text, c.answer, c.date, c.rate, c.user_id, c.approved FROM __comments c WHERE id=? LIMIT 1", intval($id));

		if($this->db->query($query))
			return $this->db->result();
		else
			return false; 
	}
	
	// Возвращает комментарий по id пользователя
	public function get_comment_by_user($user_id, $product_id)
	{
		$query = $this->db->placehold("SELECT c.id, c.object_id, c.name, c.image, c.ip, c.type, c.text, c.date, c.rate, c.user_id, c.approved FROM __comments c WHERE user_id=? AND object_id=? LIMIT 1", intval($user_id), intval($product_id));

		if($this->db->query($query))
			return $this->db->result();
		else
			return false; 
	}
	
	// Возвращает комментарии, удовлетворяющие фильтру
	public function get_comments($filter = array())
	{	
		// По умолчанию
		$limit = 0;
		$page = 1;
		$object_id_filter = '';
		$type_filter = '';
		$keyword_filter = '';
		$approved_filter = '';

		if(isset($filter['limit']))
			$limit = max(1, intval($filter['limit']));

		if(isset($filter['page']))
			$page = max(1, intval($filter['page']));

		if(isset($filter['ip']))
			$ip = $this->db->placehold("OR c.ip=?", $filter['ip']);
		if(isset($filter['approved']))
			$approved_filter = $this->db->placehold("AND (c.approved=? $ip)", intval($filter['approved']));
			
		if($limit)
			$sql_limit = $this->db->placehold(' LIMIT ?, ? ', ($page-1)*$limit, $limit);
		else
			$sql_limit = '';

		if(!empty($filter['object_id']))
			$object_id_filter = $this->db->placehold('AND c.object_id in(?@)', (array)$filter['object_id']);

		if(!empty($filter['type']))
			$type_filter = $this->db->placehold('AND c.type=?', $filter['type']);

		if(!empty($filter['keyword']))
		{
			$keywords = explode(' ', $filter['keyword']);
			foreach($keywords as $keyword)
				$keyword_filter .= $this->db->placehold('AND c.name LIKE "%'.$this->db->escape(trim($keyword)).'%" OR c.text LIKE "%'.$this->db->escape(trim($keyword)).'%" ');
		}

			
		$sort='DESC';
		
		$query = $this->db->placehold("SELECT c.id, c.object_id, c.ip, c.name, c.image, c.text, c.answer, c.type, c.date, c.approved, c.rate, c.user_id
										FROM __comments c WHERE 1 $object_id_filter $type_filter $keyword_filter $approved_filter ORDER BY id $sort $sql_limit");
	
		$this->db->query($query);
		return $this->db->results();
	}
	
	// Количество комментариев, удовлетворяющих фильтру
	public function count_comments($filter = array())
	{	
		$object_id_filter = '';
		$type_filter = '';
		$approved_filter = '';
		$keyword_filter = '';

		if(!empty($filter['object_id']))
			$object_id_filter = $this->db->placehold('AND c.object_id in(?@)', (array)$filter['object_id']);

		if(!empty($filter['type']))
			$type_filter = $this->db->placehold('AND c.type=?', $filter['type']);

		if(isset($filter['approved']))
			$approved_filter = $this->db->placehold('AND c.approved=?', intval($filter['approved']));

		if(!empty($filter['keyword']))
		{
			$keywords = explode(' ', $filter['keyword']);
			foreach($keywords as $keyword)
				$keyword_filter .= $this->db->placehold('AND c.name LIKE "%'.$this->db->escape(trim($keyword)).'%" OR c.text LIKE "%'.$this->db->escape(trim($keyword)).'%" ');
		}

		$query = $this->db->placehold("SELECT count(distinct c.id) as count
										FROM __comments c WHERE 1 $object_id_filter $type_filter $keyword_filter $approved_filter", $this->settings->date_format);
	
		$this->db->query($query);	
		return $this->db->result('count');

	}
	
	// Добавление комментария
	public function add_comment($comment)
	{	
		$query = $this->db->placehold('INSERT INTO __comments
		SET ?%,
		date = NOW()',
		$comment);

		if(!$this->db->query($query))
			return false;

		$id = $this->db->insert_id();
		return $id;
	}
	
	// Изменение комментария
	public function update_comment($id, $comment)
	{
		$date_query = '';
		if(isset($comment->date))
		{
			$date = $comment->date;
			unset($comment->date);
			$date_query = $this->db->placehold(', date=STR_TO_DATE(?, ?)', $date, $this->settings->date_format);
		}
		$query = $this->db->placehold("UPDATE __comments SET ?% $date_query WHERE id in(?@) LIMIT 1", $comment, (array)$id);
		$this->db->query($query);
		return $id;
	}
	
	// Удаление комментария
	public function delete_comment($id)
	{
		if(!empty($id))
		{
			$query = $this->db->placehold("DELETE FROM __comments WHERE id=? LIMIT 1", intval($id));
			$this->db->query($query);
		}
	}	
	
    public function delete_image($id)
    {
        $id = (array) $id;
        $query = $this->db->placehold("SELECT image FROM __comments WHERE id in(?@)", $id);
        $this->db->query($query);
        $filenames = $this->db->results('image');
        if(!empty($filenames))
        {
            $query = $this->db->placehold("UPDATE __comments SET image=NULL WHERE id in(?@)", $id);
            $this->db->query($query);
            foreach($filenames as $filename)
            {
                $query = $this->db->placehold("SELECT count(*) as count FROM __comments WHERE image=?", $filename);
                $this->db->query($query);
                $count = $this->db->result('count');
                if($count == 0)
                {            
                    @unlink($this->config->root_dir.$this->config->otzuvy_images_dir.$filename);        
                }
            }
        }
    }

}


view/ProductView

 

<?PHP
 
/**
 * Simpla CMS
 *
 * @copyright 	2011 Denis Pikusov
 * @link 		http://simplacms.ru
 * @author 		Denis Pikusov
 *
 * Этот класс использует шаблон product.tpl
 *
 */

require_once('View.php');


class ProductView extends View
{
	private $allowed_image_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico', 'bmp');
	function fetch()
	{   
		$product_url = $this->request->get('product_url', 'string');
		
		if(empty($product_url))
			return false;

		// Выбираем товар из базы
		$product = $this->products->get_product((string)$product_url);
		if(empty($product) || (!$product->visible && empty($_SESSION['admin'])))
			return false;
		
		$product->images = $this->products->get_images(array('product_id'=>$product->id));
		$product->image = reset($product->images);

		$variants = array();
		foreach($this->variants->get_variants(array('product_id'=>$product->id, 'in_stock'=>true)) as $v)
			$variants[$v->id] = $v;
		
		$product->variants = $variants;
		
		// Вариант по умолчанию
		if(($v_id = $this->request->get('variant', 'integer'))>0 && isset($variants[$v_id]))
			$product->variant = $variants[$v_id];
		else
			$product->variant = reset($variants);
					
		$product->features = $this->features->get_product_options(array('product_id'=>$product->id));
            $temp_options = array();
            foreach($product->features as $option) {
                if(empty($temp_options[$option->feature_id]))
                    $temp_options[$option->feature_id] = new stdClass;                  
               $temp_options[$option->feature_id]->feature_id = $option->feature_id;
               $temp_options[$option->feature_id]->name = $option->name;
               $temp_options[$option->feature_id]->values[] = $option->value;  
            }
                   
            foreach($temp_options as $id => $option)
               $temp_options[$id]->value = implode(', ', $temp_options[$id]->values);            
                       
            $product->features = $temp_options;
	
		// Автозаполнение имени для формы комментария
		if(!empty($this->user))
			$this->design->assign('comment_name', $this->user->name);

		// Если были отзывы от текущего пользователя
		if(!empty($this->user)) {
			$query = $this->db->placehold("SELECT c.approved, c.rate, c.name, c.text FROM __comments c WHERE object_id=? AND user_id=? LIMIT 1", $product->id, $this->user->id);
			
			if($this->db->query($query)) {
				if($result = $this->db->result())
					$this->user->comment = $result;
			}
		}
		
		// Принимаем комментарий
		if ($this->request->method('post') && $this->request->post('comment_add'))
		{
			$comment = new stdClass;
			$comment->rate 	  = $this->request->post('rate');
			$comment->name 	  = $this->request->post('name');
			$comment->text 	  = $this->request->post('text');
			$comment->user_id = $this->user->id;
			
			// Передадим комментарий обратно в шаблон - при ошибке нужно будет заполнить форму
			$this->design->assign('comment_rate', $comment->rate);
			$this->design->assign('comment_text', $comment->text);
			$this->design->assign('comment_name', $comment->name);
			
			// Проверяем заполнение формы
			if (empty($comment->name))
			{
				$this->design->assign('error', 'empty_name');
			}
			elseif (empty($comment->text))
			{
				$this->design->assign('error', 'empty_comment');
			}
			else
			{
				// Создаем комментарий
				$comment->object_id = $product->id;
				$comment->type      = 'product';
				$comment->ip        = $_SERVER['REMOTE_ADDR'];
				
				// Добавляем комментарий в базу
				$comment_id = $this->comments->add_comment($comment);
				
				// Загрузка изображения
				$image = $this->request->files('image');
				if(!empty($image['name']) && in_array(strtolower(pathinfo($image['name'], PATHINFO_EXTENSION)), $this->allowed_image_extentions))
				{
					move_uploaded_file($image['tmp_name'], $this->root_dir.$this->config->otzuvy_images_dir.$image['name']);
					$this->comments->update_comment($comment_id, array('image'=>$image['name']));
				}
				// Отправляем email
				$this->notify->email_comment_admin($comment_id);				
				
				// Приберем сохраненную капчу, иначе можно отключить загрузку рисунков и постить старую
				unset($_SESSION['captcha_code']);
				header('location: '.$_SERVER['REQUEST_URI'].'#comments');
			}			
		}
		
		// Редактируем комментарий
		if ($this->request->method('post') && $this->request->post('comment_edit'))
		{
			$comment = $this->comments->get_comment_by_user($this->user->id, $product->id);

			if ( $comment->object_id == $product->id ) {
				if($comment->approved == 1) {
					// Убираем рейтинг
					$this->products->decrease_rate_product(intval($comment->object_id), intval($comment->rate));
					$comment->approved = 0;
				}
				
				unset($comment->date);
				$comment->rate 	  = $this->request->post('rate');
				$comment->name 	  = $this->request->post('name');
				$comment->text 	  = $this->request->post('text');
				//$comment->user_id = $this->user->id;
				
				// Передадим комментарий обратно в шаблон - при ошибке нужно будет заполнить форму
				$this->design->assign('comment_rate', $rate);
				$this->design->assign('comment_text', $comment->text);
				$this->design->assign('comment_name', $comment->name);
				
				// Проверяем заполнение формы
				if (empty($comment->rate))
					$this->design->assign('error', 'empty_rate');
				elseif (empty($comment->name))
					$this->design->assign('error', 'empty_name');
				elseif (empty($comment->text))
					$this->design->assign('error', 'empty_comment');
				else
				{
					// Обновляем комментарий в базе
					$comment_id = $this->comments->update_comment($comment->id, $comment);
					
					// Отправляем email
					$this->notify->email_comment_admin($comment_id);				
					
					// Приберем сохраненную капчу, иначе можно отключить загрузку рисунков и постить старую
					//unset($_SESSION['captcha_code']);
					header('location: '.$_SERVER['REQUEST_URI'].'#comments');
				}
			} else {
				$this->design->assign('error', 'wtf');
			}	
			

		}	
		
		// Связанные товары
		$related_ids = array();
		$related_products = array();
		foreach($this->products->get_related_products($product->id) as $p)
		{
			$related_ids[] = $p->related_id;
			$related_products[$p->related_id] = null;
		}
		if(!empty($related_ids))
		{
			foreach($this->products->get_products(array('id'=>$related_ids, 'in_stock'=>1, 'visible'=>1)) as $p)
				$related_products[$p->id] = $p;
			
			$related_products_images = $this->products->get_images(array('product_id'=>array_keys($related_products)));
			foreach($related_products_images as $related_product_image)
				if(isset($related_products[$related_product_image->product_id]))
					$related_products[$related_product_image->product_id]->images[] = $related_product_image;
			$related_products_variants = $this->variants->get_variants(array('product_id'=>array_keys($related_products), 'in_stock'=>1));
			foreach($related_products_variants as $related_product_variant)
			{
				if(isset($related_products[$related_product_variant->product_id]))
				{
					$related_products[$related_product_variant->product_id]->variants[] = $related_product_variant;
				}
			}
			foreach($related_products as $id=>$r)
			{
				if(is_object($r))
				{
					$r->image = &$r->images[0];
					$r->variant = &$r->variants[0];
				}
				else
				{
					unset($related_products[$id]);
				}
			}
			
			// Категория товара
			$related_products_categories = $this->categories->get_product_categories(array_keys($related_products));
			foreach($related_products_categories as $cat)
				$related_products[$cat->product_id]->category = $this->categories->get_category((int)$cat->category_id);
				
			$this->design->assign('related_products', $related_products);
			$files = $this->files->get_files(array('object_id'=>$product->id,'type'=>'product'));
			$this->design->assign('cms_files', $files); 
		}

		// Отзывы о товаре
		$comments = $this->comments->get_comments(array('type'=>'product', 'object_id'=>$product->id, 'approved'=>1, 'ip'=>''));
		
		// Соседние товары
		$this->design->assign('next_product', $this->products->get_next_product($product->id));
		$this->design->assign('prev_product', $this->products->get_prev_product($product->id));

		// И передаем его в шаблон
		$this->design->assign('product', $product);
		$this->design->assign('comments', $comments);
		
		// Категория и бренд товара
		$product->categories = $this->categories->get_categories(array('product_id'=>$product->id));
		$this->design->assign('brand', $this->brands->get_brand(intval($product->brand_id)));		
		$this->design->assign('category', reset($product->categories));		
		

		// Добавление в историю просмотров товаров
		$max_visited_products = 100; // Максимальное число хранимых товаров в истории
		$expire = time()+60*60*24*30; // Время жизни - 30 дней
		if(!empty($_COOKIE['browsed_products']))
		{
			$browsed_products = explode(',', $_COOKIE['browsed_products']);
			// Удалим текущий товар, если он был
			if(($exists = array_search($product->id, $browsed_products)) !== false)
				unset($browsed_products[$exists]);
		}
		// Добавим текущий товар
		$browsed_products[] = $product->id;
		$cookie_val = implode(',', array_slice($browsed_products, -$max_visited_products, $max_visited_products));
		setcookie("browsed_products", $cookie_val, $expire, "/");
		
		$this->design->assign('meta_title', $product->meta_title);
		$this->design->assign('meta_keywords', $product->meta_keywords);
		$this->design->assign('meta_description', $product->meta_description);
		
		return $this->design->fetch('product.tpl');
	}
	


}


simpla/desin/html/comment.tpl

 

{* Вкладки *}
{capture name=tabs}
	<li class="active"><a href="index.php?module=CommentsAdmin">Комментарии</a></li>
	{if in_array('feedbacks', $manager->permissions)}<li><a href="index.php?module=FeedbacksAdmin">Обратная связь</a></li>{/if}
	{if in_array('reviews', $manager->permissions)}<li><a href="index.php?module=ReviewsAdmin">Отзывы</a></li>{/if}
{/capture}

{literal}
<script>
$(function() {
	$(".images a.delete").click( function() {
		$("input[name='delete_image']").val('1');
		$(this).closest("ul").fadeOut(200, function() { $(this).remove(); });
		return false;
	});
});
</script>
{/literal}

{if $delivery->id}
{$meta_title = 'Комментарий от $comment->name' scope=parent}
{else}
{$meta_title = '...' scope=parent}
{/if}

{literal}
<script src="design/js/jquery/jquery.js"></script>
<script src="design/js/jquery/jquery-ui.min.js"></script>
{/literal}


{if $message_success == 'added'}
	{if $smarty.get.return}
		<script>
			window.location.href = "{$smarty.get.return}";
		</script>
	{/if}
{/if}
	
<!-- Основная форма -->
<form method=post id=product enctype="multipart/form-data">

<input type=hidden name="session_id" value="{$smarty.session.id}">
<input name=id type="hidden" value="{$comment->id}"/> 

	<div id="name">
		<h2>Комментарий</h2>
		{$comment->text|escape|nl2br}
		<div class="checkbox">
			<input name=approved value='1' type="checkbox" id="active_checkbox" {if $comment->approved}checked{/if}/> <label for="active_checkbox">Одобрен</label>
		</div>
	</div> 

	<!-- Описагние товара -->
	<div class="block layer">
		<h2>Ответ</h2>	
		
		<textarea name="answer" style="width: 100%; min-height: 120px;">{$comment->answer|escape|nl2br}</textarea>
	</div>
	<!-- Описание товара (The End)-->
	          
	<input type=hidden name="delete_image" value="">
	{if $comment->image}
	<ul>
		<li>
			<a href='#' class="delete"><img src='design/images/cross-circle-frame.png'></a>
			<img src="../{$config->otzuvy_images_dir}{$comment->image}" alt="" />
		</li>
	</ul>
	{/if}
					
	<input class="button_green button_save" type="submit" name="" value="Сохранить" />
	
</form>
<!-- Основная форма (The End) -->



Может кто поможет решить проблему? 8 часов сижу и не могу исправить =(

Изменено пользователем Chudo
Ссылка на сообщение
Поделиться на другие сайты
  • 3 года спустя...

Так себе решение - разрешать пользователю закачивать картинку проверяя только расширение файла. Ничто не мешает мне в заголовок jpg встроить пхп код, а скорее всего папку с оригиналами отзывов не закрыли через .htaccess, то я смогу обратиться к картинке выполнив пхп код. https://www.securitylab.ru/analytics/472887.php Почитайте.

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

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

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

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

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

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

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

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

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

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