Делаем свой список желаний (избранные продукты)

2013-10-11
5.0 / 5 (4 голоса)

Сегодня хотелось бы поделится с вами результатами разработки дополнения для virtuemart 1.x, а именно - "список избранных товаров". Что это такое и зачем он вообще нужен? Это просто одна из полезных функций интернет-магазина, когда пользователю понравился какой-либо товар, но прям сейчас он его не готов купить. А добавив его в избранное, он всегда сможет к нему вернутся и не потерять его в разнообразии вашего ассортимента.

Задача стояла в следующем: "Сделать единый список товаров добавленных в избранное, без каких либо наворотов."

1 Редактируем карточку товара

Самое первое, что необходимо сделать - это отредактировать карточку товара и добавить собственно ссылку "В избранное".

componens\com_virtuemart\themes\default\templates\product_details\flypage.tpl.php

В начало файла инклудим файл обработки, о нём немного дальше

include_once "administrator".DS."components".DS."com_virtuemart".DS."html".DS."favorites.add.php";

 Дальше, в удобное место вставляем отображение ссылки. Тут же проверяем авторизирован пользователь, если нет выдаём ему форму авторизации

<?php      
      if (!ps_favorites::CheckAuthorization()) {
        echo 'Добавить в <a href="#login" title="Для добавления в избранное, необходимо авторизоваться" class="wishlist_button fancy">избранное  </a>'; //Отобразится модульное окно авторизации
      } elseif (favorites_check_add($product_id)) {
        echo 'Уже добавлено в <a href="/index.php?option=com_virtuemart&Itemid=28&lang=ru&page=favorites.index" title="">избранное</a>';
      } else {
				favorites_show_button($product_id,$category_id,$page);
        echo '<div class="favorites_add">Добавить в <a class="wishlist_button" title="Добавить в избранное" href="#"> избранное </a></div>';
      }
      ?>

2 Рабочая часть

Теперь необходимо создать новый класс, а также файлы обработки

Создаем файл, с названием класса ps_favorites, в нём будут функции непосредственно работающие с базой (обновление, удаление, получение данных)

\administrator\components\com_virtuemart\classes\ps_favorites.php

<?php
if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
/*
* @version 1.0
* @cписок желаний для VirtueMart 1.x
* @copyright by GAAlferov 2013
* http://gaalferov.com
*/
class ps_favorites {

	function FavoritesAdd (&$d) { /* Добавление товара в избранные */
      global $db, $my, $vmInputFilter; //глобальные переменные virtuemart
      $d = $vmInputFilter->safeSQL( $d );
      $this->CheckTable();
      if ($this->CheckAuthorization()) {
				if ($this->CheckFavoritesAdd($d)) {
					$q = " INSERT INTO `#__{vm}_favorites` ";
					$q .= " (`id`, `user_id`, `product_id`, `created`) VALUES ";
					$q .= " ( NULL, '" . $my->id . "', '" . $d['product_id'] . "', NOW() )";
					$result = $db->query( $q );
					echo "Товар успешно добавлен в избранное.<br>";
					return true;
				}
      }
		return false;
	}
	function FavoritesDelete (&$d) { /* Удаление товара из избранного */
      global $db, $vmInputFilter; 
      $d = $vmInputFilter->safeSQL( $d );
      $this->CheckTable();
      if ($this->CheckAuthorization()) {
					$q = " DELETE FROM `#__{vm}_favorites` ";
					$q .= " WHERE id =".$d['favorites_id'];
					$result = $db->query( $q );
					return true;
      }
		return false;
	}
  
	/*Получение списка избранных таворов, а также их атрибутов */
  function get_favorites_list($user_id) {
    global $db,$vmInputFilter;
		$user_id = $vmInputFilter->safeSQL( $user_id );

		$q = '  SELECT * FROM `#__{vm}_favorites` fav
						JOIN #__vm_product prod ON fav.product_id = prod.product_id
						JOIN #__vm_product_price prodprice ON prod.product_id = prodprice.product_id
						JOIN #__vm_product_category_xref prodcat ON prod.product_id = prodcat.product_id
						WHERE fav.`user_id` = ' . $user_id. ' ';
		$db->query( $q );
		if ($db->loadAssocList())
		{
			return $db->loadAssocList();
		}
    return false;
  }
	
  /*Проверка, есть ли вообще таблица*/
  function CheckTable() {
      global $db;
      $q = "CREATE TABLE IF NOT EXISTS `#__{vm}_favorites` (
          `id` int(11) NOT NULL AUTO_INCREMENT,
          `user_id` int(11) NOT NULL,
          `product_id` int(11) NOT NULL,
          `created` datetime NOT NULL,
          PRIMARY KEY (`id`)
          ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";
      $db->query( $q );
    return true;
  }
  
  /*Проверка авторизирован пользователь или нет*/
  function CheckAuthorization() {
      global $my;
      if ((@$_SESSION['auth']['user_id'] != $my->id)  || empty( $my->id ) || ( $my->id == 0))
      {
        return false;
      }
    return true;
  }
  
  /*Проверка. Если товар уже есть в избранном*/
  function CheckFavoritesAdd($d) {
    global $db, $my;
			$q = ' SELECT `id` FROM `#__{vm}_favorites` 
							WHERE `product_id` = ' . $d['product_id']. '
							AND `user_id` = ' . $my->id . ' ';
			$db->query( $q );
			if ($db->loadResult())
			{
				return false;
			}
    return true;
  }
	
  
}
?>

 Теперь добавим два вспомогательных файла.

administrator\components\com_virtuemart\html\favorites.add.php (вывод кнопки добавления в избранное + проверка добавлен ли товар в избранное)

<?php
if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
/*
* @version 1.0
* @cписок желаний для VirtueMart 1.x
* @copyright by GAAlferov 2013
* http://gaalferov.com
*/

mm_showMyFileName( __FILE__ );

/* Подключаем класс обработки */
require_once(CLASSPATH . 'ps_favorites.php' );

function favorites_show_button( $product_id, $category_id, $page) { // Показать ссылку на добавление товара в избранное
	echo '<form action="'.URL.'index.php?page=' . $page . '&product_id=' . $product_id . '&category_id=' . $category_id . '&option=com_virtuemart&Itemid=' . $GLOBALS['sess']->getShopItemid() . '" method="post" name="favoritesadd" id="favoritesadd">';
	echo '<input type="hidden" name="quantity" value="1">';
	echo '<input type="hidden" name="page" value="' . $page . '" />';
	echo '<input type="hidden" name="product_id" value="' . $product_id . '" />';
	echo '<input type="hidden" name="category_id" value="' . $category_id . '" />';
	echo '<input type="hidden" name="func" value="favoritesadd" />';
	echo '<input type="hidden" name="option" value="' . $GLOBALS['option'] . '" />';
	echo '<input type="hidden" name="Itemid" value="' . $GLOBALS['sess']->getShopItemid() . '" />';
	echo '</form>';
}

function favorites_check_add( $product_id) { // Проверка, добавлен ли товар в избранное
	$d=array("product_id"=>$product_id);
	if (ps_favorites::CheckFavoritesAdd($d)){
		return false; //Товар ещё не добавлен в избранные
	}
	return true; //Товар добавлен в избранные
}
?>

 administrator\components\com_virtuemart\html\favorites.index.php (вывод списка избранного в кабинете пользователя)

<?php
if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
/*
* @version 1.0
* @cписок желаний для VirtueMart 1.x
* @copyright by GAAlferov 2013
* http://gaalferov.com
*/

mm_showMyFileName( __FILE__ );

/* Подключаем классы */
require_once(CLASSPATH . 'ps_favorites.php' );
require_once(CLASSPATH . 'ps_product.php' );


// Путь (хлебные крошки)
$pathway = array();
$pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_ACCOUNT_TITLE'), $sess->url( SECUREURL .'index.php?page=account.index' ) );
$pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_FAVORITES_TITLE') );
$vm_mainframe->vmAppendPathway( $pathway );


//Получаем id пользователя
if (intval( JRequest::getInt('uid'))) {
	$user_id = intval( JRequest::getInt('uid'));
} else {
	global $my;
	$user_id = $my->id;
}


$output = ''; //В данной переменной будет всё содержимое
show_favorites_list( $output, $user_id); //Вызов функции формирования списка избранных товаров
echo $output;


function show_favorites_list( &$output, $user_id)
{
	$favories_item_list = '';
	$document = JFactory::getDocument();
  $document->setTitle($GLOBALS['VM_LANG']->_('PHPSHOP_FAVORITES_TITLE'));
	
	$favorites_list = ps_favorites::get_favorites_list( $user_id );
	if ($favorites_list) {
		foreach ($favorites_list as $all_item) 
		{
			$base_url = 'index.php?option=com_virtuemart&Itemid='.$GLOBALS['sess']->getShopItemid();
			$ps_product = new ps_product();
			$product_image = $ps_product->image_tag( $all_item['product_thumb_image'], "alt=\"" . $all_item['product_name'] . "\"", 1 );
			$product_id = $all_item['product_id'];
			$category_id = $all_item['category_id'];
			$product_url = JRoute::_($base_url . '&page=shop.product_details&flypage=flypage.tpl&category_id='.$category_id.'&product_id='.$product_id);
			$product_name = $all_item['product_name'];
			$product_price = $ps_product->show_price( $product_id );
			$addtocart_link = $base_url . '&page=shop.cart';
			$uniqid = uniqid('addtocart_');
			$product_in_stock = $all_item['product_in_stock'];
			$remove_link = $base_url . '&page=favorites.index&func=FavoritesDelete&favorites_id='.$all_item['id'];
			
			//Проверка остатка товара
			if( CHECK_STOCK == '1' && !$product_in_stock) {
				$notify = true;
			} else {
				$notify = false;
			}
			
			$favories_item_list .= '
							<tr class="wish-row">
								<td>'.$product_image.'</td>
								<td class="leftt">
									<p><a href="'.$product_url.'" title="'.$product_name.'">'.$product_name.'</a></p>
									<p>'.$product_price.'</p>
								</td>
								<td>
									<form action="'.$addtocart_link.'" method="post" name="addtocart" id="'.$uniqid.'" class="addtocart_form left" data-notifi="'.$notify.'">
										<input type="submit" style="background: url('/components/com_virtuemart/themes/images/add-cart-sm.png'); width:24px; height:24px; border:0px; padding:0px; margin:0px;" value="&nbsp;" />
										<input type="hidden" name="func" value="cartAdd" />
										<input type="hidden" name="product_id" value="'.$product_id.'" />
										<input type="hidden" name="category_id" value="'.$category_id.'" />
										<input type="hidden" name="prod_id[]" value="'.$product_id.'" />
										<input type="hidden" name="quantity" value="1" />
									</form>

									<form action="'.$remove_link.'" method="post" class="left">
										<input type="submit" style="background: url('/components/com_virtuemart/themes/default/images/remove_from_cart.png'); width:17px; height:16px; border:0px; padding:0px; margin:0px;" value="&nbsp;" />
									</form>
								</td>
							<tr>';
		}
	}
	
	$to_output = '<div class="b_article-f box-shadow">
									<h1><span>'.$GLOBALS["VM_LANG"]->_("PHPSHOP_FAVORITES_TITLE").'</span></h1>
									<table cellpadding="0" cellspacing="0" border="0" width="100%" class="bigbasket">
										<thead>
											<tr>
												<th class="leftt">Изображение</th>
												<th>Описание</th>
												<th>Действия</th>
											</tr>
										</thead>
										<tbody>
											'.$favories_item_list.'
										</tbody>
									</table>
								</div>';
	
	$output .= $to_output;
	return true;
}
?>

И в конце необходимо создать новую таблицу, модуль, и добавить две функции в virtuemart

-- Create new table
CREATE TABLE IF NOT EXISTS `gaa_vm_favorites` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `product_id` int(11) NOT NULL,
  `created` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- Add new module
INSERT INTO `gaa_vm_module` (`module_id`, `module_name`, `module_description`, `module_perms`, `module_publish`, `list_order`) VALUES
(NULL, 'favorites', 'Избранные товары', 'shopper,adder,storeadmin,admin,none', 'Y', 14);

-- Add new function
INSERT INTO `gaa_vm_function` (`function_id`, `module_id`, `function_name`, `function_class`, `function_method`, `function_description`, `function_perms`) VALUES
(NULL, 12844, 'favoritesadd', 'ps_favorites', 'favoritesadd', 'Добавить товар в избранное', 'none'),
(NULL, 12844, 'favoritesdelete', 'ps_favorites', 'FavoritesDelete', 'Удалить товар из избранного', 'none');

Конечно же по данному описанию, очень тяжело будет всё повторить начинающему программисту, но такова цель и не преследовалась. Данная информация нужна лишь как помощь программисту, который первый раз пишет хак для virtuemart.

Моменты на которые хотелось бы обратить внимание:

1) Добавление товара происходит с помощью формы, в которой фигурирует такая строка:

<input type="hidden" name="func" value="favoritesadd">

 Что это такое? Эта строка показывает какую функцию в virtuemart использовать, а именно вызывается сначала функция virtuemart - favoritesadd, а с неё идёт указатель, что использовать функцию favoritesadd из класса ps_favorites.

2) Делаем хлебные крошки в админке (favorites.index.php)

// Путь (хлебные крошки)
$pathway = array();
$pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_ACCOUNT_TITLE'), $sess->url( SECUREURL .'index.php?page=account.index' ) );
$pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_FAVORITES_TITLE') );
$vm_mainframe->vmAppendPathway( $pathway );

Ниже вы можете посмотреть как это все выглядит, а также скачать архив со всеми файлами.

Будет вопросы, обращайтесь, помогу чем смогу.

Вот тут это всё работает -> http://air-hobby.ru/

Прочитано 3060 раз Последнее изменение 2015-10-17

1 Комментарий

  • Серега
    Серега 2017-01-04

    А для virtuemart 3 ? есть такое решение?

    У меня готового решения для virtuemart 3 нет, но думаю в интернете можно поискать. Либо пойти на фриланс биржи, там сделают :)

Оставить комментарий

Все поля отмеченные (*) обязательны для заполнения