Jump to content

Recommended Posts

Часто возникает потребность добавить вторые связанные товары, вот одно из решений.

 

1. выполнить запрос в базу

CREATE TABLE `s_self_products` (
  `product_id` int(11) NOT NULL,
  `related_id` int(11) NOT NULL,
  `position` int(11) NOT NULL,
  PRIMARY KEY (`product_id`,`related_id`),
  KEY `position` (`position`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

2. в simpla/design/html/product.tpl после ф-и добавления связанного товара (255 строка примерно) добавляем

// Добавление мост товара 
var new_self_product = $('#new_self_product').clone(true);
$('#new_self_product').remove().removeAttr('id');

$("input#self_products").autocomplete({
	serviceUrl:'ajax/search_products.php',
	minChars:0,
	noCache: false, 
	onSelect:
		function(suggestion){
			$("input#self_products").val('').focus().blur(); 
			new_item = new_self_product.clone().appendTo('.self_products');
			new_item.removeAttr('id');
			new_item.find('a.self_product_name').html(suggestion.data.name);
			new_item.find('a.self_product_name').attr('href', 'index.php?module=ProductAdmin&id='+suggestion.data.id);
			new_item.find('input[name*="self_products"]').val(suggestion.data.id);
			if(suggestion.data.image)
				new_item.find('img.product_icon').attr("src", suggestion.data.image);
			else
				new_item.find('img.product_icon').remove();
			new_item.show();
		},
	formatResult:
		function(suggestions, currentValue){
			var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g');
			var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')';
				return (suggestions.data.image?"<img align=absmiddle src='"+suggestions.data.image+"'> ":'') + suggestions.value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
		}

});

3. в simpla/design/html/product.tpl после ф-и удаления связанного товара (222 строка примерно) добавляем

// Удаление мост товара
$(".self_products a.delete").live('click', function() {
	 $(this).closest("div.row").fadeOut(200, function() { $(this).remove(); });
	 return false;
});

4. в simpla/design/html/product.tpl после блока связанных товаров (736 строка примерно) добавляем

<div class="block layer">
	<h2>С этим товаром покупают</h2>
	<div id=list class="sortable self_products">
		{foreach $self_products as $self_product}
		<div class="row">
			<div class="move cell">
				<div class="move_zone"></div>
			</div>
			<div class="image cell">
			<input type=hidden name=self_products[] value='{$self_product->id}'>
			<a href="{url id=$self_product->id}">
			<img class=product_icon src='{$self_product->images[0]->filename|resize:35:35}'>
			</a>
			</div>
			<div class="name cell">
			<a href="{url id=$self_product->id}">{$self_product->name}</a>
			</div>
			<div class="icons cell">
			<a href='#' class="delete"></a>
			</div>
			<div class="clear"></div>
		</div>
		{/foreach}
		<div id="new_self_product" class="row" style='display:none;'>
			<div class="move cell">
				<div class="move_zone"></div>
			</div>
			<div class="image cell">
			<input type=hidden name=self_products[] value=''>
			<img class=product_icon src=''>
			</div>
			<div class="name cell">
			<a class="self_product_name" href=""></a>
			</div>
			<div class="icons cell">
			<a href='#' class="delete"></a>
			</div>
			<div class="clear"></div>
		</div>
	</div>
	<input type=text name=self id='self_products' class="input_autocomplete" placeholder='Выберите товар чтобы добавить его'>
</div>

5. в simpla/ProductAdmin.php добавить после

$related_products = array();

код

$self_products = array();

6. в том же файле после блока связанных товаров (строка 86) добавляем

// Мост товары
if(is_array($this->request->post('self_products')))
{
	foreach($this->request->post('self_products') as $p)
	{
		$sp[$p] = new stdClass;
		$sp[$p]->product_id = $product->id;
		$sp[$p]->related_id = $p;
	}
	$self_products = $sp;
}

7. ПЕРЕД строкой в том же файле

$query = $this->db->placehold('DELETE FROM __related_products WHERE product_id=?', $product->id);

добавляем новые связанные товары:

// Связанные товары
$query = $this->db->placehold('DELETE FROM __self_products WHERE product_id=?', $product->id);
$this->db->query($query);
    if(is_array($self_products))
{
	$pos = 0;
	foreach($self_products  as $i=>$self_product)
		$this->products->add_self_product($product->id, $self_product->related_id, $pos++);
}

8. в том же файле ПОСЛЕ

$related_products = $this->products->get_related_products(array('product_id'=>$product->id));

добавить

$self_products = $this->products->get_self_products(array('product_id'=>$product->id));

9. в том же файле ПЕРЕД

$this->design->assign('product', $product);

добавляем

if(!empty($self_products))
{
	foreach($self_products as &$s_p)
		$s_products[$s_p->related_id] = &$s_p;
	$temp_products = $this->products->get_products(array('id'=>array_keys($s_products)));
	foreach($temp_products as $temp_product)
		$s_products[$temp_product->id] = $temp_product;

	$self_products_images = $this->products->get_images(array('product_id'=>array_keys($s_products)));
	foreach($self_products_images as $image)
	{
		$s_products[$image->product_id]->images[] = $image;
	}
}

10. в этом же файле ПОСЛЕ

$this->design->assign('related_products', $related_products);

добавим

$this->design->assign('self_products', $self_products);

11. в файл api/Products.php добавить новые ф-и для новых связанных товаров

public function get_self_products($product_id = array())
{
	if(empty($product_id))
		return array();

	$product_id_filter = $this->db->placehold('AND product_id in(?@)', (array)$product_id);
			
	$query = $this->db->placehold("SELECT product_id, related_id, position
				FROM __self_products
				WHERE 
				1
				$product_id_filter   
				ORDER BY position       
				");
	
	$this->db->query($query);
	return $this->db->results();
}

public function add_self_product($product_id, $related_id, $position=0)
{
	$query = $this->db->placehold("INSERT IGNORE INTO __self_products SET product_id=?, related_id=?, position=?", $product_id, $related_id, $position);
	$this->db->query($query);
	return $related_id;
}

public function delete_self_product($product_id, $related_id)
{
	$query = $this->db->placehold("DELETE FROM __self_products WHERE product_id=? AND related_id=? LIMIT 1", intval($product_id), intval($related_id));
	$this->db->query($query);
}

12. в файл api/Products.php в ф-и удаления товара добавляем удаления вторых связанных товаров. ПЕРЕД (329 строка)

$related = $this->get_related_products($id);

добавим

$this->db->query('DELETE FROM __self_products WHERE product_id=?', intval($id));
$this->db->query('DELETE FROM __self_products WHERE related_id=?', intval($id));

13. в файл api/Products.php в функцию дублирования товара ПЕРЕД (примерно 394)

// Дублируем связанные товары

добавляем

$self = $this->get_self_products($id);
foreach($self as $s)
	$this->add_self_product($new_id, $s->related_id); 

 

14. для вывода на сайте в view/ProductView.php ПЕРЕД (строка примерно 101)

// Связанные товары
$related_ids = array();

добавить

// Связанные товары
$self_ids = array();
$self_products = array();
foreach($this->products->get_self_products($product->id) as $p)
{
	$self_ids[] = $p->related_id;
	$self_products[$p->related_id] = null;
}
if(!empty($self_ids))
{
	foreach($this->products->get_products(array('id'=>$self_ids, 'in_stock'=>1, 'visible'=>1)) as $p)
		$self_products[$p->id] = $p;
	
	$self_products_images = $this->products->get_images(array('product_id'=>array_keys($self_products)));
	foreach($self_products_images as $self_product_image)
		if(isset($self_products[$self_product_image->product_id]))
			$self_products[$self_product_image->product_id]->images[] = $self_product_image;
	$self_products_variants = $this->variants->get_variants(array('product_id'=>array_keys($self_products), 'in_stock'=>1));
	foreach($self_products_variants as $self_product_variant)
	{
		if(isset($self_products[$self_product_variant->product_id]))
		{
			$self_products[$self_product_variant->product_id]->variants[] = $self_product_variant;
		}
	}
	foreach($self_products as $id=>$s)
	{
		if(is_object($s))
		{
			$s->image = &$s->images[0];
			$s->variant = &$s->variants[0];
		}
		else
		{
			unset($self_products[$id]);
		}
	}
	$this->design->assign('self_products', $self_products);
}
15. в шаблоне выводить как вам нужно (переменная $self_products) например так:
{if $self_products}
<h2>С товаром покупают</h2>
<!-- Список каталога товаров-->
<ul class="tiny_products">
	{foreach $self_products as $self_product}
	<!-- Товар-->
	<li class="product">
		
		<!-- Фото товара -->
		{if $self_product->image}
		<div class="image">
			<a href="products/{$self_product->url}"><img src="{$self_product->image->filename|resize:200:200}" alt="{$self_product->name|escape}"/></a>
		</div>
		{/if}
		<!-- Фото товара (The End) -->

		<!-- Название товара -->
		<h3><a data-product="{$self_product->id}" href="products/{$self_product->url}">{$self_product->name|escape}</a></h3>
		<!-- Название товара (The End) -->

		{if $self_product->variants|count > 0}
		<!-- Выбор варианта товара -->
		<form class="variants" action="/cart">
			<table>
			{foreach $self_product->variants as $v}
			<tr class="variant">
				<td>
					<input id="self_{$v->id}" name="variant" value="{$v->id}" type="radio" class="variant_radiobutton"  {if $v@first}checked{/if} {if $self_product->variants|count<2} style="display:none;"{/if}/>
				</td>
				<td>
					{if $v->name}<label class="variant_name" for="self_{$v->id}">{$v->name}</label>{/if}
				</td>
				<td>
					{if $v->compare_price > 0}<span class="compare_price">{$v->compare_price|convert}</span>{/if}
					<span class="price">{$v->price|convert} <span class="currency">{$currency->sign|escape}</span></span>
				</td>
			</tr>
			{/foreach}
			</table>
			<input type="submit" class="button" value="в корзину" data-result-text="добавлено"/>
		</form>
		<!-- Выбор варианта товара (The End) -->
		{else}
			Нет в наличии
		{/if}
	</li>
	<!-- Товар (The End)-->
	{/foreach}
</ul>
{/if}

 

Скриншоты:

https://yadi.sk/i/WXrWMlJfp86jm

https://yadi.sk/i/oHtXhCzLp86vy

https://yadi.sk/i/L4welKw1p8DQ8

Edited by mishanya
Link to post
Share on other sites

Круто "респект" возьму на заметку, а есть скриншот как это будет выглядеть после прохождения всей инструкции?

 

выше добавил в конец скриншоты.

Link to post
Share on other sites
  • 2 weeks later...
  • 1 year later...
  • 1 month later...

Делаю всё по инструкции. Однако в базу не добавляет related_id, соответственно связанный товар2 не отображается (из админки ссылка на товар так же идет без id). Подскажите, как выявить проблему и исправить?

 

файлы не могу прикрепить...

Edited by pronin
Link to post
Share on other sites

Делаю всё по инструкции. Однако в базу не добавляет related_id, соответственно связанный товар2 не отображается (из админки ссылка на товар так же идет без id). Подскажите, как выявить проблему и исправить?

 

файлы не могу прикрепить...

 

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

Link to post
Share on other sites

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

Edited by saimon
Link to post
Share on other sites

Чтобы Корс сделал что-то бесплатно, да ещё и такой объем работы? В жизни не поверю.

А Мишаня молодец, много чем помог форуму.

Link to post
Share on other sites

Чтобы Корс сделал что-то бесплатно, да ещё и такой объем работы? В жизни не поверю.

А Мишаня молодец, много чем помог форуму.

Это ты бесплатно ни когда и ни чего. А Корс сделап и БЕСПЛАНО 

Edited by saimon
Link to post
Share on other sites

Чтобы Корс сделал что-то бесплатно, да ещё и такой объем работы? В жизни не поверю.

А Мишаня молодец, много чем помог форуму.

Это для тебя такой объём работы, а оказалось и не так много. И спасибо Мишане, 

Edited by saimon
Link to post
Share on other sites

Это ты бесплатно ни когда и ни чего. А Корс сделап и БЕСПЛАНО

Ты здесь новенький и ничего обо мне не знаешь.

Я принес форуму куда больше пользы чем твой Корс.

Мне кажется ты за бесплатную помощь готов в пятую точку целовать, иначе я не вижу причины так яростно его защищать.

Link to post
Share on other sites
  • 4 weeks later...

Парни, помогите решить проблему, mishanya ушел в игнор (месяц обещал).

Собственно

Делаю всё по инструкции. Однако в базу не добавляет related_id,
соответственно связанный товар2 не отображается (из админки ссылка на
товар так же идет без id). Подскажите, как выявить проблему и исправить?

 

файлы

https://yadi.sk/d/hYepaIwm3HUuJk

Link to post
Share on other sites

Инструкция неявно предполагает, что будет использоваться на последних версиях.

А у Вас, похоже, версия младше 2.3, а там скрипт автодополнения другой, потому и не работает.

Чтобы работало, надо перерабатывать под Вашу версию...

Link to post
Share on other sites
  • 4 weeks later...
  • 3 years later...

Подскажите пожалуйста. Делаю связанные товары в блоге. В админке выводится, но в БД не сохраняет (после нажатия на сохранить, товар есть, а при обновлении страницы его нет)

 

в конец api/Blog.php вставил

  

public function get_self_products_blog($product_id = array())
{
  if(empty($product_id))
    return array();

  $product_id_filter = $this->db->placehold('AND product_id in(?@)', (array)$product_id);
      
  $query = $this->db->placehold("SELECT product_id, related_id, position
        FROM __self_products_blog
        WHERE 
        1
        $product_id_filter   
        ORDER BY position       
        ");
  
  $this->db->query($query);
  return $this->db->results();
}

public function add_self_product_blog($product_id, $related_id, $position=0)
{
  $query = $this->db->placehold("INSERT IGNORE INTO __self_products_blog SET product_id=?, related_id=?, position=?", $product_id, $related_id, $position);
  $this->db->query($query);
  return $related_id;
}

public function delete_self_product_blog($product_id, $related_id)
{
  $query = $this->db->placehold("DELETE FROM __self_products_blog WHERE product_id=? AND related_id=? LIMIT 1", intval($product_id), intval($related_id));
  $this->db->query($query);
}

 

 

и еще ошибку 500 в записи дает, не пойму почему

view/BlogView.php

перед:

    // Соседние записи
    $this->design->assign('next_post', $this->blog->get_next_post($post->id));
    $this->design->assign('prev_post', $this->blog->get_prev_post($post->id));

вставляю:

$self_ids = array();
$self_products_blog = array();
foreach($this->products->get_self_products_blog($product->id) as $p)
{
  $self_ids[] = $p->related_id;
  $self_products_blog[$p->related_id] = null;
}
if(!empty($self_ids))
{
  foreach($this->products->get_products(array('id'=>$self_ids, 'in_stock'=>1, 'visible'=>1)) as $p)
    $self_products_blog[$p->id] = $p;
  
  $self_products_blog_images = $this->products->get_images(array('product_id'=>array_keys($self_products_blog)));
  foreach($self_products_blog_images as $self_product_blog_image)
    if(isset($self_products_blog[$self_product_blog_image->product_id]))
      $self_products_blog[$self_product_blog_image->product_id]->images[] = $self_product_blog_image;
  $self_products_blog_variants = $this->variants->get_variants(array('product_id'=>array_keys($self_products_blog), 'in_stock'=>1));
  foreach($self_products_blog_variants as $self_product_blog_variant)
  {
    if(isset($self_products_blog[$self_product_blog_variant->product_id]))
    {
      $self_products_blog[$self_product_blog_variant->product_id]->variants[] = $self_product_blog_variant;
    }
  }
  foreach($self_products_blog as $id=>$s)
  {
    if(is_object($s))
    {
      $s->image = &$s->images[0];
      $s->variant = &$s->variants[0];
    }
    else
    {
      unset($self_products_blog[$id]);
    }
  }
  $this->design->assign('self_products_blog', $self_products_blog);
}

 

Link to post
Share on other sites

и еще ошибку 500 в записи дает, не пойму почему

С ходу видно, что вызов

foreach($this->products->get_self_products_blog($product->id) as $p)

явно неправильный.

А судя по Вашему подходу, скорее всего, еще масса ошибок есть...

Link to post
Share on other sites

С ходу видно, что вызов

foreach($this->products->get_self_products_blog($product->id) as $p)

явно неправильный.

А судя по Вашему подходу, скорее всего, еще масса ошибок есть...

 

тю, точно))) спасибо за наводку))

убрал ошибку 500.

просмотрел код далее но не вижу причину почему не сохраняет в БД =(

Link to post
Share on other sites

тю, точно))) спасибо за наводку))

убрал ошибку 500.

просмотрел код далее но не вижу причину почему не сохраняет в БД =(

 

Надо ж не по верхам смотреть, а поглубже - проверять, есть ли вообще попытка сохранения и если есть, то каким запросом...

Link to post
Share on other sites

 

Надо ж не по верхам смотреть, а поглубже - проверять, есть ли вообще попытка сохранения и если есть, то каким запросом...

 

а не подскажете как это сделать?

Edited by n1c
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...