Jump to content

Recommended Posts

Друзья, помогите пожалуйста. Всё работает -> фото грузится в папку -> пишется в базу -> выводится на странице товаров.
Но есть проблема с удалением файла из админки. У меня создано дополнение, в виде ответа на комментарий. Собственно это и есть страница 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 часов сижу и не могу исправить =(

Edited by Chudo
Link to post
Share on other sites
  • 3 years later...

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

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...